mirror of
https://github.com/WWhiteDreamProject/wwdpublic.git
synced 2026-04-18 05:59:03 +03:00
<!-- This is a semi-strict format, you can add/remove sections as needed but the order/format should be kept the same Remove these comments before submitting --> <!-- Explain this PR in as much detail as applicable Some example prompts to consider: How might this affect the game? The codebase? What might be some alternatives to this? How/Who does this benefit/hurt [the game/codebase]? --> This PR ports https://github.com/Goob-Station/Goob-Station/pull/2409 https://github.com/Goob-Station/Goob-Station/pull/2591 https://github.com/Goob-Station/Goob-Station/pull/2599 This PR was initially intended to be merged into White Dream repo, so my changes are marked as WD edit. <!-- A list of everything you have to do before this PR is "complete" You probably won't have to complete everything before merging but it's good to leave future references --> - [ ] Port pain numbness - [ ] Port nullrods - [ ] Port tile movement --- <!-- This is default collapsed, readers click to expand it and see all your media The PR media section can get very large at times, so this is a good way to keep it clean The title is written using HTML tags The title must be within the <summary> tags or you won't see it --> <details><summary><h1>Media</h1></summary> <p>     </p> </details> --- <!-- You can add an author after the `🆑` to change the name that appears in the changelog (ex: `🆑 Death`) Leaving it blank will default to your GitHub display name This includes all available types for the changelog --> 🆑 - add: Ported Devil antag from Goobstation --------- Signed-off-by: Kai5 <68296202+Kai518@users.noreply.github.com> Signed-off-by: VMSolidus <evilexecutive@gmail.com> Co-authored-by: Solstice <solsticeofthewinter@gmail.com> Co-authored-by: VMSolidus <evilexecutive@gmail.com>
181 lines
5.7 KiB
C#
181 lines
5.7 KiB
C#
// SPDX-FileCopyrightText: 2025 GoobBot <uristmchands@proton.me>
|
|
// SPDX-FileCopyrightText: 2025 Solstice <solsticeofthewinter@gmail.com>
|
|
// SPDX-FileCopyrightText: 2025 SolsticeOfTheWinter <solsticeofthewinter@gmail.com>
|
|
//
|
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
using Content.Shared._Goobstation.Devil;
|
|
using Content.Shared._Goobstation.Devil.Condemned;
|
|
using Content.Shared._Goobstation.Religion;
|
|
using Content.Server.IdentityManagement;
|
|
using Content.Server.Polymorph.Systems;
|
|
using Content.Shared.Examine;
|
|
using Content.Shared.IdentityManagement;
|
|
using Content.Shared.Interaction.Components;
|
|
using Content.Shared.Movement.Events;
|
|
using Content.Shared.Polymorph;
|
|
using Content.Shared.Popups;
|
|
using Robust.Shared.Audio;
|
|
using Robust.Shared.Audio.Systems;
|
|
using Robust.Shared.Prototypes;
|
|
using Robust.Shared.Spawners;
|
|
|
|
namespace Content.Server._Goobstation.Devil.Condemned;
|
|
|
|
public sealed partial class CondemnedSystem : EntitySystem
|
|
{
|
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
|
[Dependency] private readonly PolymorphSystem _poly = default!;
|
|
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
SubscribeLocalEvent<CondemnedComponent, ExaminedEvent>(OnExamined);
|
|
SubscribeLocalEvent<CondemnedComponent, MapInitEvent>(OnStartup);
|
|
SubscribeLocalEvent<CondemnedComponent, ComponentRemove>(OnRemoved);
|
|
SubscribeLocalEvent<CondemnedComponent, UpdateCanMoveEvent>(OnMoveAttempt);
|
|
InitializeOnDeath();
|
|
}
|
|
|
|
public override void Update(float frameTime)
|
|
{
|
|
base.Update(frameTime);
|
|
|
|
var query = EntityQueryEnumerator<CondemnedComponent>();
|
|
while (query.MoveNext(out var uid, out var comp))
|
|
{
|
|
switch (comp.CurrentPhase)
|
|
{
|
|
case CondemnedPhase.PentagramActive:
|
|
UpdatePentagramPhase(uid, frameTime, comp);
|
|
break;
|
|
case CondemnedPhase.HandActive:
|
|
UpdateHandPhase(uid, frameTime, comp);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnStartup(Entity<CondemnedComponent> condemned, ref MapInitEvent args)
|
|
{
|
|
if (condemned.Comp.SoulOwnedNotDevil)
|
|
return;
|
|
|
|
if (HasComp<WeakToHolyComponent>(condemned))
|
|
condemned.Comp.WasWeakToHoly = true;
|
|
else
|
|
EnsureComp<WeakToHolyComponent>(condemned).AlwaysTakeHoly = true;
|
|
}
|
|
|
|
private void OnRemoved(Entity<CondemnedComponent> condemned, ref ComponentRemove args)
|
|
{
|
|
if (condemned.Comp.SoulOwnedNotDevil)
|
|
return;
|
|
|
|
if (!condemned.Comp.WasWeakToHoly)
|
|
RemComp<WeakToHolyComponent>(condemned);
|
|
}
|
|
|
|
private void OnMoveAttempt(Entity<CondemnedComponent> condemned, ref UpdateCanMoveEvent args)
|
|
{
|
|
if (!condemned.Comp.FreezeDuringCondemnation
|
|
|| condemned.Comp.CurrentPhase != CondemnedPhase.Waiting)
|
|
return;
|
|
|
|
args.Cancel();
|
|
}
|
|
|
|
public void StartCondemnation(
|
|
EntityUid uid,
|
|
bool freezeEntity = true,
|
|
bool doFlavor = true,
|
|
CondemnedBehavior behavior = CondemnedBehavior.Delete)
|
|
{
|
|
var comp = EnsureComp<CondemnedComponent>(uid);
|
|
comp.CondemnOnDeath = false;
|
|
|
|
if (freezeEntity)
|
|
comp.FreezeDuringCondemnation = true;
|
|
|
|
var coords = Transform(uid).Coordinates;
|
|
Spawn(comp.PentagramProto, coords);
|
|
_audio.PlayPvs(comp.SoundEffect, coords);
|
|
|
|
if (comp.CondemnedBehavior == CondemnedBehavior.Delete && doFlavor)
|
|
_popup.PopupCoordinates(Loc.GetString("condemned-start", ("target", uid)), coords, PopupType.LargeCaution);
|
|
|
|
comp.CurrentPhase = CondemnedPhase.PentagramActive;
|
|
comp.PhaseTimer = 0f;
|
|
comp.CondemnedBehavior = behavior;
|
|
}
|
|
|
|
private void UpdatePentagramPhase(EntityUid uid, float frameTime, CondemnedComponent? comp = null)
|
|
{
|
|
if (!Resolve(uid, ref comp))
|
|
return;
|
|
|
|
comp.PhaseTimer += frameTime;
|
|
|
|
if (comp.PhaseTimer < 3f)
|
|
return;
|
|
|
|
var coords = Transform(uid).Coordinates;
|
|
var handEntity = Spawn(comp.HandProto, coords);
|
|
|
|
comp.HandDuration = TryComp<TimedDespawnComponent>(handEntity, out var timedDespawn)
|
|
? timedDespawn.Lifetime
|
|
: 1f;
|
|
|
|
comp.CurrentPhase = CondemnedPhase.HandActive;
|
|
comp.PhaseTimer = 0f;
|
|
}
|
|
|
|
private void UpdateHandPhase(EntityUid uid, float frameTime, CondemnedComponent? comp = null)
|
|
{
|
|
if (!Resolve(uid, ref comp))
|
|
return;
|
|
|
|
comp.PhaseTimer += frameTime;
|
|
|
|
if (comp.PhaseTimer < comp.HandDuration)
|
|
return;
|
|
|
|
DoCondemnedBehavior(uid, comp);
|
|
|
|
comp.CurrentPhase = CondemnedPhase.Complete;
|
|
}
|
|
|
|
private void DoCondemnedBehavior(EntityUid uid, CondemnedComponent? comp = null)
|
|
{
|
|
if (!Resolve(uid, ref comp))
|
|
return;
|
|
|
|
switch (comp)
|
|
{
|
|
case { CondemnedBehavior: CondemnedBehavior.Delete }:
|
|
QueueDel(uid);
|
|
break;
|
|
case { CondemnedBehavior: CondemnedBehavior.Banish }:
|
|
_poly.PolymorphEntity(uid, comp.BanishProto);
|
|
break;
|
|
}
|
|
|
|
RemCompDeferred(uid, comp);
|
|
}
|
|
|
|
private void OnExamined(Entity<CondemnedComponent> condemned, ref ExaminedEvent args)
|
|
{
|
|
if (!args.IsInDetailsRange
|
|
|| condemned.Comp.SoulOwnedNotDevil)
|
|
return;
|
|
|
|
var ev = new IsEyesCoveredCheckEvent();
|
|
RaiseLocalEvent(condemned, ev);
|
|
|
|
if (ev.IsEyesProtected)
|
|
return;
|
|
|
|
args.PushMarkup(Loc.GetString("condemned-component-examined", ("target", Identity.Entity(condemned, EntityManager) )));
|
|
}
|
|
}
|