diff --git a/Content.Server/Chemistry/TileReactions/SpillTileReaction.cs b/Content.Server/Chemistry/TileReactions/SpillTileReaction.cs index cb469ad0a4..7744746ee1 100644 --- a/Content.Server/Chemistry/TileReactions/SpillTileReaction.cs +++ b/Content.Server/Chemistry/TileReactions/SpillTileReaction.cs @@ -5,6 +5,7 @@ using Content.Shared.Chemistry.Reagent; using Content.Shared.FixedPoint; using Content.Shared.Slippery; using Content.Shared.StepTrigger; +using Content.Shared.StepTrigger.Systems; using JetBrains.Annotations; using Robust.Shared.Map; diff --git a/Content.Server/Damage/Components/DamageOnTriggerComponent.cs b/Content.Server/Damage/Components/DamageUserOnTriggerComponent.cs similarity index 80% rename from Content.Server/Damage/Components/DamageOnTriggerComponent.cs rename to Content.Server/Damage/Components/DamageUserOnTriggerComponent.cs index b73c0164ab..4d313e8d6d 100644 --- a/Content.Server/Damage/Components/DamageOnTriggerComponent.cs +++ b/Content.Server/Damage/Components/DamageUserOnTriggerComponent.cs @@ -3,7 +3,7 @@ using Content.Shared.Damage; namespace Content.Server.Damage.Components; [RegisterComponent] -public sealed class DamageOnTriggerComponent : Component +public sealed class DamageUserOnTriggerComponent : Component { [DataField("ignoreResistances")] public bool IgnoreResistances; diff --git a/Content.Server/Damage/Systems/DamageOnTriggerSystem.cs b/Content.Server/Damage/Systems/DamageOnTriggerSystem.cs deleted file mode 100644 index 2c3a5d4753..0000000000 --- a/Content.Server/Damage/Systems/DamageOnTriggerSystem.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Content.Server.Damage.Components; -using Content.Shared.Damage; -using Content.Shared.StepTrigger; - -namespace Content.Server.Damage.Systems; - -// System for damage that occurs on specific triggers. -// This is originally meant for mousetraps, but could -// probably be extended to fit other triggers as well. -public sealed class DamageOnTriggerSystem : EntitySystem -{ - [Dependency] private readonly DamageableSystem _damageableSystem = default!; - - public override void Initialize() - { - SubscribeLocalEvent(OnStepTrigger); - } - - private void OnStepTrigger(EntityUid uid, DamageOnTriggerComponent component, ref StepTriggeredEvent args) - { - OnDamageTrigger(uid, args.Tripper, component); - } - - private void OnDamageTrigger(EntityUid source, EntityUid target, DamageOnTriggerComponent? component = null) - { - if (!Resolve(source, ref component)) - { - return; - } - - var damage = new DamageSpecifier(component.Damage); - var ev = new BeforeDamageOnTriggerEvent(damage, target); - RaiseLocalEvent(source, ev, true); - - _damageableSystem.TryChangeDamage(target, ev.Damage, component.IgnoreResistances); - } -} - -public sealed class BeforeDamageOnTriggerEvent : EntityEventArgs -{ - public DamageSpecifier Damage { get; set; } - public EntityUid Tripper { get; } - - public BeforeDamageOnTriggerEvent(DamageSpecifier damage, EntityUid target) - { - Damage = damage; - Tripper = target; - } -} diff --git a/Content.Server/Damage/Systems/DamageUserOnTriggerSystem.cs b/Content.Server/Damage/Systems/DamageUserOnTriggerSystem.cs new file mode 100644 index 0000000000..a32c68c4fd --- /dev/null +++ b/Content.Server/Damage/Systems/DamageUserOnTriggerSystem.cs @@ -0,0 +1,52 @@ +using Content.Server.Damage.Components; +using Content.Server.Explosion.EntitySystems; +using Content.Shared.Damage; +using Content.Shared.StepTrigger; +using Content.Shared.StepTrigger.Systems; + +namespace Content.Server.Damage.Systems; + +// System for damage that occurs on specific trigger, towards the user.. +public sealed class DamageUserOnTriggerSystem : EntitySystem +{ + [Dependency] private readonly DamageableSystem _damageableSystem = default!; + + public override void Initialize() + { + SubscribeLocalEvent(OnTrigger); + } + + private void OnTrigger(EntityUid uid, DamageUserOnTriggerComponent component, TriggerEvent args) + { + if (args.User is null) + return; + + args.Handled |= OnDamageTrigger(uid, args.User.Value, component); + } + + private bool OnDamageTrigger(EntityUid source, EntityUid target, DamageUserOnTriggerComponent? component = null) + { + if (!Resolve(source, ref component)) + { + return false; + } + + var damage = new DamageSpecifier(component.Damage); + var ev = new BeforeDamageUserOnTriggerEvent(damage, target); + RaiseLocalEvent(source, ev); + + return _damageableSystem.TryChangeDamage(target, ev.Damage, component.IgnoreResistances) is not null; + } +} + +public sealed class BeforeDamageUserOnTriggerEvent : EntityEventArgs +{ + public DamageSpecifier Damage { get; set; } + public EntityUid Tripper { get; } + + public BeforeDamageUserOnTriggerEvent(DamageSpecifier damage, EntityUid target) + { + Damage = damage; + Tripper = target; + } +} diff --git a/Content.Server/Explosion/Components/TriggerOnStepTriggerComponent.cs b/Content.Server/Explosion/Components/TriggerOnStepTriggerComponent.cs new file mode 100644 index 0000000000..9539e78768 --- /dev/null +++ b/Content.Server/Explosion/Components/TriggerOnStepTriggerComponent.cs @@ -0,0 +1,10 @@ +namespace Content.Server.Explosion.Components; + +/// +/// This is used for entities that want the more generic 'trigger' behavior after a step trigger occurs. +/// Not done by default, since it's not useful for everything and might cause weird behavior. But it is useful for a lot of stuff like mousetraps. +/// +[RegisterComponent] +public sealed class TriggerOnStepTriggerComponent : Component +{ +} diff --git a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs index fc913a958e..9627bfd8b9 100644 --- a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs +++ b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs @@ -14,6 +14,7 @@ using Content.Shared.Trigger; using Content.Shared.Database; using Content.Shared.Explosion; using Content.Shared.Interaction; +using Content.Shared.StepTrigger.Systems; namespace Content.Server.Explosion.EntitySystems { @@ -52,6 +53,7 @@ namespace Content.Server.Explosion.EntitySystems SubscribeLocalEvent(OnTriggerCollide); SubscribeLocalEvent(OnActivate); + SubscribeLocalEvent(OnStepTriggered); SubscribeLocalEvent(HandleDeleteTrigger); SubscribeLocalEvent(HandleExplodeTrigger); @@ -91,6 +93,11 @@ namespace Content.Server.Explosion.EntitySystems args.Handled = true; } + private void OnStepTriggered(EntityUid uid, TriggerOnStepTriggerComponent component, ref StepTriggeredEvent args) + { + Trigger(uid, args.Tripper); + } + public bool Trigger(EntityUid trigger, EntityUid? user = null) { var triggerEvent = new TriggerEvent(trigger, user); diff --git a/Content.Server/Fluids/EntitySystems/PuddleSystem.cs b/Content.Server/Fluids/EntitySystems/PuddleSystem.cs index b71cdcad34..ce71d87474 100644 --- a/Content.Server/Fluids/EntitySystems/PuddleSystem.cs +++ b/Content.Server/Fluids/EntitySystems/PuddleSystem.cs @@ -5,6 +5,8 @@ using Content.Shared.Examine; using Content.Shared.FixedPoint; using Content.Shared.Fluids; using Content.Shared.StepTrigger; +using Content.Shared.StepTrigger.Components; +using Content.Shared.StepTrigger.Systems; using JetBrains.Annotations; using Robust.Shared.Audio; using Robust.Shared.Player; diff --git a/Content.Server/LandMines/LandMineComponent.cs b/Content.Server/LandMines/LandMineComponent.cs index 459d9ac1f6..b2cc775474 100644 --- a/Content.Server/LandMines/LandMineComponent.cs +++ b/Content.Server/LandMines/LandMineComponent.cs @@ -3,6 +3,4 @@ [RegisterComponent] public sealed class LandMineComponent : Component { - [DataField("deleteOnActivate")] - public bool DeleteOnActivate = true; } diff --git a/Content.Server/LandMines/LandMineSystem.cs b/Content.Server/LandMines/LandMineSystem.cs index a526e493d9..b8b6b15ed2 100644 --- a/Content.Server/LandMines/LandMineSystem.cs +++ b/Content.Server/LandMines/LandMineSystem.cs @@ -1,6 +1,7 @@ using Content.Server.Explosion.EntitySystems; using Content.Shared.Popups; using Content.Shared.StepTrigger; +using Content.Shared.StepTrigger.Systems; using Robust.Shared.Player; namespace Content.Server.LandMines; @@ -27,6 +28,8 @@ public sealed class LandMineSystem : EntitySystem private void HandleTriggered(EntityUid uid, LandMineComponent component, ref StepTriggeredEvent args) { + // This doesn't use TriggerOnStepTrigger since we don't want to display the popup if nothing happens + // and I didn't feel like making an `AfterTrigger` event if (_trigger.Trigger(uid, args.Tripper)) { _popupSystem.PopupCoordinates( @@ -35,9 +38,6 @@ public sealed class LandMineSystem : EntitySystem Filter.Entities(args.Tripper), PopupType.LargeCaution); } - - if (component.DeleteOnActivate) - QueueDel(uid); } } diff --git a/Content.Server/Mousetrap/MousetrapComponent.cs b/Content.Server/Mousetrap/MousetrapComponent.cs index c06986782f..fb31964eec 100644 --- a/Content.Server/Mousetrap/MousetrapComponent.cs +++ b/Content.Server/Mousetrap/MousetrapComponent.cs @@ -15,7 +15,4 @@ public sealed class MousetrapComponent : Component [ViewVariables(VVAccess.ReadWrite)] [DataField("massBalance")] public int MassBalance = 10; - - [DataField("ignoreDamageIfInventorySlotsFilled")] - public List IgnoreDamageIfSlotFilled = new(); } diff --git a/Content.Server/Mousetrap/MousetrapSystem.cs b/Content.Server/Mousetrap/MousetrapSystem.cs index bfa78e7a5d..27d9db4fbc 100644 --- a/Content.Server/Mousetrap/MousetrapSystem.cs +++ b/Content.Server/Mousetrap/MousetrapSystem.cs @@ -5,6 +5,7 @@ using Content.Shared.Interaction.Events; using Content.Shared.Inventory; using Content.Shared.Mousetrap; using Content.Shared.StepTrigger; +using Content.Shared.StepTrigger.Systems; using Robust.Shared.Player; namespace Content.Server.Mousetrap; @@ -18,9 +19,9 @@ public sealed class MousetrapSystem : EntitySystem public override void Initialize() { SubscribeLocalEvent(OnUseInHand); - SubscribeLocalEvent(BeforeDamageOnTrigger); + SubscribeLocalEvent(BeforeDamageOnTrigger); SubscribeLocalEvent(OnStepTriggerAttempt); - SubscribeLocalEvent(OnStepTrigger); + SubscribeLocalEvent(OnTrigger); } private void OnUseInHand(EntityUid uid, MousetrapComponent component, UseInHandEvent args) @@ -37,27 +38,11 @@ public sealed class MousetrapSystem : EntitySystem private void OnStepTriggerAttempt(EntityUid uid, MousetrapComponent component, ref StepTriggerAttemptEvent args) { - args.Continue = component.IsActive; + args.Continue |= component.IsActive; } - private void BeforeDamageOnTrigger(EntityUid uid, MousetrapComponent component, BeforeDamageOnTriggerEvent args) + private void BeforeDamageOnTrigger(EntityUid uid, MousetrapComponent component, BeforeDamageUserOnTriggerEvent args) { - foreach (var slot in component.IgnoreDamageIfSlotFilled) - { - if (!_inventorySystem.TryGetSlotContainer(args.Tripper, slot, out var container, out _)) - { - continue; - } - - // This also means that wearing slippers won't - // hurt the entity. - if (container.ContainedEntity != null) - { - args.Damage *= 0; - return; - } - } - if (TryComp(args.Tripper, out PhysicsComponent? physics) && physics.Mass != 0) { // The idea here is inverse, @@ -69,11 +54,9 @@ public sealed class MousetrapSystem : EntitySystem } } - private void OnStepTrigger(EntityUid uid, MousetrapComponent component, ref StepTriggeredEvent args) + private void OnTrigger(EntityUid uid, MousetrapComponent component, TriggerEvent args) { component.IsActive = false; - _triggerSystem.Trigger(uid); - UpdateVisuals(uid); } diff --git a/Content.Shared/Slippery/SharedSlipperySystem.cs b/Content.Shared/Slippery/SharedSlipperySystem.cs index 73a851e074..e2dc51c589 100644 --- a/Content.Shared/Slippery/SharedSlipperySystem.cs +++ b/Content.Shared/Slippery/SharedSlipperySystem.cs @@ -2,7 +2,7 @@ using Content.Shared.Administration.Logs; using Content.Shared.Database; using Content.Shared.Inventory; using Content.Shared.StatusEffect; -using Content.Shared.StepTrigger; +using Content.Shared.StepTrigger.Systems; using Content.Shared.Stunnable; using JetBrains.Annotations; using Robust.Shared.Containers; diff --git a/Content.Shared/Slippery/SlipperyComponent.cs b/Content.Shared/Slippery/SlipperyComponent.cs index bba71b824f..496671d0c2 100644 --- a/Content.Shared/Slippery/SlipperyComponent.cs +++ b/Content.Shared/Slippery/SlipperyComponent.cs @@ -1,5 +1,6 @@ using Content.Shared.Sound; using Content.Shared.StepTrigger; +using Content.Shared.StepTrigger.Components; using Robust.Shared.GameStates; using Robust.Shared.Serialization; diff --git a/Content.Shared/StepTrigger/Components/ShoesRequiredStepTriggerComponent.cs b/Content.Shared/StepTrigger/Components/ShoesRequiredStepTriggerComponent.cs new file mode 100644 index 0000000000..cde93ea355 --- /dev/null +++ b/Content.Shared/StepTrigger/Components/ShoesRequiredStepTriggerComponent.cs @@ -0,0 +1,11 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.StepTrigger.Components; + +/// +/// This is used for cancelling step trigger events if the user is wearing shoes, such as for glass shards. +/// +[RegisterComponent, NetworkedComponent] +public sealed class ShoesRequiredStepTriggerComponent : Component +{ +} diff --git a/Content.Shared/StepTrigger/StepTriggerComponent.cs b/Content.Shared/StepTrigger/Components/StepTriggerComponent.cs similarity index 95% rename from Content.Shared/StepTrigger/StepTriggerComponent.cs rename to Content.Shared/StepTrigger/Components/StepTriggerComponent.cs index 5a8b5a245a..08e794ffad 100644 --- a/Content.Shared/StepTrigger/StepTriggerComponent.cs +++ b/Content.Shared/StepTrigger/Components/StepTriggerComponent.cs @@ -1,7 +1,8 @@ +using Content.Shared.StepTrigger.Systems; using Robust.Shared.GameStates; using Robust.Shared.Serialization; -namespace Content.Shared.StepTrigger; +namespace Content.Shared.StepTrigger.Components; [RegisterComponent] [NetworkedComponent] diff --git a/Content.Shared/StepTrigger/Systems/ShoesRequiredStepTriggerSystem.cs b/Content.Shared/StepTrigger/Systems/ShoesRequiredStepTriggerSystem.cs new file mode 100644 index 0000000000..a1f6338b37 --- /dev/null +++ b/Content.Shared/StepTrigger/Systems/ShoesRequiredStepTriggerSystem.cs @@ -0,0 +1,33 @@ +using Content.Shared.Examine; +using Content.Shared.Inventory; +using Content.Shared.StepTrigger.Components; + +namespace Content.Shared.StepTrigger.Systems; + +public sealed class ShoesRequiredStepTriggerSystem : EntitySystem +{ + [Dependency] private readonly InventorySystem _inventory = default!; + + /// + public override void Initialize() + { + SubscribeLocalEvent(OnStepTriggerAttempt); + SubscribeLocalEvent(OnExamined); + } + + private void OnStepTriggerAttempt(EntityUid uid, ShoesRequiredStepTriggerComponent component, ref StepTriggerAttemptEvent args) + { + if (!TryComp(args.Tripper, out var inventory)) + return; + + if (_inventory.TryGetSlotEntity(args.Tripper, "shoes", out _, inventory)) + { + args.Cancelled = true; + } + } + + private void OnExamined(EntityUid uid, ShoesRequiredStepTriggerComponent component, ExaminedEvent args) + { + args.PushMarkup(Loc.GetString("shoes-required-step-trigger-examine")); + } +} diff --git a/Content.Shared/StepTrigger/StepTriggerSystem.cs b/Content.Shared/StepTrigger/Systems/StepTriggerSystem.cs similarity index 95% rename from Content.Shared/StepTrigger/StepTriggerSystem.cs rename to Content.Shared/StepTrigger/Systems/StepTriggerSystem.cs index ad57889ff5..6a01bb9d18 100644 --- a/Content.Shared/StepTrigger/StepTriggerSystem.cs +++ b/Content.Shared/StepTrigger/Systems/StepTriggerSystem.cs @@ -1,8 +1,9 @@ +using Content.Shared.StepTrigger.Components; using Robust.Shared.Collections; using Robust.Shared.GameStates; using Robust.Shared.Physics.Dynamics; -namespace Content.Shared.StepTrigger; +namespace Content.Shared.StepTrigger.Systems; public sealed class StepTriggerSystem : EntitySystem { @@ -93,7 +94,7 @@ public sealed class StepTriggerSystem : EntitySystem RaiseLocalEvent(uid, ref msg, true); - return msg.Continue; + return msg.Continue && !msg.Cancelled; } private void HandleCollide(EntityUid uid, StepTriggerComponent component, StartCollideEvent args) @@ -177,6 +178,10 @@ public struct StepTriggerAttemptEvent public EntityUid Source; public EntityUid Tripper; public bool Continue; + /// + /// Set by systems which wish to cancel the step trigger event, regardless of event ordering. + /// + public bool Cancelled; } [ByRefEvent] diff --git a/Resources/Locale/en-US/step-trigger/shoes-required.ftl b/Resources/Locale/en-US/step-trigger/shoes-required.ftl new file mode 100644 index 0000000000..8c1369a49f --- /dev/null +++ b/Resources/Locale/en-US/step-trigger/shoes-required.ftl @@ -0,0 +1 @@ +shoes-required-step-trigger-examine = You probably shouldn't step on this barefoot. diff --git a/Resources/Prototypes/Entities/Objects/Devices/mousetrap.yml b/Resources/Prototypes/Entities/Objects/Devices/mousetrap.yml index 8ca251110d..d5881e83cc 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/mousetrap.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/mousetrap.yml @@ -2,6 +2,7 @@ name: mousetrap parent: BaseItem id: Mousetrap + description: Useful for catching rodents sneaking into your kitchen. components: - type: Sprite sprite: Objects/Devices/mousetrap.rsi @@ -13,9 +14,9 @@ intersectRatio: 0.2 requiredTriggeredSpeed: 0 - type: Mousetrap - ignoreDamageIfInventorySlotsFilled: - - shoes # shoes - - type: DamageOnTrigger + - type: TriggerOnStepTrigger + - type: ShoesRequiredStepTrigger + - type: DamageUserOnTrigger damage: types: Blunt: 2 # base damage, scales based on mass diff --git a/Resources/Prototypes/Entities/Objects/Fun/dice.yml b/Resources/Prototypes/Entities/Objects/Fun/dice.yml index 2a640ea5be..39c30f0f19 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/dice.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/dice.yml @@ -92,3 +92,33 @@ sides: 4 - type: Sprite state: d44 + - type: CollisionWake + enabled: false + - type: Fixtures + fixtures: + - shape: + !type:PhysShapeAabb + bounds: "-0.2,-0.2,0.2,0.2" + id: "slips" + hard: false + layer: + - LowImpassable + - shape: + !type:PhysShapeAabb + bounds: "-0.2,-0.2,0.2,0.2" + mass: 5 + mask: + - ItemMask + - type: StepTrigger + intersectRatio: 0.2 + requiredTriggeredSpeed: 0 + - type: TriggerOnStepTrigger + - type: ShoesRequiredStepTrigger + - type: Slippery + slipSound: + path: /Audio/Effects/glass_step.ogg + launchForwardsMultiplier: 0 + - type: DamageUserOnTrigger + damage: + types: + Piercing: 5 diff --git a/Resources/Prototypes/Entities/Objects/Materials/shards.yml b/Resources/Prototypes/Entities/Objects/Materials/shards.yml index d9ded9e844..c599c6b00b 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/shards.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/shards.yml @@ -19,6 +19,23 @@ Slash: 5 - type: Item sprite: Objects/Materials/Shards/shard.rsi + - type: CollisionWake + enabled: false + - type: Fixtures + fixtures: + - shape: + !type:PhysShapeAabb + bounds: "-0.2,-0.2,0.2,0.2" + id: "slips" + hard: false + layer: + - LowImpassable + - shape: + !type:PhysShapeAabb + bounds: "-0.2,-0.2,0.2,0.2" + mass: 5 + mask: + - ItemMask - type: DamageOtherOnHit damage: types: @@ -39,12 +56,25 @@ behaviors: - !type:DoActsBehavior acts: [ "Destruction" ] + - type: StepTrigger + intersectRatio: 0.2 + requiredTriggeredSpeed: 0 + - type: ShoesRequiredStepTrigger + - type: Slippery + slipSound: + path: /Audio/Effects/glass_step.ogg + launchForwardsMultiplier: 0 + - type: TriggerOnStepTrigger + - type: DamageUserOnTrigger + damage: + types: + Piercing: 5 - type: entity parent: ShardBase id: ShardGlass name: glass shard - description: A small piece of glass. It looks sharp, you wouldn't want to step on it barefoot. + description: A small piece of glass. components: - type: Sprite color: "#bbeeff" @@ -53,12 +83,16 @@ - type: WelderRefinable refineResult: - SheetGlass1 + - type: DamageUserOnTrigger + damage: + types: + Piercing: 5 - type: entity parent: ShardBase id: ShardGlassReinforced name: reinforced glass shard - description: A small piece of reinforced glass. It looks sharp, you wouldn't want to step on it barefoot. + description: A small piece of reinforced glass. components: - type: Sprite color: "#96cdef" @@ -68,12 +102,16 @@ refineResult: - SheetGlass1 - SheetSteel1 + - type: DamageUserOnTrigger + damage: + types: + Piercing: 10 - type: entity parent: ShardBase id: ShardGlassPlasma name: plasma glass shard - description: A small piece of plasma glass. It looks sharp, you wouldn't want to step on it barefoot. + description: A small piece of plasma glass. components: - type: Sprite color: "#f3b489" @@ -83,3 +121,7 @@ refineResult: - SheetGlass1 - SheetPlasma1 + - type: DamageUserOnTrigger + damage: + types: + Piercing: 15 diff --git a/Resources/Prototypes/Entities/Objects/Misc/land_mine.yml b/Resources/Prototypes/Entities/Objects/Misc/land_mine.yml index d9d53b18c6..0a7608a5a6 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/land_mine.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/land_mine.yml @@ -35,6 +35,7 @@ - !type:DoActsBehavior acts: [ "Destruction" ] - type: LandMine + - type: TriggerOnStepTrigger - type: StepTrigger requiredTriggeredSpeed: 0 @@ -44,6 +45,7 @@ id: LandMineKick components: - type: GhostKickUserOnTrigger + - type: DeleteOnTrigger - type: entity name: modular mine @@ -56,7 +58,6 @@ graph: ModularMineGraph node: emptyCase - type: LandMine - deleteOnActivate: false - type: entity name: explosive mine @@ -70,3 +71,4 @@ intensitySlope: 3 totalIntensity: 120 # about a ~4 tile radius canCreateVacuum: false + - type: DeleteOnTrigger