Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversion update #30

Merged
merged 1 commit into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions Content.Client/Stories/Conversion/ConversionSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Content.Shared.StatusIcon;
using Content.Shared.StatusIcon.Components;
using Content.Shared.Stories.Conversion;
using Robust.Shared.Prototypes;

namespace Content.Client.Stories.Conversion;

public sealed partial class ConversionSystem : SharedConversionSystem
{
[Dependency] private readonly IPrototypeManager _prototype = default!;
public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<ConversionableComponent, GetStatusIconsEvent>(OnGetStatusIconsEvent);
}
private void OnGetStatusIconsEvent(EntityUid uid, ConversionableComponent component, ref GetStatusIconsEvent args)
{
foreach (var (key, conversion) in component.ActiveConversions)
{
var proto = _prototype.Index(conversion.Prototype);
if (proto.StatusIcon == null)
continue;

var iconProto = _prototype.Index<StatusIconPrototype>(proto.StatusIcon);
args.StatusIcons.Add(iconProto);
}
}
}
21 changes: 1 addition & 20 deletions Content.Client/Stories/Empire/EmpireSystem.cs
Original file line number Diff line number Diff line change
@@ -1,40 +1,21 @@
using Content.Shared.StatusIcon.Components;
using Content.Shared.StatusIcon;
using Robust.Shared.Prototypes;
using Robust.Client.Player;
using Content.Shared.Ghost;
using Content.Shared.SpaceStories.Empire.Components;
using Content.Shared.SpaceStories.Conversion;

namespace Content.Client.SpaceStories.Empire;
public sealed class EmpireSystem : SharedStatusIconSystem
{
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly IPlayerManager _player = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<EmpireComponent, GetStatusIconsEvent>(OnGetStatusIconsEvent);
SubscribeLocalEvent<HypnotizedEmpireComponent, GetStatusIconsEvent>(OnGetStatusIconsEvent);
}
private void OnGetStatusIconsEvent(EntityUid uid, EmpireComponent component, ref GetStatusIconsEvent args)
{
if (!HasComp<HypnotizedEmpireComponent>(uid))
GetStatusIcon(component.StatusIcon, ref args, component.IconVisibleToGhost);
}
private void OnGetStatusIconsEvent(EntityUid uid, HypnotizedEmpireComponent component, ref GetStatusIconsEvent args)
{
GetStatusIcon(component.StatusIcon, ref args, component.IconVisibleToGhost);
}
private void GetStatusIcon(string antagStatusIcon, ref GetStatusIconsEvent args, bool visibleToGhost = true)
{
var ent = _player.LocalSession?.AttachedEntity;

if (!HasComp<EmpireComponent>(ent) && !HasComp<GhostComponent>(ent))
return;

args.StatusIcons.Add(_prototype.Index<StatusIconPrototype>(antagStatusIcon));
args.StatusIcons.Add(_prototype.Index(component.StatusIcon));
}
}
167 changes: 167 additions & 0 deletions Content.Server/Stories/Conversion/ConversionSystem.API.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
using Content.Shared.Mind;
using Content.Shared.Roles;
using Content.Shared.Stories.Conversion;
using Robust.Shared.Prototypes;
using Content.Server.Radio.Components;
using Content.Shared.Database;
using System.Diagnostics.CodeAnalysis;

namespace Content.Server.Stories.Conversion;

public sealed partial class ConversionSystem
{
public HashSet<EntityUid> GetEntitiesConvertedBy(EntityUid? uid, ProtoId<ConversionPrototype> prototype)
{
HashSet<EntityUid> entities = new();
var query = AllEntityQuery<ConversionableComponent>();

while (query.MoveNext(out var entity, out var comp))
{
foreach (var conversion in comp.ActiveConversions)
{
if (conversion.Key == prototype.Id && GetEntity(conversion.Value.Owner) == uid)
entities.Add(entity);
}
}

return entities;
}
public bool TryGetConversion(EntityUid uid, [NotNullWhen(true)] out ConversionData? data, ProtoId<ConversionPrototype> prototype, ConversionableComponent? component = null)
{
if (Resolve(uid, ref component) && component.ActiveConversions.TryGetValue(prototype.Id, out var conversion))
{
data = conversion;
return true;
}
data = null;
return false;
}
public bool TryRevert(EntityUid target, ProtoId<ConversionPrototype> prototype, EntityUid? performer = null, ConversionableComponent? component = null)
{
if (!Resolve(target, ref component, false))
return false;

if (!_prototype.TryIndex(prototype, out var proto))
return false;

if (!CanRevert(target, prototype, performer, component))
return false;

Revert(target, proto, performer, component);
return true;
}
public void Revert(EntityUid target, ConversionPrototype proto, EntityUid? performer = null, ConversionableComponent? component = null)
{
if (!Resolve(target, ref component))
return;

if (!component.ActiveConversions.TryGetValue(proto.ID, out var data))
return;

if (!_mind.TryGetMind(target, out var mindId, out var mind))
return;

if (proto.EndBriefing != null)
_antag.SendBriefing(target, Loc.GetString(proto.EndBriefing.Value.Text ?? ""), proto.EndBriefing.Value.Color, proto.EndBriefing.Value.Sound);

EntityManager.RemoveComponents(target, registry: proto.Components);
MindRemoveRoles(mindId, proto.MindComponents);

if (proto.Channels.Count > 0)
{
EnsureComp<IntrinsicRadioReceiverComponent>(target);
EnsureComp<IntrinsicRadioTransmitterComponent>(target).Channels.ExceptWith(proto.Channels);
EnsureComp<ActiveRadioComponent>(target).Channels.ExceptWith(proto.Channels);
}

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<ConversionPrototype> prototype, EntityUid? performer = null, ConversionableComponent? component = null)
{
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);
return true;
}
public void Convert(EntityUid target, ConversionPrototype proto, EntityUid? performer = null, ConversionableComponent? component = null)
{
if (!Resolve(target, ref component))
return;

if (!_mind.TryGetMind(target, out var mindId, out var mind))
return;

if (proto.Briefing != null)
_antag.SendBriefing(target, Loc.GetString(proto.Briefing.Value.Text ?? ""), proto.Briefing.Value.Color, proto.Briefing.Value.Sound);

EntityManager.AddComponents(target, registry: proto.Components);
_role.MindAddRoles(mindId, proto.MindComponents);

if (proto.Channels.Count > 0)
{
EnsureComp<IntrinsicRadioReceiverComponent>(target);
EnsureComp<IntrinsicRadioTransmitterComponent>(target).Channels.UnionWith(proto.Channels);
EnsureComp<ActiveRadioComponent>(target).Channels.UnionWith(proto.Channels);
}

var conversion = new ConversionData()
{
Owner = GetNetEntity(performer),
Prototype = proto.ID,
StartTime = _timing.CurTime,
EndTime = proto.Duration == null ? null : _timing.CurTime + TimeSpan.FromSeconds(proto.Duration.Value),
};

component.ActiveConversions.Add(proto.ID, conversion);

var ev = new ConvertedEvent(target, performer, conversion);
RaiseLocalEvent(target, (object)ev, true);
Dirty(target, component);
}
public void MindRemoveRoles(EntityUid mindId, ComponentRegistry components, MindComponent? mind = null, bool silent = false)
{
if (!Resolve(mindId, ref mind))
return;

EntityManager.RemoveComponents(mindId, components);
var antagonist = false;
foreach (var compReg in components.Values)
{
var compType = compReg.Component.GetType();

var comp = EntityManager.ComponentFactory.GetComponent(compType);
if (_role.IsAntagonistRole(comp.GetType()))
{
antagonist = true;
break;
}
}

var message = new RoleRemovedEvent(mindId, mind, antagonist);

if (mind.OwnedEntity != null)
{
RaiseLocalEvent(mind.OwnedEntity.Value, message, true);
}

_adminLogger.Add(LogType.Mind, LogImpact.Low,
$"Role components {string.Join(components.Keys.ToString(), ", ")} removed to mind of {_mind.MindOwnerLoggingString(mind)}");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Content.Shared.Mindshield.Components;
using Content.Shared.Stories.Conversion;
using Content.Shared.Stories.Mindshield;

namespace Content.Server.Stories.Conversion;

public sealed partial class ConversionSystem
{
// TODO: Имплант не должен защищать от всех конвертаций.
private void InitializeMindShield()
{
base.Initialize();
SubscribeLocalEvent<MindShieldComponent, ConvertAttemptEvent>(OnConvertAttempt);
SubscribeLocalEvent<ConversionableComponent, MindShieldImplantedEvent>(OnImplanted);
}
private void OnConvertAttempt(EntityUid uid, MindShieldComponent component, ConvertAttemptEvent args)
{
args.Cancel();
}
private void OnImplanted(EntityUid uid, ConversionableComponent component, MindShieldImplantedEvent args)
{
foreach (var (key, conversion) in component.ActiveConversions)
{
Revert(uid, _prototype.Index(conversion.Prototype));
}
}
}
78 changes: 24 additions & 54 deletions Content.Server/Stories/Conversion/ConversionSystem.cs
Original file line number Diff line number Diff line change
@@ -1,70 +1,40 @@
using Content.Shared.IdentityManagement;
using Content.Shared.Popups;
using Content.Shared.SpaceStories.Empire.Components;
using Content.Shared.Stunnable;
using Content.Shared.Chat;
using Content.Shared.Mind;
using Content.Shared.Mobs;
using Content.Shared.Roles;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Audio;
using Content.Shared.Stories.Mindshield;
using Content.Shared.SpaceStories.Conversion;
using Content.Server.Antag;
using Content.Server.Roles;
using Content.Shared.Stories.Conversion;
using Robust.Shared.Timing;
using Content.Server.Administration.Logs;
using Robust.Shared.Prototypes;
using Content.Shared.Mindshield.Components;
using Content.Shared.Actions;
using Content.Shared.Weapons.Ranged.Events;
using Content.Shared.SpaceStories.Force.LightSaber;
using Content.Shared.Alert;
using Robust.Shared.Serialization.Manager;
using Content.Shared.SpaceStories.Force;
using Content.Server.Chat.Managers;
using Content.Server.Radio.Components;
using System.Linq;

namespace Content.Server.SpaceStories.Conversion;
namespace Content.Server.Stories.Conversion;

public sealed class ConversionSystem : SharedConversionSystem
public sealed partial class ConversionSystem : SharedConversionSystem
{
[Dependency] private readonly IChatManager _chatManager = default!;
[Dependency] private readonly SharedMindSystem _mind = default!;
[Dependency] private readonly SharedStunSystem _stun = default!;
[Dependency] private readonly RoleSystem _role = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly AntagSelectionSystem _antag = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ConversionableComponent, ConvertedEvent>(OnConvert);
SubscribeLocalEvent<ConversionableComponent, RevertedEvent>(OnRevert);
InitializeMindShield();
}
private void OnRevert(EntityUid uid, ConversionableComponent component, RevertedEvent args)
public override void Update(float frameTime)
{
if (!_mind.TryGetMind(uid, out var mindId, out var mind))
return;
if (args.Prototype.GoodbyeMessage != null && mind.Session != null && args.Prototype.NeedMind)
{
var message = Loc.GetString(args.Prototype.GoodbyeMessage);
var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", message));
_chatManager.ChatMessageToOne(ChatChannel.Server, message, wrappedMessage, default, false, mind.Session.Channel, Color.Red);
}

EnsureComp<IntrinsicRadioReceiverComponent>(uid);
EnsureComp<IntrinsicRadioTransmitterComponent>(uid).Channels.ExceptWith(args.Prototype.Channels);
EnsureComp<ActiveRadioComponent>(uid).Channels.ExceptWith(args.Prototype.Channels);
base.Update(frameTime);

_stun.TryParalyze(uid, TimeSpan.FromSeconds(3), true);
}
private void OnConvert(EntityUid uid, ConversionableComponent component, ConvertedEvent args)
{
if (!_mind.TryGetMind(uid, out var mindId, out var mind))
return;
if (args.Prototype.WelcomeMessage != null && mind.Session != null && args.Prototype.NeedMind)
var query = EntityQueryEnumerator<ConversionableComponent>();
while (query.MoveNext(out var uid, out var comp))
{
var message = Loc.GetString(args.Prototype.WelcomeMessage);
var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", message));
_chatManager.ChatMessageToOne(ChatChannel.Server, message, wrappedMessage, default, false, mind.Session.Channel, Color.Red);
foreach (var (key, conversion) in comp.ActiveConversions)
{
if (conversion.EndTime > _timing.CurTime)
continue;
var proto = _prototype.Index(conversion.Prototype);
Revert(uid, proto);
}
}

EnsureComp<IntrinsicRadioReceiverComponent>(uid);
EnsureComp<IntrinsicRadioTransmitterComponent>(uid).Channels.UnionWith(args.Prototype.Channels);
EnsureComp<ActiveRadioComponent>(uid).Channels.UnionWith(args.Prototype.Channels);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ private void OnDash(ForceDashActionEvent args)
private void OnHypnosis(HypnosisTargetActionEvent args)
{
if (args.Handled || _mobState.IsIncapacitated(args.Target) || HasComp<MindShieldComponent>(args.Target)) return;
_conversion.TryConvert(args.Target, "HypnotizedEmpire");
_conversion.TryConvert(args.Target, "HypnotizedEmpire", args.Performer); // FIXME: Hardcode. Исправим в обновлении инквизитора.
args.Handled = true;
}
private void OnIgnite(IgniteTargetActionEvent args)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
using Content.Server.Beam;
using Content.Server.SpaceStories.ForceUser.ProtectiveBubble.Systems;
using Robust.Shared.Prototypes;
using Content.Server.SpaceStories.Conversion;
using Content.Server.Stories.Conversion;

namespace Content.Server.SpaceStories.ForceUser;
public sealed partial class ForceUserSystem : SharedForceUserSystem
Expand Down
Loading
Loading