diff --git a/Content.Server/Stories/Conversion/ConversionSystem.API.cs b/Content.Server/Stories/Conversion/ConversionSystem.API.cs index ec5463da4b..fc9d6a3ffb 100644 --- a/Content.Server/Stories/Conversion/ConversionSystem.API.cs +++ b/Content.Server/Stories/Conversion/ConversionSystem.API.cs @@ -26,15 +26,14 @@ public HashSet GetEntitiesConvertedBy(EntityUid? uid, ProtoId prototype, ConversionableComponent? component = null) + public bool TryGetConversion(EntityUid uid, string id, [NotNullWhen(true)] out ConversionData? conversion, ConversionableComponent? component = null) { - if (Resolve(uid, ref component) && component.ActiveConversions.TryGetValue(prototype.Id, out var conversion)) - { - data = conversion; - return true; - } - data = null; - return false; + conversion = null; + + if (!Resolve(uid, ref component)) + return false; + + return component.ActiveConversions.TryGetValue(id, out conversion); } public bool TryRevert(EntityUid target, ProtoId prototype, EntityUid? performer = null, ConversionableComponent? component = null) { @@ -47,10 +46,10 @@ public bool TryRevert(EntityUid target, ProtoId prototype, if (!CanRevert(target, prototype, performer, component)) return false; - Revert(target, proto, performer, component); + DoRevert(target, proto, performer, component); return true; } - public void Revert(EntityUid target, ConversionPrototype proto, EntityUid? performer = null, ConversionableComponent? component = null) + private void DoRevert(EntityUid target, ConversionPrototype proto, EntityUid? performer = null, ConversionableComponent? component = null) { if (!Resolve(target, ref component)) return; @@ -61,6 +60,10 @@ public void Revert(EntityUid target, ConversionPrototype proto, EntityUid? perfo if (!_mind.TryGetMind(target, out var mindId, out var mind)) return; + // До удаления компонентов, чтобы эти компоненты могли его обработать. + var ev = new RevertedEvent(target, performer, data); + RaiseLocalEvent(target, (object) ev, true); + if (proto.EndBriefing != null) _antag.SendBriefing(target, Loc.GetString(proto.EndBriefing.Value.Text ?? ""), proto.EndBriefing.Value.Color, proto.EndBriefing.Value.Sound); @@ -76,8 +79,6 @@ public void Revert(EntityUid target, ConversionPrototype proto, EntityUid? perfo component.ActiveConversions.Remove(proto.ID); - var ev = new RevertedEvent(target, performer, proto); - RaiseLocalEvent(target, (object)ev, true); Dirty(target, component); } public bool TryConvert(EntityUid target, ProtoId prototype, EntityUid? performer = null, ConversionableComponent? component = null) @@ -85,22 +86,16 @@ public bool TryConvert(EntityUid target, ProtoId prototype, if (!Resolve(target, ref component, false)) return false; - Logger.Error("1"); - if (!_prototype.TryIndex(prototype, out var proto)) return false; - Logger.Error("2"); - if (!CanConvert(target, prototype, performer, component)) return false; - Logger.Error("3"); - - Convert(target, proto, performer, component); + DoConvert(target, proto, performer, component); return true; } - public void Convert(EntityUid target, ConversionPrototype proto, EntityUid? performer = null, ConversionableComponent? component = null) + private void DoConvert(EntityUid target, ConversionPrototype proto, EntityUid? performer = null, ConversionableComponent? component = null) { if (!Resolve(target, ref component)) return; @@ -132,7 +127,7 @@ public void Convert(EntityUid target, ConversionPrototype proto, EntityUid? perf component.ActiveConversions.Add(proto.ID, conversion); var ev = new ConvertedEvent(target, performer, conversion); - RaiseLocalEvent(target, (object)ev, true); + RaiseLocalEvent(target, (object) ev, true); Dirty(target, component); } public void MindRemoveRoles(EntityUid mindId, ComponentRegistry components, MindComponent? mind = null, bool silent = false) diff --git a/Content.Server/Stories/Conversion/ConversionSystem.MindShield.cs b/Content.Server/Stories/Conversion/ConversionSystem.MindShield.cs index 3a6e3357f6..4ce56934ae 100644 --- a/Content.Server/Stories/Conversion/ConversionSystem.MindShield.cs +++ b/Content.Server/Stories/Conversion/ConversionSystem.MindShield.cs @@ -21,7 +21,7 @@ private void OnImplanted(EntityUid uid, ConversionableComponent component, MindS { foreach (var (key, conversion) in component.ActiveConversions) { - Revert(uid, _prototype.Index(conversion.Prototype)); + DoRevert(uid, _prototype.Index(conversion.Prototype)); } } } diff --git a/Content.Server/Stories/Conversion/ConversionSystem.cs b/Content.Server/Stories/Conversion/ConversionSystem.cs index 03f43b5543..93de6c8fdb 100644 --- a/Content.Server/Stories/Conversion/ConversionSystem.cs +++ b/Content.Server/Stories/Conversion/ConversionSystem.cs @@ -30,10 +30,12 @@ public override void Update(float frameTime) { foreach (var (key, conversion) in comp.ActiveConversions) { + if (conversion.EndTime == null) + continue; if (conversion.EndTime > _timing.CurTime) continue; var proto = _prototype.Index(conversion.Prototype); - Revert(uid, proto); + DoRevert(uid, proto); } } } diff --git a/Content.Shared/Stories/Conversion/ConversionPrototype.cs b/Content.Shared/Stories/Conversion/ConversionPrototype.cs index 3c71bd1ba5..593678adbc 100644 --- a/Content.Shared/Stories/Conversion/ConversionPrototype.cs +++ b/Content.Shared/Stories/Conversion/ConversionPrototype.cs @@ -1,3 +1,4 @@ +using Content.Shared.Mobs; using Content.Shared.StatusIcon; using Content.Shared.Whitelist; using Robust.Shared.Audio; @@ -32,6 +33,9 @@ public sealed partial class ConversionPrototype : IPrototype #endregion #region Whitelist + [DataField] + public HashSet? AllowedMobStates = [MobState.Alive]; + [DataField] public EntityWhitelist? Whitelist; diff --git a/Content.Shared/Stories/Conversion/ConversionSystem.cs b/Content.Shared/Stories/Conversion/ConversionSystem.cs index 75f697bf7b..45207e6be8 100644 --- a/Content.Shared/Stories/Conversion/ConversionSystem.cs +++ b/Content.Shared/Stories/Conversion/ConversionSystem.cs @@ -1,3 +1,4 @@ +using Content.Shared.Mobs.Components; using Content.Shared.Whitelist; using Robust.Shared.Prototypes; @@ -26,6 +27,11 @@ public bool CanConvert(EntityUid target, ProtoId prototype, var proto = _prototype.Index(prototype); + if (TryComp(target, out var mobState) && + proto.AllowedMobStates != null && + !proto.AllowedMobStates.Contains(mobState.CurrentState)) + return false; + if (_entityWhitelist.IsWhitelistFail(proto.Whitelist, target)) return false; diff --git a/Content.Shared/Stories/Conversion/ConversionableComponent.cs b/Content.Shared/Stories/Conversion/ConversionableComponent.cs index f20e0d5785..6dec3b87a0 100644 --- a/Content.Shared/Stories/Conversion/ConversionableComponent.cs +++ b/Content.Shared/Stories/Conversion/ConversionableComponent.cs @@ -31,9 +31,9 @@ public sealed class ConvertedEvent(EntityUid target, EntityUid? performer, Conve public readonly EntityUid? Performer = performer; public readonly ConversionData Data = data; } -public sealed class RevertedEvent(EntityUid target, EntityUid? performer, ConversionPrototype prototype) : HandledEntityEventArgs +public sealed class RevertedEvent(EntityUid target, EntityUid? performer, ConversionData data) : HandledEntityEventArgs { public readonly EntityUid Target = target; public readonly EntityUid? Performer = performer; - public readonly ConversionPrototype Prototype = prototype; + public readonly ConversionData Data = data; }