diff --git a/Barotrauma/BarotraumaShared/Source/DebugConsole.cs b/Barotrauma/BarotraumaShared/Source/DebugConsole.cs index bf228f6b5..5dfb8f46f 100644 --- a/Barotrauma/BarotraumaShared/Source/DebugConsole.cs +++ b/Barotrauma/BarotraumaShared/Source/DebugConsole.cs @@ -1006,26 +1006,28 @@ namespace Barotrauma } })); - commands.Add(new Command("explosion", "explosion [range] [force] [damage] [structuredamage]: Creates an explosion at the position of the cursor.", (string[] args) => + commands.Add(new Command("explosion", "explosion [range] [force] [damage] [structuredamage] [emp strength]: Creates an explosion at the position of the cursor.", (string[] args) => { Vector2 explosionPos = GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition); - float range = 500, force = 10, damage = 50, structureDamage = 10; + float range = 500, force = 10, damage = 50, structureDamage = 10, empStrength = 0.0f; if (args.Length > 0) float.TryParse(args[0], out range); if (args.Length > 1) float.TryParse(args[1], out force); if (args.Length > 2) float.TryParse(args[2], out damage); if (args.Length > 3) float.TryParse(args[3], out structureDamage); - new Explosion(range, force, damage, structureDamage).Explode(explosionPos); + if (args.Length > 4) float.TryParse(args[4], out empStrength); + new Explosion(range, force, damage, structureDamage, empStrength).Explode(explosionPos); }, null, - (Client client, Vector2 cursorWorldPos, string[] args) => + (Client client, Vector2 cursorWorldPos, string[] args) => { Vector2 explosionPos = cursorWorldPos; - float range = 500, force = 10, damage = 50, structureDamage = 10; + float range = 500, force = 10, damage = 50, structureDamage = 10, empStrength = 0.0f; ; if (args.Length > 0) float.TryParse(args[0], out range); if (args.Length > 1) float.TryParse(args[1], out force); if (args.Length > 2) float.TryParse(args[2], out damage); if (args.Length > 3) float.TryParse(args[3], out structureDamage); - new Explosion(range, force, damage, structureDamage).Explode(explosionPos); + if (args.Length > 4) float.TryParse(args[4], out empStrength); + new Explosion(range, force, damage, structureDamage, empStrength).Explode(explosionPos); })); commands.Add(new Command("fixitems", "fixitems: Repairs all items and restores them to full condition.", (string[] args) => diff --git a/Barotrauma/BarotraumaShared/Source/Map/Explosion.cs b/Barotrauma/BarotraumaShared/Source/Map/Explosion.cs index d77fe8809..02bd404de 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Explosion.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Explosion.cs @@ -1,4 +1,5 @@ -using Barotrauma.Networking; +using Barotrauma.Items.Components; +using Barotrauma.Networking; using FarseerPhysics; using Microsoft.Xna.Framework; using System; @@ -17,14 +18,17 @@ namespace Barotrauma private bool sparks, shockwave, flames, smoke, flash; + private float empStrength; + private string decal; private float decalSize; - public Explosion(float range, float force, float damage, float structureDamage) + public Explosion(float range, float force, float damage, float structureDamage, float empStrength = 0.0f) { attack = new Attack(damage, structureDamage, 0.0f, range); attack.SeverLimbsProbability = 1.0f; this.force = force; + this.empStrength = empStrength; sparks = true; shockwave = true; flames = true; @@ -42,6 +46,8 @@ namespace Barotrauma smoke = element.GetAttributeBool("smoke", true); flash = element.GetAttributeBool("flash", true); + empStrength = element.GetAttributeFloat("empstrength", 0.0f); + decal = element.GetAttributeString("decal", ""); decalSize = element.GetAttributeFloat("decalSize", 1.0f); @@ -57,14 +63,43 @@ namespace Barotrauma float displayRange = attack.Range; if (displayRange < 0.1f) return; - float cameraDist = Vector2.Distance(GameMain.GameScreen.Cam.Position, worldPosition)/2.0f; + float cameraDist = Vector2.Distance(GameMain.GameScreen.Cam.Position, worldPosition) / 2.0f; GameMain.GameScreen.Cam.Shake = CameraShake * Math.Max((displayRange - cameraDist) / displayRange, 0.0f); - + if (attack.GetStructureDamage(1.0f) > 0.0f) { RangedStructureDamage(worldPosition, displayRange, attack.GetStructureDamage(1.0f)); } + if (empStrength > 0.0f) + { + float displayRangeSqr = displayRange * displayRange; + foreach (Item item in Item.ItemList) + { + float distSqr = Vector2.DistanceSquared(item.WorldPosition, worldPosition); + if (distSqr > displayRangeSqr) continue; + + //ignore reactors (don't want to blow them up) + if (item.GetComponent() == null) continue; + + float distFactor = 1.0f - (float)Math.Sqrt(distSqr) / displayRange; + + //damage repairable power-consuming items + var powerTransfer = item.GetComponent(); + if (powerTransfer != null && item.FixRequirements.Count > 0) + { + item.Condition -= 100 * empStrength * distFactor; + } + + //discharge batteries + var powerContainer = item.GetComponent(); + if (powerContainer != null) + { + powerContainer.Charge -= powerContainer.Capacity * empStrength * distFactor; + } + } + } + if (force == 0.0f && attack.Stun == 0.0f && attack.GetDamage(1.0f) == 0.0f) return; ApplyExplosionForces(worldPosition, attack, force);