+++ /dev/null
-using Content.Shared.FixedPoint;
-using Content.Shared.Physics;
-using Robust.Shared.GameStates;
-
-namespace Content.Shared.Projectiles;
-
-[RegisterComponent, NetworkedComponent]
-public sealed partial class CanPenetrateComponent : Component
-{
- /// <summary>
- /// Should the projectile keep the ability to deal damage after colliding.
- /// </summary>
- [DataField]
- public bool DamageAfterCollide = true;
-
- /// <summary>
- /// The CollisionLayer, up to and including the one set, the projectile is allowed to penetrate.
- /// </summary>
- ///<remarks>
- /// Can penetrate everything if this value is not set.
- /// </remarks>
- [DataField]
- public CollisionGroup? PenetrationLayer;
-
- /// <summary>
- /// How many times the projectile is allowed to deal damage.
- /// </summary>
- /// <remarks>
- /// Can deal damage on every collision if this value is not set.
- /// </remarks>
- [DataField]
- public float? PenetrationPower;
-
- /// <summary>
- /// Modifies the damage of a projectile after it has penetrated an entity.
- /// </summary>
- /// <remarks>
- /// Won't modify the projectile's damage if this value is not set.
- /// </remarks>
- [DataField]
- public FixedPoint2? DamageModifier;
-}
/// </summary>
private void AfterProjectileHit(EntityUid uid, ProjectileComponent component, ref AfterProjectileHitEvent args)
{
- if (!TryComp<CanPenetrateComponent>(uid, out var damageAfterCollide))
- return;
-
- //Delete the projectile if it hits an entity with a CollisionLayer that has a higher value than it's PenetrationLayer.
- //This allows a projectile to only penetrate a specific set of entities.
- if (damageAfterCollide.PenetrationLayer != null)
- {
- if (args.Fixture.CollisionLayer > (int) damageAfterCollide.PenetrationLayer ||
- damageAfterCollide.PenetrationPower == 0)
- {
- QueueDel(uid);
- return;
- }
- }
-
- //Allow the projectile to deal damage again.
- if(damageAfterCollide.DamageAfterCollide)
- component.DamagedEntity = false;
-
- //If the projectile has a limit on the amount of penetrations, reduce it.
- if (damageAfterCollide.PenetrationPower != null)
- damageAfterCollide.PenetrationPower -= 1;
-
- //Apply the penetration damage modifier if the projectile has one.
- if (damageAfterCollide.DamageModifier != null)
- component.Damage *= damageAfterCollide.DamageModifier.Value;
-
//Overrides the original DeleteOnCollide if the projectile passes all penetration checks.
//This is to prevent having to set DeleteOnCollide to false on every prototype
//you want to give the ability to penetrate entities.