2024-08-09 08:24:05 +02:00
using System.Linq ;
2023-07-08 14:08:32 +10:00
using System.Numerics ;
2024-04-30 20:11:27 -07:00
using Content.Server.Atmos.EntitySystems ;
2024-08-09 08:24:05 +02:00
using Content.Server.Explosion.Components ;
2022-11-27 23:24:35 +13:00
using Content.Shared.CCVar ;
2022-04-01 15:39:26 +13:00
using Content.Shared.Damage ;
2024-08-09 08:24:05 +02:00
using Content.Shared.Database ;
2022-04-01 15:39:26 +13:00
using Content.Shared.Explosion ;
2024-02-01 07:29:01 -06:00
using Content.Shared.Explosion.Components ;
2024-08-04 20:15:07 -07:00
using Content.Shared.Explosion.EntitySystems ;
2022-04-01 15:39:26 +13:00
using Content.Shared.Maps ;
using Content.Shared.Physics ;
2023-05-07 14:57:23 +12:00
using Content.Shared.Projectiles ;
using Content.Shared.Tag ;
2022-04-01 15:39:26 +13:00
using Robust.Shared.Map ;
2022-11-22 13:12:04 +11:00
using Robust.Shared.Map.Components ;
2022-04-01 15:39:26 +13:00
using Robust.Shared.Physics ;
2022-09-14 17:26:26 +10:00
using Robust.Shared.Physics.Components ;
2022-10-27 23:37:55 +11:00
using Robust.Shared.Physics.Dynamics ;
2024-08-09 08:24:05 +02:00
using Robust.Shared.Player ;
2022-04-01 15:39:26 +13:00
using Robust.Shared.Random ;
using Robust.Shared.Timing ;
2023-10-15 03:48:25 +11:00
using Robust.Shared.Utility ;
2023-09-30 14:35:32 +10:00
using TimedDespawnComponent = Robust . Shared . Spawners . TimedDespawnComponent ;
2024-09-19 00:01:40 +00:00
2022-04-01 15:39:26 +13:00
namespace Content.Server.Explosion.EntitySystems ;
2024-09-19 00:01:40 +00:00
public sealed partial class ExplosionSystem
2022-04-01 15:39:26 +13:00
{
2024-03-14 00:27:08 -04:00
[Dependency] private readonly FlammableSystem _flammableSystem = default ! ;
2022-04-01 15:39:26 +13:00
/// <summary>
/// Used to limit explosion processing time. See <see cref="MaxProcessingTime"/>.
/// </summary>
internal readonly Stopwatch Stopwatch = new ( ) ;
/// <summary>
/// How many tiles to explode before checking the stopwatch timer
/// </summary>
internal static int TileCheckIteration = 1 ;
/// <summary>
/// Queue for delayed processing of explosions. If there is an explosion that covers more than <see
/// cref="TilesPerTick"/> tiles, other explosions will actually be delayed slightly. Unless it's a station
/// nuke, this delay should never really be noticeable.
2024-03-29 23:46:05 +00:00
/// This is also used to combine explosion intensities of the same kind.
2022-04-01 15:39:26 +13:00
/// </summary>
2024-03-29 23:46:05 +00:00
private Queue < QueuedExplosion > _explosionQueue = new ( ) ;
/// <summary>
/// All queued explosions that will be processed in <see cref="_explosionQueue"/>.
/// These always have the same contents.
/// </summary>
private HashSet < QueuedExplosion > _queuedExplosions = new ( ) ;
2022-04-01 15:39:26 +13:00
/// <summary>
/// The explosion currently being processed.
/// </summary>
private Explosion ? _activeExplosion ;
2023-11-19 17:44:42 +00:00
/// <summary>
/// This list is used when raising <see cref="BeforeExplodeEvent"/> to avoid allocating a new list per event.
/// </summary>
private readonly List < EntityUid > _containedEntities = new ( ) ;
private readonly List < ( EntityUid , DamageSpecifier ) > _toDamage = new ( ) ;
2023-11-19 17:06:00 +13:00
private List < EntityUid > _anchored = new ( ) ;
2022-04-05 19:22:35 +12:00
private void OnMapChanged ( MapChangedEvent ev )
{
// If a map was deleted, check the explosion currently being processed belongs to that map.
if ( ev . Created )
return ;
if ( _activeExplosion ? . Epicenter . MapId ! = ev . Map )
return ;
2022-11-27 23:24:35 +13:00
QueueDel ( _activeExplosion . VisualEnt ) ;
2022-04-05 19:22:35 +12:00
_activeExplosion = null ;
2022-11-04 14:24:41 +13:00
_nodeGroupSystem . PauseUpdating = false ;
_pathfindingSystem . PauseUpdating = false ;
2022-04-05 19:22:35 +12:00
}
2022-04-01 15:39:26 +13:00
/// <summary>
/// Process the explosion queue.
/// </summary>
public override void Update ( float frameTime )
{
if ( _activeExplosion = = null & & _explosionQueue . Count = = 0 )
// nothing to do
return ;
Stopwatch . Restart ( ) ;
var x = Stopwatch . Elapsed . TotalMilliseconds ;
var tilesRemaining = TilesPerTick ;
while ( tilesRemaining > 0 & & MaxProcessingTime > Stopwatch . Elapsed . TotalMilliseconds )
{
// if there is no active explosion, get a new one to process
if ( _activeExplosion = = null )
{
// EXPLOSION TODO allow explosion spawning to be interrupted by time limit. In the meantime, ensure that
// there is at-least 1ms of time left before creating a new explosion
2024-03-14 00:27:08 -04:00
if ( MathF . Max ( MaxProcessingTime - 1 , 0.1f ) < Stopwatch . Elapsed . TotalMilliseconds )
2022-04-01 15:39:26 +13:00
break ;
2024-03-29 23:46:05 +00:00
if ( ! _explosionQueue . TryDequeue ( out var queued ) )
2022-04-01 15:39:26 +13:00
break ;
2024-03-29 23:46:05 +00:00
_queuedExplosions . Remove ( queued ) ;
_activeExplosion = SpawnExplosion ( queued ) ;
2022-04-01 15:39:26 +13:00
// explosion spawning can be null if something somewhere went wrong. (e.g., negative explosion
// intensity).
if ( _activeExplosion = = null )
continue ;
// just a lil nap
if ( SleepNodeSys )
{
2022-11-04 14:24:41 +13:00
_nodeGroupSystem . PauseUpdating = true ;
_pathfindingSystem . PauseUpdating = true ;
2022-04-01 15:39:26 +13:00
// snooze grid-chunk regeneration?
// snooze power network (recipients look for new suppliers as wires get destroyed).
}
if ( _activeExplosion . Area > SingleTickAreaLimit )
break ; // start processing next turn.
}
// TODO EXPLOSION check if active explosion is on a paused map. If it is... I guess support swapping out &
// storing the "currently active" explosion?
2022-07-01 06:42:10 +12:00
#if EXCEPTION_TOLERANCE
try
{
#endif
2024-03-14 00:27:08 -04:00
var processed = _activeExplosion . Process ( tilesRemaining ) ;
tilesRemaining - = processed ;
2022-07-01 06:42:10 +12:00
2024-03-14 00:27:08 -04:00
// has the explosion finished processing?
if ( _activeExplosion . FinishedProcessing )
2022-11-27 23:24:35 +13:00
{
var comp = EnsureComp < TimedDespawnComponent > ( _activeExplosion . VisualEnt ) ;
comp . Lifetime = _cfg . GetCVar ( CCVars . ExplosionPersistence ) ;
_appearance . SetData ( _activeExplosion . VisualEnt , ExplosionAppearanceData . Progress , int . MaxValue ) ;
_activeExplosion = null ;
}
2022-07-01 06:42:10 +12:00
#if EXCEPTION_TOLERANCE
}
catch ( Exception e )
{
// Ensure the system does not get stuck in an error-loop.
2022-11-27 23:24:35 +13:00
if ( _activeExplosion ! = null )
QueueDel ( _activeExplosion . VisualEnt ) ;
2022-04-01 15:39:26 +13:00
_activeExplosion = null ;
2022-11-04 14:24:41 +13:00
_nodeGroupSystem . PauseUpdating = false ;
_pathfindingSystem . PauseUpdating = false ;
2022-08-07 16:01:21 +12:00
throw ;
2022-07-01 06:42:10 +12:00
}
#endif
2022-04-01 15:39:26 +13:00
}
2024-03-10 01:15:13 +01:00
Log . Info ( $"Processed {TilesPerTick - tilesRemaining} tiles in {Stopwatch.Elapsed.TotalMilliseconds}ms" ) ;
2022-04-01 15:39:26 +13:00
// we have finished processing our tiles. Is there still an ongoing explosion?
if ( _activeExplosion ! = null )
{
2022-11-27 23:24:35 +13:00
_appearance . SetData ( _activeExplosion . VisualEnt , ExplosionAppearanceData . Progress , _activeExplosion . CurrentIteration + 1 ) ;
2022-04-01 15:39:26 +13:00
return ;
}
if ( _explosionQueue . Count > 0 )
return ;
//wakey wakey
2022-11-04 14:24:41 +13:00
_nodeGroupSystem . PauseUpdating = false ;
_pathfindingSystem . PauseUpdating = false ;
2022-04-01 15:39:26 +13:00
}
/// <summary>
/// Determines whether an entity is blocking a tile or not. (whether it can prevent the tile from being uprooted
/// by an explosion).
/// </summary>
/// <remarks>
/// Used for a variation of <see cref="TurfHelpers.IsBlockedTurf()"/> that makes use of the fact that we have
/// already done an entity lookup on a tile, and don't need to do so again.
/// </remarks>
2023-10-15 03:48:25 +11:00
public bool IsBlockingTurf ( EntityUid uid )
2022-04-01 15:39:26 +13:00
{
if ( EntityManager . IsQueuedForDeletion ( uid ) )
return false ;
2023-10-15 03:48:25 +11:00
if ( ! _physicsQuery . TryGetComponent ( uid , out var physics ) )
2022-04-01 15:39:26 +13:00
return false ;
return physics . CanCollide & & physics . Hard & & ( physics . CollisionLayer & ( int ) CollisionGroup . Impassable ) ! = 0 ;
}
/// <summary>
/// Find entities on a grid tile using the EntityLookupComponent and apply explosion effects.
/// </summary>
/// <returns>True if the underlying tile can be uprooted, false if the tile is blocked by a dense entity</returns>
2022-10-27 23:37:55 +11:00
internal bool ExplodeTile ( BroadphaseComponent lookup ,
2023-11-19 17:06:00 +13:00
Entity < MapGridComponent > grid ,
2022-04-01 15:39:26 +13:00
Vector2i tile ,
float throwForce ,
DamageSpecifier damage ,
MapCoordinates epicenter ,
HashSet < EntityUid > processed ,
2024-03-14 00:27:08 -04:00
string id ,
2024-08-09 08:24:05 +02:00
float? fireStacks ,
EntityUid ? cause )
2022-04-01 15:39:26 +13:00
{
2023-11-19 17:06:00 +13:00
var size = grid . Comp . TileSize ;
var gridBox = new Box2 ( tile * size , ( tile + 1 ) * size ) ;
2022-04-01 15:39:26 +13:00
// get the entities on a tile. Note that we cannot process them directly, or we get
// enumerator-changed-while-enumerating errors.
2023-10-15 03:48:25 +11:00
List < ( EntityUid , TransformComponent ) > list = new ( ) ;
2024-09-19 00:01:40 +00:00
var state = ( list , processed , EntityManager . TransformQuery ) ;
2022-04-01 15:39:26 +13:00
2022-07-08 15:29:43 +12:00
// get entities:
2022-10-27 23:37:55 +11:00
lookup . DynamicTree . QueryAabb ( ref state , GridQueryCallback , gridBox , true ) ;
lookup . StaticTree . QueryAabb ( ref state , GridQueryCallback , gridBox , true ) ;
lookup . SundriesTree . QueryAabb ( ref state , GridQueryCallback , gridBox , true ) ;
2022-10-28 14:57:00 +13:00
lookup . StaticSundriesTree . QueryAabb ( ref state , GridQueryCallback , gridBox , true ) ;
2022-04-01 15:39:26 +13:00
// process those entities
2023-10-15 03:48:25 +11:00
foreach ( var ( uid , xform ) in list )
2022-04-01 15:39:26 +13:00
{
2024-08-09 08:24:05 +02:00
ProcessEntity ( uid , epicenter , damage , throwForce , id , xform , fireStacks , cause ) ;
2022-04-01 15:39:26 +13:00
}
// process anchored entities
var tileBlocked = false ;
2023-11-19 17:06:00 +13:00
_anchored . Clear ( ) ;
_map . GetAnchoredEntities ( grid , tile , _anchored ) ;
foreach ( var entity in _anchored )
2022-04-01 15:39:26 +13:00
{
processed . Add ( entity ) ;
2024-08-09 08:24:05 +02:00
ProcessEntity ( entity , epicenter , damage , throwForce , id , null , fireStacks , cause ) ;
2022-04-09 09:07:02 +12:00
}
// 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.
2023-11-19 17:06:00 +13:00
if ( _anchored . Count > 0 )
2022-04-09 09:07:02 +12:00
{
2023-11-19 17:06:00 +13:00
_anchored . Clear ( ) ;
_map . GetAnchoredEntities ( grid , tile , _anchored ) ;
foreach ( var entity in _anchored )
2022-04-09 09:07:02 +12:00
{
2023-10-15 03:48:25 +11:00
tileBlocked | = IsBlockingTurf ( entity ) ;
2022-04-09 09:07:02 +12:00
}
2022-04-01 15:39:26 +13:00
}
// Next, we get the intersecting entities AGAIN, but purely for throwing. This way, glass shards spawned from
// windows will be flung outwards, and not stay where they spawned. This is however somewhat unnecessary, and a
// prime candidate for computational cost-cutting. Alternatively, it would be nice if there was just some sort
// of spawned-on-destruction event that could be used to automatically assemble a list of new entities that need
// to be thrown.
//
// All things considered, until entity spawning & destruction is sped up, this isn't all that time consuming.
// And throwing is disabled for nukes anyways.
if ( throwForce < = 0 )
return ! tileBlocked ;
list . Clear ( ) ;
2022-10-27 23:37:55 +11:00
lookup . DynamicTree . QueryAabb ( ref state , GridQueryCallback , gridBox , true ) ;
lookup . SundriesTree . QueryAabb ( ref state , GridQueryCallback , gridBox , true ) ;
2022-04-01 15:39:26 +13:00
2023-10-15 03:48:25 +11:00
foreach ( var ( uid , xform ) in list )
2022-04-01 15:39:26 +13:00
{
// Here we only throw, no dealing damage. Containers n such might drop their entities after being destroyed, but
// they should handle their own damage pass-through, with their own damage reduction calculation.
2024-08-09 08:24:05 +02:00
ProcessEntity ( uid , epicenter , null , throwForce , id , xform , null , cause ) ;
2022-04-01 15:39:26 +13:00
}
return ! tileBlocked ;
}
2023-11-28 20:02:24 -05:00
private static bool GridQueryCallback (
2023-10-15 03:48:25 +11:00
ref ( List < ( EntityUid , TransformComponent ) > List , HashSet < EntityUid > Processed , EntityQuery < TransformComponent > XformQuery ) state ,
2022-07-08 15:29:43 +12:00
in EntityUid uid )
{
if ( state . Processed . Add ( uid ) & & state . XformQuery . TryGetComponent ( uid , out var xform ) )
2023-10-15 03:48:25 +11:00
state . List . Add ( ( uid , xform ) ) ;
2022-07-08 15:29:43 +12:00
return true ;
}
2023-11-28 20:02:24 -05:00
private static bool GridQueryCallback (
2023-10-15 03:48:25 +11:00
ref ( List < ( EntityUid , TransformComponent ) > List , HashSet < EntityUid > Processed , EntityQuery < TransformComponent > XformQuery ) state ,
2022-10-27 23:37:55 +11:00
in FixtureProxy proxy )
{
2023-05-09 19:21:26 +12:00
var owner = proxy . Entity ;
2022-10-27 23:37:55 +11:00
return GridQueryCallback ( ref state , in owner ) ;
}
2022-04-01 15:39:26 +13:00
/// <summary>
/// Same as <see cref="ExplodeTile"/>, but for SPAAAAAAACE.
/// </summary>
2022-10-27 23:37:55 +11:00
internal void ExplodeSpace ( BroadphaseComponent lookup ,
2024-06-02 05:07:41 +01:00
Matrix3x2 spaceMatrix ,
Matrix3x2 invSpaceMatrix ,
2022-04-01 15:39:26 +13:00
Vector2i tile ,
float throwForce ,
DamageSpecifier damage ,
MapCoordinates epicenter ,
HashSet < EntityUid > processed ,
2024-03-14 00:27:08 -04:00
string id ,
2024-08-09 08:24:05 +02:00
float? fireStacks ,
EntityUid ? cause )
2022-04-01 15:39:26 +13:00
{
2023-07-08 14:08:32 +10:00
var gridBox = Box2 . FromDimensions ( tile * DefaultTileSize , new Vector2 ( DefaultTileSize , DefaultTileSize ) ) ;
2022-04-01 15:39:26 +13:00
var worldBox = spaceMatrix . TransformBox ( gridBox ) ;
2023-10-15 03:48:25 +11:00
var list = new List < ( EntityUid , TransformComponent ) > ( ) ;
2024-09-19 00:01:40 +00:00
var state = ( list , processed , invSpaceMatrix , lookup . Owner , EntityManager . TransformQuery , gridBox , _transformSystem ) ;
2022-04-01 15:39:26 +13:00
2022-07-08 15:29:43 +12:00
// get entities:
2022-10-27 23:37:55 +11:00
lookup . DynamicTree . QueryAabb ( ref state , SpaceQueryCallback , worldBox , true ) ;
lookup . StaticTree . QueryAabb ( ref state , SpaceQueryCallback , worldBox , true ) ;
lookup . SundriesTree . QueryAabb ( ref state , SpaceQueryCallback , worldBox , true ) ;
2022-10-28 14:57:00 +13:00
lookup . StaticSundriesTree . QueryAabb ( ref state , SpaceQueryCallback , worldBox , true ) ;
2022-04-01 15:39:26 +13:00
2023-10-15 03:48:25 +11:00
foreach ( var ( uid , xform ) in state . Item1 )
2022-04-01 15:39:26 +13:00
{
2023-10-15 03:48:25 +11:00
processed . Add ( uid ) ;
2024-08-09 08:24:05 +02:00
ProcessEntity ( uid , epicenter , damage , throwForce , id , xform , fireStacks , cause ) ;
2022-04-01 15:39:26 +13:00
}
if ( throwForce < = 0 )
return ;
// Also, throw any entities that were spawned as shrapnel. Compared to entity spawning & destruction, this extra
// lookup is relatively minor computational cost, and throwing is disabled for nukes anyways.
list . Clear ( ) ;
2022-10-27 23:37:55 +11:00
lookup . DynamicTree . QueryAabb ( ref state , SpaceQueryCallback , worldBox , true ) ;
lookup . SundriesTree . QueryAabb ( ref state , SpaceQueryCallback , worldBox , true ) ;
2022-07-08 15:29:43 +12:00
2023-10-15 03:48:25 +11:00
foreach ( var ( uid , xform ) in list )
2022-04-01 15:39:26 +13:00
{
2024-08-09 08:24:05 +02:00
ProcessEntity ( uid , epicenter , null , throwForce , id , xform , fireStacks , cause ) ;
2022-04-01 15:39:26 +13:00
}
}
2023-11-28 20:02:24 -05:00
private static bool SpaceQueryCallback (
2024-06-02 05:07:41 +01:00
ref ( List < ( EntityUid , TransformComponent ) > List , HashSet < EntityUid > Processed , Matrix3x2 InvSpaceMatrix , EntityUid LookupOwner , EntityQuery < TransformComponent > XformQuery , Box2 GridBox , SharedTransformSystem System ) state ,
2022-07-08 15:29:43 +12:00
in EntityUid uid )
{
if ( state . Processed . Contains ( uid ) )
return true ;
var xform = state . XformQuery . GetComponent ( uid ) ;
if ( xform . ParentUid = = state . LookupOwner )
{
// parented directly to the map, use local position
2024-06-02 05:07:41 +01:00
if ( state . GridBox . Contains ( Vector2 . Transform ( xform . LocalPosition , state . InvSpaceMatrix ) ) )
2023-10-15 03:48:25 +11:00
state . List . Add ( ( uid , xform ) ) ;
2022-07-08 15:29:43 +12:00
return true ;
}
// finally check if it intersects our tile
2023-11-28 20:02:24 -05:00
var wpos = state . System . GetWorldPosition ( xform ) ;
2024-06-02 05:07:41 +01:00
if ( state . GridBox . Contains ( Vector2 . Transform ( wpos , state . InvSpaceMatrix ) ) )
2023-10-15 03:48:25 +11:00
state . List . Add ( ( uid , xform ) ) ;
2022-07-08 15:29:43 +12:00
return true ;
}
2023-11-28 20:02:24 -05:00
private static bool SpaceQueryCallback (
2024-06-02 05:07:41 +01:00
ref ( List < ( EntityUid , TransformComponent ) > List , HashSet < EntityUid > Processed , Matrix3x2 InvSpaceMatrix , EntityUid LookupOwner , EntityQuery < TransformComponent > XformQuery , Box2 GridBox , SharedTransformSystem System ) state ,
2022-10-27 23:37:55 +11:00
in FixtureProxy proxy )
{
2023-05-09 19:21:26 +12:00
var uid = proxy . Entity ;
return SpaceQueryCallback ( ref state , in uid ) ;
2022-10-27 23:37:55 +11:00
}
2023-11-19 17:44:42 +00:00
private DamageSpecifier GetDamage ( EntityUid uid ,
string id , DamageSpecifier damage )
2022-04-01 15:39:26 +13:00
{
2023-11-19 17:44:42 +00:00
// TODO Explosion Performance
// Cache this? I.e., instead of raising an event, check for a component?
var resistanceEv = new GetExplosionResistanceEvent ( id ) ;
RaiseLocalEvent ( uid , ref resistanceEv ) ;
resistanceEv . DamageCoefficient = Math . Max ( 0 , resistanceEv . DamageCoefficient ) ;
// ReSharper disable once CompareOfFloatsByEqualityOperator
if ( resistanceEv . DamageCoefficient ! = 1 )
damage * = resistanceEv . DamageCoefficient ;
return damage ;
}
private void GetEntitiesToDamage ( EntityUid uid , DamageSpecifier originalDamage , string prototype )
{
_toDamage . Clear ( ) ;
2023-12-11 09:43:00 +00:00
// don't raise BeforeExplodeEvent if the entity is completely immune to explosions
var thisDamage = GetDamage ( uid , prototype , originalDamage ) ;
2024-05-31 14:28:11 +12:00
if ( thisDamage . Empty )
2023-12-11 09:43:00 +00:00
return ;
_toDamage . Add ( ( uid , thisDamage ) ) ;
2022-04-01 15:39:26 +13:00
2023-11-19 17:44:42 +00:00
for ( var i = 0 ; i < _toDamage . Count ; i + + )
{
var ( ent , damage ) = _toDamage [ i ] ;
_containedEntities . Clear ( ) ;
var ev = new BeforeExplodeEvent ( damage , prototype , _containedEntities ) ;
RaiseLocalEvent ( ent , ref ev ) ;
2022-07-06 23:15:20 -04:00
2023-11-19 17:44:42 +00:00
if ( _containedEntities . Count = = 0 )
continue ;
2023-10-15 03:48:25 +11:00
// ReSharper disable once CompareOfFloatsByEqualityOperator
if ( ev . DamageCoefficient ! = 1 )
damage * = ev . DamageCoefficient ;
2023-11-19 17:44:42 +00:00
_toDamage . EnsureCapacity ( _toDamage . Count + _containedEntities . Count ) ;
foreach ( var contained in _containedEntities )
2022-04-01 15:39:26 +13:00
{
2023-11-19 17:44:42 +00:00
var newDamage = GetDamage ( contained , prototype , damage ) ;
_toDamage . Add ( ( contained , newDamage ) ) ;
2022-04-01 15:39:26 +13:00
}
}
2023-11-19 17:44:42 +00:00
}
2022-04-01 15:39:26 +13:00
2023-11-19 17:44:42 +00:00
/// <summary>
/// This function actually applies the explosion affects to an entity.
/// </summary>
private void ProcessEntity (
EntityUid uid ,
MapCoordinates epicenter ,
DamageSpecifier ? originalDamage ,
float throwForce ,
string id ,
2024-03-14 00:27:08 -04:00
TransformComponent ? xform ,
2024-08-09 08:24:05 +02:00
float? fireStacksOnIgnite ,
EntityUid ? cause )
2023-11-19 17:44:42 +00:00
{
if ( originalDamage ! = null )
2023-11-13 22:57:52 +00:00
{
2023-11-19 17:44:42 +00:00
GetEntitiesToDamage ( uid , originalDamage , id ) ;
foreach ( var ( entity , damage ) in _toDamage )
2023-11-13 22:57:52 +00:00
{
2024-08-09 08:24:05 +02:00
if ( damage . GetTotal ( ) > 0 & & TryComp < ActorComponent > ( entity , out var actorComponent ) )
{
// Log damage to player entities only, cause this will create a massive amount of log spam otherwise.
if ( cause ! = null )
{
_adminLogger . Add ( LogType . ExplosionHit , LogImpact . Medium , $"Explosion of {ToPrettyString(cause):actor} dealt {damage.GetTotal()} damage to {ToPrettyString(entity):subject}" ) ;
}
else
{
_adminLogger . Add ( LogType . ExplosionHit , LogImpact . Medium , $"Explosion at {epicenter:epicenter} dealt {damage.GetTotal()} damage to {ToPrettyString(entity):subject}" ) ;
}
}
2023-11-19 17:44:42 +00:00
// TODO EXPLOSIONS turn explosions into entities, and pass the the entity in as the damage origin.
_damageableSystem . TryChangeDamage ( entity , damage , ignoreResistances : true ) ;
2024-03-14 00:27:08 -04:00
}
}
// ignite
if ( fireStacksOnIgnite ! = null )
{
if ( _flammableQuery . TryGetComponent ( uid , out var flammable ) )
{
flammable . FireStacks + = fireStacksOnIgnite . Value ;
_flammableSystem . Ignite ( uid , uid , flammable ) ;
2023-11-13 22:57:52 +00:00
}
}
2022-04-01 15:39:26 +13:00
// throw
2023-11-19 17:44:42 +00:00
if ( xform ! = null // null implies anchored or in a container
2022-04-01 15:39:26 +13:00
& & ! xform . Anchored
& & throwForce > 0
& & ! EntityManager . IsQueuedForDeletion ( uid )
2023-10-15 03:48:25 +11:00
& & _physicsQuery . TryGetComponent ( uid , out var physics )
2022-04-01 15:39:26 +13:00
& & physics . BodyType = = BodyType . Dynamic )
{
2023-10-15 03:48:25 +11:00
var pos = _transformSystem . GetWorldPosition ( xform ) ;
2024-10-04 14:43:45 +06:00
var dir = pos - epicenter . Position ;
if ( dir . IsLengthZero ( ) )
dir = _robustRandom . NextVector2 ( ) . Normalized ( ) ;
2023-05-07 14:57:23 +12:00
_throwingSystem . TryThrow (
uid ,
2024-10-04 14:43:45 +06:00
dir ,
2023-05-07 14:57:23 +12:00
physics ,
xform ,
2023-10-15 03:48:25 +11:00
_projectileQuery ,
2023-05-07 14:57:23 +12:00
throwForce ) ;
2022-04-01 15:39:26 +13:00
}
}
/// <summary>
/// Tries to damage floor tiles. Not to be confused with the function that damages entities intersecting the
/// grid tile.
/// </summary>
public void DamageFloorTile ( TileRef tileRef ,
2022-04-05 19:22:35 +12:00
float effectiveIntensity ,
int maxTileBreak ,
2022-04-09 09:07:02 +12:00
bool canCreateVacuum ,
2022-04-01 15:39:26 +13:00
List < ( Vector2i GridIndices , Tile Tile ) > damagedTiles ,
ExplosionPrototype type )
{
Upstream sync (#786)
* Box Station - Dechristmassified (#34135)
* dechrismassified
* removed camera from shower
* Marathon Station - Dechristmassified (#34136)
* dechristmassified
* further dechristmassified
* Loop Station Decal and maints additions (#34103)
* many changes
* contentingregrationtests
* serialized invalid removed
* blank
* "Changes and fixes as suggested"
* blank
* blank
* added desk bells
* engi rework rework rework
* added gate to content integration
* tweaks
* aaa
* bbb
* added holopads
* ccc
* Update default.yml
* hotfix
* aaa
* bbb
* many many tweaks and fixes
* aaa
* decals and maints
* aaa
* bbb
* ccc
---------
Co-authored-by: Emisse <99158783+Emisse@users.noreply.github.com>
* Rename cryobed yml file (#34134)
renamed cryopod.yml to cryogenic_sleep_unit.yml
* Cog update (not very merry) (#34144)
removed christmas merry
* bagel update (#34145)
* Add hair pulato (#34117)
* add sprite pulato
* update
* add pulato hair
* add pulato hair
* add pulato hair
* update meta "pulato"
* Automatic changelog update
* Holopad UI tweak for incoming calls (#34137)
* Initial commit
* Update
* Comment correction
* Minor margin increase
* Holopads no longer log broadcasted speech and emotes in the chat (#34114)
Initial commit
* Automatic changelog update
* Fixes borgs not being able to check their laws in crit (#34133)
* fix
* fix2
* Add contraband parent to laser gun safe (#34132)
* Automatic changelog update
* Add Holopad Circuit Board to A/V Communication Technology (#34150)
Added the holopad circuit board to the AV Communication technology and circuit imprinter lathe.
* Automatic changelog update
* Fix disposal signal routers sprites (#34139)
* Fix disposal signal routers sprites
* Remove old shitcode
* Automatic changelog update
* Meta station overhaul (#33506)
* added mail, moved some things around, and fixed a lot of APCs
* fixed my mistakes
* Fixed a few mistakes and AI camera names
* Redid south medbay and more wiring
* Finished sci overhaul, and fixed all issues that I could find.
* rebuilt botany, removed vox box, fixed all known issues.
* Overhauled security
* Minor commit as I prepare to update my copy
* Rebalanced role counts
* Final changes, ready for review!
* Emisse and other people fixed issues with the station
* Finalized changes (for real this time)!
* Standardize shotgun ammo in storagefills (#34156)
shotgun ammo changes
* Automatic changelog update
* meta update (#34158)
* Amber Station Adjustments (#34126)
* Made a couple fixes to various decals, cleaned up some entities, gave the clown their bag and the bartender a handlabeler
* Several changes, more cameras, lighting fixes, adjusted hydro a bit, gave sec a bunch of shutters
* Added new random spawners for science and added them to Amber
* fixed the science spawners and modified amber slightly
* Fixed the random instrument entry
* Fix friendly vent spiders (#34153)
Swapped order of parents for MobGiantSpiderAngry
* Removed UseDelay component from RCD (#34149)
* Automatic changelog update
* Decrease hp for rusted walls (#34043)
* Automatic changelog update
* FIX: Thief beacon doubled steal targets (#33750)
* Automatic changelog update
* remove nukemass song (#34066)
* Automatic changelog update
* Corrected all ghost role names to title case. (#34155)
* Corrected all ghost role names to title case.
* Removes full stop from Hamlet's title.
* Updated ghost role names not in the main ghost roles .ftl
* Two capitals corrections
* Packed Update (Remove Christmas & New Evac) (#34168)
* Packed update (remove christmas, new shuttle)
* Fix invalid
* the voices
* Omega Update (Remove Christmas) (#34174)
omega soap
* Renamed "Irish Car Bomb" drink to "Irish Slammer" (#34107)
* Renamed "Irish Car Bomb" drink to "Irish Slammer", due to concerns over insensitivity.
* Fixing some missed references
* Added prototype id changes to migration.yml. Removed any reference to the troubles (and corrected ale to stout for flavour text).
* Corrected description back to "Irish Cream"
* Removed non-entities from migration.yml
* Automatic changelog update
* Bugfix for the AI player's eye getting stuck when their broadcast is interrupted (#34093)
Initial commit
* Speech is relayed by holopad holograms (#33978)
* Initial commit
* Corrected a field attribute
* Make JPEG a PNG (#34176)
Make 3.png a PNG
* Removed Undesirable Ion Storm Verbs (#34175)
* Remove Undesirable Laws
* empty
* added basic admin logs for PDA notekeeper notes (#34118)
* added basic admin logs for PDA notekeeper notes
* formatting
* added new LogType 'PdaInteract' and changed PDA notekeeper logs to it
---------
Co-authored-by: dylanhunter <dylan2.whittingham@live.uwe.ac.uk>
* Automatic changelog update
* Sprites defined for all non-generic computer boards. Added new syndicate computer board sprite. (#34104)
* Defined sprites for non-generic computer boards. Added new syndicate computer board sprite.
* Added new sprite to meta.json and updated attribution.
* Reformatted module.rsi meta.json to match other meta file styles.
* Syndicate board sprite made less yellow/gold, changed outer chips to black. Using grey/silver for CPU centre, akin to syndie agent PDA theme, and to keep distinctive from security board.
* Corrected indentation spacing for currently edited entities.
* Update Resources/Prototypes/Entities/Objects/Devices/Circuitboards/computer.yml
* add pr link to attribution
---------
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
Co-authored-by: Errant <35878406+Errant-4@users.noreply.github.com>
* Added pricegun sound (#34119)
added pricegun sound
Co-authored-by: dylanhunter <dylan2.whittingham@live.uwe.ac.uk>
* Automatic changelog update
* Separate Tables n' Counters (#32673)
* Update tables.yml
* Remove Extra base: state_
* Update tables.yml
* Automatic changelog update
* Add Chameleon PDA (#30514)
* V1 commit
* Remove PDA name and unnecessary pda state
* Adds PDA to Chameleon backpack & thief toolbox
* Change to use AppearanceDataInit
* Add basic PDA state to ensure there's always a sprite before AppearanceData can be applied
* Revert PDA name (this will be changed to another way later)
* Update PDA name updating to new system
* Fix yaml, and fix Agent ID chameleon
* Updated based on review
* Automatic changelog update
* Add some ion storm actions to replace removed ones (#34180)
* Add some ion storm actions to replace removed ones
* Remove other country references, replace
* Some more tuning of the storm values, removing real-world countries
* boldy basics
* Automatic changelog update
* Amber Station and Science Spawner Tweaks (#34187)
* Modified science spawners a bit since I realized including maints loot was undesireable
* Linked Medical doors to buttons, redesigned the floor of the dining area a bit, placed more science spawners
* Somehow I overlooked that I was importing the maints loot table instead of the sci loot table
* Gave sci an EOD closet
* named the evac shuttle
* Core update (#34201)
add
* Elkridge Depot (The station formerly known as Cell) (#34085)
* named apcs, doors, air alarms, cameras, fire alarms, substations, SMESs
* updated PostMapInitTest.cs to include Cell
* added psychologist spawn
* fixed scanner console link, fixed disposals conveyors, and more
* added janitor service lights, maints firelocks, and more
* added more fun maint rooms
* improved head offices, kitchen, psych. added maints between science and arrivals
* fixed spawners placed over solid objects
* added unique evac shuttle, the Cilium
* evac shuttle is now orientated correctly
* added unique cargo shuttle
* updated kitchen area
* renamed Cell Station to Elkridge Depot, removed most main hall airlocks for smoother travel
* general last-minute touch-ups around the bridge and sec
* changed station name in PostMapInitTest.cs
* Add Elkridge Depot into Map Rotation (#34206)
* named apcs, doors, air alarms, cameras, fire alarms, substations, SMESs
* updated PostMapInitTest.cs to include Cell
* added psychologist spawn
* fixed scanner console link, fixed disposals conveyors, and more
* added janitor service lights, maints firelocks, and more
* added more fun maint rooms
* improved head offices, kitchen, psych. added maints between science and arrivals
* fixed spawners placed over solid objects
* added unique evac shuttle, the Cilium
* evac shuttle is now orientated correctly
* added unique cargo shuttle
* updated kitchen area
* renamed Cell Station to Elkridge Depot, removed most main hall airlocks for smoother travel
* general last-minute touch-ups around the bridge and sec
* changed station name in PostMapInitTest.cs
* added Elkridge to default map pool
* added myself to map_attribution.yml credits
* Automatic changelog update
* Packed Update (#34208)
Packed Update (decals mostly)
* Apply forensics when loading with an ammo box (#32280)
* Automatic changelog update
* Update Credits (#34220)
Co-authored-by: PJBot <pieterjan.briers+bot@gmail.com>
* Fix rainbow lizard plushie inhands (#34128)
* fix rainbow plushie inhands
* address requested changes
* attribute sprites
* wielding refactor/fixes (#32188)
* refactor wieldable events
* fix inconsitency with wielding and use updated events
* wieldable cosmetic refactoring
* Update Content.Shared/Wieldable/Events.cs
Co-authored-by: Centronias <charlie.t.santos@gmail.com>
* real
Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com>
---------
Co-authored-by: deltanedas <@deltanedas:kde.org>
Co-authored-by: Centronias <charlie.t.santos@gmail.com>
Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com>
* Automatic changelog update
* Lobby chat width and custom lobby titles (#33783)
* lobby name cvar
* panel width
* skrek
* server name localization fix
* comment format fix
Co-authored-by: Thomas <87614336+Aeshus@users.noreply.github.com>
* remove redundant newline
Co-authored-by: Thomas <87614336+Aeshus@users.noreply.github.com>
* string.empty
Co-authored-by: Thomas <87614336+Aeshus@users.noreply.github.com>
* use SetWidth
* Update Resources/Locale/en-US/lobby/lobby-gui.ftl
---------
Co-authored-by: Thomas <87614336+Aeshus@users.noreply.github.com>
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Automatic changelog update
* Adds bullet collision to station lights (#34070)
Adds collision with bullets to lights
* Automatic changelog update
* Oasis Update (#34245)
santa is keel.
* Amber Station - Minor Fixes (#34246)
* Moved the stand clear decal in front of the janitor's shutters up two pixels
* added tech maints under most maints doors, fixed power issues in cargo, and fixed a couple minor issues
* Make station anchor hitbox less insufferable (#34217)
* Automatic changelog update
* Remove kessler and zombeteors gamemodes from the secret pool (#34051)
* Remove kessler, zombeteors gameodes
* Probably should keep the protos in case an admin wants to torture players secretly
* address slart review
* Automatic changelog update
* Added distinct ad and bye chatter to Dr. Gibb vending (#34182)
* Added distinct ad and bye chatter to Dr. Gibb vending
* Correcting revert mistake
* Changed ad pack names to better match naming convention
* Implement approved rule changes (#34233)
* Special reagents now appear in the guidebook (#34265)
* Special reagents now appear in the guidebook
* Improved guidebook wording for reagent category
* Automatic changelog update
* Implement approved rule changes (#34233)
* Fix compilation errors in tests from update (#34272)
Required for https://github.com/space-wizards/RobustToolbox/pull/5590 to not cause compile fails, but can be merged on its own
* Fix portable scrubber appearing powered on spawn (#34274)
* [HOTFIX] Fix chameleon PDAs renaming IDs (#34249)
Fix chameleon PDA
* [HOTFIX] Fix Meta station power (#34256)
* hotfix meta power
* fixed AME
* add missing cargo shuttle pilot console to cargo
* Update vessel_warning.ogg (#34263)
* Update vessel_warning.ogg
Remove DC offset and apply short fade out.
* Update attributions.yml
* Update attributions.yml
* Add bleating accent to goats (#34273)
* Automatic changelog update
* Happy New Year (#34288)
happy new year
* Amber Station - Balance Improvements (#34294)
changed the center area in med bay to a garden, weakened meteor shielding in some areas, also general touch ups around the station
* Fixed Loop Station's southern solar array unlinked airlocks (#34296)
Fixed Southern solar external airlock door bolts
* Fix empty lines in adminwho with stealthmins. (#34122)
Don't print newline if admin is hidden.
* Automatic changelog update
* Added missing cameras to Loop Station (#34308)
* Added missing cameras
* Added missing cameras
* Amber Station - Fixes and Warm Lights (#34324)
* Added warm lights, placed them around the map, also fixed an issue with the MV wire in the cafeteria
* Fixed lv wiring in caf, and adjusted a couple things
* Empty commit to force checks to rerun
* Automatic changelog update
* change locking to use ComplexInteraction (#34326)
Co-authored-by: deltanedas <@deltanedas:kde.org>
* Automatic changelog update
* Drink titles and soda vendor consistency (#34178)
* Made capitalisation of proper names consistent.
* Roy Rogers is presumably a proper name.
* Second pass at distinguishing proper names only.
* Two nitpicking/minor changes
* Fixed some overlooked can brand names. Matched case with descriptions.
* Switched generic sodas with brands for SodaInventory
* Removed commonly available branded cans
* Matched case consistency used elsewhere. Minor SPAG corrections.
* Added "nothing" and some missing alcohol bottles to RandomSpawner
* Added distinct ad and bye chatter to Dr. Gibb machines.
* Revert "Added distinct ad and bye chatter to Dr. Gibb machines."
This reverts commit f90b8a470556de05aca81255db8b6b03596ae944.
* Revert "Removed commonly available branded cans"
This reverts commit 43b82168dac1f73b187b7677f34ecdd33b6bb81a.
* Revert "Switched generic sodas with brands for SodaInventory"
This reverts commit f1790f0ce61ef135c79068de6a741e8bb50d85d3.
* Lowercased DrinkGlass suffix. Moved alcoholic drinks from drinks to alcohol.
* Renamed energy drink to Red Bool. Corrected and added some jug descriptions.
* Added reagent names for all bottles except poison-wine
* Revision of title case for cocktails
* SPAG and fixed the only brand reagen with unbranded name.
* Possibly controversial, shortened some bran names to better fit the UI.
* Fixed some inconsistencies in naming
* Matched brand localisation change
* Two name style edits
* Fixed Smite bottle name
* Minor, punctuation
* Blank line to end of file
* Upgraded descriptive names to title case
* Banana Mama
* reverts change, moved to another PR to avoid conflict.
* Removed caffeine reference.
* Minor, corrected some more inconsistencies
* Removed Bottle of Nothing from random spawner.
* Automatic changelog update
* Fix access configurator debug assert (#34330)
* fix
* greytide fix
* fix admin log
* Dirty
* Renamed water melon juice to watermelon juice (#34341)
* Fix battery charging stopping just short of being full (#34028)
* Add copy threshold button to air alarms (#34346)
* Automatic changelog update
* Oasis updoot the dimmining (#34347)
updooty
* Fland Station - Dirt Fix (#34352)
Fland
* Omega Station - Dirt Fix (#34353)
omega
* Marathon Station - Dirt Fix (#34354)
* Marathon
* Rerunning tests
* Cog Station - Dirt Fix (#34355)
Cog
* Box Station - Dirt Fix (#34356)
Box
* Bagel Station - Dirt Fix (#34357)
Bagel
* Packed Station - Dirt Fix (#34351)
* packed
* Rerunning tests
* Replace some sound PlayEntity with PlayPvs (#34317)
* Fixed Forensic Gloves to be Security Contraband (#34193)
* added BaseRestrictedContraband to forensic gloves
* moved from id to parent
* Automatic changelog update
* add large instruments to the cargo request computer (#34240)
* added the church organ to the cargo console (will add more in this PR, assuming i did this right (HOW DO YOU BUY CARGO ORDERS IN DEV ENVIROMENT???? *sobs))
* added other structure instruments to cargo Catalog
* fixed an epic copy/paste fail
* changed prices
* fixed epic copy/paste fail #2
---------
Co-authored-by: TeenSarlacc <baddiepro123@gmail.com>
* Automatic changelog update
* Fix crayon losing durability on stamped paper (#34202)
* Automatic changelog update
* Adds a border to Oppenhopper poster (#34219)
* border
* Update meta.json
* Update Resources/Textures/Structures/Wallmounts/posters.rsi/meta.json
---------
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Trim trailing newlines from examine messages (#33381)
* Trim trailing newlines from examine messages
* TrimTrailingNewlines -> TrimEnd
* Add a popup message when ghost Boo action does nothing (#34369)
* fix ghost_component.ftl locale grammar (#34372)
fix ghost component locale grammar
* Let ghosts sometimes make certain devices say creepy things (#34368)
* Add SpookySpeaker component/system
* Shuffle Boo action targets before trying to activate them
* Add SpookySpeaker to vending machines
* Fix chatcode eating messages starting with "..."
* Add SpookySpeaker to recycler
* Oops
* Decrease speak probability for vending machines
* Add spooky speaker to arcade machines
* Automatic changelog update
* Add directional escape pod sign (#34367)
* Make indestructible tiles not breakable by explosions (#34339)
* No more Ai Spacing
* Move guard into earlier guard statement
* Automatic changelog update
* Arachnid stomach organ yaml fix (#34298)
Arachnid stomach yaml fix
Arachnids had their stomach `updateInterval` set to 1.5, 50% slower than
normal. But this doesn't actually slow down the speed that the stomach
digests things, only the rate at which it updates to check if enough
time has passed. (See https://github.com/space-wizards/space-station-14/blob/23f0b304f284d2600cb2c6b4c9d36fdca7f99ec4/Content.Server/Body/Systems/StomachSystem.cs#L57 )
This PR changes arachnid stomachs to have a `digestionDelay` of 30 (20
is default) to achive the desired effect.
Stasis beds are also bugged in a similar manner. They are intended to
slow down the digestion speed, but similarly all they do is change the
update rate. But fixing that requires actual code changes and is out of
scope for this commit.
* Automatic changelog update
* Bended radiator (#34251)
* Automatic changelog update
* Remove Entity<T> data-fields (#34083)
* Update submodule, .NET 9 (#34320)
* Role Types (#33420)
* mindcomponent namespace
* wip MindRole stuff
* admin player tab
* mindroletype comment
* mindRolePrototype redesign
* broken param
* wip RoleType implementation
* basic role type switching for antags
* traitor fix
* fix AdminPanel update
* the renameningTM
* cleanup
* feature uncreeping
* roletypes on mind roles
* update MindComponent.RoleType when MindRoles change
* ghostrole configuration
* ghostrole config improvements
* live update of roleType on the character window
* logging stuff and notes
* remove thing no one asked for
* weh
* Mind Role Entities wip
* headrev count fix
* silicon stuff, cleanup
* exclusive antag config, cleanup
* jobroleadd overwerite
* logging stuff
* MindHasRole cleanup, admin log stuff
* last second cleanup
* ocd
* move roletypeprototype to its own file, minor note stuff
* remove Roletype.Created
* log stuff
* roletype setup for ghostroles and autotraitor reinforcements
* ghostrole type configs
* adjustable admin overlay
* cleanup
* fix this in its own PR
* silicon antagonist
* borg stuff
* mmi roletype handling
* spawnable borg roletype handling
* weh
* ghost role cleanup
* weh
* RoleEvent update
* polish
* log stuff
* admin overlay config
* ghostrolecomponent cleanup
* weh
* admin overlay code cleanup
* minor cleanup
* Obsolete MindRoleAddedEvent
* comment
* minor code cleanup
* MindOnDoGreeting fix
* Role update message
* fix duplicate job greeting for cyborgs
* fix emag job message dupe
* nicer-looking role type update
* crew aligned
* syndicate assault borg role fix
* fix test fail
* fix a merge mistake
* fix LoneOp role type
* Update Content.Client/Administration/AdminNameOverlay.cs
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Update Content.Shared/Roles/SharedRoleSystem.cs
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* comment formatting
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* change logging category
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* fix a space
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* use MindAddRoles
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* get MindComponent from TryGetMind
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* move var declaration outside loop
* remove TryComp
* take RoleEnum behind the barn
* don't use ensurecomp unnecessarily
* cvar comments
* toggleableghostrolecomponent documentation
* skrek
* use EntProtoId
* mindrole config
* merge baserolecomponent into basemindrolecomponent
* ai and borg silicon role tweaks
* formatting
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* I will end you (the color)
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* use LocId type for a locale id
* update RoleEvent documentation
* update RoleEvent documentation
* remove obsolete MindRoleAddedEvent
* refine MindRolesUpdate()
* use dependency
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* inject dependency
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* roleType.Name no longer required
* reformatted draw code logic
* GhostRoleMarkerRoleComponent comment
* minor SharedRoleSystem cleanup
* StartingMindRoleComponent, unhardcode roundstart silicon
* Update Content.Shared/Roles/SharedRoleSystem.cs
* remove a whitespace
---------
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Automatic changelog update
* Update Credits (#34389)
Co-authored-by: PJBot <pieterjan.briers+bot@gmail.com>
* Elkridge Depot Improvements (#34377)
* updates decals
* more decal work, more dinginess in certain areas
* added decals under doors
* Fix force-feeding Loc strings not using target's gender (#34276)
* HOTFIX Tweaked air alarm default settings for nitrogen breathing crew (#34198)
air alarm default settings modified for anaerobic crew
* #33571 Bomb defusal lockers always should have tools (#34394)
* Automatic changelog update
* [HOTFIX] fix holopads with multiple ai cores dying (#34289)
change return to continue
Co-authored-by: deltanedas <@deltanedas:kde.org>
* Reduce Panic Bunker Minimum Playtime to 2 hours (#34401)
* Add IPIntel API support. (#33339)
Co-authored-by: PJB3005 <pieterjan.briers+git@gmail.com>
* Automatic changelog update
* Fland Reporters Room (#34408)
changed the command checkpoint to a reporters room.
* Automatic changelog update
* Add a high-capacity water tank to the janitor's closet of Oasis (#34366)
added high capacity water tank
* Darkened Service job interface icons for better contrast (#34270)
* Darkened Service job interface icons for better contrast
* Fixed Botanist job interface icon dark handle hole
* Change to new, darker, service color in all resource yml files
* Revert Map file service color changes
* Use new darker service color on id cards
* Revert Service color change in mapping_actions.yml
* Revert salvage difficulties service color
* Redo service ID and job colors to match advanced palette
* Revert all service color yml file changes
* Switch icons to use existing service pallete colors from advanced pallete
* Update meta.json for darkened service icons
---------
Co-authored-by: Erskin Cherry <frobnic8@gmail.com>
* Amber Station - Moved Vents Around (#34410)
* Moved all vents around, made some small changes
* Finished work
* Removed insuls spawner since they're not merged yet
* Insuls Spawner (#34407)
* Added insuls spawner, time to test
* adjusted whitespace since that was causing issues
* Update Resources/Prototypes/Entities/Markers/Spawners/Random/maintenance.yml
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
---------
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Manual Valves Resprite (#34378)
* resprited manual valves to be colourblind friendly
* Update Resources/Textures/Structures/Piping/Atmospherics/pump.rsi/meta.json
Co-authored-by: Errant <35878406+Errant-4@users.noreply.github.com>
---------
Co-authored-by: Errant <35878406+Errant-4@users.noreply.github.com>
* Automatic changelog update
* loop station door access fixes and air sink (#34414)
small fixes
* Raise syndicate kobold reinforcement HP crit threshold from 75 to 100 to match monkey. (#34409)
kobold ops have 100 health
* Anomaly dragging exploit fix and QOL changes (#34280)
* Wood wall is now built from barricade congraph and on top of a barricade instead of using rods
* APE dragging exploit fix
* Fixed doors being blocked with mousetraps, and other Collidable items (#34045)
* Changed SharedDoorSystem.GetColliding() to allow non-LowImpassible mask entities to stay in the door while it closes
* Update Content.Shared/Doors/Systems/SharedDoorSystem.cs
Clarifies comment of how the mask is used
Co-authored-by: Centronias <charlie.t.santos@gmail.com>
---------
Co-authored-by: Centronias <charlie.t.santos@gmail.com>
* Fixed Jazz Instrument for Electric Guitars (#33363)
* fixed jazz midi program byte
* swapped around jazz and clean in instrumentList
* Automatic changelog update
* Porting Pride-O-Mat to Upstream (#34412)
* Pride-O-Mat (#1322)
* Added Pride-O-Mat
* Yep
* Updated license to the correct one
* Added more lines, reconfigured settings a bit, also added cloaks to inventory, set coder socks to emag inventory
* Removed bunny ears, fixed typo
* Made requested changes
Webedit lmao
---------
Co-authored-by: Dorragon <101672978+Dorragon@users.noreply.github.com>
* Automatic changelog update
* Oasis Power Rebalance + Misc fixes (#34425)
* balance oasis power as a stopgap
* change waste color to proper waste color
* Fix IPIntel causing frequent errors with the cleanup job. (#34428)
Co-authored-by: Pieter-Jan Briers <pieterjan.briers@gmail.com>
* craftable pet carrier (#34431)
* craftable pet carrier
* epic integration test fail
* Update Resources/Prototypes/Recipes/Crafting/improvised.yml
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Update Resources/Prototypes/Recipes/Crafting/Graphs/storage/pet_carrier.yml
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Update Resources/Prototypes/Recipes/Crafting/Graphs/storage/pet_carrier.yml
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Update Resources/Prototypes/Entities/Objects/Misc/pet_carrier.yml
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* extra tab begone
* epic linter fail
* how did linter not see this???
---------
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Automatic changelog update
* Adds omnisexual pin (#34439)
* Make important change (#7)
This is to help julian test his bot
* Omnibus
* Remove random test file from testing a gh bot
* Add pin to vendor, spawners and loadout
---------
Co-authored-by: nikthechampiongr <32041239+nikthechampiongr@users.noreply.github.com>
* Fix bad Rider analysis error in AccessOverriderWindow.xaml.cs (#34213)
* Disable meta-atlas for big rare RSIs (#33643)
* Persist deadmin to database, add admin suspension system (#34048)
* Automatic changelog update
* STAThread client content start (#34212)
* Minor client packaging changes (#33787)
* Fix muzzle accent (#34419)
* Automatic changelog update
* Add Discord webhook on watchlist connection (#33483)
* Automatic changelog update
* Fixed Thief starting gear failing on specific bag inventories. (#34430)
Fixed it yayyy
* Added missing details from worn capes to head of department beadsheets (#34396)
* Added key and missing details from worn cape to HOP bedsheet
* Corrected canvas size for sprite
* Subtle tweak to shading to reduce color blurring at pillow edge
* Matched Hue and tone to cape
* Tweak chekered pattern marks for gold trim
* Removed accidental palette inclusion
* Clearer wording and corrected attribution name.
* Tweaked shading on key image to fit in better with bed aesthetics
* Added CE cape icon to bedsheet
* Added cape image to HOP bedsheet. Made gold trim better match cape visuals
* RD cape icon added. Colour tweaked to better match cape.
* Updates json
* Tweaks to gold trim shading to match bed aesthetics
* Added better shading for HOP sheet side. Halved file size.
* Optimised HOS RD and CE sheet sprites
* Corrected sprite title in attribution
* Replace ERT Medic's Advanced Medkits with 2 Combat Medkits (#34380)
Replaced Adv kits with 2 combat kits
* Fix nonsensical RegEx for name restriction (#34375)
* Fixed nonsense RegEx
"-" character is a range, caused an error.
No need for "," to repeat so much, it's not a separator.
"\\" - just why?
* Further optimized RegEx structure
Added:
"@" delimiter for consistency
"/" to escape "-" for good and to avoid further problems
* Remove the ability to print the station anchor circuit board (#34358)
remove the ability to print the station anchor circuit board
* Automatic changelog update
* Meta hotfix (#34306)
* Fixed major issues with power, cargo shuttle docking, etc.
* remove serialized invalids
* Finished fixing the critical issues, ready for merge?
* Empty commit
* Added new break room to sci (they deserve it)
* Fixed up other minor issues
* if this map isnt PERFECT Emisse has permission to gib me and turn me into a cyborg
* added Roomba's changes
---------
Co-authored-by: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com>
* Make Mime PDA interactions silent (#34426)
* make insert and eject datafields in ItemSlotsComponent.cs nullable, make mime PDA silent
* make it so that you can't fit wirecutters into the slots, among other various things
* Automatic changelog update
* Smite vending machine (#34420)
* Added smite machine to YAML
* Added smite ads and inventory
* Added smite vendor sprites
* Changed the description of the machine to not repeat and ad line.
* Added newline to end of inventory .yml
* Corrected erroneous edit.
* Tweaked all sprites
* Added tesla toy to contraband. Reduced number of drinks available
* Reduced soda varieties but increased can numbers.
* Removed tesla toy from contraband inventory
* Removed speech component from vending machines that already inherit it
* Moved Sprite component to top of list
* Added Smite vendors to random spanwers
* Alphabetised spawn prototypes, commented where name is unclear
* Automatic changelog update
* Printable bedsheets (#34034)
* Bedsheets
* that one fixes yellow bedsheet and delete american bedsheet
* Automatic changelog update
* Update RT to v239.0.1 (#34454)
* Remove christmas anomaly spawn (#34053)
Update anomaly.yml
* Automatic changelog update
* Remove baby jail (#34443)
* Remove baby jail
Closes #33893
* Test fail fix.
* Add a CCVar to allow from hiding admins in the reported player count. (#34406)
Good for:
- Keeping admins hidden
- Not confuse players seeing 84/80 players
Nicely pairs up with the ``admin.admins_count_for_max_players`` ccvar
* Automatic changelog update
* Fix Mixed puddles not updating slips when evap (#34303)
* Fix Mixed puddles not updating slips when evap
* Remove Comment that isn't needed
Co-authored-by: Centronias <charlie.t.santos@gmail.com>
* CR - use SolutionContainerSystem.UpdateChemicals
* CR - cleanup unused imports
---------
Co-authored-by: Centronias <charlie.t.santos@gmail.com>
* Automatic changelog update
* WizDen config update for IPIntel (#34457)
* Fix DNA scrambler updating station record (#34091)
* Fix DNA scrambler updating station record
* Update Content.Server/Implants/SubdermalImplantSystem.cs
---------
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Automatic changelog update
* New and Modified Map Spawners (#34424)
* Added spanwers and modified others
* adjusted values to be more in line with what I want
* this comment may have caused that test fail
* oh my god another typo
* Modified door crate to be engineering flavored
* reduced the pride vendor odds
Webedit lmao
* Elkridge Depot Fixes Again (#34461)
fixes evac shuttle, fix north solars, fix vents and scrubbers
* Space Ruins Variant (#34445)
* Space Ruins Variant
* Updated File
* Added Goliaths/Removed some mobs
* Plasma Station (#33991)
* Plasma Station initial commit
* Map fixes 1
Expanded science's SMES array
Added advanced SMES
Redone stamped documents with custom stamps
Expanded atmospherics with more storage tanks
Added status displays
Add missing beacons to solars
Replaced the passive gates in science with valves
Removed protolathe in engineering
Added guitar to CE office
Replaced throngler plushie with weh cloak
Add a lattice tile outside the atmos burn chamber and storange tanks
Added atmos network monitor in bridge
* Add cargo and emergency shuttle
* Updated maps
* Add plasma to map testing list
* Map fixes 2
Reworked pipenets to not go under walls
Redid salvage and disposals
Reworked the bar to include a new bar extension facing the pool
Replaced arrivals cryo with an arcade
Replaced the toilets in the service plaza with cryo
Removed the cryo in dorms
Added more details to hallways
Redid tools room to include a front desk for the janitor closet
Reconnected sci to power roundstart
Removed some unideal spawns
Expanded the TEG airlock to be 2x3 instead of 1x3
Reduced the size of the SMES bank from 10 to 6
Disabled the plasma miners (downstreams or admins can re-enable them)
Replaced illegal maint items
* Fixes a 6 pack destroying the universe
Ok maybe cracking a cold one with the boys wasn't a great idea.
* Map fixes 3
* Quick research assistant fix
* Map fixes 4
* Map fixes 5
* webedit go brrrt
* Map fixes 6
* Map fixes 7
* Map fixes 8
* Fixes non-existent object
It's amazing this game runs at all
* Map fixes 9
* update pools
* Map fixes 10
* forgot to clear my multitool
I love mapping I love mapping I love mapping I love mapping I love mapping
---------
Co-authored-by: Emisse <99158783+Emisse@users.noreply.github.com>
* Automatic changelog update
* Plasma station population tweak (#34462)
* Plasma Station initial commit
* Map fixes 1
Expanded science's SMES array
Added advanced SMES
Redone stamped documents with custom stamps
Expanded atmospherics with more storage tanks
Added status displays
Add missing beacons to solars
Replaced the passive gates in science with valves
Removed protolathe in engineering
Added guitar to CE office
Replaced throngler plushie with weh cloak
Add a lattice tile outside the atmos burn chamber and storange tanks
Added atmos network monitor in bridge
* Add cargo and emergency shuttle
* Updated maps
* Add plasma to map testing list
* Map fixes 2
Reworked pipenets to not go under walls
Redid salvage and disposals
Reworked the bar to include a new bar extension facing the pool
Replaced arrivals cryo with an arcade
Replaced the toilets in the service plaza with cryo
Removed the cryo in dorms
Added more details to hallways
Redid tools room to include a front desk for the janitor closet
Reconnected sci to power roundstart
Removed some unideal spawns
Expanded the TEG airlock to be 2x3 instead of 1x3
Reduced the size of the SMES bank from 10 to 6
Disabled the plasma miners (downstreams or admins can re-enable them)
Replaced illegal maint items
* Fixes a 6 pack destroying the universe
Ok maybe cracking a cold one with the boys wasn't a great idea.
* Map fixes 3
* Quick research assistant fix
* Map fixes 4
* Map fixes 5
* webedit go brrrt
* Map fixes 6
* Map fixes 7
* Map fixes 8
* Fixes non-existent object
It's amazing this game runs at all
* Map fixes 9
* update pools
* Map fixes 10
* forgot to clear my multitool
I love mapping I love mapping I love mapping I love mapping I love mapping
* Tweaked player counts
---------
Co-authored-by: Emisse <99158783+Emisse@users.noreply.github.com>
* Automatic changelog update
* Fix inconsistent borg flashlight state (#33027)
* Fix borg light being stuck on if no cell is inserted
* Fix HandheldLightComponent.Activted becoming out of sync with SharedPointLightComponent.Enabled
* Fix for entities which don't have a handheld light component
* FIX: Uranium, Cak, and BreadDog are not garbage! (#34192)
* FIX: Uranium, Cak, and BreadDog are not garbage!
* Fixed bread typo for spacegarbage change.
* Style: moved ediblebase
* Update Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/bread.yml
* Update Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/cake.yml
---------
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Automatic changelog update
* Fix the HoS mantle metashield break (#33831)
Changes 'nukies' to 'syndicate agents' in the HoS mantle's description.
* fix for climbable pianos (#33690)
fix for climable pianos
Co-authored-by: aa5g21 <aa5g21@soton.ac.uk>
* Automatic changelog update
* BorgChassis transfer their mind to a dropped BorgBrain fix (#34464)
Fix
* Staging: Add taped logo back for 10th anniversary (#34486)
* Update engine to v240.0.1 (#34497)
* mind roles
* partial ritual serialization fix
* Update CP14RoundEndSystem.cs
* delete worldEdge system
* Delete StencilOverlay.WorldEdge.cs
* Update CP14MagicEffectComponent.cs
* delete rituals system
* fix demiplane serialization
* mapdamage fix serialization
* common objectives fix
* remove failed personal goals endscreen
* fix special selling, fix serialization
* more fixes
* more fixes x2
* final bruh
* fix
---------
Co-authored-by: Southbridge <7013162+southbridge-fur@users.noreply.github.com>
Co-authored-by: TytosB <54259736+TytosB@users.noreply.github.com>
Co-authored-by: Emisse <99158783+Emisse@users.noreply.github.com>
Co-authored-by: Booblesnoot42 <108703193+Booblesnoot42@users.noreply.github.com>
Co-authored-by: Spessmann <156740760+Spessmann@users.noreply.github.com>
Co-authored-by: ~DreamlyJack~ <148849095+DreamlyJack@users.noreply.github.com>
Co-authored-by: PJBot <pieterjan.briers+bot@gmail.com>
Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com>
Co-authored-by: PopGamer46 <yt1popgamer@gmail.com>
Co-authored-by: crazybrain23 <44417085+crazybrain23@users.noreply.github.com>
Co-authored-by: amatwiedle <amatwiedle@gmail.com>
Co-authored-by: justdie12 <125140938+justdie12@users.noreply.github.com>
Co-authored-by: Nox <nebulousnox38@gmail.com>
Co-authored-by: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com>
Co-authored-by: lzk <124214523+lzk228@users.noreply.github.com>
Co-authored-by: ReeZer2 <63300653+ReeZer2@users.noreply.github.com>
Co-authored-by: Errant <35878406+Errant-4@users.noreply.github.com>
Co-authored-by: Alpaccalypse <21291379+Alpaccalypse@users.noreply.github.com>
Co-authored-by: Spanky <scott@wearejacob.com>
Co-authored-by: Thomas <87614336+Aeshus@users.noreply.github.com>
Co-authored-by: Dylan Hunter Whittingham <45404433+DylanWhittingham@users.noreply.github.com>
Co-authored-by: dylanhunter <dylan2.whittingham@live.uwe.ac.uk>
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
Co-authored-by: Ps3Moira <113228053+ps3moira@users.noreply.github.com>
Co-authored-by: SlamBamActionman <83650252+SlamBamActionman@users.noreply.github.com>
Co-authored-by: Hannah Giovanna Dawson <karakkaraz@gmail.com>
Co-authored-by: Ubaser <134914314+UbaserB@users.noreply.github.com>
Co-authored-by: Deerstop <edainturner@gmail.com>
Co-authored-by: themias <89101928+themias@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: deltanedas <39013340+deltanedas@users.noreply.github.com>
Co-authored-by: Centronias <charlie.t.santos@gmail.com>
Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com>
Co-authored-by: SpaceRox1244 <138547931+SpaceRox1244@users.noreply.github.com>
Co-authored-by: IProduceWidgets <107586145+IProduceWidgets@users.noreply.github.com>
Co-authored-by: nikthechampiongr <32041239+nikthechampiongr@users.noreply.github.com>
Co-authored-by: Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
Co-authored-by: Tayrtahn <tayrtahn@gmail.com>
Co-authored-by: Pancake <Pangogie@users.noreply.github.com>
Co-authored-by: Piras314 <p1r4s@proton.me>
Co-authored-by: flymo5678 <86871317+flymo5678@users.noreply.github.com>
Co-authored-by: c4llv07e <igor@c4llv07e.xyz>
Co-authored-by: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com>
Co-authored-by: Coolsurf6 <coolsurf24@yahoo.com.au>
Co-authored-by: TeenSarlacc <46608342+TeenSarlacc@users.noreply.github.com>
Co-authored-by: TeenSarlacc <baddiepro123@gmail.com>
Co-authored-by: SpaceManiac <tad@platymuus.com>
Co-authored-by: War Pigeon <54217755+minus1over12@users.noreply.github.com>
Co-authored-by: Zachary Higgs <compgeek223@gmail.com>
Co-authored-by: 0x6273 <0x40@keemail.me>
Co-authored-by: Floxington <florian.decker@mailbox.org>
Co-authored-by: Myra <vasilis@pikachu.systems>
Co-authored-by: SlimSlam <73899110+Stewie523@users.noreply.github.com>
Co-authored-by: frobnic8 <erskin@eldritch.org>
Co-authored-by: Erskin Cherry <frobnic8@gmail.com>
Co-authored-by: hyperDelegate <zachary1064@gmail.com>
Co-authored-by: JustinWinningham <justinmwinningham@gmail.com>
Co-authored-by: zHonys <69396539+zHonys@users.noreply.github.com>
Co-authored-by: Dorragon <101672978+Dorragon@users.noreply.github.com>
Co-authored-by: Pieter-Jan Briers <pieterjan.briers@gmail.com>
Co-authored-by: Killerqu00 <47712032+Killerqu00@users.noreply.github.com>
Co-authored-by: Julian Giebel <juliangiebel@live.de>
Co-authored-by: Palladinium <patrick.chieppe@hotmail.com>
Co-authored-by: Alpha-Two <92269094+Alpha-Two@users.noreply.github.com>
Co-authored-by: Hyper B <137433177+HyperB1@users.noreply.github.com>
Co-authored-by: kosticia <kosticia46@gmail.com>
Co-authored-by: compilatron <40789662+jbox144@users.noreply.github.com>
Co-authored-by: eoineoineoin <github@eoinrul.es>
Co-authored-by: Patrik Caes-Sayrs <heartofgoldfish@gmail.com>
Co-authored-by: ApolloVector <149586366+ApolloVector@users.noreply.github.com>
Co-authored-by: Gansu <68031780+GansuLalan@users.noreply.github.com>
Co-authored-by: aa5g21 <aa5g21@soton.ac.uk>
2025-01-21 23:57:12 +03:00
if ( _tileDefinitionManager [ tileRef . Tile . TypeId ] is not ContentTileDefinition tileDef
| | tileDef . Indestructible )
2022-04-09 09:07:02 +12:00
return ;
2024-04-30 20:11:27 -07:00
if ( ! CanCreateVacuum )
canCreateVacuum = false ;
else if ( tileDef . MapAtmosphere )
2022-04-09 09:07:02 +12:00
canCreateVacuum = true ; // is already a vacuum.
2022-04-01 15:39:26 +13:00
2022-04-05 19:22:35 +12:00
int tileBreakages = 0 ;
while ( maxTileBreak > tileBreakages & & _robustRandom . Prob ( type . TileBreakChance ( effectiveIntensity ) ) )
2022-04-01 15:39:26 +13:00
{
2022-04-05 19:22:35 +12:00
tileBreakages + + ;
effectiveIntensity - = type . TileBreakRerollReduction ;
2022-04-01 15:39:26 +13:00
2022-04-09 09:07:02 +12:00
// does this have a base-turf that we can break it down to?
2023-05-19 08:10:56 +01:00
if ( string . IsNullOrEmpty ( tileDef . BaseTurf ) )
2022-04-01 15:39:26 +13:00
break ;
2023-05-19 08:10:56 +01:00
if ( _tileDefinitionManager [ tileDef . BaseTurf ] is not ContentTileDefinition newDef )
2022-04-09 09:07:02 +12:00
break ;
2024-03-24 03:34:56 +11:00
if ( newDef . MapAtmosphere & & ! canCreateVacuum )
2022-04-01 15:39:26 +13:00
break ;
2022-04-09 09:07:02 +12:00
tileDef = newDef ;
2022-04-01 15:39:26 +13:00
}
if ( tileDef . TileId = = tileRef . Tile . TypeId )
return ;
damagedTiles . Add ( ( tileRef . GridIndices , new Tile ( tileDef . TileId ) ) ) ;
}
}
/// <summary>
/// This is a data class that stores information about the area affected by an explosion, for processing by <see
/// cref="ExplosionSystem"/>.
/// </summary>
/// <remarks>
2022-04-05 19:22:35 +12:00
/// This is basically the output of <see cref="ExplosionSystem.GetExplosionTiles()"/>, but with some utility functions for
/// iterating over the tiles, along with the ability to keep track of what entities have already been damaged by
2022-04-01 15:39:26 +13:00
/// this explosion.
/// </remarks>
sealed class Explosion
{
2022-04-05 19:22:35 +12:00
/// <summary>
/// For every grid (+ space) that the explosion reached, this data struct stores information about the tiles and
/// caches the entity-lookup component so that it doesn't have to be re-fetched for every tile.
/// </summary>
2022-04-01 15:39:26 +13:00
struct ExplosionData
{
2022-04-05 19:22:35 +12:00
/// <summary>
/// The tiles that the explosion damaged, grouped by the iteration (can be thought of as the distance from the epicenter)
/// </summary>
2022-04-01 15:39:26 +13:00
public Dictionary < int , List < Vector2i > > TileLists ;
2022-04-05 19:22:35 +12:00
/// <summary>
/// Lookup component for this grid (or space/map).
/// </summary>
2022-10-27 23:37:55 +11:00
public BroadphaseComponent Lookup ;
2022-04-05 19:22:35 +12:00
/// <summary>
/// The actual grid that this corresponds to. If null, this implies space.
/// </summary>
2022-11-22 13:12:04 +11:00
public MapGridComponent ? MapGrid ;
2022-04-01 15:39:26 +13:00
}
2022-04-05 19:22:35 +12:00
private readonly List < ExplosionData > _explosionData = new ( ) ;
/// <summary>
/// The explosion intensity associated with each tile iteration.
/// </summary>
private readonly List < float > _tileSetIntensity ;
2022-04-01 15:39:26 +13:00
/// <summary>
/// Used to avoid applying explosion effects repeatedly to the same entity. Particularly important if the
/// explosion throws this entity, as then it will be moving while the explosion is happening.
/// </summary>
public readonly HashSet < EntityUid > ProcessedEntities = new ( ) ;
/// <summary>
2022-04-06 19:35:18 +10:00
/// This integer tracks how much of this explosion has been processed.
2022-04-01 15:39:26 +13:00
/// </summary>
public int CurrentIteration { get ; private set ; } = 0 ;
2022-04-05 19:22:35 +12:00
/// <summary>
/// The prototype for this explosion. Determines tile break chance, damage, etc.
/// </summary>
2022-04-01 15:39:26 +13:00
public readonly ExplosionPrototype ExplosionType ;
2022-04-05 19:22:35 +12:00
/// <summary>
/// The center of the explosion. Used for physics throwing. Also used to identify the map on which the explosion is happening.
/// </summary>
2022-04-01 15:39:26 +13:00
public readonly MapCoordinates Epicenter ;
2022-04-05 19:22:35 +12:00
/// <summary>
2022-07-08 15:29:43 +12:00
/// The matrix that defines the reference frame for the explosion in space.
2022-04-05 19:22:35 +12:00
/// </summary>
2024-06-02 05:07:41 +01:00
private readonly Matrix3x2 _spaceMatrix ;
2022-04-01 15:39:26 +13:00
2022-04-05 19:22:35 +12:00
/// <summary>
/// Inverse of <see cref="_spaceMatrix"/>
/// </summary>
2024-06-02 05:07:41 +01:00
private readonly Matrix3x2 _invSpaceMatrix ;
2022-04-01 15:39:26 +13:00
2022-04-05 19:22:35 +12:00
/// <summary>
/// Have all the tiles on all the grids been processed?
/// </summary>
2022-04-01 15:39:26 +13:00
public bool FinishedProcessing ;
2022-04-05 19:22:35 +12:00
// Variables used for enumerating over tiles, grids, etc
2022-04-01 15:39:26 +13:00
private DamageSpecifier _currentDamage = default ! ;
2023-10-15 03:48:25 +11:00
#if DEBUG
private DamageSpecifier ? _expectedDamage ;
#endif
2022-10-27 23:37:55 +11:00
private BroadphaseComponent _currentLookup = default ! ;
2022-11-22 13:12:04 +11:00
private MapGridComponent ? _currentGrid ;
2022-04-01 15:39:26 +13:00
private float _currentIntensity ;
private float _currentThrowForce ;
private List < Vector2i > . Enumerator _currentEnumerator ;
private int _currentDataIndex ;
2022-04-05 19:22:35 +12:00
/// <summary>
/// The set of tiles that need to be updated when the explosion has finished processing. Used to avoid having
/// the explosion trigger chunk regeneration & shuttle-system processing every tick.
/// </summary>
2022-11-22 13:12:04 +11:00
private readonly Dictionary < MapGridComponent , List < ( Vector2i , Tile ) > > _tileUpdateDict = new ( ) ;
2022-04-05 19:22:35 +12:00
// Entity Queries
private readonly EntityQuery < TransformComponent > _xformQuery ;
private readonly EntityQuery < PhysicsComponent > _physicsQuery ;
private readonly EntityQuery < DamageableComponent > _damageQuery ;
2023-05-07 14:57:23 +12:00
private readonly EntityQuery < ProjectileComponent > _projectileQuery ;
private readonly EntityQuery < TagComponent > _tagQuery ;
2022-04-05 19:22:35 +12:00
/// <summary>
/// Total area that the explosion covers.
/// </summary>
public readonly int Area ;
/// <summary>
/// factor used to scale the tile break chances.
/// </summary>
private readonly float _tileBreakScale ;
2022-04-01 15:39:26 +13:00
2022-04-05 19:22:35 +12:00
/// <summary>
/// Maximum number of times that an explosion will break a single tile.
/// </summary>
private readonly int _maxTileBreak ;
2022-04-01 15:39:26 +13:00
2022-04-09 09:07:02 +12:00
/// <summary>
/// Whether this explosion can turn non-vacuum tiles into vacuum-tiles.
/// </summary>
private readonly bool _canCreateVacuum ;
2022-04-05 19:22:35 +12:00
private readonly IEntityManager _entMan ;
2022-04-01 15:39:26 +13:00
private readonly ExplosionSystem _system ;
2024-09-29 02:27:47 +03:00
private readonly SharedMapSystem _mapSystem ;
2022-04-01 15:39:26 +13:00
2022-11-27 23:24:35 +13:00
public readonly EntityUid VisualEnt ;
2024-08-09 08:24:05 +02:00
public readonly EntityUid ? Cause ;
2022-04-05 19:22:35 +12:00
/// <summary>
/// Initialize a new instance for processing
/// </summary>
2022-04-01 15:39:26 +13:00
public Explosion ( ExplosionSystem system ,
ExplosionPrototype explosionType ,
2022-04-05 19:22:35 +12:00
ExplosionSpaceTileFlood ? spaceData ,
List < ExplosionGridTileFlood > gridData ,
2022-04-01 15:39:26 +13:00
List < float > tileSetIntensity ,
MapCoordinates epicenter ,
2024-06-02 05:07:41 +01:00
Matrix3x2 spaceMatrix ,
2022-04-01 15:39:26 +13:00
int area ,
2022-04-05 19:22:35 +12:00
float tileBreakScale ,
int maxTileBreak ,
2022-04-09 09:07:02 +12:00
bool canCreateVacuum ,
2022-04-01 15:39:26 +13:00
IEntityManager entMan ,
2022-11-27 23:24:35 +13:00
IMapManager mapMan ,
2024-08-09 08:24:05 +02:00
EntityUid visualEnt ,
2024-09-29 02:27:47 +03:00
EntityUid ? cause ,
SharedMapSystem mapSystem )
2022-04-01 15:39:26 +13:00
{
2022-11-27 23:24:35 +13:00
VisualEnt = visualEnt ;
2024-08-09 08:24:05 +02:00
Cause = cause ;
2022-04-01 15:39:26 +13:00
_system = system ;
2024-09-29 02:27:47 +03:00
_mapSystem = mapSystem ;
2022-04-01 15:39:26 +13:00
ExplosionType = explosionType ;
_tileSetIntensity = tileSetIntensity ;
Epicenter = epicenter ;
Area = area ;
2022-04-05 19:22:35 +12:00
_tileBreakScale = tileBreakScale ;
_maxTileBreak = maxTileBreak ;
2022-04-09 09:07:02 +12:00
_canCreateVacuum = canCreateVacuum ;
2022-04-05 19:22:35 +12:00
_entMan = entMan ;
2022-04-01 15:39:26 +13:00
_xformQuery = entMan . GetEntityQuery < TransformComponent > ( ) ;
_physicsQuery = entMan . GetEntityQuery < PhysicsComponent > ( ) ;
_damageQuery = entMan . GetEntityQuery < DamageableComponent > ( ) ;
2023-05-07 14:57:23 +12:00
_tagQuery = entMan . GetEntityQuery < TagComponent > ( ) ;
_projectileQuery = entMan . GetEntityQuery < ProjectileComponent > ( ) ;
2022-04-01 15:39:26 +13:00
if ( spaceData ! = null )
{
var mapUid = mapMan . GetMapEntityId ( epicenter . MapId ) ;
_explosionData . Add ( new ( )
{
TileLists = spaceData . TileLists ,
2022-10-27 23:37:55 +11:00
Lookup = entMan . GetComponent < BroadphaseComponent > ( mapUid ) ,
2022-04-01 15:39:26 +13:00
MapGrid = null
} ) ;
_spaceMatrix = spaceMatrix ;
2024-06-02 05:07:41 +01:00
Matrix3x2 . Invert ( spaceMatrix , out _invSpaceMatrix ) ;
2022-04-01 15:39:26 +13:00
}
foreach ( var grid in gridData )
{
2023-01-19 03:56:45 +01:00
_explosionData . Add ( new ExplosionData
2022-04-01 15:39:26 +13:00
{
TileLists = grid . TileLists ,
2023-01-19 03:56:45 +01:00
Lookup = entMan . GetComponent < BroadphaseComponent > ( grid . Grid . Owner ) ,
MapGrid = grid . Grid ,
2022-04-01 15:39:26 +13:00
} ) ;
}
if ( TryGetNextTileEnumerator ( ) )
MoveNext ( ) ;
}
2022-04-05 19:22:35 +12:00
/// <summary>
/// Find the next tile-enumerator. This either means retrieving a set of tiles on the next grid, or incrementing
/// the tile iteration by one and moving back to the first grid. This will also update the current damage, current entity-lookup, etc.
/// </summary>
2022-04-01 15:39:26 +13:00
private bool TryGetNextTileEnumerator ( )
{
while ( CurrentIteration < _tileSetIntensity . Count )
{
_currentIntensity = _tileSetIntensity [ CurrentIteration ] ;
2023-10-15 03:48:25 +11:00
2024-03-14 00:27:08 -04:00
#if DEBUG
2023-10-15 03:48:25 +11:00
if ( _expectedDamage ! = null )
{
// Check that explosion processing hasn't somehow accidentally mutated the damage set.
DebugTools . Assert ( _expectedDamage . Equals ( _currentDamage ) ) ;
_expectedDamage = ExplosionType . DamagePerIntensity * _currentIntensity ;
}
2024-03-14 00:27:08 -04:00
#endif
2023-10-15 03:48:25 +11:00
2022-04-01 15:39:26 +13:00
_currentDamage = ExplosionType . DamagePerIntensity * _currentIntensity ;
// only throw if either the explosion is small, or if this is the outer ring of a large explosion.
var doThrow = Area < _system . ThrowLimit | | CurrentIteration > _tileSetIntensity . Count - 6 ;
_currentThrowForce = doThrow ? 10 * MathF . Sqrt ( _currentIntensity ) : 0 ;
// for each grid/space tile set
while ( _currentDataIndex < _explosionData . Count )
{
// try get any tile hash-set corresponding to this intensity
var tileSets = _explosionData [ _currentDataIndex ] . TileLists ;
if ( ! tileSets . TryGetValue ( CurrentIteration , out var tileList ) )
{
_currentDataIndex + + ;
continue ;
}
_currentEnumerator = tileList . GetEnumerator ( ) ;
_currentLookup = _explosionData [ _currentDataIndex ] . Lookup ;
_currentGrid = _explosionData [ _currentDataIndex ] . MapGrid ;
_currentDataIndex + + ;
2022-04-05 19:22:35 +12:00
// sanity checks, in case something changed while the explosion was being processed over several ticks.
2022-12-12 14:59:02 +11:00
if ( _currentLookup . Deleted | | _currentGrid ! = null & & ! _entMan . EntityExists ( _currentGrid . Owner ) )
2022-04-05 19:22:35 +12:00
continue ;
2022-04-01 15:39:26 +13:00
return true ;
}
2022-04-05 19:22:35 +12:00
// All the tiles belonging to this explosion iteration have been processed. Move onto the next iteration and
// reset the grid counter.
2022-04-01 15:39:26 +13:00
CurrentIteration + + ;
_currentDataIndex = 0 ;
}
2022-04-05 19:22:35 +12:00
// No more explosion tiles to process
2022-04-01 15:39:26 +13:00
FinishedProcessing = true ;
return false ;
}
2022-04-05 19:22:35 +12:00
/// <summary>
/// Get the next tile that needs processing
/// </summary>
2022-04-01 15:39:26 +13:00
private bool MoveNext ( )
{
if ( FinishedProcessing )
return false ;
while ( ! FinishedProcessing )
{
if ( _currentEnumerator . MoveNext ( ) )
return true ;
else
TryGetNextTileEnumerator ( ) ;
}
return false ;
}
2022-04-05 19:22:35 +12:00
/// <summary>
2022-04-06 19:35:18 +10:00
/// Attempt to process (i.e., damage entities) some number of grid tiles.
2022-04-05 19:22:35 +12:00
/// </summary>
2022-04-01 15:39:26 +13:00
public int Process ( int processingTarget )
{
// In case the explosion terminated early last tick due to exceeding the allocated processing time, use this
// time to update the tiles.
SetTiles ( ) ;
int processed ;
for ( processed = 0 ; processed < processingTarget ; processed + + )
{
if ( processed % ExplosionSystem . TileCheckIteration = = 0 & &
_system . Stopwatch . Elapsed . TotalMilliseconds > _system . MaxProcessingTime )
{
break ;
}
2022-04-05 19:22:35 +12:00
// Is the current tile on a grid (instead of in space)?
2022-04-01 15:39:26 +13:00
if ( _currentGrid ! = null & &
_currentGrid . TryGetTileRef ( _currentEnumerator . Current , out var tileRef ) & &
! tileRef . Tile . IsEmpty )
{
if ( ! _tileUpdateDict . TryGetValue ( _currentGrid , out var tileUpdateList ) )
{
tileUpdateList = new ( ) ;
_tileUpdateDict [ _currentGrid ] = tileUpdateList ;
}
2022-04-05 19:22:35 +12:00
// damage entities on the tile. Also figures out whether there are any solid entities blocking the floor
// from being destroyed.
2022-04-01 15:39:26 +13:00
var canDamageFloor = _system . ExplodeTile ( _currentLookup ,
2023-11-19 17:06:00 +13:00
( _currentGrid . Owner , _currentGrid ) ,
2022-04-01 15:39:26 +13:00
_currentEnumerator . Current ,
_currentThrowForce ,
_currentDamage ,
Epicenter ,
ProcessedEntities ,
2024-03-14 00:27:08 -04:00
ExplosionType . ID ,
2024-08-09 08:24:05 +02:00
ExplosionType . FireStacks ,
Cause ) ;
2022-04-01 15:39:26 +13:00
2022-04-05 19:22:35 +12:00
// If the floor is not blocked by some dense object, damage the floor tiles.
2022-04-01 15:39:26 +13:00
if ( canDamageFloor )
2022-04-09 09:07:02 +12:00
_system . DamageFloorTile ( tileRef , _currentIntensity * _tileBreakScale , _maxTileBreak , _canCreateVacuum , tileUpdateList , ExplosionType ) ;
2022-04-01 15:39:26 +13:00
}
else
{
2022-04-05 19:22:35 +12:00
// The current "tile" is in space. Damage any entities in that region
2022-04-01 15:39:26 +13:00
_system . ExplodeSpace ( _currentLookup ,
_spaceMatrix ,
_invSpaceMatrix ,
_currentEnumerator . Current ,
_currentThrowForce ,
_currentDamage ,
Epicenter ,
ProcessedEntities ,
2024-03-14 00:27:08 -04:00
ExplosionType . ID ,
2024-08-09 08:24:05 +02:00
ExplosionType . FireStacks ,
Cause ) ;
2022-04-01 15:39:26 +13:00
}
if ( ! MoveNext ( ) )
break ;
}
2022-04-05 19:22:35 +12:00
// Update damaged/broken tiles on the grid.
2022-04-01 15:39:26 +13:00
SetTiles ( ) ;
return processed ;
}
private void SetTiles ( )
{
2022-04-05 19:22:35 +12:00
// Updating the grid can result in chunk collision regeneration & slow processing by the shuttle system.
// Therefore, tile breaking may be configure to only happen at the end of an explosion, rather than during every
// tick.
2022-04-01 15:39:26 +13:00
if ( ! _system . IncrementalTileBreaking & & ! FinishedProcessing )
return ;
foreach ( var ( grid , list ) in _tileUpdateDict )
{
2022-12-12 14:59:02 +11:00
if ( list . Count > 0 & & _entMan . EntityExists ( grid . Owner ) )
2022-04-01 15:39:26 +13:00
{
2024-09-29 02:27:47 +03:00
_mapSystem . SetTiles ( grid . Owner , grid , list ) ;
2022-04-01 15:39:26 +13:00
}
}
_tileUpdateDict . Clear ( ) ;
}
}
2024-03-29 23:46:05 +00:00
/// <summary>
/// Data needed to spawn an explosion with <see cref="ExplosionSystem.SpawnExplosion"/>.
/// </summary>
public sealed class QueuedExplosion
{
public MapCoordinates Epicenter ;
public ExplosionPrototype Proto = new ( ) ;
public float TotalIntensity , Slope , MaxTileIntensity , TileBreakScale ;
public int MaxTileBreak ;
public bool CanCreateVacuum ;
2024-08-09 08:24:05 +02:00
public EntityUid ? Cause ; // The entity that exploded, for logging purposes.
2024-03-29 23:46:05 +00:00
}