From 4a466f4927c7f83ca43f5f80abcea71cd3f73961 Mon Sep 17 00:00:00 2001 From: Moony Date: Fri, 4 Mar 2022 13:48:01 -0600 Subject: [PATCH] Explosion refactor TEST MERG (#6995) * Explosions * fix yaml typo and prevent silly UI inputs * oop Co-authored-by: ElectroJr --- .../SpawnExplosion/ExplosionDebugOverlay.cs | 185 ++++++ .../UI/SpawnExplosion/SpawnExplosionEui.cs | 75 +++ .../SpawnExplosion/SpawnExplosionWindow.xaml | 46 ++ .../SpawnExplosionWindow.xaml.cs | 142 +++++ Content.Client/Entry/IgnoredComponents.cs | 1 + Content.Client/Explosion/ExplosionOverlay.cs | 120 ++++ .../Explosion/ExplosionOverlaySystem.cs | 190 ++++++ Content.Server/AME/AMENodeGroup.cs | 11 +- .../Administration/AdminVerbSystem.cs | 6 +- .../Commands/ExplosionCommand.cs | 142 ++++- .../Administration/UI/SpawnExplosionEui.cs | 39 ++ .../Atmos/Components/GasTankComponent.cs | 4 +- .../Atmos/EntitySystems/AirtightSystem.cs | 3 + .../ExplosionReactionEffect.cs | 90 ++- .../Destructible/DestructibleSystem.cs | 38 ++ .../Thresholds/Behaviors/ExplodeBehavior.cs | 2 +- .../Components/ExplosionLaunchedComponent.cs | 42 +- .../ExplosionResistanceComponent.cs | 30 + .../Components/ExplosiveComponent.cs | 77 ++- .../EntitySystems/ExplosionSystem.Airtight.cs | 141 ++++ .../EntitySystems/ExplosionSystem.GridMap.cs | 438 +++++++++++++ .../ExplosionSystem.Processing.cs | 569 +++++++++++++++++ .../EntitySystems/ExplosionSystem.TileFill.cs | 334 ++++++++++ .../EntitySystems/ExplosionSystem.cs | 600 +++++++----------- .../EntitySystems/ExplosionSystem.cvars.cs | 44 ++ .../Explosion/EntitySystems/GridExplosion.cs | 311 +++++++++ .../Explosion/EntitySystems/SpaceExplosion.cs | 157 +++++ .../Explosion/EntitySystems/TileExplosion.cs | 116 ++++ .../Explosion/EntitySystems/TriggerSystem.cs | 24 +- .../EntitySystems/NodeGroupSystem.cs | 9 +- Content.Server/Nuke/NukeComponent.cs | 51 +- Content.Server/Nuke/NukeSystem.cs | 25 +- .../Components/RoguePointingArrowComponent.cs | 4 - .../EntitySystems/RoguePointingSystem.cs | 9 +- Content.Server/PowerCell/PowerCellSystem.cs | 6 +- .../Components/EntityStorageComponent.cs | 20 +- .../Components/ServerStorageComponent.cs | 26 +- Content.Shared/Acts/ActSystem.cs | 40 +- .../Administration/SpawnExplosionEuiMsg.cs | 52 ++ Content.Shared/CCVar/CCVars.cs | 79 +++ .../Damage/Components/DamageableComponent.cs | 23 +- Content.Shared/Explosion/ExplosionEvents.cs | 81 +++ .../Explosion/ExplosionPrototype.cs | 89 +++ Content.Shared/FixedPoint/FixedPoint2.cs | 5 + .../Inventory/InventoryComponent.cs | 30 +- .../Inventory/InventorySystem.Relay.cs | 5 +- Resources/Audio/Effects/explosion1.ogg | Bin 20834 -> 32032 bytes Resources/Audio/Effects/explosion2.ogg | Bin 21899 -> 32735 bytes .../ui/admin-spawn-explosion-eui.ftl | 16 + .../Entities/Clothing/Head/helmets.yml | 2 + .../Entities/Clothing/OuterClothing/suits.yml | 6 +- .../Entities/Effects/explosion_light.yml | 9 + .../Entities/Objects/Devices/nuke.yml | 5 + .../Entities/Objects/Power/powercells.yml | 2 + .../Entities/Objects/Tools/gas_tanks.yml | 3 + .../Weapons/Guns/Projectiles/meteors.yml | 12 +- .../Weapons/Guns/Projectiles/projectiles.yml | 21 +- .../Objects/Weapons/Throwable/grenades.yml | 23 +- .../Structures/Power/Generation/ame.yml | 4 + .../Entities/Structures/Power/substation.yml | 8 +- .../Storage/Closets/Lockers/lockers.yml | 2 + .../Structures/Storage/Tanks/tanks.yml | 8 +- .../Entities/Structures/Walls/barricades.yml | 1 - .../Entities/Structures/Walls/girder.yml | 3 - .../Recipes/Reactions/chemicals.yml | 12 +- .../Recipes/Reactions/pyrotechnic.yml | 10 +- Resources/Prototypes/explosion.yml | 39 ++ .../Textures/Effects/fire_greyscale.rsi/1.png | Bin 0 -> 62870 bytes .../Textures/Effects/fire_greyscale.rsi/2.png | Bin 0 -> 110683 bytes .../Textures/Effects/fire_greyscale.rsi/3.png | Bin 0 -> 18528 bytes .../Effects/fire_greyscale.rsi/meta.json | 1 + 71 files changed, 3958 insertions(+), 760 deletions(-) create mode 100644 Content.Client/Administration/UI/SpawnExplosion/ExplosionDebugOverlay.cs create mode 100644 Content.Client/Administration/UI/SpawnExplosion/SpawnExplosionEui.cs create mode 100644 Content.Client/Administration/UI/SpawnExplosion/SpawnExplosionWindow.xaml create mode 100644 Content.Client/Administration/UI/SpawnExplosion/SpawnExplosionWindow.xaml.cs create mode 100644 Content.Client/Explosion/ExplosionOverlay.cs create mode 100644 Content.Client/Explosion/ExplosionOverlaySystem.cs create mode 100644 Content.Server/Administration/UI/SpawnExplosionEui.cs create mode 100644 Content.Server/Explosion/Components/ExplosionResistanceComponent.cs create mode 100644 Content.Server/Explosion/EntitySystems/ExplosionSystem.Airtight.cs create mode 100644 Content.Server/Explosion/EntitySystems/ExplosionSystem.GridMap.cs create mode 100644 Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs create mode 100644 Content.Server/Explosion/EntitySystems/ExplosionSystem.TileFill.cs create mode 100644 Content.Server/Explosion/EntitySystems/ExplosionSystem.cvars.cs create mode 100644 Content.Server/Explosion/EntitySystems/GridExplosion.cs create mode 100644 Content.Server/Explosion/EntitySystems/SpaceExplosion.cs create mode 100644 Content.Server/Explosion/EntitySystems/TileExplosion.cs create mode 100644 Content.Shared/Administration/SpawnExplosionEuiMsg.cs create mode 100644 Content.Shared/Explosion/ExplosionEvents.cs create mode 100644 Content.Shared/Explosion/ExplosionPrototype.cs create mode 100644 Resources/Locale/en-US/administration/ui/admin-spawn-explosion-eui.ftl create mode 100644 Resources/Prototypes/Entities/Effects/explosion_light.yml create mode 100644 Resources/Prototypes/explosion.yml create mode 100644 Resources/Textures/Effects/fire_greyscale.rsi/1.png create mode 100644 Resources/Textures/Effects/fire_greyscale.rsi/2.png create mode 100644 Resources/Textures/Effects/fire_greyscale.rsi/3.png create mode 100644 Resources/Textures/Effects/fire_greyscale.rsi/meta.json diff --git a/Content.Client/Administration/UI/SpawnExplosion/ExplosionDebugOverlay.cs b/Content.Client/Administration/UI/SpawnExplosion/ExplosionDebugOverlay.cs new file mode 100644 index 0000000000..e6e18d994a --- /dev/null +++ b/Content.Client/Administration/UI/SpawnExplosion/ExplosionDebugOverlay.cs @@ -0,0 +1,185 @@ +using JetBrains.Annotations; +using Robust.Client.Graphics; +using Robust.Client.ResourceManagement; +using Robust.Shared.Enums; +using Robust.Shared.Map; +using System.Linq; + +namespace Content.Client.Administration.UI.SpawnExplosion; + +[UsedImplicitly] +public sealed class ExplosionDebugOverlay : Overlay +{ + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly IEyeManager _eyeManager = default!; + [Dependency] private readonly IMapManager _mapManager = default!; + + public Dictionary>? SpaceTiles; + public Dictionary>> Tiles = new(); + public List Intensity = new(); + public float TotalIntensity; + public float Slope; + + public override OverlaySpace Space => OverlaySpace.WorldSpace | OverlaySpace.ScreenSpace; + + public Matrix3 SpaceMatrix; + public MapId Map; + + private readonly Font _font; + + public ExplosionDebugOverlay() + { + IoCManager.InjectDependencies(this); + + var cache = IoCManager.Resolve(); + _font = new VectorFont(cache.GetResource("/Fonts/NotoSans/NotoSans-Regular.ttf"), 8); + } + + protected override void Draw(in OverlayDrawArgs args) + { + if (Map != _eyeManager.CurrentMap) + return; + + if (Tiles.Count == 0 && SpaceTiles == null) + return; + + switch (args.Space) + { + case OverlaySpace.ScreenSpace: + DrawScreen(args); + break; + case OverlaySpace.WorldSpace: + DrawWorld(args); + break; + } + } + + private void DrawScreen(OverlayDrawArgs args) + { + var handle = args.ScreenHandle; + Box2 gridBounds; + + foreach (var (gridId, tileSets) in Tiles) + { + if (!_mapManager.TryGetGrid(gridId, out var grid)) + continue; + + var gridXform = _entityManager.GetComponent(grid.GridEntityId); + gridBounds = gridXform.InvWorldMatrix.TransformBox(args.WorldBounds); + + DrawText(handle, gridBounds, gridXform.WorldMatrix, tileSets); + } + + if (SpaceTiles == null) + return; + + gridBounds = Matrix3.Invert(SpaceMatrix).TransformBox(args.WorldBounds); + + DrawText(handle, gridBounds, SpaceMatrix, SpaceTiles); + } + + private void DrawText( + DrawingHandleScreen handle, + Box2 gridBounds, + Matrix3 transform, + Dictionary> tileSets) + { + for (var i = 1; i < Intensity.Count; i++) + { + if (!tileSets.TryGetValue(i, out var tiles)) + continue; + + foreach (var tile in tiles) + { + // is the center of this tile visible to the user? + if (!gridBounds.Contains((Vector2) tile + 0.5f)) + continue; + + var worldCenter = transform.Transform((Vector2) tile + 0.5f); + + var screenCenter = _eyeManager.WorldToScreen(worldCenter); + + if (Intensity![i] > 9) + screenCenter += (-12, -8); + else + screenCenter += (-8, -8); + + handle.DrawString(_font, screenCenter, Intensity![i].ToString("F2")); + } + } + + if (tileSets.ContainsKey(0)) + { + var epicenter = tileSets[0].First(); + var worldCenter = transform.Transform((Vector2) epicenter + 0.5f); + var screenCenter = _eyeManager.WorldToScreen(worldCenter) + (-24, -24); + var text = $"{Intensity![0]:F2}\nΣ={TotalIntensity:F1}\nΔ={Slope:F1}"; + handle.DrawString(_font, screenCenter, text); + } + } + + private void DrawWorld(in OverlayDrawArgs args) + { + var handle = args.WorldHandle; + Box2 gridBounds; + + foreach (var (gridId, tileSets) in Tiles) + { + if (!_mapManager.TryGetGrid(gridId, out var grid)) + continue; + + var gridXform = _entityManager.GetComponent(grid.GridEntityId); + handle.SetTransform(gridXform.WorldMatrix); + gridBounds = gridXform.InvWorldMatrix.TransformBox(args.WorldBounds); + + DrawTiles(handle, gridBounds, tileSets); + } + + if (SpaceTiles == null) + return; + + gridBounds = Matrix3.Invert(SpaceMatrix).TransformBox(args.WorldBounds); + handle.SetTransform(SpaceMatrix); + + DrawTiles(handle, gridBounds, SpaceTiles); + } + + private void DrawTiles( + DrawingHandleWorld handle, + Box2 gridBounds, + Dictionary> tileSets) + { + for (var i = 0; i < Intensity.Count; i++) + { + var color = ColorMap(Intensity![i]); + var colorTransparent = color; + colorTransparent.A = 0.2f; + + + if (!tileSets.TryGetValue(i, out var tiles)) + continue; + + foreach (var tile in tiles) + { + // is the center of this tile visible to the user? + if (!gridBounds.Contains((Vector2) tile + 0.5f)) + continue; + + var box = Box2.UnitCentered.Translated((Vector2) tile + 0.5f); + handle.DrawRect(box, color, false); + handle.DrawRect(box, colorTransparent); + } + } + } + + private Color ColorMap(float intensity) + { + var frac = 1 - intensity / Intensity![0]; + Color result; + if (frac < 0.5f) + result = Color.InterpolateBetween(Color.Red, Color.Orange, frac * 2); + else + result = Color.InterpolateBetween(Color.Orange, Color.Yellow, (frac - 0.5f) * 2); + return result; + } +} diff --git a/Content.Client/Administration/UI/SpawnExplosion/SpawnExplosionEui.cs b/Content.Client/Administration/UI/SpawnExplosion/SpawnExplosionEui.cs new file mode 100644 index 0000000000..7bcfb3b069 --- /dev/null +++ b/Content.Client/Administration/UI/SpawnExplosion/SpawnExplosionEui.cs @@ -0,0 +1,75 @@ +using Content.Client.Eui; +using Content.Shared.Administration; +using Content.Shared.Eui; +using JetBrains.Annotations; +using Robust.Client.Graphics; +using Robust.Shared.Map; + +namespace Content.Client.Administration.UI.SpawnExplosion; + +[UsedImplicitly] +public sealed class SpawnExplosionEui : BaseEui +{ + [Dependency] private readonly IOverlayManager _overlayManager = default!; + + private readonly SpawnExplosionWindow _window; + private ExplosionDebugOverlay? _debugOverlay; + + public SpawnExplosionEui() + { + IoCManager.InjectDependencies(this); + _window = new SpawnExplosionWindow(this); + _window.OnClose += () => SendMessage(new SpawnExplosionEuiMsg.Close()); + } + + public override void Opened() + { + base.Opened(); + _window.OpenCentered(); + } + + public override void Closed() + { + base.Closed(); + _window.OnClose -= () => SendMessage(new SpawnExplosionEuiMsg.Close()); + _window.Close(); + ClearOverlay(); + } + + public void ClearOverlay() + { + if (_overlayManager.HasOverlay()) + _overlayManager.RemoveOverlay(); + _debugOverlay = null; + } + + public void RequestPreviewData(MapCoordinates epicenter, string typeId, float totalIntensity, float intensitySlope, float maxIntensity) + { + var msg = new SpawnExplosionEuiMsg.PreviewRequest(epicenter, typeId, totalIntensity, intensitySlope, maxIntensity); + SendMessage(msg); + } + + /// + /// Receive explosion preview data and add a client-side explosion preview overlay + /// + /// + public override void HandleMessage(EuiMessageBase msg) + { + if (msg is not SpawnExplosionEuiMsg.PreviewData data) + return; + + if (_debugOverlay == null) + { + _debugOverlay = new(); + _overlayManager.AddOverlay(_debugOverlay); + } + + _debugOverlay.Tiles = data.Explosion.Tiles; + _debugOverlay.SpaceTiles = data.Explosion.SpaceTiles; + _debugOverlay.Intensity = data.Explosion.Intensity; + _debugOverlay.Slope = data.Slope; + _debugOverlay.TotalIntensity = data.TotalIntensity; + _debugOverlay.Map = data.Explosion.Epicenter.MapId; + _debugOverlay.SpaceMatrix = data.Explosion.SpaceMatrix; + } +} diff --git a/Content.Client/Administration/UI/SpawnExplosion/SpawnExplosionWindow.xaml b/Content.Client/Administration/UI/SpawnExplosion/SpawnExplosionWindow.xaml new file mode 100644 index 0000000000..f1dcd35cb8 --- /dev/null +++ b/Content.Client/Administration/UI/SpawnExplosion/SpawnExplosionWindow.xaml @@ -0,0 +1,46 @@ + + + + + + + + + + + + +