Mini bomb changes (#7454)
This commit is contained in:
@@ -60,13 +60,20 @@ public sealed class ExplosiveComponent : Component
|
|||||||
public float TileBreakScale = 1f;
|
public float TileBreakScale = 1f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Maximum number of times that an explosive can break a tile. Currently, for normal space ships breaking a
|
/// Maximum number of times that an explosive can break a tile. Currently, for normal space stations breaking a
|
||||||
/// tile twice will result in a vacuum.
|
/// tile twice will generally result in a vacuum.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
[DataField("maxTileBreak")]
|
[DataField("maxTileBreak")]
|
||||||
public int MaxTileBreak = int.MaxValue;
|
public int MaxTileBreak = int.MaxValue;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether this explosive should be able to create a vacuum by breaking tiles.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("canCreateVacuum")]
|
||||||
|
public bool CanCreateVacuum = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Avoid somehow double-triggering this explosion (e.g. by damaging this entity from its own explosion.
|
/// Avoid somehow double-triggering this explosion (e.g. by damaging this entity from its own explosion.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -182,8 +182,7 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
string id,
|
string id,
|
||||||
EntityQuery<TransformComponent> xformQuery,
|
EntityQuery<TransformComponent> xformQuery,
|
||||||
EntityQuery<DamageableComponent> damageQuery,
|
EntityQuery<DamageableComponent> damageQuery,
|
||||||
EntityQuery<PhysicsComponent> physicsQuery,
|
EntityQuery<PhysicsComponent> physicsQuery)
|
||||||
EntityQuery<MetaDataComponent> metaQuery)
|
|
||||||
{
|
{
|
||||||
var gridBox = new Box2(tile * grid.TileSize, (tile + 1) * grid.TileSize);
|
var gridBox = new Box2(tile * grid.TileSize, (tile + 1) * grid.TileSize);
|
||||||
|
|
||||||
@@ -216,11 +215,23 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
|
|
||||||
// process anchored entities
|
// process anchored entities
|
||||||
var tileBlocked = false;
|
var tileBlocked = false;
|
||||||
foreach (var entity in grid.GetAnchoredEntities(tile).ToList())
|
var anchoredList = grid.GetAnchoredEntities(tile).ToList();
|
||||||
|
foreach (var entity in anchoredList)
|
||||||
{
|
{
|
||||||
processed.Add(entity);
|
processed.Add(entity);
|
||||||
ProcessEntity(entity, epicenter, damage, throwForce, id, damageQuery, physicsQuery);
|
ProcessEntity(entity, epicenter, damage, throwForce, id, damageQuery, physicsQuery);
|
||||||
tileBlocked |= IsBlockingTurf(entity, physicsQuery);
|
}
|
||||||
|
|
||||||
|
// Walls and reinforced walls will break into girders. These girders will also be considered turf-blocking for
|
||||||
|
// the purposes of destroying floors. Again, ideally the process of damaging an entity should somehow return
|
||||||
|
// information about the entities that were spawned as a result, but without that information we just have to
|
||||||
|
// re-check for new anchored entities. Compared to entity spawning & deleting, this should still be relatively minor.
|
||||||
|
if (anchoredList.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (var entity in grid.GetAnchoredEntities(tile))
|
||||||
|
{
|
||||||
|
tileBlocked |= IsBlockingTurf(entity, physicsQuery);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next, we get the intersecting entities AGAIN, but purely for throwing. This way, glass shards spawned from
|
// Next, we get the intersecting entities AGAIN, but purely for throwing. This way, glass shards spawned from
|
||||||
@@ -261,8 +272,7 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
string id,
|
string id,
|
||||||
EntityQuery<TransformComponent> xformQuery,
|
EntityQuery<TransformComponent> xformQuery,
|
||||||
EntityQuery<DamageableComponent> damageQuery,
|
EntityQuery<DamageableComponent> damageQuery,
|
||||||
EntityQuery<PhysicsComponent> physicsQuery,
|
EntityQuery<PhysicsComponent> physicsQuery)
|
||||||
EntityQuery<MetaDataComponent> metaQuery)
|
|
||||||
{
|
{
|
||||||
var gridBox = new Box2(tile * DefaultTileSize, (DefaultTileSize, DefaultTileSize));
|
var gridBox = new Box2(tile * DefaultTileSize, (DefaultTileSize, DefaultTileSize));
|
||||||
var worldBox = spaceMatrix.TransformBox(gridBox);
|
var worldBox = spaceMatrix.TransformBox(gridBox);
|
||||||
@@ -370,10 +380,15 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
public void DamageFloorTile(TileRef tileRef,
|
public void DamageFloorTile(TileRef tileRef,
|
||||||
float effectiveIntensity,
|
float effectiveIntensity,
|
||||||
int maxTileBreak,
|
int maxTileBreak,
|
||||||
|
bool canCreateVacuum,
|
||||||
List<(Vector2i GridIndices, Tile Tile)> damagedTiles,
|
List<(Vector2i GridIndices, Tile Tile)> damagedTiles,
|
||||||
ExplosionPrototype type)
|
ExplosionPrototype type)
|
||||||
{
|
{
|
||||||
var tileDef = _tileDefinitionManager[tileRef.Tile.TypeId];
|
if (_tileDefinitionManager[tileRef.Tile.TypeId] is not ContentTileDefinition tileDef)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (tileDef.IsSpace)
|
||||||
|
canCreateVacuum = true; // is already a vacuum.
|
||||||
|
|
||||||
int tileBreakages = 0;
|
int tileBreakages = 0;
|
||||||
while (maxTileBreak > tileBreakages && _robustRandom.Prob(type.TileBreakChance(effectiveIntensity)))
|
while (maxTileBreak > tileBreakages && _robustRandom.Prob(type.TileBreakChance(effectiveIntensity)))
|
||||||
@@ -381,14 +396,17 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
tileBreakages++;
|
tileBreakages++;
|
||||||
effectiveIntensity -= type.TileBreakRerollReduction;
|
effectiveIntensity -= type.TileBreakRerollReduction;
|
||||||
|
|
||||||
if (tileDef is not ContentTileDefinition contentTileDef)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// does this have a base-turf that we can break it down to?
|
// does this have a base-turf that we can break it down to?
|
||||||
if (contentTileDef.BaseTurfs.Count == 0)
|
if (tileDef.BaseTurfs.Count == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
tileDef = _tileDefinitionManager[contentTileDef.BaseTurfs[^1]];
|
if (_tileDefinitionManager[tileDef.BaseTurfs[^1]] is not ContentTileDefinition newDef)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (newDef.IsSpace && !canCreateVacuum)
|
||||||
|
break;
|
||||||
|
|
||||||
|
tileDef = newDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tileDef.TileId == tileRef.Tile.TypeId)
|
if (tileDef.TileId == tileRef.Tile.TypeId)
|
||||||
@@ -493,7 +511,6 @@ sealed class Explosion
|
|||||||
private readonly EntityQuery<TransformComponent> _xformQuery;
|
private readonly EntityQuery<TransformComponent> _xformQuery;
|
||||||
private readonly EntityQuery<PhysicsComponent> _physicsQuery;
|
private readonly EntityQuery<PhysicsComponent> _physicsQuery;
|
||||||
private readonly EntityQuery<DamageableComponent> _damageQuery;
|
private readonly EntityQuery<DamageableComponent> _damageQuery;
|
||||||
private readonly EntityQuery<MetaDataComponent> _metaQuery;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Total area that the explosion covers.
|
/// Total area that the explosion covers.
|
||||||
@@ -510,6 +527,11 @@ sealed class Explosion
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly int _maxTileBreak;
|
private readonly int _maxTileBreak;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether this explosion can turn non-vacuum tiles into vacuum-tiles.
|
||||||
|
/// </summary>
|
||||||
|
private readonly bool _canCreateVacuum;
|
||||||
|
|
||||||
private readonly IEntityManager _entMan;
|
private readonly IEntityManager _entMan;
|
||||||
private readonly ExplosionSystem _system;
|
private readonly ExplosionSystem _system;
|
||||||
|
|
||||||
@@ -526,6 +548,7 @@ sealed class Explosion
|
|||||||
int area,
|
int area,
|
||||||
float tileBreakScale,
|
float tileBreakScale,
|
||||||
int maxTileBreak,
|
int maxTileBreak,
|
||||||
|
bool canCreateVacuum,
|
||||||
IEntityManager entMan,
|
IEntityManager entMan,
|
||||||
IMapManager mapMan)
|
IMapManager mapMan)
|
||||||
{
|
{
|
||||||
@@ -537,12 +560,12 @@ sealed class Explosion
|
|||||||
|
|
||||||
_tileBreakScale = tileBreakScale;
|
_tileBreakScale = tileBreakScale;
|
||||||
_maxTileBreak = maxTileBreak;
|
_maxTileBreak = maxTileBreak;
|
||||||
|
_canCreateVacuum = canCreateVacuum;
|
||||||
_entMan = entMan;
|
_entMan = entMan;
|
||||||
|
|
||||||
_xformQuery = entMan.GetEntityQuery<TransformComponent>();
|
_xformQuery = entMan.GetEntityQuery<TransformComponent>();
|
||||||
_physicsQuery = entMan.GetEntityQuery<PhysicsComponent>();
|
_physicsQuery = entMan.GetEntityQuery<PhysicsComponent>();
|
||||||
_damageQuery = entMan.GetEntityQuery<DamageableComponent>();
|
_damageQuery = entMan.GetEntityQuery<DamageableComponent>();
|
||||||
_metaQuery = entMan.GetEntityQuery<MetaDataComponent>();
|
|
||||||
|
|
||||||
if (spaceData != null)
|
if (spaceData != null)
|
||||||
{
|
{
|
||||||
@@ -682,12 +705,11 @@ sealed class Explosion
|
|||||||
ExplosionType.ID,
|
ExplosionType.ID,
|
||||||
_xformQuery,
|
_xformQuery,
|
||||||
_damageQuery,
|
_damageQuery,
|
||||||
_physicsQuery,
|
_physicsQuery);
|
||||||
_metaQuery);
|
|
||||||
|
|
||||||
// If the floor is not blocked by some dense object, damage the floor tiles.
|
// If the floor is not blocked by some dense object, damage the floor tiles.
|
||||||
if (canDamageFloor)
|
if (canDamageFloor)
|
||||||
_system.DamageFloorTile(tileRef, _currentIntensity * _tileBreakScale, _maxTileBreak, tileUpdateList, ExplosionType);
|
_system.DamageFloorTile(tileRef, _currentIntensity * _tileBreakScale, _maxTileBreak, _canCreateVacuum, tileUpdateList, ExplosionType);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -703,8 +725,7 @@ sealed class Explosion
|
|||||||
ExplosionType.ID,
|
ExplosionType.ID,
|
||||||
_xformQuery,
|
_xformQuery,
|
||||||
_damageQuery,
|
_damageQuery,
|
||||||
_physicsQuery,
|
_physicsQuery);
|
||||||
_metaQuery);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MoveNext())
|
if (!MoveNext())
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
explosive.MaxIntensity,
|
explosive.MaxIntensity,
|
||||||
explosive.TileBreakScale,
|
explosive.TileBreakScale,
|
||||||
explosive.MaxTileBreak,
|
explosive.MaxTileBreak,
|
||||||
|
explosive.CanCreateVacuum,
|
||||||
user);
|
user);
|
||||||
|
|
||||||
if (delete)
|
if (delete)
|
||||||
@@ -190,13 +191,14 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
float maxTileIntensity,
|
float maxTileIntensity,
|
||||||
float tileBreakScale = 1f,
|
float tileBreakScale = 1f,
|
||||||
int maxTileBreak = int.MaxValue,
|
int maxTileBreak = int.MaxValue,
|
||||||
|
bool canCreateVacuum = true,
|
||||||
EntityUid? user = null,
|
EntityUid? user = null,
|
||||||
bool addLog = false)
|
bool addLog = false)
|
||||||
{
|
{
|
||||||
var pos = Transform(uid).MapPosition;
|
var pos = Transform(uid).MapPosition;
|
||||||
|
|
||||||
|
|
||||||
QueueExplosion(pos, typeId, totalIntensity, slope, maxTileIntensity, tileBreakScale, maxTileBreak, addLog: false);
|
QueueExplosion(pos, typeId, totalIntensity, slope, maxTileIntensity, tileBreakScale, maxTileBreak, canCreateVacuum, addLog: false);
|
||||||
|
|
||||||
if (!addLog)
|
if (!addLog)
|
||||||
return;
|
return;
|
||||||
@@ -219,6 +221,7 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
float maxTileIntensity,
|
float maxTileIntensity,
|
||||||
float tileBreakScale = 1f,
|
float tileBreakScale = 1f,
|
||||||
int maxTileBreak = int.MaxValue,
|
int maxTileBreak = int.MaxValue,
|
||||||
|
bool canCreateVacuum = true,
|
||||||
bool addLog = false)
|
bool addLog = false)
|
||||||
{
|
{
|
||||||
if (totalIntensity <= 0 || slope <= 0)
|
if (totalIntensity <= 0 || slope <= 0)
|
||||||
@@ -234,7 +237,7 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
_logsSystem.Add(LogType.Explosion, LogImpact.High, $"Explosion spawned at {epicenter:coordinates} with intensity {totalIntensity} slope {slope}");
|
_logsSystem.Add(LogType.Explosion, LogImpact.High, $"Explosion spawned at {epicenter:coordinates} with intensity {totalIntensity} slope {slope}");
|
||||||
|
|
||||||
_explosionQueue.Enqueue(() => SpawnExplosion(epicenter, type, totalIntensity,
|
_explosionQueue.Enqueue(() => SpawnExplosion(epicenter, type, totalIntensity,
|
||||||
slope, maxTileIntensity, tileBreakScale, maxTileBreak));
|
slope, maxTileIntensity, tileBreakScale, maxTileBreak, canCreateVacuum));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -248,7 +251,8 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
float slope,
|
float slope,
|
||||||
float maxTileIntensity,
|
float maxTileIntensity,
|
||||||
float tileBreakScale,
|
float tileBreakScale,
|
||||||
int maxTileBreak)
|
int maxTileBreak,
|
||||||
|
bool canCreateVacuum)
|
||||||
{
|
{
|
||||||
if (!_mapManager.MapExists(epicenter.MapId))
|
if (!_mapManager.MapExists(epicenter.MapId))
|
||||||
return null;
|
return null;
|
||||||
@@ -283,6 +287,7 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
area,
|
area,
|
||||||
tileBreakScale,
|
tileBreakScale,
|
||||||
maxTileBreak,
|
maxTileBreak,
|
||||||
|
canCreateVacuum,
|
||||||
EntityManager,
|
EntityManager,
|
||||||
_mapManager);
|
_mapManager);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,7 @@
|
|||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: Syndicate minibomb
|
name: Syndicate minibomb
|
||||||
description: A syndicate manufactured explosive used to sow destruction and chaos.
|
description: Creates a small but powerful explosion that is strong enough to break through walls.
|
||||||
parent: BaseItem
|
parent: BaseItem
|
||||||
id: SyndieMiniBomb
|
id: SyndieMiniBomb
|
||||||
components:
|
components:
|
||||||
@@ -95,10 +95,11 @@
|
|||||||
delay: 5
|
delay: 5
|
||||||
- type: Explosive
|
- type: Explosive
|
||||||
explosionType: Default
|
explosionType: Default
|
||||||
# About a 3-3.5 tile radius, strong enough to break reinforced walls near centre.
|
# About a 2.5 tile radius. If placed next to walls, will destroy a line of 3-normal walls and turn 3 reinforced walls into girders.
|
||||||
totalIntensity: 800
|
totalIntensity: 492
|
||||||
intensitySlope: 15
|
intensitySlope: 20.5
|
||||||
maxTileBreak: 1 # for destroying walls, not spacing the hallway
|
maxIntensity: 41
|
||||||
|
canCreateVacuum: false # for destroying walls, not spacing the hallway
|
||||||
- type: ExplodeOnTrigger
|
- type: ExplodeOnTrigger
|
||||||
- type: Damageable
|
- type: Damageable
|
||||||
damageContainer: Inorganic
|
damageContainer: Inorganic
|
||||||
|
|||||||
Reference in New Issue
Block a user