diff --git a/Content.Server/Bed/Cryostorage/CryostorageSystem.cs b/Content.Server/Bed/Cryostorage/CryostorageSystem.cs index 646f4694ffa54d..2edc4541f8f34d 100644 --- a/Content.Server/Bed/Cryostorage/CryostorageSystem.cs +++ b/Content.Server/Bed/Cryostorage/CryostorageSystem.cs @@ -31,6 +31,7 @@ using Robust.Shared.Utility; using Content.Shared.Roles; // SS220 Cryostorage ghost role fix using Robust.Shared.Prototypes; // SS220 Cryostorage ghost role fix +using Content.Server.SS220.Bed.Cryostorage; //SS220 Cult_hotfix_4 namespace Content.Server.Bed.Cryostorage; @@ -222,6 +223,10 @@ public void HandleEnterCryostorage(Entity ent, Ne } comp.AllowReEnteringBody = false; + //SS220 start Cult_hotfix_4 + var ev = new BeingCryoDeletedEvent(); + RaiseLocalEvent(ent, ref ev); + //SS220 end Cult_hotfix_4 _transform.SetParent(ent, PausedMap.Value); cryostorageComponent.StoredPlayers.Add(ent); Dirty(ent, comp); diff --git a/Content.Server/Database/ServerBanDef.cs b/Content.Server/Database/ServerBanDef.cs index 4f97ba54710159..63cbc197339b4f 100644 --- a/Content.Server/Database/ServerBanDef.cs +++ b/Content.Server/Database/ServerBanDef.cs @@ -87,6 +87,7 @@ public string FormatBanMessage(IConfigurationManager cfg, ILocalizationManager l return $""" {loc.GetString("ban-banned-1")} + {loc.GetString("ban-banned-8", ("banId", Id.HasValue ? Id.Value : "-"))} {loc.GetString("ban-banned-4", ("admin", BanningAdminName ?? "Console"))} {loc.GetString("ban-banned-6", ("round", StatedRound != 0 ? StatedRound : loc.GetString("ban-banned-7")))} {loc.GetString("ban-banned-2", ("reason", Reason))} diff --git a/Content.Server/SS220/Bed/Cryostorage/BeingCryoDeletedEvent.cs b/Content.Server/SS220/Bed/Cryostorage/BeingCryoDeletedEvent.cs new file mode 100644 index 00000000000000..37dbd11ecc0464 --- /dev/null +++ b/Content.Server/SS220/Bed/Cryostorage/BeingCryoDeletedEvent.cs @@ -0,0 +1,7 @@ +namespace Content.Server.SS220.Bed.Cryostorage; + +/// +/// Raised before body will deleted by a cryostorages +/// +[ByRefEvent] +public readonly record struct BeingCryoDeletedEvent(); diff --git a/Content.Server/SS220/CultYogg/Cultists/CultYoggSystem.cs b/Content.Server/SS220/CultYogg/Cultists/CultYoggSystem.cs index 4683568942892d..571da95579f0e7 100644 --- a/Content.Server/SS220/CultYogg/Cultists/CultYoggSystem.cs +++ b/Content.Server/SS220/CultYogg/Cultists/CultYoggSystem.cs @@ -43,6 +43,8 @@ public sealed class CultYoggSystem : SharedCultYoggSystem [Dependency] private readonly ThirstSystem _thirstSystem = default!; [Dependency] private readonly VomitSystem _vomitSystem = default!; + private const string CultDefaultMarking = "CultStage-Halo"; + public override void Initialize() { base.Initialize(); @@ -78,41 +80,41 @@ private void UpdateStage(Entity entity, ref ChangeCultYoggSta huAp.EyeColor = Color.Green; break; case 2: - if (!_prototype.HasIndex("CultStage-Halo")) - { - Log.Error("CultStage-Halo marking doesn't exist"); - return; - } - - if (!huAp.MarkingSet.Markings.ContainsKey(MarkingCategories.Special)) + if (_prototype.HasIndex(CultDefaultMarking)) { - huAp.MarkingSet.Markings.Add(MarkingCategories.Special, new List([new Marking("CultStage-Halo", colorCount: 1)])); + if (!huAp.MarkingSet.Markings.ContainsKey(MarkingCategories.Special)) + { + huAp.MarkingSet.Markings.Add(MarkingCategories.Special, new List([new Marking(CultDefaultMarking, colorCount: 1)])); + } + else + { + _humanoidAppearance.SetMarkingId(entity.Owner, + MarkingCategories.Special, + 0, + CultDefaultMarking, + huAp); + } } else { - _humanoidAppearance.SetMarkingId(entity.Owner, - MarkingCategories.Special, - 0, - "CultStage-Halo", - huAp); + Log.Error($"{CultDefaultMarking} marking doesn't exist"); } - Dirty(entity.Owner, huAp); - var newMarkingId = $"CultStage-{huAp.Species}"; - if (!_prototype.HasIndex(newMarkingId)) + if (_prototype.HasIndex(newMarkingId)) { - Log.Error($"{newMarkingId} marking doesn't exist"); - return; + if (huAp.MarkingSet.Markings.TryGetValue(MarkingCategories.Special, out var value)) + { + entity.Comp.PreviousTail = value.FirstOrDefault(); + value.Clear(); + huAp.MarkingSet.Markings[MarkingCategories.Special].Add(new Marking(newMarkingId, colorCount: 1)); + } } - - if (huAp.MarkingSet.Markings.TryGetValue(MarkingCategories.Tail, out var value)) + else { - entity.Comp.PreviousTail = value.FirstOrDefault(); - value.Clear(); - huAp.MarkingSet.Markings[MarkingCategories.Special].Add(new Marking(newMarkingId, colorCount: 1)); - Dirty(entity.Owner, huAp); + // We have species-marking only for the Nians, so this log only leads to unnecessary errors. + //Log.Error($"{newMarkingId} marking doesn't exist"); } break; case 3: diff --git a/Content.Server/SS220/CultYogg/MiGo/MiGoReplacementSystem.cs b/Content.Server/SS220/CultYogg/MiGo/MiGoReplacementSystem.cs deleted file mode 100644 index 5ea55844a4c4ff..00000000000000 --- a/Content.Server/SS220/CultYogg/MiGo/MiGoReplacementSystem.cs +++ /dev/null @@ -1,120 +0,0 @@ -// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt -using Content.Shared.Mind; -using Content.Shared.Mind.Components; -using Content.Shared.Mobs; -using Content.Shared.Mobs.Systems; -using Content.Shared.SS220.CultYogg.MiGo; -using Content.Server.SS220.GameTicking.Rules; -using Robust.Shared.Player; -using Robust.Shared.Timing; - -namespace Content.Server.SS220.CultYogg.MiGo; - -public sealed partial class MiGoReplacementSystem : SharedMiGoSystem -{ - [Dependency] private readonly MobStateSystem _mobState = default!; - [Dependency] private readonly SharedMindSystem _mind = default!; - [Dependency] private readonly IGameTiming _timing = default!; - - public override void Initialize() //ToDo check for stupidity - { - SubscribeLocalEvent(OnMobState); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); - } - private void OnPlayerAttached(Entity ent, ref PlayerAttachedEvent args) - { - CheckTimerConditions(ent, ent.Comp); - } - private void OnPlayerDetached(Entity ent, ref PlayerDetachedEvent args) - { - CheckTimerConditions(ent, ent.Comp); - } - - /// - /// On death removes active comps and gives genetic damage to prevent cloning, reduce this to allow cloning. - /// - private void OnMobState(Entity ent, ref MobStateChangedEvent args) - { - CheckTimerConditions(ent, ent.Comp); - } - - public override void Update(float frameTime) - { - base.Update(frameTime); - - var query = EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out var migoComp)) - { - //if timer is on then count it - if (!migoComp.ShouldBeCounted) - continue; - - if (migoComp.ReplacementEventTime == null) - continue; - - if (_timing.CurTime < migoComp.ReplacementEventTime) - continue; - - var meta = MetaData(uid); - - var ev = new CultYoggAnouncementEvent(uid, Loc.GetString("cult-yogg-migo-can-replace", ("name", meta.EntityName))); - RaiseLocalEvent(uid, ref ev, true); - migoComp.ShouldBeCounted = false; - } - } - - //Timer tweaking - private void StartTimer(MiGoComponent comp) - { - if (comp.ReplacementEventTime != null) - return; - - comp.ReplacementEventTime = _timing.CurTime + comp.BeforeReplacementCooldown; - comp.ShouldBeCounted = true; - } - - //Delete replacement marker from a MiGo - private void RemoveReplacement(EntityUid uid, MiGoComponent сomp) - { - сomp.ReplacementEventTime = null; - - var meta = MetaData(uid); - - var ev = new CultYoggAnouncementEvent(uid, Loc.GetString("cult-yogg-migo-cancel-replace", ("name", meta.EntityName))); - RaiseLocalEvent(uid, ref ev, true); - } - - private void CheckTimerConditions(EntityUid uid, MiGoComponent comp) - { - if (_mobState.IsDead(uid)) //if you are dead = timer - { - StartTimer(comp); - return; - } - /* - if (!TryComp(uid, out var mindComp) || mindComp == null) - return; - - if (mindComp.Mind == null) // if you ghosted = timer - { - StartTimer(comp); - return; - } - */ - - if (!_mind.TryGetMind(uid, out var mind, out var userMidComp) || (userMidComp == null)) - { - StartTimer(comp); - return; - } - - if (userMidComp.Session == null) // if you left = timer - { - StartTimer(comp); - return; - } - - RemoveReplacement(uid, comp); - } -} diff --git a/Content.Server/SS220/CultYogg/Sacraficials/SacraficialReplacementEvent.cs b/Content.Server/SS220/CultYogg/Sacraficials/SacraficialReplacementEvent.cs index 3cb0b1576a96a5..069dd1b4442c14 100644 --- a/Content.Server/SS220/CultYogg/Sacraficials/SacraficialReplacementEvent.cs +++ b/Content.Server/SS220/CultYogg/Sacraficials/SacraficialReplacementEvent.cs @@ -7,11 +7,9 @@ namespace Content.Server.SS220.CultYogg.Sacraficials; public sealed class SacraficialReplacementEvent : EntityEventArgs { public readonly EntityUid Entity; - public readonly NetUserId Player; - public SacraficialReplacementEvent(EntityUid entity, NetUserId player) + public SacraficialReplacementEvent(EntityUid entity) { Entity = entity; - Player = player; } } diff --git a/Content.Server/SS220/CultYogg/Sacraficials/SacraficialReplacementSystem.cs b/Content.Server/SS220/CultYogg/Sacraficials/SacraficialReplacementSystem.cs index ccb967302187b3..0b5935e2f434da 100644 --- a/Content.Server/SS220/CultYogg/Sacraficials/SacraficialReplacementSystem.cs +++ b/Content.Server/SS220/CultYogg/Sacraficials/SacraficialReplacementSystem.cs @@ -6,6 +6,7 @@ using Robust.Shared.Network; using Robust.Shared.Player; using Robust.Shared.Timing; +using Content.Server.SS220.Bed.Cryostorage; namespace Content.Server.SS220.CultYogg.Sacraficials; @@ -13,9 +14,10 @@ public sealed partial class SacraficialReplacementSystem : EntitySystem { [Dependency] private readonly IGameTiming _timing = default!; + //dictionary of sacraficials uids and time when they left body by gibbing/ghosting/leaving anything - private Dictionary<(EntityUid, NetUserId), TimeSpan> _replaceSacrSchedule = new(); - private Dictionary<(EntityUid, NetUserId), TimeSpan> _announceSchedule = new(); + private Dictionary _replaceSacrSchedule = []; + private Dictionary _announceSchedule = []; //Count down the moment when sacraficial will be raplaced private TimeSpan _beforeReplacementCooldown = TimeSpan.FromSeconds(900); @@ -31,6 +33,7 @@ public override void Initialize() SubscribeLocalEvent(OnRemove); SubscribeLocalEvent(OnPlayerAttached); SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnCryoDeleted); } private void OnInit(Entity ent, ref ComponentInit args) { @@ -40,6 +43,9 @@ private void OnInit(Entity ent, ref ComponentInit { RaiseLocalEvent(uid, ref ev); } + + var ev2 = new CultYoggAnouncementEvent(ent, Loc.GetString("cult-yogg-sacraficial-was-picked", ("name", MetaData(ent).EntityName))); + RaiseLocalEvent(ent, ref ev, true); } private void OnRemove(Entity ent, ref ComponentRemove args) { @@ -52,19 +58,28 @@ private void OnRemove(Entity ent, ref ComponentRem } private void OnPlayerAttached(Entity ent, ref PlayerAttachedEvent args) { - _replaceSacrSchedule.Remove((ent, args.Player.UserId)); - _announceSchedule.Remove((ent, args.Player.UserId)); + _replaceSacrSchedule.Remove(ent); - var meta = MetaData(ent); + if(_announceSchedule.ContainsKey(ent))//if the announcement was not sent + { + _announceSchedule.Remove(ent); + return; + } - var ev = new CultYoggAnouncementEvent(ent, Loc.GetString("cult-yogg-sacraficial-cant-be-replaced", ("name", meta.EntityName))); + var ev = new CultYoggAnouncementEvent(ent, Loc.GetString("cult-yogg-sacraficial-cant-be-replaced", ("name", MetaData(ent).EntityName))); RaiseLocalEvent(ent, ref ev, true); } private void OnPlayerDetached(Entity ent, ref PlayerDetachedEvent args) { - _replaceSacrSchedule.Add((ent, args.Player.UserId), _timing.CurTime); - _announceSchedule.Add((ent, args.Player.UserId), _timing.CurTime); + _replaceSacrSchedule.Add(ent, _timing.CurTime + ent.Comp.ReplacementCooldown); + _announceSchedule.Add(ent, _timing.CurTime + ent.Comp.AnnounceReplacementCooldown); + } + + private void OnCryoDeleted(Entity ent, ref BeingCryoDeletedEvent args) + { + var ev = new SacraficialReplacementEvent(ent); + RaiseLocalEvent(ent, ref ev, true); } private void ReplacamantStatusAnnounce(EntityUid uid) @@ -72,9 +87,8 @@ private void ReplacamantStatusAnnounce(EntityUid uid) if (!TryComp(uid, out var comp)) return; - var meta = MetaData(uid); - - var ev = new CultYoggAnouncementEvent(uid, Loc.GetString("cult-yogg-sacraficial-may-be-replaced", ("name", meta.EntityName))); + var time = (comp.ReplacementCooldown.TotalSeconds - comp.AnnounceReplacementCooldown.TotalSeconds).ToString(); + var ev = new CultYoggAnouncementEvent(uid, Loc.GetString("cult-yogg-sacraficial-will-be-replaced", ("name", MetaData(uid).EntityName), ("time", time))); RaiseLocalEvent(uid, ref ev, true); } @@ -83,21 +97,21 @@ public override void Update(float frameTime) base.Update(frameTime); foreach (var pair in _replaceSacrSchedule) { - if (_timing.CurTime < pair.Value + _beforeReplacementCooldown) + if (_timing.CurTime < pair.Value) continue; - var ev = new SacraficialReplacementEvent(pair.Key.Item1, pair.Key.Item2); - RaiseLocalEvent(pair.Key.Item1, ref ev, true); + var ev = new SacraficialReplacementEvent(pair.Key); + RaiseLocalEvent(pair.Key, ref ev, true); _replaceSacrSchedule.Remove(pair.Key); } foreach (var pair in _announceSchedule)//it is stupid, but idk how to make it 1 time event without second System :( { - if (_timing.CurTime < pair.Value + _announceReplacementCooldown) + if (_timing.CurTime < pair.Value) continue; - ReplacamantStatusAnnounce(pair.Key.Item1); + ReplacamantStatusAnnounce(pair.Key); _announceSchedule.Remove(pair.Key); } diff --git a/Content.Server/SS220/GameTicking/Rules/Components/CultYoggRuleComponent.cs b/Content.Server/SS220/GameTicking/Rules/Components/CultYoggRuleComponent.cs index f5747b00b50b90..7860abcc239956 100644 --- a/Content.Server/SS220/GameTicking/Rules/Components/CultYoggRuleComponent.cs +++ b/Content.Server/SS220/GameTicking/Rules/Components/CultYoggRuleComponent.cs @@ -41,8 +41,6 @@ public sealed partial class CultYoggRuleComponent : Component /// /// Storage for a sacraficials /// - public readonly List SacraficialsList = []; - public readonly int[] TierOfSacraficials = [1, 2, 3];//trying to save tier in target, so they might be replaced with the same lvl target /// diff --git a/Content.Server/SS220/GameTicking/Rules/CultYoggRuleSystem.cs b/Content.Server/SS220/GameTicking/Rules/CultYoggRuleSystem.cs index 2d2975af411b2b..986ba4cb9b237d 100644 --- a/Content.Server/SS220/GameTicking/Rules/CultYoggRuleSystem.cs +++ b/Content.Server/SS220/GameTicking/Rules/CultYoggRuleSystem.cs @@ -193,9 +193,6 @@ private void SetSacraficials(CultYoggRuleComponent component) if (!_job.MindTryGetJob(mind, out var prototype)) continue; - if (HasComp(mind))//shouldn't be already a target - continue; - if (_sacraficialTiers[tier].Contains(prototype.ID)) allSuitable.Add(mind); } @@ -223,17 +220,11 @@ private void SetSacraficeTarget(CultYoggRuleComponent component, EntityUid? uid, if (mind.Session.AttachedEntity is null) return; - var meta = MetaData(uid.Value); - //_adminLogger.Add(LogType.EventRan, LogImpact.High, $"CultYogg person {meta.EntityName} where picked for a tier: {tier}"); - EnsureComp(uid.Value); //ToDo figure out do i need this? - var sacrComp = EnsureComp(mind.Session.AttachedEntity.Value); sacrComp.Tier = tier; - - component.SacraficialsList.Add(uid.Value); } private List GetAliveNoneCultHumans()//maybe add here sacraficials and cultists filter @@ -252,6 +243,9 @@ private List GetAliveNoneCultHumans()//maybe add here sacraficials an if (HasComp(uid)) continue; + if (HasComp(uid)) + continue; + // the player has to be alive if (_mobState.IsAlive(uid, mobState)) allHumans.Add(mc.Mind.Value); @@ -299,19 +293,8 @@ private void SacraficialReplacement(ref SacraficialReplacementEvent args) RemComp(args.Entity); - if (!_mind.TryGetMind(args.Player, out var mindUid, out var mind)) - return; - - if (mindUid == null) - return; - - var meta = MetaData(args.Entity); - var ev = new CultYoggAnouncementEvent(args.Entity, Loc.GetString("cult-yogg-migo-can-replace", ("name", meta.EntityName))); + var ev = new CultYoggAnouncementEvent(args.Entity, Loc.GetString("cult-yogg-sacraficial-was-replaced", ("name", MetaData(args.Entity).EntityName))); RaiseLocalEvent(args.Entity, ref ev, true); - - cultRuleComp.SacraficialsList.Remove(mindUid.Value); - - RemComp(mindUid.Value); } private void SetNewSacraficial(CultYoggRuleComponent comp, int tier) { @@ -442,15 +425,14 @@ public void DeMakeCultist(EntityUid uid, CultYoggRuleComponent component) private void SendCultAnounce(ref CultYoggAnouncementEvent args) { //ToDo refactor without spam - /* - GetCultGameRule(out var comp); - if (comp == null) + var ruleComp = GetCultGameRule(); + + if (ruleComp == null) return; - var ev = new TelepathyAnnouncementSendEvent(args.Message, comp.TelepathyChannel); - RaiseLocalEvent(ref ev); - */ + var ev = new TelepathyAnnouncementSendEvent(args.Message, ruleComp.TelepathyChannel); + RaiseLocalEvent(args.Entity, ev, true); } #endregion diff --git a/Content.Server/SS220/Objectives/Systems/CultYoggSummonConditionSystem.cs b/Content.Server/SS220/Objectives/Systems/CultYoggSummonConditionSystem.cs index ee77864cb3fcc0..d6bf76316d4e0b 100644 --- a/Content.Server/SS220/Objectives/Systems/CultYoggSummonConditionSystem.cs +++ b/Content.Server/SS220/Objectives/Systems/CultYoggSummonConditionSystem.cs @@ -19,6 +19,7 @@ public sealed class CultYoggSummonConditionSystem : EntitySystem [Dependency] private readonly CultYoggRuleSystem _cultRule = default!; [Dependency] private readonly MetaDataSystem _metaData = default!; [Dependency] private readonly SharedJobSystem _job = default!; + [Dependency] private readonly SharedMindSystem _minds = default!; public override void Initialize() { @@ -74,18 +75,20 @@ private void SacraficialsUpdate(Entity ent) var title = new StringBuilder(); title.AppendLine(Loc.GetString("objective-cult-yogg-sacrafice-start")); - var query = EntityQueryEnumerator(); + var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var _)) { var targetName = "Unknown"; - if (TryComp(uid, out var mind) && mind.CharacterName != null) + var jobTitle = "Unknown"; + if (_minds.TryGetMind(uid, out var mindId, out var mind) && mind.CharacterName != null) { targetName = mind.CharacterName; - } - var jobName = _job.MindTryGetJobName(uid); + if (_job.MindTryGetJobName(mindId, out var jobName)) + jobTitle = jobName; + } - title.AppendLine(Loc.GetString("objective-condition-cult-yogg-sacrafice-person", ("targetName", targetName), ("job", jobName))); + title.AppendLine(Loc.GetString("objective-condition-cult-yogg-sacrafice-person", ("targetName", targetName), ("job", jobTitle))); } _metaData.SetEntityName(ent, title.ToString()); diff --git a/Content.Server/SS220/Telepathy/TelepathySystem.cs b/Content.Server/SS220/Telepathy/TelepathySystem.cs index 7c29a49978a50a..8d03334d562428 100644 --- a/Content.Server/SS220/Telepathy/TelepathySystem.cs +++ b/Content.Server/SS220/Telepathy/TelepathySystem.cs @@ -32,7 +32,7 @@ public override void Initialize() SubscribeLocalEvent(OnRoundStart); SubscribeLocalEvent(OnTelepathySend); - SubscribeLocalEvent(OnTelepathyAnnouncementSend); + SubscribeLocalEvent(OnTelepathyAnnouncementSend); } private void OnRoundStart(RoundStartedEvent args) @@ -43,7 +43,7 @@ private void OnRoundStart(RoundStartedEvent args) } } - private void OnTelepathyAnnouncementSend(Entity ent, ref TelepathyAnnouncementSendEvent args) + private void OnTelepathyAnnouncementSend(TelepathyAnnouncementSendEvent args) { SendMessageToEveryoneWithRightChannel(args.TelepathyChannel, args.Message, null); } @@ -151,7 +151,9 @@ private string GetWrappedTelepathyMessage(string messageString, EntityUid? sende { return Loc.GetString( "chat-manager-send-telepathy-announce", - ("announce", FormattedMessage.EscapeText(messageString)) + ("announce", FormattedMessage.EscapeText(messageString)), + ("channel", $"\\[{Loc.GetString(telepathyChannelParameters.Name)}\\]"), + ("color", telepathyChannelParameters.Color) ); } diff --git a/Content.Server/Telephone/TelephoneSystem.cs b/Content.Server/Telephone/TelephoneSystem.cs index b4874191074c89..c1d51f413d78d6 100644 --- a/Content.Server/Telephone/TelephoneSystem.cs +++ b/Content.Server/Telephone/TelephoneSystem.cs @@ -22,6 +22,8 @@ using Content.Shared.Silicons.StationAi; using Content.Shared.Silicons.Borgs.Components; using Content.Shared.SS220.TTS; +using Content.Shared.SS220.CCVars; +using Robust.Shared.Configuration; namespace Content.Server.Telephone; @@ -38,6 +40,11 @@ public sealed class TelephoneSystem : SharedTelephoneSystem [Dependency] private readonly IAdminLogManager _adminLogger = default!; [Dependency] private readonly IReplayRecordingManager _replay = default!; + // SS220 performance-test-begin + [Dependency] private readonly IConfigurationManager _configManager = default!; + private bool _lessSound; + // SS220 performance-test-end + // Has set used to prevent telephone feedback loops private HashSet<(EntityUid, string, Entity)> _recentChatMessages = new(); @@ -50,6 +57,8 @@ public override void Initialize() SubscribeLocalEvent(OnAttemptListen); SubscribeLocalEvent(OnListen); SubscribeLocalEvent(OnTelephoneMessageReceived); + + Subs.CVar(_configManager, CCVars220.LessSoundSources, value => _lessSound = value, true); // SS220 performance-test } #region: Events @@ -151,6 +160,11 @@ public override void Update(float frameTime) if (_timing.CurTime > telephone.StateStartTime + TimeSpan.FromSeconds(telephone.RingingTimeout)) EndTelephoneCalls(entity); + // SS220 performance-test + if (_lessSound) + break; + // SS220 performace-test + else if (telephone.RingTone != null && _timing.CurTime > telephone.NextRingToneTime) { @@ -160,7 +174,7 @@ public override void Update(float frameTime) break; - // Try to hang up if their has been no recent in-call activity + // Try to hang up if their has been no recent in-call activity case TelephoneState.InCall: if (_timing.CurTime > telephone.StateStartTime + TimeSpan.FromSeconds(telephone.IdlingTimeout)) EndTelephoneCalls(entity); diff --git a/Content.Shared/Humanoid/Markings/MarkingManager.cs b/Content.Shared/Humanoid/Markings/MarkingManager.cs index 7bf0be998b6968..ac035de2e72ae1 100644 --- a/Content.Shared/Humanoid/Markings/MarkingManager.cs +++ b/Content.Shared/Humanoid/Markings/MarkingManager.cs @@ -59,7 +59,8 @@ public FrozenDictionary MarkingsByCategory(MarkingCate /// /// public IReadOnlyDictionary MarkingsByCategoryAndSpecies(MarkingCategories category, - string species) + string species, + bool showHidden = false) // SS220 cult markings fix { var speciesProto = _prototypeManager.Index(species); var onlyWhitelisted = _prototypeManager.Index(speciesProto.MarkingPoints).OnlyWhitelisted; @@ -67,6 +68,11 @@ public IReadOnlyDictionary MarkingsByCategoryAndSpecie foreach (var (key, marking) in MarkingsByCategory(category)) { + // SS220 cult markings fix begin + if (!showHidden && marking.Hidden) + continue; + // SS220 cult markings fix end + if (onlyWhitelisted && marking.SpeciesRestrictions == null) { continue; @@ -93,12 +99,18 @@ public IReadOnlyDictionary MarkingsByCategoryAndSpecie /// /// public IReadOnlyDictionary MarkingsByCategoryAndSex(MarkingCategories category, - Sex sex) + Sex sex, + bool showHidden = false) // SS220 cult markings fix { var res = new Dictionary(); foreach (var (key, marking) in MarkingsByCategory(category)) { + // SS220 cult markings fix begin + if (!showHidden && marking.Hidden) + continue; + // SS220 cult markings fix end + if (marking.SexRestriction != null && marking.SexRestriction != sex) { continue; @@ -122,7 +134,8 @@ public IReadOnlyDictionary MarkingsByCategoryAndSex(Ma /// /// public IReadOnlyDictionary MarkingsByCategoryAndSpeciesAndSex(MarkingCategories category, - string species, Sex sex) + string species, Sex sex, + bool showHidden = false) // SS220 cult markings fix { var speciesProto = _prototypeManager.Index(species); var onlyWhitelisted = _prototypeManager.Index(speciesProto.MarkingPoints).OnlyWhitelisted; @@ -130,6 +143,11 @@ public IReadOnlyDictionary MarkingsByCategoryAndSpecie foreach (var (key, marking) in MarkingsByCategory(category)) { + // SS220 cult markings fix begin + if (!showHidden && marking.Hidden) + continue; + // SS220 cult markings fix end + if (onlyWhitelisted && marking.SpeciesRestrictions == null) { continue; diff --git a/Content.Shared/Humanoid/Markings/MarkingPrototype.cs b/Content.Shared/Humanoid/Markings/MarkingPrototype.cs index 28bfd71c0da49d..35ac859b88afb4 100644 --- a/Content.Shared/Humanoid/Markings/MarkingPrototype.cs +++ b/Content.Shared/Humanoid/Markings/MarkingPrototype.cs @@ -34,6 +34,14 @@ public sealed partial class MarkingPrototype : IPrototype [DataField("forcedColoring")] public bool ForcedColoring { get; private set; } = false; + // SS220 cult markings fix begin + /// + /// Is the marking hidden from the marking picker + /// + [DataField] + public bool Hidden = false; + // SS220 cult markings fix end + [DataField("coloring")] public MarkingColors Coloring { get; private set; } = new(); diff --git a/Content.Shared/Movement/Systems/MovementSoundSystem.cs b/Content.Shared/Movement/Systems/MovementSoundSystem.cs index 9a1146779fac27..a37b37f3cf3570 100644 --- a/Content.Shared/Movement/Systems/MovementSoundSystem.cs +++ b/Content.Shared/Movement/Systems/MovementSoundSystem.cs @@ -1,6 +1,8 @@ using Content.Shared.Movement.Components; using Content.Shared.Movement.Events; +using Content.Shared.SS220.CCVars; using Robust.Shared.Audio.Systems; +using Robust.Shared.Configuration; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -14,10 +16,17 @@ public sealed class MovementSoundSystem : EntitySystem [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; + // SS220 performance-test-begin + [Dependency] private readonly IConfigurationManager _configManager = default!; + private bool _lessSound; + // SS220 performance-test-end + public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnMoveInput); + + Subs.CVar(_configManager, CCVars220.LessSoundSources, value => _lessSound = value, true); // SS220 performance-test } private void OnMoveInput(Entity ent, ref MoveInputEvent args) @@ -31,6 +40,11 @@ private void OnMoveInput(Entity ent, ref MoveInputEvent if (oldMoving == moving) return; + // SS220 performance-test + if (_lessSound) + return; + // SS220 performace-test + if (moving) { DebugTools.Assert(ent.Comp.SoundEntity == null); diff --git a/Content.Shared/Movement/Systems/SharedMoverController.cs b/Content.Shared/Movement/Systems/SharedMoverController.cs index 472d56b1d692d7..ca8c4cd47d3e6a 100644 --- a/Content.Shared/Movement/Systems/SharedMoverController.cs +++ b/Content.Shared/Movement/Systems/SharedMoverController.cs @@ -9,6 +9,7 @@ using Content.Shared.Mobs.Systems; using Content.Shared.Movement.Components; using Content.Shared.Movement.Events; +using Content.Shared.SS220.CCVars; using Content.Shared.Tag; using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; @@ -66,6 +67,7 @@ public abstract partial class SharedMoverController : VirtualController private float _stopSpeed; private bool _relativeMovement; + private bool _lessSound; // SS220 Performance-test /// /// Cache the mob movement calculation to re-use elsewhere. @@ -93,6 +95,7 @@ public override void Initialize() InitializeRelay(); Subs.CVar(_configManager, CCVars.RelativeMovement, value => _relativeMovement = value, true); Subs.CVar(_configManager, CCVars.StopSpeed, value => _stopSpeed = value, true); + Subs.CVar(_configManager, CCVars220.LessSoundSources, value => _lessSound = value, true); // SS220 performance-test UpdatesBefore.Add(typeof(TileFrictionController)); } @@ -401,7 +404,8 @@ private bool TryGetSound( { sound = null; - if (!CanSound() || !_tags.HasTag(uid, "FootstepSound")) + // if (!CanSound() || !_tags.HasTag(uid, "FootstepSound") // SS220 performance test + if (!CanSound() || !_tags.HasTag(uid, "FootstepSound") || _lessSound) // SS220 performance test return false; var coordinates = xform.Coordinates; diff --git a/Content.Shared/SS220/CCVars/CCVars220.Performance.cs b/Content.Shared/SS220/CCVars/CCVars220.Performance.cs new file mode 100644 index 00000000000000..402dd88df16cc0 --- /dev/null +++ b/Content.Shared/SS220/CCVars/CCVars220.Performance.cs @@ -0,0 +1,12 @@ +using Robust.Shared.Configuration; + +namespace Content.Shared.SS220.CCVars; + +public sealed partial class CCVars220 +{ + /// + /// Cvar which turns off most of player generatish sounds like steps, telephones and etc. Do not affect TTS. + /// + public static readonly CVarDef LessSoundSources = + CVarDef.Create("audio.less_sound_sources", false, CVar.SERVER | CVar.REPLICATED, "serve to turn off most of player generatish sounds like steps, telephones and etc. Do not affect TTS."); +} diff --git a/Content.Shared/SS220/CCVars/CCVars220.cs b/Content.Shared/SS220/CCVars/CCVars220.cs index c03fed7258523c..a1b14a1101610c 100644 --- a/Content.Shared/SS220/CCVars/CCVars220.cs +++ b/Content.Shared/SS220/CCVars/CCVars220.cs @@ -3,7 +3,7 @@ namespace Content.Shared.SS220.CCVars; [CVarDefs] -public sealed class CCVars220 +public sealed partial class CCVars220 { /// /// Whether is bloom lighting eanbled or not diff --git a/Content.Shared/SS220/CultYogg/Corruption/CultYoggCorruptedPrototype.cs b/Content.Shared/SS220/CultYogg/Corruption/CultYoggCorruptedPrototype.cs index 04c00858676d5c..44626052f7765d 100644 --- a/Content.Shared/SS220/CultYogg/Corruption/CultYoggCorruptedPrototype.cs +++ b/Content.Shared/SS220/CultYogg/Corruption/CultYoggCorruptedPrototype.cs @@ -43,6 +43,12 @@ public sealed partial class CultYoggCorruptedPrototype : IPrototype [DataField("emptyStorage", required: false)] public bool EmptyStorage { get; private set; } + /// + /// At what stage is this corruption result available + /// + [DataField("avaliableOnStage", required: false)] + public int AvaliableOnStage = 0; + } [DataDefinition] diff --git a/Content.Shared/SS220/CultYogg/Corruption/SharedCultYoggCorruptedSystem.cs b/Content.Shared/SS220/CultYogg/Corruption/SharedCultYoggCorruptedSystem.cs index 78ded45a18c31e..692aa1e894bcf0 100644 --- a/Content.Shared/SS220/CultYogg/Corruption/SharedCultYoggCorruptedSystem.cs +++ b/Content.Shared/SS220/CultYogg/Corruption/SharedCultYoggCorruptedSystem.cs @@ -14,6 +14,8 @@ using Robust.Shared.Random; using Robust.Shared.Serialization; using System.Diagnostics.CodeAnalysis; +using Robust.Shared.GameObjects; +using Content.Shared.Popups; namespace Content.Shared.SS220.CultYogg.Corruption; @@ -33,6 +35,7 @@ public sealed class SharedCultYoggCorruptedSystem : EntitySystem [Dependency] private readonly SharedTransformSystem _transformSystem = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly SharedSoftDeleteSystem _softDeleteSystem = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; private readonly TimeSpan _corruptionDuration = TimeSpan.FromSeconds(1.8); private readonly Dictionary, CultYoggCorruptedPrototype> _recipesBySourcePrototypeId = []; @@ -138,10 +141,16 @@ public bool IsCorrupted(EntityUid entity) /// Flag indicating that the target entity is in hand /// Optional callback to fire when finished /// if corruption process has been started, otherwise - public bool TryCorruptContinuously(EntityUid user, EntityUid entity, bool isInHand, Action? callback = null) + public bool TryCorruptContinuously(EntityUid user, CultYoggComponent comp, EntityUid entity, bool isInHand, Action? callback = null) { if (!TryGetCorruptionRecipe(entity, out var recipe)) { + _popup.PopupClient(Loc.GetString("cult-yogg-corrupt-no-proto"), entity, user); + return false; + } + if (comp.CurrentStage < recipe.AvaliableOnStage) + { + _popup.PopupClient(Loc.GetString("cult-yogg-corrupt-too-low-tier"), entity, user); return false; } var e = new CultYoggCorruptDoAfterEvent(recipe, isInHand, callback); diff --git a/Content.Shared/SS220/CultYogg/Cultists/SharedCultYoggSystem.cs b/Content.Shared/SS220/CultYogg/Cultists/SharedCultYoggSystem.cs index 2f3ebbf1fdbd71..97b706f429730b 100644 --- a/Content.Shared/SS220/CultYogg/Cultists/SharedCultYoggSystem.cs +++ b/Content.Shared/SS220/CultYogg/Cultists/SharedCultYoggSystem.cs @@ -89,9 +89,8 @@ private void CorruptItemAction(Entity uid, ref CultYoggCorrup return; } - if (!_cultYoggCorruptedSystem.TryCorruptContinuously(uid, args.Target, false)) + if (!_cultYoggCorruptedSystem.TryCorruptContinuously(uid, uid.Comp, args.Target, false)) { - _popup.PopupClient(Loc.GetString("cult-yogg-corrupt-no-proto"), args.Target, uid); return; } args.Handled = true; @@ -120,9 +119,8 @@ private void CorruptItemInHandAction(Entity uid, ref CultYogg return; } - if (!_cultYoggCorruptedSystem.TryCorruptContinuously(uid, handItem.Value, true)) + if (!_cultYoggCorruptedSystem.TryCorruptContinuously(uid, uid.Comp, handItem.Value, true)) { - _popup.PopupClient(Loc.GetString("cult-yogg-corrupt-no-proto"), handItem.Value, uid); return; } args.Handled = true; diff --git a/Content.Shared/SS220/CultYogg/Pod/CultYoggPodComponent.cs b/Content.Shared/SS220/CultYogg/Pod/CultYoggPodComponent.cs index fb9eb6dfa2b15e..3acdee32208c1c 100644 --- a/Content.Shared/SS220/CultYogg/Pod/CultYoggPodComponent.cs +++ b/Content.Shared/SS220/CultYogg/Pod/CultYoggPodComponent.cs @@ -3,6 +3,7 @@ using Robust.Shared.Containers; using Robust.Shared.Serialization; using Content.Shared.Damage; +using Content.Shared.DoAfter; using Content.Shared.Whitelist; using Robust.Shared.GameStates; using Content.Shared.SS220.CultYogg.MiGo; @@ -18,6 +19,9 @@ public sealed partial class CultYoggPodComponent : Component [DataField] public TimeSpan HealingFreq = TimeSpan.FromSeconds(1); + [DataField] + public TimeSpan InsertDelay = TimeSpan.FromSeconds(6); + /// /// Whitelist of entities that are cultists /// diff --git a/Content.Shared/SS220/CultYogg/Pod/SharedCultYoggPodSystem.cs b/Content.Shared/SS220/CultYogg/Pod/SharedCultYoggPodSystem.cs index eebabe52e3e605..2bf5b7e7fbb05e 100644 --- a/Content.Shared/SS220/CultYogg/Pod/SharedCultYoggPodSystem.cs +++ b/Content.Shared/SS220/CultYogg/Pod/SharedCultYoggPodSystem.cs @@ -1,12 +1,14 @@ // © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt using Content.Shared.Damage; +using Content.Shared.DoAfter; using Content.Shared.DragDrop; using Content.Shared.Mobs.Components; using Content.Shared.Popups; using Content.Shared.Verbs; using Content.Shared.Whitelist; using Robust.Shared.Containers; +using Robust.Shared.Serialization; namespace Content.Shared.SS220.CultYogg.Pod; @@ -15,6 +17,7 @@ public abstract class SharedCultYoggPodSystem : EntitySystem [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly SharedContainerSystem _container = default!; [Dependency] private readonly EntityWhitelistSystem _entityWhitelist = default!; + [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; public override void Initialize() { @@ -23,6 +26,13 @@ public override void Initialize() SubscribeLocalEvent(OnCompInit); SubscribeLocalEvent(OnPodCanDrop); SubscribeLocalEvent>(AddInsertVerb); + SubscribeLocalEvent(OnPodInsert); + } + + private void OnPodInsert(Entity ent, ref AfterPodInserted args) + { + var xform = Transform(args.User); + _container.Insert((args.User, xform), ent.Comp.MobContainer); } private void OnPodCanDrop(Entity ent, ref CanDropTargetEvent args) @@ -86,11 +96,24 @@ public bool TryInsert(EntityUid entToEnsert, Entity podEnt return false; } - var xform = Transform(entToEnsert); + var insertDoAfter = new DoAfterArgs( + EntityManager, + entToEnsert, + podEnt.Comp.InsertDelay, + new AfterPodInserted(), + podEnt) + { + Broadcast = false, + BreakOnDamage = true, + BreakOnMove = true, + NeedHand = false, - _container.Insert((entToEnsert, xform), podEnt.Comp.MobContainer); + BlockDuplicate = true, + CancelDuplicate = true, + DuplicateCondition = DuplicateConditions.SameEvent + }; - return true; + return _doAfter.TryStartDoAfter(insertDoAfter); } public bool TryEject(EntityUid entToEject, Entity podEnt) @@ -103,3 +126,9 @@ public bool TryEject(EntityUid entToEject, Entity podEnt) return true; } } + +[Serializable, NetSerializable] +public sealed partial class AfterPodInserted : DoAfterEvent +{ + public override DoAfterEvent Clone() => this; +} diff --git a/Content.Shared/SS220/CultYogg/Sacraficials/CultYoggSacrificialComponent.cs b/Content.Shared/SS220/CultYogg/Sacraficials/CultYoggSacrificialComponent.cs index 7c668fe7218269..defd53f59ea257 100644 --- a/Content.Shared/SS220/CultYogg/Sacraficials/CultYoggSacrificialComponent.cs +++ b/Content.Shared/SS220/CultYogg/Sacraficials/CultYoggSacrificialComponent.cs @@ -21,6 +21,23 @@ public sealed partial class CultYoggSacrificialComponent : Component [DataField] public ProtoId StatusIcon { get; set; } = "CultYoggSacraficialTargetIcon"; + /// + /// Tier number required for replacement if it needed + /// + [DataField] public int Tier = 0;//initilize as max possible tier + + /// + /// Time required for announcement + /// + [DataField] + public TimeSpan AnnounceReplacementCooldown = TimeSpan.FromSeconds(60); + /// + /// Time required for replacement + /// + [DataField] + public TimeSpan ReplacementCooldown = TimeSpan.FromSeconds(300); + + public bool WasSacraficed = false; } diff --git a/Content.Shared/SS220/CultYogg/Sacraficials/CultYoggSacrificialMindComponent.cs b/Content.Shared/SS220/CultYogg/Sacraficials/CultYoggSacrificialMindComponent.cs deleted file mode 100644 index 18988d6ae61a61..00000000000000 --- a/Content.Shared/SS220/CultYogg/Sacraficials/CultYoggSacrificialMindComponent.cs +++ /dev/null @@ -1,15 +0,0 @@ -// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt - -using Content.Shared.StatusIcon; -using Robust.Shared.GameStates; -using Robust.Shared.Prototypes; - -namespace Content.Shared.SS220.CultYogg.Sacraficials; - -/// -/// Used to markup cult's sacrificials minds -/// -[RegisterComponent, NetworkedComponent] -public sealed partial class CultYoggSacrificialMindComponent : Component -{ -} diff --git a/Content.Shared/Sound/SharedEmitSoundSystem.cs b/Content.Shared/Sound/SharedEmitSoundSystem.cs index f92b30250e0806..940734e53503f0 100644 --- a/Content.Shared/Sound/SharedEmitSoundSystem.cs +++ b/Content.Shared/Sound/SharedEmitSoundSystem.cs @@ -7,12 +7,14 @@ using Content.Shared.Mobs; using Content.Shared.Popups; using Content.Shared.Sound.Components; +using Content.Shared.SS220.CCVars; using Content.Shared.Throwing; using Content.Shared.UserInterface; using Content.Shared.Whitelist; using JetBrains.Annotations; using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; +using Robust.Shared.Configuration; using Robust.Shared.Map; using Robust.Shared.Map.Components; using Robust.Shared.Network; @@ -39,6 +41,11 @@ public abstract class SharedEmitSoundSystem : EntitySystem [Dependency] private readonly SharedMapSystem _map = default!; [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; + // SS220 performance-test-begin + [Dependency] private readonly IConfigurationManager _configManager = default!; + private bool _lessSound; + // SS220 performance-test-end + public override void Initialize() { base.Initialize(); @@ -55,6 +62,8 @@ public override void Initialize() SubscribeLocalEvent(OnEmitSoundOnCollide); SubscribeLocalEvent(OnMobState); + + Subs.CVar(_configManager, CCVars220.LessSoundSources, value => _lessSound = value, true); // SS220 performance-test } private void HandleEmitSoundOnUIOpen(EntityUid uid, EmitSoundOnUIOpenComponent component, AfterActivatableUIOpenEvent args) @@ -143,7 +152,8 @@ private void OnEmitSoundOnInteractUsing(Entity