diff --git a/Content.Client/Light/Components/LightFadeComponent.cs b/Content.Client/Light/Components/LightFadeComponent.cs new file mode 100644 index 0000000000..3327c9432e --- /dev/null +++ b/Content.Client/Light/Components/LightFadeComponent.cs @@ -0,0 +1,11 @@ +namespace Content.Client.Light.Components; + +/// +/// Fades out the attached to this entity. +/// +[RegisterComponent] +public sealed class LightFadeComponent : Component +{ + [ViewVariables(VVAccess.ReadWrite), DataField("duration")] + public float Duration = 0.5f; +} diff --git a/Content.Client/Light/EntitySystems/LightFadeSystem.cs b/Content.Client/Light/EntitySystems/LightFadeSystem.cs new file mode 100644 index 0000000000..c4e4fff5fb --- /dev/null +++ b/Content.Client/Light/EntitySystems/LightFadeSystem.cs @@ -0,0 +1,46 @@ +using Content.Client.Light.Components; +using Robust.Client.Animations; +using Robust.Client.GameObjects; +using Robust.Shared.Animations; + +namespace Content.Client.Light.EntitySystems; + +public sealed class LightFadeSystem : EntitySystem +{ + [Dependency] private readonly AnimationPlayerSystem _player = default!; + + private const string FadeTrack = "light-fade"; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnFadeStartup); + } + + private void OnFadeStartup(EntityUid uid, LightFadeComponent component, ComponentStartup args) + { + if (!TryComp(uid, out var light)) + return; + + var animation = new Animation() + { + Length = TimeSpan.FromSeconds(component.Duration), + AnimationTracks = + { + new AnimationTrackComponentProperty() + { + Property = nameof(PointLightComponent.Energy), + ComponentType = typeof(PointLightComponent), + InterpolationMode = AnimationInterpolationMode.Cubic, + KeyFrames = + { + new AnimationTrackProperty.KeyFrame(light.Energy, 0f), + new AnimationTrackProperty.KeyFrame(0f, component.Duration) + } + } + } + }; + + _player.Play(uid, animation, FadeTrack); + } +} diff --git a/Content.Server/Entry/IgnoredComponents.cs b/Content.Server/Entry/IgnoredComponents.cs index eae00c7502..a1db7163a0 100644 --- a/Content.Server/Entry/IgnoredComponents.cs +++ b/Content.Server/Entry/IgnoredComponents.cs @@ -20,6 +20,7 @@ namespace Content.Server.Entry "UIFragment", "PDABorderColor", "InventorySlots", + "LightFade", }; } } diff --git a/Content.Server/Explosion/Components/SpawnOnTriggerComponent.cs b/Content.Server/Explosion/Components/SpawnOnTriggerComponent.cs new file mode 100644 index 0000000000..0821d30881 --- /dev/null +++ b/Content.Server/Explosion/Components/SpawnOnTriggerComponent.cs @@ -0,0 +1,12 @@ +using Content.Server.Explosion.EntitySystems; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + +namespace Content.Server.Explosion.Components; + +[RegisterComponent, Access(typeof(TriggerSystem))] +public sealed class SpawnOnTriggerComponent : Component +{ + [ViewVariables(VVAccess.ReadWrite), DataField("proto", required: true, customTypeSerializer:typeof(PrototypeIdSerializer))] + public string Proto = string.Empty; +} diff --git a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs index 6e4360b5f8..4fbd646585 100644 --- a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs +++ b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs @@ -70,12 +70,25 @@ namespace Content.Server.Explosion.EntitySystems SubscribeLocalEvent(OnStepTriggered); SubscribeLocalEvent(OnSlipTriggered); + SubscribeLocalEvent(OnSpawnTrigger); SubscribeLocalEvent(HandleDeleteTrigger); SubscribeLocalEvent(HandleExplodeTrigger); SubscribeLocalEvent(HandleFlashTrigger); SubscribeLocalEvent(HandleGibTrigger); } + private void OnSpawnTrigger(EntityUid uid, SpawnOnTriggerComponent component, TriggerEvent args) + { + var xform = Transform(uid); + + var coords = xform.Coordinates; + + if (!coords.IsValid(EntityManager)) + return; + + Spawn(component.Proto, coords); + } + private void HandleExplodeTrigger(EntityUid uid, ExplodeOnTriggerComponent component, TriggerEvent args) { _explosions.TriggerExplosive(uid, user: args.User); diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml index 85e35faff1..638855646d 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml @@ -60,12 +60,28 @@ sound: path: "/Audio/Effects/flash_bang.ogg" - type: DeleteOnTrigger + - type: SpawnOnTrigger + proto: GrenadeFlashEffect - type: Appearance visuals: - type: TimerTriggerVisualizer countdown_sound: path: /Audio/Effects/countdown.ogg +- type: entity + id: GrenadeFlashEffect + noSpawn: true + components: + - type: PointLight + enabled: true + netsync: false + radius: 5 + energy: 8 + - type: LightFade + duration: 0.5 + - type: TimedDespawn + lifetime: 0.5 + - type: entity name: Syndicate minibomb description: A precision sabotage explosive for quickly destroying a machine, dead body, or whatever else needs to go.