diff --git a/Content.Server/ImmovableRod/ImmovableRodSystem.cs b/Content.Server/ImmovableRod/ImmovableRodSystem.cs index 36a16695f5..99c949ebce 100644 --- a/Content.Server/ImmovableRod/ImmovableRodSystem.cs +++ b/Content.Server/ImmovableRod/ImmovableRodSystem.cs @@ -3,12 +3,10 @@ using Content.Server.Popups; using Content.Shared.Body.Components; using Content.Shared.Examine; using Content.Shared.Popups; -using Robust.Shared.Audio; using Robust.Shared.Map; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Events; using Robust.Shared.Physics.Systems; -using Robust.Shared.Player; using Robust.Shared.Random; namespace Content.Server.ImmovableRod; @@ -21,6 +19,7 @@ public sealed class ImmovableRodSystem : EntitySystem [Dependency] private readonly BodySystem _bodySystem = default!; [Dependency] private readonly PopupSystem _popup = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; public override void Update(float frameTime) { @@ -44,11 +43,11 @@ public sealed class ImmovableRodSystem : EntitySystem base.Initialize(); SubscribeLocalEvent(OnCollide); - SubscribeLocalEvent(OnComponentInit); + SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnExamined); } - private void OnComponentInit(EntityUid uid, ImmovableRodComponent component, ComponentInit args) + private void OnMapInit(EntityUid uid, ImmovableRodComponent component, MapInitEvent args) { if (EntityManager.TryGetComponent(uid, out PhysicsComponent? phys)) { @@ -77,7 +76,7 @@ public sealed class ImmovableRodSystem : EntitySystem if (_random.Prob(component.HitSoundProbability)) { - SoundSystem.Play(component.Sound.GetSound(), Filter.Pvs(uid), uid, component.Sound.Params); + _audio.PlayPvs(component.Sound, uid); } if (HasComp(ent)) diff --git a/Content.Server/StationEvents/Components/ImmovableRodRuleComponent.cs b/Content.Server/StationEvents/Components/ImmovableRodRuleComponent.cs new file mode 100644 index 0000000000..e204de16cd --- /dev/null +++ b/Content.Server/StationEvents/Components/ImmovableRodRuleComponent.cs @@ -0,0 +1,12 @@ +using Content.Server.StationEvents.Events; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + +namespace Content.Server.StationEvents.Components; + +[RegisterComponent, Access(typeof(ImmovableRodRule))] +public sealed class ImmovableRodRuleComponent : Component +{ + [DataField("rodPrototype", customTypeSerializer: typeof(PrototypeIdSerializer))] + public string RodPrototype = "ImmovableRodKeepTilesStill"; +} diff --git a/Content.Server/StationEvents/Events/ImmovableRodRule.cs b/Content.Server/StationEvents/Events/ImmovableRodRule.cs new file mode 100644 index 0000000000..e6c868fa18 --- /dev/null +++ b/Content.Server/StationEvents/Events/ImmovableRodRule.cs @@ -0,0 +1,36 @@ +using Content.Server.GameTicking.Rules.Components; +using Content.Server.ImmovableRod; +using Content.Server.StationEvents.Components; +using Content.Server.Weapons.Ranged.Systems; +using Content.Shared.Spawners.Components; +using Robust.Shared.Prototypes; + +namespace Content.Server.StationEvents.Events; + +public sealed class ImmovableRodRule : StationEventSystem +{ + [Dependency] private readonly SharedTransformSystem _transform = default!; + [Dependency] private readonly GunSystem _gun = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + + protected override void Started(EntityUid uid, ImmovableRodRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args) + { + base.Started(uid, component, gameRule, args); + + var proto = _prototypeManager.Index(component.RodPrototype); + if (proto.TryGetComponent(out var rod) && proto.TryGetComponent(out var despawn)) + { + TryFindRandomTile(out _, out _, out _, out var targetCoords); + var speed = RobustRandom.NextFloat(rod.MinSpeed, rod.MaxSpeed); + var angle = RobustRandom.NextAngle(); + var direction = angle.ToVec(); + var spawnCoords = targetCoords.ToMap(EntityManager, _transform).Offset(-direction * speed * despawn.Lifetime / 2); + var ent = Spawn(component.RodPrototype, spawnCoords); + _gun.ShootProjectile(ent, direction, Vector2.Zero, uid, speed: speed); + } + else + { + Sawmill.Error($"Invalid immovable rod prototype: {component.RodPrototype}"); + } + } +} diff --git a/Resources/Locale/en-US/station-events/events/immovable-rod.ftl b/Resources/Locale/en-US/station-events/events/immovable-rod.ftl new file mode 100644 index 0000000000..06abcc85c3 --- /dev/null +++ b/Resources/Locale/en-US/station-events/events/immovable-rod.ftl @@ -0,0 +1 @@ +station-event-immovable-rod-start-announcement = High velocity unidentified object is on a collision course with the station. Impact imminent. diff --git a/Resources/Prototypes/Entities/Objects/Fun/immovable_rod.yml b/Resources/Prototypes/Entities/Objects/Fun/immovable_rod.yml index d956f5cdee..466e433e8b 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/immovable_rod.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/immovable_rod.yml @@ -1,6 +1,4 @@ - # Immovable rod - -- type: entity +- type: entity id: ImmovableRod name: immovable rod description: You can sense that it's hungry. That's usually a bad sign. @@ -33,12 +31,32 @@ layer: - Impassable - Opaque + - type: WarpPoint + follow: true + location: immovable rod - type: entity + parent: ImmovableRod id: ImmovableRodSlow suffix: Slow - parent: ImmovableRod components: - type: ImmovableRod minSpeed: 1 maxSpeed: 5 + +- type: entity + parent: ImmovableRod + id: ImmovableRodKeepTiles + suffix: Keep Tiles + components: + - type: ImmovableRod + destroyTiles: false + hitSoundProbability: 1.0 + +- type: entity + parent: ImmovableRodKeepTiles + id: ImmovableRodKeepTilesStill + suffix: Keep Tiles, Still + components: + - type: ImmovableRod + randomizeVelocity: false diff --git a/Resources/Prototypes/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml index b781e8753a..d39079aa7d 100644 --- a/Resources/Prototypes/GameRules/events.yml +++ b/Resources/Prototypes/GameRules/events.yml @@ -332,3 +332,18 @@ maxSoundDistance: 7 sounds: collection: Paracusia + +- type: entity + id: ImmovableRodSpawn + parent: BaseGameRule + noSpawn: true + components: + - type: StationEvent + startAnnouncement: station-event-immovable-rod-start-announcement + startAudio: + path: /Audio/Announcements/attention.ogg + weight: 1 + duration: 1 + earliestStart: 45 + minimumPlayers: 20 + - type: ImmovableRodRule