-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
conversion duration & conversion status icon & less shitcode
- Loading branch information
Doublechest
committed
Jul 19, 2024
1 parent
9bc6159
commit 5bd847f
Showing
16 changed files
with
400 additions
and
383 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
167
Content.Server/Stories/Conversion/ConversionSystem.API.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
27
Content.Server/Stories/Conversion/ConversionSystem.MindShield.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.