Added "electromagnetic pulse strength" parameter to explosions. EMPs damage repairable power items (e.g. junction boxes) and discharge power containers (e.g. batteries and supercapacitors).

This commit is contained in:
Joonas Rikkonen
2018-02-02 15:15:46 +02:00
parent 67d6bf6a1d
commit b4e5aad2ce
2 changed files with 47 additions and 10 deletions

View File

@@ -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) =>

View File

@@ -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<Reactor>() == null) continue;
float distFactor = 1.0f - (float)Math.Sqrt(distSqr) / displayRange;
//damage repairable power-consuming items
var powerTransfer = item.GetComponent<Powered>();
if (powerTransfer != null && item.FixRequirements.Count > 0)
{
item.Condition -= 100 * empStrength * distFactor;
}
//discharge batteries
var powerContainer = item.GetComponent<PowerContainer>();
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);