Skip to content

Commit

Permalink
conversion duration & conversion status icon & less shitcode (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
doublechest0 authored Jul 19, 2024
1 parent 9bc6159 commit 503b64f
Show file tree
Hide file tree
Showing 16 changed files with 400 additions and 383 deletions.
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)}");
}
}
27 changes: 27 additions & 0 deletions Content.Server/Stories/Conversion/ConversionSystem.MindShield.cs
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

0 comments on commit 503b64f

Please sign in to comment.