mirror of
https://github.com/DeltaV-Station/Delta-v.git
synced 2026-10-01 16:47:26 +00:00
* Added the blood writing ability to revenants (cherry picked from commit 8157d155e1f7a3840992b54475c59031d2a75f25) * Added the revenant Animate action (cherry picked from commit 1b53520849a60538598cae641c6e598b1a5d7534) * Added Animate action sprite and fixed revenant action sprites being small (cherry picked from commit 5c88ce9b21cf517023cd136ddb8aaa361f72fbfe) * Revenants in stasis can now be crafted into sentient revenant plushies Revenants in stasis can now talk (cherry picked from commit af84083da6e17bb7671d9f00993dc6bcc0b0a583) * Revenant plushies and ectoplasm now talk with their trapped revenant's name (cherry picked from commit 855b25aeb7f29ed6ff2dcc0d4ab1e589ae7e2e16) * Added a yml nerf option in case revenant is too powerful (cherry picked from commit 6895a5ca929f32267dea1e326aee62302dc151b8) * Added a yml nerf option in case revenant is too powerful (cherry picked from commit 6895a5ca929f32267dea1e326aee62302dc151b8) * Passing over salt ore now reveals revenants (cherry picked from commit beea55885f98adc72e34751ba6f798bfadd8dd31) * Salt puddles now reveal revenants Hooray for EnsureTileReaction! (cherry picked from commit b69304747e3b5aa867c5afd8917d2c170c65253e) * Bibles now reveal revenants Localization strings added (cherry picked from commit 62f7ec604748697e5fecc942c4a5d14ff682c596) * Added the revenant Haunt action (cherry picked from commit fb692c4cab3f411c11a3004fa73f30122e0ff7f9) * Haunt witnesses now have an icon over their head on the revenant's client (cherry picked from commit 5d1b3c6b0af4508ebee7aa8738f7a5f3aa9e53ca) * Slight revenant nerfs and an additional escape hatch (cherry picked from commit 490e4c525b75b03502497bfa89827f915f6c7fb2) * Fixed revenant speech name, and other fixes This is a few changes clumped into one. I should've broken this one up, but I got overzealous. - Revenant's ectoplasm now properly uses TransformSpeakerNameEvent - Revenants crafted into plushies now use VoiceOverrideComponent instead of VoiceMaskComponent - Plushies now have a custom speaking noise - Moved Impstation-specific revenant code to the _Impstation subdirectory (cherry picked from commit a5e0b0c9383e4011e69edc0592c8a4cf40b06402) * Fixed revenant haunt witness sprite not disappearing (cherry picked from commit 0c06d4a8f48f6eee324cd944dbcb1fce3258eb58) * New artifact effectr: animate nearby items (like a revenant) (cherry picked from commit 6ba1b4d8b313eda9e5ff82246ed7425e80287d0f) * Revenant cleanups * Revenant Fixes * add audio * haunt fixes * salt fixes * grinder gamer * stasis * cleanup and comments * deltav ectoplasm * clean up imp comment * event weight and guidebook gaming * catalog * alert fix * window nerf * effectprobfake * mapinit * no braincells ops Signed-off-by: Lyndomen <49795619+Lyndomen@users.noreply.github.com> * add physics * remove phyiscs * add physics realer * bible --------- Signed-off-by: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Co-authored-by: TGRCDev <tgrc@tgrc.dev> Co-authored-by: TheGrimbeeper <thegrimbeeper.11@gmail.com>
211 lines
8.2 KiB
C#
211 lines
8.2 KiB
C#
using Content.Server.Bible;
|
|
using Content.Server.Bible.Components;
|
|
using Content.Server.Construction;
|
|
using Content.Server.Explosion.EntitySystems;
|
|
using Content.Server.Ghost.Roles;
|
|
using Content.Server.Ghost.Roles.Components;
|
|
using Content.Server.Kitchen.EntitySystems;
|
|
using Content.Server.Mind;
|
|
using Content.Server.Revenant.Components;
|
|
using Content.Server.Speech.Components;
|
|
using Content.Shared.Alert;
|
|
using Content.Shared.Chat;
|
|
using Content.Shared.DoAfter;
|
|
using Content.Shared.Examine;
|
|
using Content.Shared.Interaction;
|
|
using Content.Shared.Interaction.Events;
|
|
using Content.Shared.Movement.Components;
|
|
using Content.Shared.Popups;
|
|
using Content.Shared.Revenant;
|
|
using Content.Shared.Speech;
|
|
using Content.Shared.StatusEffect;
|
|
using Content.Shared.Tag;
|
|
using Robust.Shared.Player;
|
|
using Robust.Shared.Prototypes;
|
|
|
|
namespace Content.Server.Revenant.EntitySystems;
|
|
|
|
public sealed partial class RevenantStasisSystem : EntitySystem
|
|
{
|
|
[Dependency] private readonly StatusEffectsSystem _statusEffects = default!;
|
|
[Dependency] private readonly MindSystem _mind = default!;
|
|
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
|
|
[Dependency] private readonly GhostRoleSystem _ghostRoles = default!;
|
|
[Dependency] private readonly MetaDataSystem _meta = default!;
|
|
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
|
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
|
[Dependency] private readonly TagSystem _tags = default!;
|
|
[Dependency] private readonly ExplosionSystem _explosion = default!;
|
|
[Dependency] private readonly IPrototypeManager _protoMan = default!;
|
|
|
|
[ValidatePrototypeId<StatusEffectPrototype>]
|
|
private const string RevenantStasisId = "Stasis";
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
SubscribeLocalEvent<RevenantStasisComponent, ComponentStartup>(OnStartup);
|
|
SubscribeLocalEvent<RevenantStasisComponent, ComponentShutdown>(OnShutdown);
|
|
SubscribeLocalEvent<RevenantStasisComponent, StatusEffectEndedEvent>(OnStatusEnded);
|
|
SubscribeLocalEvent<RevenantStasisComponent, ChangeDirectionAttemptEvent>(OnAttemptDirection);
|
|
SubscribeLocalEvent<RevenantStasisComponent, ExaminedEvent>(OnExamine);
|
|
SubscribeLocalEvent<RevenantStasisComponent, ConstructionConsumedObjectEvent>(OnCrafted);
|
|
SubscribeLocalEvent<RevenantStasisComponent, ReagentGrinderSystem.GrindAttemptEvent>(OnGrindAttempt);
|
|
SubscribeLocalEvent<RevenantStasisComponent, TransformSpeakerNameEvent>(OnTransformName);
|
|
SubscribeLocalEvent<RevenantStasisComponent, AfterInteractUsingEvent>(OnBibleInteract, before: [typeof(BibleSystem)]);
|
|
SubscribeLocalEvent<RevenantStasisComponent, ExorciseRevenantDoAfterEvent>(OnExorcise);
|
|
}
|
|
|
|
private void OnStartup(EntityUid uid, RevenantStasisComponent component, ComponentStartup args)
|
|
{
|
|
EnsureComp<AlertsComponent>(uid);
|
|
|
|
EnsureComp<StatusEffectsComponent>(uid);
|
|
_statusEffects.TryAddStatusEffect(uid, RevenantStasisId, component.StasisDuration, true);
|
|
|
|
var mover = EnsureComp<InputMoverComponent>(uid);
|
|
mover.CanMove = false;
|
|
Dirty(uid, mover);
|
|
|
|
var speech = EnsureComp<SpeechComponent>(uid);
|
|
speech.SpeechVerb = "Ghost";
|
|
Dirty(uid, speech);
|
|
|
|
if (TryComp<GhostRoleComponent>(uid, out var ghostRole))
|
|
_ghostRoles.UnregisterGhostRole((uid, ghostRole));
|
|
}
|
|
|
|
private void OnTransformName(EntityUid uid, RevenantStasisComponent comp, TransformSpeakerNameEvent args)
|
|
{
|
|
args.VoiceName = Name(comp.Revenant);
|
|
args.SpeechVerb = "Ghost";
|
|
}
|
|
|
|
private void OnShutdown(EntityUid uid, RevenantStasisComponent component, ComponentShutdown args)
|
|
{
|
|
if (_statusEffects.HasStatusEffect(uid, RevenantStasisId))
|
|
{
|
|
if (_mind.TryGetMind(uid, out var mindId, out var _))
|
|
_mind.TransferTo(mindId, null);
|
|
QueueDel(component.Revenant);
|
|
}
|
|
}
|
|
|
|
private void OnStatusEnded(EntityUid uid, RevenantStasisComponent component, StatusEffectEndedEvent args)
|
|
{
|
|
if (args.Key == "Stasis")
|
|
{
|
|
_transformSystem.SetCoordinates(component.Revenant, Transform(uid).Coordinates);
|
|
_transformSystem.AttachToGridOrMap(component.Revenant);
|
|
_meta.SetEntityPaused(component.Revenant, false);
|
|
if (_mind.TryGetMind(uid, out var mindId, out var _))
|
|
_mind.TransferTo(mindId, component.Revenant);
|
|
QueueDel(uid);
|
|
}
|
|
}
|
|
|
|
private void OnExamine(Entity<RevenantStasisComponent> entity, ref ExaminedEvent args)
|
|
{
|
|
args.PushMarkup(Loc.GetString("revenant-stasis-regenerating"));
|
|
}
|
|
|
|
private void OnCrafted(EntityUid uid, RevenantStasisComponent comp, ConstructionConsumedObjectEvent args)
|
|
{
|
|
// Permanently sealed into revenant plushie
|
|
EnsureComp<InputMoverComponent>(args.New);
|
|
|
|
var voice = EnsureComp<VoiceOverrideComponent>(args.New);
|
|
voice.SpeechVerbOverride = "Ghost";
|
|
voice.NameOverride = Name(comp.Revenant);
|
|
|
|
if (_mind.TryGetMind(uid, out var mindId, out var _))
|
|
_mind.TransferTo(mindId, args.New);
|
|
}
|
|
|
|
private void OnGrindAttempt(EntityUid uid, RevenantStasisComponent comp, ReagentGrinderSystem.GrindAttemptEvent args)
|
|
{
|
|
if (!comp.Revenant.Comp.GrindingRequiresSalt)
|
|
return;
|
|
|
|
foreach (var reagent in args.Reagents)
|
|
{
|
|
if (_tags.HasAnyTag(reagent, "Salt", "Holy"))
|
|
return;
|
|
}
|
|
|
|
// Ripped off the changeling blood explosion variables
|
|
_explosion.QueueExplosion(
|
|
args.Grinder.Owner,
|
|
"Default",
|
|
7.5f, // totalIntensity
|
|
4f, // slope
|
|
2f // maxTileIntensity
|
|
);
|
|
|
|
args.Cancel();
|
|
}
|
|
|
|
private void OnAttemptDirection(EntityUid uid, RevenantStasisComponent comp, ChangeDirectionAttemptEvent args)
|
|
{
|
|
args.Cancel();
|
|
}
|
|
|
|
private void OnBibleInteract(EntityUid uid, RevenantStasisComponent comp, ref AfterInteractUsingEvent args)
|
|
{
|
|
if (args.Handled)
|
|
return;
|
|
if (args.Target == null)
|
|
return;
|
|
var bible = args.Used;
|
|
var target = args.Target.Value;
|
|
var user = args.User;
|
|
if (!HasComp<BibleComponent>(args.Used))
|
|
return;
|
|
|
|
if (!TryComp<RevenantStasisComponent>(target, out var stasis))
|
|
return;
|
|
|
|
var revenant = stasis.Revenant;
|
|
|
|
if (revenant.Comp.ExorcismRequiresBibleUser && !HasComp<BibleUserComponent>(args.User))
|
|
{
|
|
_popup.PopupEntity(Loc.GetString("revenant-exorcise-fail", ("bible", bible)), user, user);
|
|
return;
|
|
}
|
|
|
|
var doAfterEventArgs = new DoAfterArgs(EntityManager, user, TimeSpan.FromSeconds(10), new ExorciseRevenantDoAfterEvent(), target, target, bible)
|
|
{
|
|
BreakOnMove = true,
|
|
BreakOnWeightlessMove = false,
|
|
BreakOnDamage = true,
|
|
NeedHand = true,
|
|
DistanceThreshold = 1f
|
|
};
|
|
|
|
if (!_doAfter.TryStartDoAfter(doAfterEventArgs))
|
|
return;
|
|
|
|
args.Handled = true;
|
|
|
|
_popup.PopupEntity(Loc.GetString("revenant-exorcise-begin-user", [("bible", bible), ("user", user), ("revenant", revenant.Owner)]), user, user);
|
|
_popup.PopupEntity(Loc.GetString("revenant-exorcise-begin-target", [("bible", bible), ("user", user), ("revenant", revenant.Owner)]), target, target, PopupType.MediumCaution);
|
|
_popup.PopupEntity(Loc.GetString("revenant-exorcise-begin-other", [("bible", bible), ("user", user), ("revenant", revenant.Owner)]), target, Filter.Pvs(target).RemovePlayersByAttachedEntity([user, target]), true);
|
|
}
|
|
|
|
private void OnExorcise(EntityUid uid, RevenantStasisComponent comp, ExorciseRevenantDoAfterEvent args)
|
|
{
|
|
if (args.Cancelled)
|
|
return;
|
|
if (args.Target == null || args.Used == null)
|
|
return;
|
|
|
|
var target = args.Target.Value;
|
|
var used = args.Used.Value;
|
|
|
|
_popup.PopupEntity(Loc.GetString("revenant-exorcise-success", [("bible", used), ("user", args.User), ("revenant", comp.Revenant.Owner)]), target);
|
|
|
|
RemComp<RevenantStasisComponent>(args.Target.Value);
|
|
}
|
|
}
|