CatStation/Content.Shared/Screech/ScreechSystem.cs
KeTuFaisPiKiNut cd6d356005
Screeching & Changeling Screech (#44432)
* pcmasterrace

* RMC screech port + i guess it works more

* i made a magic commit that mostly duplicates the flash system but different TM

* it just works nya

* final touchups

* Revert "pcmasterrace"

This reverts commit b75e9265610924c3a1a30761e5e050cb6ee63bc8.

* there, support for more :godo:

* Update Content.Shared/Screech/SharedScreechSystem.cs

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>

* all feedback except the big one

* i lied

* mfw code

* fix

* le shader temp

* vfx

* Revert "le shader temp"

This reverts commit 0180a8c1a6ffe82f0ae8d151c07d0794c3eb4984.

* Update Content.Client/Effects/ScreechShockWaveSystem.cs

Co-authored-by: Pok <113675512+Pok27@users.noreply.github.com>

* Update Content.Client/Overlays/ScreechShockWaveOverlay.cs

Co-authored-by: Pok <113675512+Pok27@users.noreply.github.com>

* Update Content.Client/Overlays/ScreechShockWaveOverlay.cs

Co-authored-by: Pok <113675512+Pok27@users.noreply.github.com>

* Update Content.Client/Overlays/ScreechShockWaveOverlay.cs

Co-authored-by: Pok <113675512+Pok27@users.noreply.github.com>

* Update Content.Shared/Screech/ScreechShockWaveComponent.cs

Co-authored-by: Pok <113675512+Pok27@users.noreply.github.com>

* Update Content.Client/Effects/ScreechShockWaveSystem.cs

Co-authored-by: Pok <113675512+Pok27@users.noreply.github.com>

* Update Content.Client/Overlays/ScreechShockWaveOverlay.cs

Co-authored-by: Pok <113675512+Pok27@users.noreply.github.com>

* Update Content.Client/Overlays/ScreechShockWaveOverlay.cs

Co-authored-by: Pok <113675512+Pok27@users.noreply.github.com>

* rwrw

* Update Content.Client/Overlays/ScreechShockWaveOverlay.cs

Co-authored-by: Pok <113675512+Pok27@users.noreply.github.com>

* Update Content.Client/Overlays/ScreechShockWaveOverlay.cs

Co-authored-by: Pok <113675512+Pok27@users.noreply.github.com>

* Update Content.Client/Overlays/ScreechShockWaveOverlay.cs

Co-authored-by: Pok <113675512+Pok27@users.noreply.github.com>

* Update Content.Shared/Screech/ScreechSystem.cs

Co-authored-by: Pok <113675512+Pok27@users.noreply.github.com>

* Update Content.Client/Overlays/ScreechShockWaveOverlay.cs

Co-authored-by: Pok <113675512+Pok27@users.noreply.github.com>

* Update Content.Client/Overlays/ScreechShockWaveOverlay.cs

Co-authored-by: Pok <113675512+Pok27@users.noreply.github.com>

* Update Content.Client/Overlays/ScreechShockWaveOverlay.cs

Co-authored-by: Pok <113675512+Pok27@users.noreply.github.com>

* :godo:

* Update Content.Client/Overlays/ScreechShockWaveOverlay.cs

Co-authored-by: Pok <113675512+Pok27@users.noreply.github.com>

* Update Content.Client/Effects/ScreechShockWaveSystem.cs

Co-authored-by: Pok <113675512+Pok27@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Pok <113675512+Pok27@users.noreply.github.com>

* Effects

* sexy

* lang

* scub

* nya

* e

* fixed shader

* entity effects

* FNAF IS THIS WHERE U WANNA BE???????

* Update Resources/Locale/en-US/screech/screech.ftl

Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com>

* Update Content.Shared/Screech/NoiseProtection.cs

Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com>

* weeeee

* scar whyyyyy

* Update Content.Shared/Screech/ScreechSystem.cs

Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com>

* Update Content.Shared/Screech/ScreechSystem.cs

Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com>

* Update Content.Shared/Screech/ScreechSystem.cs

Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com>

* e

* they've got allen wrenches gerbil feeders toilet seat electric heaters

* cleanup

* datafield ig

* Revert "datafield ig"

This reverts commit dd0d9421452f156b0b1ebc527ac9b142d657ae50.

* comments

---------

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Co-authored-by: nomdéraisonnablementlong <you@example.com>
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
Co-authored-by: Pok <113675512+Pok27@users.noreply.github.com>
Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com>
Co-authored-by: ScarKy0 <scarky0@onet.eu>
2026-07-22 23:16:46 +00:00

126 lines
4.3 KiB
C#

using Content.Shared.Actions;
using Content.Shared.EntityEffects;
using Content.Shared.Examine;
using Content.Shared.Inventory;
using Content.Shared.StatusEffect;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Shared.Screech;
public sealed partial class ScreechSystem : EntitySystem
{
[Dependency] private IGameTiming _timing = default!;
[Dependency] private EntityLookupSystem _entityLookup = default!;
[Dependency] private SharedAudioSystem _audio = default!;
[Dependency] private SharedEntityEffectsSystem _effects = default!;
[Dependency] private EntityQuery<StatusEffectsComponent> _statusEffectsQuery = default!;
private readonly HashSet<EntityUid> _entSet = [];
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<NoiseProtectionComponent, InventoryRelayedEvent<ScreechEffectAttemptEvent>>((a, ref b) => OnScreechProtected(a, ref b.Args));
}
[SubscribeLocalEvent]
private void OnExamine(Entity<NoiseProtectionComponent> ent, ref ExaminedEvent args)
{
if (ent.Comp.ExamineText.HasValue)
{
args.PushMarkup(Loc.GetString(ent.Comp.ExamineText.Value));
}
}
[SubscribeLocalEvent]
private void OnScreechAction(Entity<ScreechActionComponent> ent, ref ScreechActionEvent args)
{
args.Handled = true;
var param = ent.Comp; // shorthand
Screech(args.Performer, param.Range, param.Vfx, param.ScreechSound, param.Effects);
}
[SubscribeLocalEvent]
private void OnScreechProtected(Entity<NoiseProtectionComponent> ent, ref ScreechEffectAttemptEvent args)
{
args.Cancelled = true;
}
[SubscribeLocalEvent]
private void OnComponentInit(Entity<ScreechShockWaveComponent> ent, ref ComponentInit args)
{
ent.Comp.InitTime = _timing.CurTime;
Dirty(ent);
}
/// <summary>
/// Makes the entity "source" screech, applying the "effects" to every entity in "range" that does not have screech protection.
/// </summary>
public void Screech(EntityUid source, float range, EntProtoId? vfx = null, SoundSpecifier? screechSound = null, List<EntityEffect>? effects = null)
{
// first, we spawn the vfx attached to the source
if (vfx.HasValue)
PredictedSpawnAttachedTo(vfx.Value, new EntityCoordinates(source, 0f, 0f));
// then, we do the screech per-se
var transform = Transform(source);
// reset entset cache
_entSet.Clear();
_entityLookup.GetEntitiesInRange(transform.Coordinates, range, _entSet);
foreach (var entity in _entSet)
{
// Is the entity affected by the screech via status effects? (It would be a good idea to check for ears instead but IDK how to do that in a way that's performant :P)
// The entity that screeched is also immune to the screech
if (!_statusEffectsQuery.HasComponent(entity) || entity == source)
continue;
EntityHeardIt(entity, source, effects);
}
_audio.PlayPredicted(screechSound, source, source);
}
/// <summary>
/// Tests if that singular entity heard it (it may have screech protection) and if it did it will receive the entity effects.
/// </summary>
private void EntityHeardIt(EntityUid ent, EntityUid source, List<EntityEffect>? effects)
{
var ev = new ScreechEffectAttemptEvent(source);
RaiseLocalEvent(ent, ref ev);
if (ev.Cancelled)
return; // if we return here, the entity had screech protection
// apply entity effects to the target
if (effects != null)
{
foreach (var effect in effects)
{
_effects.TryApplyEffect(ent, effect, user: source);
}
}
}
}
/// <summary>
/// Event that is used to check if an entity hears the screech & feels its full effects.
/// </summary>
[ByRefEvent]
public record struct ScreechEffectAttemptEvent(EntityUid Source, bool Cancelled = false) : IInventoryRelayEvent
{
public SlotFlags TargetSlots => SlotFlags.HEAD | SlotFlags.EARS | SlotFlags.EYES;
}
/// <summary>
/// Event that is fire when an entity uses a screech action.
/// </summary>
public sealed partial class ScreechActionEvent : InstantActionEvent;