Explosion now throws affected entities, fixes probability/severi… (#732)
* throwforce and probability fixes for explosions Applies force to all affected by explosion entities with ItemComponent Fixes probability issues with explosion related callbacks * dependency fix, throw helper * delete TODO Co-authored-by: gituhabu <48828502+gituhabu@users.noreply.github.com>
This commit is contained in:
@@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using Content.Server.GameObjects.Components.Mobs;
|
using Content.Server.GameObjects.Components.Mobs;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Shared.Maps;
|
using Content.Shared.Maps;
|
||||||
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Server.GameObjects.EntitySystems;
|
using Robust.Server.GameObjects.EntitySystems;
|
||||||
using Robust.Server.Interfaces.GameObjects;
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
using Robust.Server.Interfaces.Player;
|
using Robust.Server.Interfaces.Player;
|
||||||
@@ -66,7 +67,7 @@ namespace Content.Server.Explosions
|
|||||||
}
|
}
|
||||||
var exAct = entitySystemManager.GetEntitySystem<ActSystem>();
|
var exAct = entitySystemManager.GetEntitySystem<ActSystem>();
|
||||||
//exAct.HandleExplosion(Owner, entity, severity);
|
//exAct.HandleExplosion(Owner, entity, severity);
|
||||||
exAct.HandleExplosion(null, entity, severity);
|
exAct.HandleExplosion(coords, entity, severity);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Tile damage calculation mockup
|
//Tile damage calculation mockup
|
||||||
@@ -88,9 +89,10 @@ namespace Content.Server.Explosions
|
|||||||
{
|
{
|
||||||
mapGrid.SetTile(tileLoc, new Tile(tileDefinitionManager[baseTurfs[0]].TileId));
|
mapGrid.SetTile(tileLoc, new Tile(tileDefinitionManager[baseTurfs[0]].TileId));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (distanceFromTile < heavyImpactRange)
|
else if (distanceFromTile < heavyImpactRange)
|
||||||
{
|
{
|
||||||
if (robustRandom.Prob(80))
|
if (robustRandom.Prob(0.8f))
|
||||||
{
|
{
|
||||||
mapGrid.SetTile(tileLoc, new Tile(tileDefinitionManager[baseTurfs[^1]].TileId));
|
mapGrid.SetTile(tileLoc, new Tile(tileDefinitionManager[baseTurfs[^1]].TileId));
|
||||||
}
|
}
|
||||||
@@ -99,9 +101,10 @@ namespace Content.Server.Explosions
|
|||||||
mapGrid.SetTile(tileLoc, new Tile(tileDefinitionManager[baseTurfs[0]].TileId));
|
mapGrid.SetTile(tileLoc, new Tile(tileDefinitionManager[baseTurfs[0]].TileId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (distanceFromTile < lightImpactRange)
|
else if (distanceFromTile < lightImpactRange)
|
||||||
{
|
{
|
||||||
if (robustRandom.Prob(50))
|
if (robustRandom.Prob(0.5f))
|
||||||
{
|
{
|
||||||
mapGrid.SetTile(tileLoc, new Tile(tileDefinitionManager[baseTurfs[^1]].TileId));
|
mapGrid.SetTile(tileLoc, new Tile(tileDefinitionManager[baseTurfs[^1]].TileId));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ namespace Content.Server.GameObjects.Components.Damage
|
|||||||
_actSystem.HandleBreakage(Owner);
|
_actSystem.HandleBreakage(Owner);
|
||||||
break;
|
break;
|
||||||
case ExplosionSeverity.Light:
|
case ExplosionSeverity.Light:
|
||||||
if(prob.Prob(40))
|
if(prob.Prob(0.4f))
|
||||||
_actSystem.HandleBreakage(Owner);
|
_actSystem.HandleBreakage(Owner);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,10 +91,11 @@ namespace Content.Server.GameObjects.Components.Destructible
|
|||||||
_actSystem.HandleDestruction(Owner, false);
|
_actSystem.HandleDestruction(Owner, false);
|
||||||
break;
|
break;
|
||||||
case ExplosionSeverity.Heavy:
|
case ExplosionSeverity.Heavy:
|
||||||
_actSystem.HandleDestruction(Owner, true);
|
var spawnWreckOnHeavy = prob.Prob(0.5f);
|
||||||
|
_actSystem.HandleDestruction(Owner, spawnWreckOnHeavy);
|
||||||
break;
|
break;
|
||||||
case ExplosionSeverity.Light:
|
case ExplosionSeverity.Light:
|
||||||
if (prob.Prob(40))
|
if (prob.Prob(0.4f))
|
||||||
_actSystem.HandleDestruction(Owner, true);
|
_actSystem.HandleDestruction(Owner, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
using Content.Server.GameObjects.EntitySystems;
|
using System;
|
||||||
|
using Content.Server.GameObjects.Components;
|
||||||
|
using Content.Server.GameObjects.Components.Destructible;
|
||||||
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects;
|
||||||
|
using Content.Server.Throw;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
using Content.Shared.GameObjects.Components.Items;
|
using Content.Shared.GameObjects.Components.Items;
|
||||||
using Content.Shared.Physics;
|
using Content.Shared.Physics;
|
||||||
@@ -7,12 +11,15 @@ using Robust.Server.GameObjects;
|
|||||||
using Robust.Server.Interfaces.GameObjects;
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects.Components;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Interfaces.Map;
|
using Robust.Shared.Interfaces.Map;
|
||||||
using Robust.Shared.Interfaces.Physics;
|
using Robust.Shared.Interfaces.Physics;
|
||||||
using Robust.Shared.Interfaces.Random;
|
using Robust.Shared.Interfaces.Random;
|
||||||
|
using Robust.Shared.Interfaces.Timing;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
|
using Robust.Shared.Physics;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
@@ -20,7 +27,7 @@ namespace Content.Server.GameObjects
|
|||||||
{
|
{
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
[ComponentReference(typeof(StoreableComponent))]
|
[ComponentReference(typeof(StoreableComponent))]
|
||||||
public class ItemComponent : StoreableComponent, IAttackHand
|
public class ItemComponent : StoreableComponent, IAttackHand, IExAct
|
||||||
{
|
{
|
||||||
public override string Name => "Item";
|
public override string Name => "Item";
|
||||||
public override uint? NetID => ContentNetIDs.ITEM;
|
public override uint? NetID => ContentNetIDs.ITEM;
|
||||||
@@ -28,6 +35,7 @@ namespace Content.Server.GameObjects
|
|||||||
#pragma warning disable 649
|
#pragma warning disable 649
|
||||||
[Dependency] private readonly IRobustRandom _robustRandom;
|
[Dependency] private readonly IRobustRandom _robustRandom;
|
||||||
[Dependency] private readonly IEntitySystemManager _entitySystemManager;
|
[Dependency] private readonly IEntitySystemManager _entitySystemManager;
|
||||||
|
[Dependency] private readonly IMapManager _mapManager;
|
||||||
#pragma warning restore 649
|
#pragma warning restore 649
|
||||||
|
|
||||||
private string _equippedPrefix;
|
private string _equippedPrefix;
|
||||||
@@ -139,5 +147,29 @@ namespace Content.Server.GameObjects
|
|||||||
return (_robustRandom.NextFloat() * size) - size / 2;
|
return (_robustRandom.NextFloat() * size) - size / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnExplosion(ExplosionEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
var sourceLocation = eventArgs.Source;
|
||||||
|
var targetLocation = eventArgs.Target.Transform.GridPosition;
|
||||||
|
var dirVec = (targetLocation.ToMapPos(_mapManager) - sourceLocation.ToMapPos(_mapManager)).Normalized;
|
||||||
|
|
||||||
|
var throwForce = 1.0f;
|
||||||
|
|
||||||
|
switch (eventArgs.Severity)
|
||||||
|
{
|
||||||
|
case ExplosionSeverity.Destruction:
|
||||||
|
throwForce = 3.0f;
|
||||||
|
break;
|
||||||
|
case ExplosionSeverity.Heavy:
|
||||||
|
throwForce = 2.0f;
|
||||||
|
break;
|
||||||
|
case ExplosionSeverity.Light:
|
||||||
|
throwForce = 1.0f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThrowHelper.Throw(Owner, throwForce, targetLocation, sourceLocation, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -190,8 +190,8 @@ namespace Content.Server.GameObjects
|
|||||||
bruteDamage += 30;
|
bruteDamage += 30;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Owner.GetComponent<DamageableComponent>().TakeDamage(DamageType.Brute, bruteDamage, eventArgs.Source);
|
Owner.GetComponent<DamageableComponent>().TakeDamage(DamageType.Brute, bruteDamage, null);
|
||||||
Owner.GetComponent<DamageableComponent>().TakeDamage(DamageType.Heat, burnDamage, eventArgs.Source);
|
Owner.GetComponent<DamageableComponent>().TakeDamage(DamageType.Heat, burnDamage, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Linq;
|
|||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.GameObjects.Systems;
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.Map;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.EntitySystems
|
namespace Content.Server.GameObjects.EntitySystems
|
||||||
{
|
{
|
||||||
@@ -46,7 +47,7 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
|
|
||||||
public class ExplosionEventArgs : EventArgs
|
public class ExplosionEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public IEntity Source { get; set; }
|
public GridCoordinates Source { get; set; }
|
||||||
public IEntity Target { get; set; }
|
public IEntity Target { get; set; }
|
||||||
public ExplosionSeverity Severity { get; set; }
|
public ExplosionSeverity Severity { get; set; }
|
||||||
}
|
}
|
||||||
@@ -70,7 +71,7 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
owner.Delete();
|
owner.Delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleExplosion(IEntity source, IEntity target, ExplosionSeverity severity)
|
public void HandleExplosion(GridCoordinates source, IEntity target, ExplosionSeverity severity)
|
||||||
{
|
{
|
||||||
var eventArgs = new ExplosionEventArgs
|
var eventArgs = new ExplosionEventArgs
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using Content.Server.GameObjects.Components;
|
using Content.Server.GameObjects.Components;
|
||||||
using Content.Server.GameObjects.Components.Stack;
|
using Content.Server.GameObjects.Components.Stack;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects;
|
||||||
|
using Content.Server.Throw;
|
||||||
using Content.Shared.Input;
|
using Content.Shared.Input;
|
||||||
using Content.Shared.Physics;
|
using Content.Shared.Physics;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
@@ -185,41 +186,7 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
newStackComp.Count = 1;
|
newStackComp.Count = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!throwEnt.TryGetComponent(out CollidableComponent colComp))
|
ThrowHelper.Throw(throwEnt, ThrowForce, coords, plyEnt.Transform.GridPosition, false, plyEnt);
|
||||||
return true;
|
|
||||||
|
|
||||||
colComp.CollisionEnabled = true;
|
|
||||||
// I can now collide with player, so that i can do damage.
|
|
||||||
|
|
||||||
if (!throwEnt.TryGetComponent(out ThrownItemComponent projComp))
|
|
||||||
{
|
|
||||||
projComp = throwEnt.AddComponent<ThrownItemComponent>();
|
|
||||||
|
|
||||||
if(colComp.PhysicsShapes.Count == 0)
|
|
||||||
colComp.PhysicsShapes.Add(new PhysShapeAabb());
|
|
||||||
|
|
||||||
colComp.PhysicsShapes[0].CollisionMask |= (int)CollisionGroup.MobImpassable;
|
|
||||||
colComp.IsScrapingFloor = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
projComp.User = plyEnt;
|
|
||||||
projComp.IgnoreEntity(plyEnt);
|
|
||||||
|
|
||||||
var transform = plyEnt.Transform;
|
|
||||||
var dirVec = (coords.ToMapPos(_mapManager) - transform.WorldPosition).Normalized;
|
|
||||||
|
|
||||||
if (!throwEnt.TryGetComponent(out PhysicsComponent physComp))
|
|
||||||
physComp = throwEnt.AddComponent<PhysicsComponent>();
|
|
||||||
|
|
||||||
// TODO: Move this into PhysicsSystem, we need an ApplyForce function.
|
|
||||||
var a = ThrowForce / (float) Math.Max(0.001, physComp.Mass); // a = f / m
|
|
||||||
|
|
||||||
var timing = IoCManager.Resolve<IGameTiming>();
|
|
||||||
var spd = a / (1f / timing.TickRate); // acceleration is applied in 1 tick instead of 1 second, scale appropriately
|
|
||||||
|
|
||||||
physComp.LinearVelocity = dirVec * spd;
|
|
||||||
|
|
||||||
transform.LocalRotation = new Angle(dirVec).GetCardinalDir().ToAngle();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
72
Content.Server/Throw/ThrowHelper.cs
Normal file
72
Content.Server/Throw/ThrowHelper.cs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
using Content.Server.GameObjects.Components;
|
||||||
|
using Content.Shared.Physics;
|
||||||
|
using Robust.Server.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects.Components;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.Map;
|
||||||
|
using Robust.Shared.Interfaces.Random;
|
||||||
|
using Robust.Shared.Interfaces.Timing;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
using Robust.Shared.Physics;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Content.Server.Throw
|
||||||
|
{
|
||||||
|
public static class ThrowHelper
|
||||||
|
{
|
||||||
|
public static void Throw(IEntity thrownEnt, float throwForce, GridCoordinates targetLoc, GridCoordinates sourceLoc, bool spread = false, IEntity throwSourceEnt = null)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if (!thrownEnt.TryGetComponent(out CollidableComponent colComp))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var mapManager = IoCManager.Resolve<IMapManager>();
|
||||||
|
|
||||||
|
colComp.CollisionEnabled = true;
|
||||||
|
// I can now collide with player, so that i can do damage.
|
||||||
|
|
||||||
|
if (!thrownEnt.TryGetComponent(out ThrownItemComponent projComp))
|
||||||
|
{
|
||||||
|
projComp = thrownEnt.AddComponent<ThrownItemComponent>();
|
||||||
|
|
||||||
|
if (colComp.PhysicsShapes.Count == 0)
|
||||||
|
colComp.PhysicsShapes.Add(new PhysShapeAabb());
|
||||||
|
|
||||||
|
colComp.PhysicsShapes[0].CollisionMask |= (int) CollisionGroup.MobImpassable;
|
||||||
|
colComp.IsScrapingFloor = false;
|
||||||
|
}
|
||||||
|
var angle = new Angle(targetLoc.ToMapPos(mapManager) - sourceLoc.ToMapPos(mapManager));
|
||||||
|
|
||||||
|
if (spread)
|
||||||
|
{
|
||||||
|
var spreadRandom = IoCManager.Resolve<IRobustRandom>();
|
||||||
|
angle += Angle.FromDegrees(spreadRandom.NextGaussian(0, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (throwSourceEnt != null)
|
||||||
|
{
|
||||||
|
projComp.User = throwSourceEnt;
|
||||||
|
projComp.IgnoreEntity(throwSourceEnt);
|
||||||
|
|
||||||
|
throwSourceEnt.Transform.LocalRotation = angle.GetCardinalDir().ToAngle();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!thrownEnt.TryGetComponent(out PhysicsComponent physComp))
|
||||||
|
physComp = thrownEnt.AddComponent<PhysicsComponent>();
|
||||||
|
|
||||||
|
// TODO: Move this into PhysicsSystem, we need an ApplyForce function.
|
||||||
|
var a = throwForce / (float) Math.Max(0.001, physComp.Mass); // a = f / m
|
||||||
|
|
||||||
|
var timing = IoCManager.Resolve<IGameTiming>();
|
||||||
|
var spd = a / (1f / timing.TickRate); // acceleration is applied in 1 tick instead of 1 second, scale appropriately
|
||||||
|
|
||||||
|
physComp.LinearVelocity = angle.ToVec() * spd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user