diff --git a/Content.Client/Popups/PopupSystem.cs b/Content.Client/Popups/PopupSystem.cs index 36d1087e29..b2fd764809 100644 --- a/Content.Client/Popups/PopupSystem.cs +++ b/Content.Client/Popups/PopupSystem.cs @@ -38,25 +38,25 @@ namespace Content.Client.Popups #region Actual Implementation - public void PopupCursor(string message) + public void PopupCursor(string message, PopupType type=PopupType.Small) { var label = new CursorPopupLabel(_inputManager.MouseScreenPosition) { Text = message, - StyleClasses = { StyleNano.StyleClassPopupMessage }, + StyleClasses = { GetStyleClass(type) }, }; _userInterfaceManager.PopupRoot.AddChild(label); _aliveCursorLabels.Add(label); } - public void PopupCoordinates(string message, EntityCoordinates coordinates) + public void PopupCoordinates(string message, EntityCoordinates coordinates, PopupType type=PopupType.Small) { if (_eyeManager.CurrentMap != Transform(coordinates.EntityId).MapID) return; - PopupMessage(message, coordinates, null); + PopupMessage(message, type, coordinates, null); } - public void PopupEntity(string message, EntityUid uid) + public void PopupEntity(string message, EntityUid uid, PopupType type=PopupType.Small) { if (!EntityManager.EntityExists(uid)) return; @@ -65,16 +65,16 @@ namespace Content.Client.Popups if (_eyeManager.CurrentMap != transform.MapID) return; // TODO: entity may be outside of PVS, but enter PVS at a later time. So the pop-up should still get tracked? - PopupMessage(message, transform.Coordinates, uid); + PopupMessage(message, type, transform.Coordinates, uid); } - private void PopupMessage(string message, EntityCoordinates coordinates, EntityUid? entity = null) + private void PopupMessage(string message, PopupType type, EntityCoordinates coordinates, EntityUid? entity = null) { var label = new WorldPopupLabel(_eyeManager, EntityManager) { Entity = entity, Text = message, - StyleClasses = { StyleNano.StyleClassPopupMessage }, + StyleClasses = { GetStyleClass(type) }, }; _userInterfaceManager.PopupRoot.AddChild(label); @@ -88,28 +88,28 @@ namespace Content.Client.Popups #region Abstract Method Implementations - public override void PopupCursor(string message, Filter filter) + public override void PopupCursor(string message, Filter filter, PopupType type=PopupType.Small) { if (!filter.CheckPrediction) return; - PopupCursor(message); + PopupCursor(message, type); } - public override void PopupCoordinates(string message, EntityCoordinates coordinates, Filter filter) + public override void PopupCoordinates(string message, EntityCoordinates coordinates, Filter filter, PopupType type=PopupType.Small) { if (!filter.CheckPrediction) return; - PopupCoordinates(message, coordinates); + PopupCoordinates(message, coordinates, type); } - public override void PopupEntity(string message, EntityUid uid, Filter filter) + public override void PopupEntity(string message, EntityUid uid, Filter filter, PopupType type=PopupType.Small) { if (!filter.CheckPrediction) return; - PopupEntity(message, uid); + PopupEntity(message, uid, type); } #endregion @@ -118,17 +118,17 @@ namespace Content.Client.Popups private void OnPopupCursorEvent(PopupCursorEvent ev) { - PopupCursor(ev.Message); + PopupCursor(ev.Message, ev.Type); } private void OnPopupCoordinatesEvent(PopupCoordinatesEvent ev) { - PopupCoordinates(ev.Message, ev.Coordinates); + PopupCoordinates(ev.Message, ev.Coordinates, ev.Type); } private void OnPopupEntityEvent(PopupEntityEvent ev) { - PopupEntity(ev.Message, ev.Uid); + PopupEntity(ev.Message, ev.Uid, ev.Type); } private void OnRoundRestart(RoundRestartCleanupEvent ev) @@ -143,6 +143,16 @@ namespace Content.Client.Popups #endregion + private static string GetStyleClass(PopupType type) => + type switch + { + PopupType.Small => StyleNano.StyleClassPopupMessageSmall, + PopupType.Medium => StyleNano.StyleClassPopupMessageMedium, + PopupType.Large => StyleNano.StyleClassPopupMessageLarge, + PopupType.Critical => StyleNano.StyleClassPopupMessageCritical, + _ => StyleNano.StyleClassPopupMessageSmall + }; + public override void FrameUpdate(float frameTime) { if (_aliveWorldLabels.Count == 0) return; diff --git a/Content.Client/Stylesheets/StyleNano.cs b/Content.Client/Stylesheets/StyleNano.cs index c2333d5171..53e973d255 100644 --- a/Content.Client/Stylesheets/StyleNano.cs +++ b/Content.Client/Stylesheets/StyleNano.cs @@ -74,7 +74,11 @@ namespace Content.Client.Stylesheets public const string StyleClassLabelSecondaryColor = "LabelSecondaryColor"; public const string StyleClassLabelBig = "LabelBig"; public const string StyleClassButtonBig = "ButtonBig"; - public const string StyleClassPopupMessage = "PopupMessage"; + + public const string StyleClassPopupMessageSmall = "PopupMessageSmall"; + public const string StyleClassPopupMessageMedium = "PopupMessageMedium"; + public const string StyleClassPopupMessageLarge = "PopupMessageLarge"; + public const string StyleClassPopupMessageCritical = "PopupMessageCritical"; public static readonly Color NanoGold = Color.FromHex("#A88B5E"); public static readonly Color GoodGreenFore = Color.FromHex("#31843E"); @@ -134,6 +138,8 @@ namespace Content.Client.Stylesheets var notoSansItalic12 = resCache.NotoStack(variation: "Italic", size: 12); var notoSansBold12 = resCache.NotoStack(variation: "Bold", size: 12); var notoSansBoldItalic12 = resCache.NotoStack(variation: "BoldItalic", size: 12); + var notoSansBoldItalic14 = resCache.NotoStack(variation: "BoldItalic", size: 14); + var notoSansBoldItalic16 = resCache.NotoStack(variation: "BoldItalic", size: 16); var notoSansDisplayBold14 = resCache.NotoStack(variation: "Bold", display: true, size: 14); var notoSansDisplayBold16 = resCache.NotoStack(variation: "Bold", display: true, size: 16); var notoSans15 = resCache.NotoStack(variation: "Regular", size: 15); @@ -1033,13 +1039,34 @@ namespace Content.Client.Stylesheets }), // Popup messages - new StyleRule(new SelectorElement(typeof(Label), new[] {StyleClassPopupMessage}, null, null), + new StyleRule(new SelectorElement(typeof(Label), new[] {StyleClassPopupMessageSmall}, null, null), new[] { new StyleProperty("font", notoSansItalic10), + new StyleProperty("font-color", Color.White), + }), + + new StyleRule(new SelectorElement(typeof(Label), new[] {StyleClassPopupMessageMedium}, null, null), + new[] + { + new StyleProperty("font", notoSansItalic12), new StyleProperty("font-color", Color.LightGray), }), + new StyleRule(new SelectorElement(typeof(Label), new[] {StyleClassPopupMessageLarge}, null, null), + new[] + { + new StyleProperty("font", notoSansBoldItalic14), + new StyleProperty("font-color", Color.LightGray), + }), + + new StyleRule(new SelectorElement(typeof(Label), new[] {StyleClassPopupMessageCritical}, null, null), + new[] + { + new StyleProperty("font", notoSansBoldItalic16), + new StyleProperty("font-color", Color.Red), + }), + //APC and SMES power state label colors new StyleRule(new SelectorElement(typeof(Label), new[] {StyleClassPowerStateNone}, null, null), new[] { diff --git a/Content.Server/AME/AntimatterEngineSystem.cs b/Content.Server/AME/AntimatterEngineSystem.cs index 29e1761987..1aa203aa76 100644 --- a/Content.Server/AME/AntimatterEngineSystem.cs +++ b/Content.Server/AME/AntimatterEngineSystem.cs @@ -5,6 +5,7 @@ using Content.Server.Hands.Components; using Content.Server.Popups; using Content.Server.Tools; using Content.Shared.Interaction; +using Content.Shared.Popups; using Robust.Shared.Map; using Robust.Shared.Player; using Robust.Shared.Audio; @@ -69,7 +70,8 @@ namespace Content.Server.AME else { component.JarSlot.Insert(args.Used); - _popupSystem.PopupEntity(Loc.GetString("ame-controller-component-interact-using-success"), uid, Filter.Entities(args.User)); + _popupSystem.PopupEntity(Loc.GetString("ame-controller-component-interact-using-success"), uid, + Filter.Entities(args.User), PopupType.Medium); component.UpdateUserInterface(); } } diff --git a/Content.Server/Access/Systems/IdCardSystem.cs b/Content.Server/Access/Systems/IdCardSystem.cs index 1889e2d1b0..de769790a8 100644 --- a/Content.Server/Access/Systems/IdCardSystem.cs +++ b/Content.Server/Access/Systems/IdCardSystem.cs @@ -8,6 +8,7 @@ using Content.Shared.Access; using Content.Shared.Access.Components; using Content.Shared.Access.Systems; using Content.Shared.PDA; +using Content.Shared.Popups; using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; @@ -46,7 +47,7 @@ namespace Content.Server.Access.Systems if (transformComponent != null) { _popupSystem.PopupCoordinates(Loc.GetString("id-card-component-microwave-burnt", ("id", uid)), - transformComponent.Coordinates, Filter.Pvs(uid)); + transformComponent.Coordinates, Filter.Pvs(uid), PopupType.Medium); EntityManager.SpawnEntity("FoodBadRecipe", transformComponent.Coordinates); } @@ -63,7 +64,7 @@ namespace Content.Server.Access.Systems else { _popupSystem.PopupEntity(Loc.GetString("id-card-component-microwave-safe", ("id", uid)), - uid, Filter.Pvs(uid)); + uid, Filter.Pvs(uid), PopupType.Medium); } // Give them a wonderful new access to compensate for everything diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs b/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs index 4292e2cdf7..1af8d22d8f 100644 --- a/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs +++ b/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs @@ -34,6 +34,7 @@ using Content.Shared.MobState; using Content.Shared.MobState.Components; using Content.Shared.Movement.Components; using Content.Shared.Nutrition.Components; +using Content.Shared.Popups; using Content.Shared.Tabletop.Components; using Content.Shared.Verbs; using Robust.Server.GameObjects; @@ -109,8 +110,11 @@ public sealed partial class AdminVerbSystem EnsureComp(args.Target); RemComp(args.Target); // So they can be dragged around. var xform = Transform(args.Target); - _popupSystem.PopupEntity(Loc.GetString("admin-smite-chess-self"), args.Target, Filter.Entities(args.Target)); - _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-chess-others", ("name", args.Target)), xform.Coordinates, Filter.Pvs(args.Target).RemoveWhereAttachedEntity(x => x == args.Target)); + _popupSystem.PopupEntity(Loc.GetString("admin-smite-chess-self"), args.Target, + Filter.Entities(args.Target), PopupType.Critical); + _popupSystem.PopupCoordinates( + Loc.GetString("admin-smite-chess-others", ("name", args.Target)), xform.Coordinates, + Filter.PvsExcept(args.Target), PopupType.Critical); var board = Spawn("ChessBoard", xform.Coordinates); var session = _tabletopSystem.EnsureSession(Comp(board)); xform.Coordinates = EntityCoordinates.FromMap(_mapManager, session.Position); @@ -134,8 +138,10 @@ public sealed partial class AdminVerbSystem flammable.FireStacks = 99999.9f; _flammableSystem.Ignite(args.Target); var xform = Transform(args.Target); - _popupSystem.PopupEntity(Loc.GetString("admin-smite-set-alight-self"), args.Target, Filter.Entities(args.Target)); - _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-set-alight-others", ("name", args.Target)), xform.Coordinates, Filter.Pvs(args.Target).RemoveWhereAttachedEntity(x => x == args.Target)); + _popupSystem.PopupEntity(Loc.GetString("admin-smite-set-alight-self"), args.Target, + Filter.Entities(args.Target), PopupType.Critical); + _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-set-alight-others", ("name", args.Target)), xform.Coordinates, + Filter.PvsExcept(args.Target), PopupType.Critical); }, Impact = LogImpact.Extreme, Message = "Makes them burn.", @@ -252,8 +258,10 @@ public sealed partial class AdminVerbSystem { _bloodstreamSystem.SpillAllSolutions(args.Target, bloodstream); var xform = Transform(args.Target); - _popupSystem.PopupEntity(Loc.GetString("admin-smite-remove-blood-self"), args.Target, Filter.Entities(args.Target)); - _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-remove-blood-others", ("name", args.Target)), xform.Coordinates, Filter.Pvs(args.Target).RemoveWhereAttachedEntity(x => x == args.Target)); + _popupSystem.PopupEntity(Loc.GetString("admin-smite-remove-blood-self"), args.Target, + Filter.Entities(args.Target), PopupType.Critical); + _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-remove-blood-others", ("name", args.Target)), xform.Coordinates, + Filter.PvsExcept(args.Target), PopupType.Critical); }, Impact = LogImpact.Extreme, Message = "Removes their blood. All of it.", @@ -283,8 +291,10 @@ public sealed partial class AdminVerbSystem xform.Coordinates = baseXform.Coordinates.Offset(_random.NextVector2(0.5f,0.75f)); } - _popupSystem.PopupEntity(Loc.GetString("admin-smite-vomit-organs-self"), args.Target, Filter.Entities(args.Target)); - _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-vomit-organs-others", ("name", args.Target)), baseXform.Coordinates, Filter.Pvs(args.Target).RemoveWhereAttachedEntity(x => x == args.Target)); + _popupSystem.PopupEntity(Loc.GetString("admin-smite-vomit-organs-self"), args.Target, + Filter.Entities(args.Target), PopupType.Critical); + _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-vomit-organs-others", ("name", args.Target)), baseXform.Coordinates, + Filter.PvsExcept(args.Target), PopupType.Critical); }, Impact = LogImpact.Extreme, Message = "Causes them to vomit, including their internal organs.", @@ -304,8 +314,10 @@ public sealed partial class AdminVerbSystem body.RemovePart(part); Transform(part.Owner).Coordinates = baseXform.Coordinates; } - _popupSystem.PopupEntity(Loc.GetString("admin-smite-remove-hands-self"), args.Target, Filter.Entities(args.Target)); - _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-remove-hands-others", ("name", args.Target)), baseXform.Coordinates, Filter.Pvs(args.Target).RemoveWhereAttachedEntity(x => x == args.Target)); + _popupSystem.PopupEntity(Loc.GetString("admin-smite-remove-hands-self"), args.Target, + Filter.Entities(args.Target), PopupType.Critical); + _popupSystem.PopupCoordinates(Loc.GetString("admin-smite-remove-hands-others", ("name", args.Target)), baseXform.Coordinates, + Filter.PvsExcept(args.Target), PopupType.Medium); }, Impact = LogImpact.Extreme, Message = "Removes the target's hands.", @@ -482,7 +494,8 @@ public sealed partial class AdminVerbSystem { EntityManager.QueueDeleteEntity(args.Target); Spawn("Ash", Transform(args.Target).Coordinates); - _popupSystem.PopupEntity(Loc.GetString("admin-smite-turned-ash-other", ("name", args.Target)), args.Target, Filter.Pvs(args.Target)); + _popupSystem.PopupEntity(Loc.GetString("admin-smite-turned-ash-other", ("name", args.Target)), args.Target, + Filter.Pvs(args.Target), PopupType.Critical); }, Impact = LogImpact.Extreme, Message = "Reduces the target to a small pile of ash.", diff --git a/Content.Server/Animals/Systems/UdderSystem.cs b/Content.Server/Animals/Systems/UdderSystem.cs index 63547068b6..c1dfa4caa6 100644 --- a/Content.Server/Animals/Systems/UdderSystem.cs +++ b/Content.Server/Animals/Systems/UdderSystem.cs @@ -5,6 +5,7 @@ using Content.Server.DoAfter; using Content.Server.Nutrition.Components; using Content.Server.Popups; using Content.Shared.Nutrition.Components; +using Content.Shared.Popups; using Content.Shared.Verbs; using Robust.Shared.Player; @@ -109,7 +110,8 @@ namespace Content.Server.Animals.Systems var split = _solutionContainerSystem.SplitSolution(uid, solution, quantity); _solutionContainerSystem.TryAddSolution(ev.ContainerUid, targetSolution, split); - _popupSystem.PopupEntity(Loc.GetString("udder-system-success", ("amount", quantity), ("target", ev.ContainerUid)), uid, Filter.Entities(ev.UserUid)); + _popupSystem.PopupEntity(Loc.GetString("udder-system-success", ("amount", quantity), ("target", ev.ContainerUid)), uid, + Filter.Entities(ev.UserUid), PopupType.Medium); } private void OnMilkingFailed(EntityUid uid, UdderComponent component, MilkingFailEvent ev) diff --git a/Content.Server/Atmos/Piping/EntitySystems/AtmosUnsafeUnanchorSystem.cs b/Content.Server/Atmos/Piping/EntitySystems/AtmosUnsafeUnanchorSystem.cs index 9968b7191e..49447f43ee 100644 --- a/Content.Server/Atmos/Piping/EntitySystems/AtmosUnsafeUnanchorSystem.cs +++ b/Content.Server/Atmos/Piping/EntitySystems/AtmosUnsafeUnanchorSystem.cs @@ -5,6 +5,7 @@ using Content.Server.NodeContainer.Nodes; using Content.Server.Popups; using Content.Shared.Atmos; using Content.Shared.Construction.Components; +using Content.Shared.Popups; using JetBrains.Annotations; using Robust.Shared.Player; @@ -37,7 +38,8 @@ namespace Content.Server.Atmos.Piping.EntitySystems if ((pipe.Air.Pressure - environment.Pressure) > 2 * Atmospherics.OneAtmosphere) { args.Delay += 1.5f; - _popupSystem.PopupCursor(Loc.GetString("comp-atmos-unsafe-unanchor-warning"), Filter.Entities(args.User)); + _popupSystem.PopupCursor(Loc.GetString("comp-atmos-unsafe-unanchor-warning"), + Filter.Entities(args.User), PopupType.Large); return; // Show the warning only once. } } diff --git a/Content.Server/Bible/BibleSystem.cs b/Content.Server/Bible/BibleSystem.cs index b03ba09146..5082c98dcf 100644 --- a/Content.Server/Bible/BibleSystem.cs +++ b/Content.Server/Bible/BibleSystem.cs @@ -10,6 +10,7 @@ using Content.Server.Cooldown; using Content.Server.Bible.Components; using Content.Server.MobState; using Content.Server.Popups; +using Content.Shared.Popups; using Robust.Shared.Random; using Robust.Shared.Audio; using Robust.Shared.Player; @@ -75,7 +76,8 @@ namespace Content.Server.Bible summonableComp.Summon = null; } summonableComp.AlreadySummoned = false; - _popupSystem.PopupEntity(Loc.GetString("bible-summon-respawn-ready", ("book", summonableComp.Owner)), summonableComp.Owner, Filter.Pvs(summonableComp.Owner)); + _popupSystem.PopupEntity(Loc.GetString("bible-summon-respawn-ready", ("book", summonableComp.Owner)), summonableComp.Owner, + Filter.Pvs(summonableComp.Owner), PopupType.Medium); SoundSystem.Play("/Audio/Effects/radpulse9.ogg", Filter.Pvs(summonableComp.Owner), summonableComp.Owner, AudioParams.Default.WithVolume(-4f)); // Clean up the accumulator and respawn tracking component summonableComp.Accumulator = 0; @@ -120,10 +122,10 @@ namespace Content.Server.Bible if (_random.Prob(component.FailChance)) { var othersFailMessage = Loc.GetString(component.LocPrefix + "-heal-fail-others", ("user", args.User),("target", args.Target),("bible", uid)); - _popupSystem.PopupEntity(othersFailMessage, args.User, Filter.Pvs(args.User).RemoveWhereAttachedEntity(puid => puid == args.User)); + _popupSystem.PopupEntity(othersFailMessage, args.User, Filter.PvsExcept(args.User)); var selfFailMessage = Loc.GetString(component.LocPrefix + "-heal-fail-self", ("target", args.Target),("bible", uid)); - _popupSystem.PopupEntity(selfFailMessage, args.User, Filter.Entities(args.User)); + _popupSystem.PopupEntity(selfFailMessage, args.User, Filter.Entities(args.User), PopupType.Medium); SoundSystem.Play("/Audio/Effects/hit_kick.ogg", Filter.Pvs(args.Target.Value), args.User); _damageableSystem.TryChangeDamage(args.Target.Value, component.DamageOnFail, true); @@ -132,10 +134,10 @@ namespace Content.Server.Bible } var othersMessage = Loc.GetString(component.LocPrefix + "-heal-success-others", ("user", args.User),("target", args.Target),("bible", uid)); - _popupSystem.PopupEntity(othersMessage, args.User, Filter.Pvs(args.User).RemoveWhereAttachedEntity(puid => puid == args.User)); + _popupSystem.PopupEntity(othersMessage, args.User, Filter.PvsExcept(args.User), PopupType.Medium); var selfMessage = Loc.GetString(component.LocPrefix + "-heal-success-self", ("target", args.Target),("bible", uid)); - _popupSystem.PopupEntity(selfMessage, args.User, Filter.Entities(args.User)); + _popupSystem.PopupEntity(selfMessage, args.User, Filter.Entities(args.User), PopupType.Large); SoundSystem.Play(component.HealSoundPath.GetSound(), Filter.Pvs(args.Target.Value), args.User); _damageableSystem.TryChangeDamage(args.Target.Value, component.Damage, true); diff --git a/Content.Server/Body/Systems/BloodstreamSystem.cs b/Content.Server/Body/Systems/BloodstreamSystem.cs index 2353f0dc6b..d2eb1fcb90 100644 --- a/Content.Server/Body/Systems/BloodstreamSystem.cs +++ b/Content.Server/Body/Systems/BloodstreamSystem.cs @@ -10,6 +10,7 @@ using Content.Shared.Damage; using Content.Shared.Damage.Prototypes; using Content.Shared.FixedPoint; using Content.Shared.MobState.Components; +using Content.Shared.Popups; using Robust.Shared.Audio; using Robust.Shared.Player; using Robust.Shared.Prototypes; @@ -164,7 +165,7 @@ public sealed class BloodstreamSystem : EntitySystem // We'll play a special sound and popup for feedback. SoundSystem.Play(component.BloodHealedSound.GetSound(), Filter.Pvs(uid), uid, AudioParams.Default); _popupSystem.PopupEntity(Loc.GetString("bloodstream-component-wounds-cauterized"), uid, - Filter.Entities(uid)); + Filter.Entities(uid), PopupType.Medium); ; } } diff --git a/Content.Server/Botany/Systems/BotanySystem.Seed.cs b/Content.Server/Botany/Systems/BotanySystem.Seed.cs index 922a2126b6..88e87c4599 100644 --- a/Content.Server/Botany/Systems/BotanySystem.Seed.cs +++ b/Content.Server/Botany/Systems/BotanySystem.Seed.cs @@ -4,6 +4,7 @@ using Content.Server.Botany.Components; using Content.Server.Kitchen.Components; using Content.Shared.Botany; using Content.Shared.Examine; +using Content.Shared.Popups; using Content.Shared.Random.Helpers; using Robust.Server.GameObjects; using Robust.Shared.Map; @@ -106,12 +107,12 @@ public sealed partial class BotanySystem if (proto.ProductPrototypes.Count == 0 || proto.Yield <= 0) { _popupSystem.PopupCursor(Loc.GetString("botany-harvest-fail-message"), - Filter.Entities(user)); + Filter.Entities(user), PopupType.Medium); return Enumerable.Empty(); } _popupSystem.PopupCursor(Loc.GetString("botany-harvest-success-message", ("name", proto.DisplayName)), - Filter.Entities(user)); + Filter.Entities(user), PopupType.Medium); return GenerateProduct(proto, Transform(user).Coordinates, yieldMod); } @@ -132,7 +133,7 @@ public sealed partial class BotanySystem if (totalYield > 1 || proto.HarvestRepeat != HarvestType.NoRepeat) proto.Unique = false; - + for (var i = 0; i < totalYield; i++) { var product = _robustRandom.Pick(proto.ProductPrototypes); diff --git a/Content.Server/Botany/Systems/PlantHolderSystem.cs b/Content.Server/Botany/Systems/PlantHolderSystem.cs index e36ffc73b8..a735d5ef6a 100644 --- a/Content.Server/Botany/Systems/PlantHolderSystem.cs +++ b/Content.Server/Botany/Systems/PlantHolderSystem.cs @@ -8,6 +8,7 @@ using Content.Shared.Examine; using Content.Shared.Tag; using Content.Shared.FixedPoint; using Content.Shared.Audio; +using Content.Shared.Popups; using Content.Shared.Random.Helpers; using Robust.Shared.Player; using Robust.Shared.Timing; @@ -102,7 +103,7 @@ namespace Content.Server.Botany.Systems _popupSystem.PopupCursor(Loc.GetString("plant-holder-component-plant-success-message", ("seedName", seed.Name), - ("seedNoun", seed.Noun)), Filter.Entities(args.User)); + ("seedNoun", seed.Noun)), Filter.Entities(args.User), PopupType.Medium); component.Seed = seed; component.Dead = false; @@ -119,7 +120,7 @@ namespace Content.Server.Botany.Systems } _popupSystem.PopupCursor(Loc.GetString("plant-holder-component-already-seeded-message", - ("name", Comp(uid).EntityName)), Filter.Entities(args.User)); + ("name", Comp(uid).EntityName)), Filter.Entities(args.User), PopupType.Medium); return; } @@ -128,9 +129,9 @@ namespace Content.Server.Botany.Systems if (component.WeedLevel > 0) { _popupSystem.PopupCursor(Loc.GetString("plant-holder-component-remove-weeds-message", - ("name", Comp(uid).EntityName)), Filter.Entities(args.User)); + ("name", Comp(uid).EntityName)), Filter.Entities(args.User), PopupType.Medium); _popupSystem.PopupEntity(Loc.GetString("plant-holder-component-remove-weeds-others-message", - ("otherName", Comp(args.User).EntityName)), uid, Filter.Pvs(args.User).RemoveWhereAttachedEntity(puid => puid == args.User)); + ("otherName", Comp(args.User).EntityName)), uid, Filter.PvsExcept(args.User)); component.WeedLevel = 0; component.UpdateSprite(); } @@ -147,9 +148,9 @@ namespace Content.Server.Botany.Systems if (component.Seed != null) { _popupSystem.PopupCursor(Loc.GetString("plant-holder-component-remove-plant-message", - ("name", Comp(uid).EntityName)), Filter.Entities(args.User)); + ("name", Comp(uid).EntityName)), Filter.Entities(args.User), PopupType.Medium); _popupSystem.PopupEntity(Loc.GetString("plant-holder-component-remove-plant-others-message", - ("name", Comp(args.User).EntityName)), uid, Filter.Pvs(args.User).RemoveWhereAttachedEntity(puid => puid == args.User)); + ("name", Comp(args.User).EntityName)), uid, Filter.PvsExcept(args.User)); component.RemovePlant(); } else @@ -185,7 +186,7 @@ namespace Content.Server.Botany.Systems _popupSystem.PopupCursor(Loc.GetString("plant-holder-component-spray-message", ("owner", uid), - ("amount", split.TotalVolume)), Filter.Entities(args.User)); + ("amount", split.TotalVolume)), Filter.Entities(args.User), PopupType.Medium); _solutionSystem.TryAddSolution(targetEntity, targetSolution, split); @@ -238,11 +239,11 @@ namespace Content.Server.Botany.Systems { _popupSystem.PopupCursor(Loc.GetString("plant-holder-component-compost-message", ("owner", uid), - ("usingItem", args.Used)), Filter.Entities(args.User)); + ("usingItem", args.Used)), Filter.Entities(args.User), PopupType.Medium); _popupSystem.PopupEntity(Loc.GetString("plant-holder-component-compost-others-message", ("user", args.User), ("usingItem", args.Used), - ("owner", uid)), uid, Filter.Pvs(args.User).RemoveWhereAttachedEntity(puid => puid == args.User)); + ("owner", uid)), uid, Filter.PvsExcept(args.User)); if (_solutionSystem.TryGetSolution(args.Used, produce.SolutionName, out var solution2)) { diff --git a/Content.Server/Botany/Systems/SeedExtractorSystem.cs b/Content.Server/Botany/Systems/SeedExtractorSystem.cs index 6f2f890154..e8035ceeb2 100644 --- a/Content.Server/Botany/Systems/SeedExtractorSystem.cs +++ b/Content.Server/Botany/Systems/SeedExtractorSystem.cs @@ -3,6 +3,7 @@ using Content.Server.Popups; using Content.Server.Power.Components; using Content.Server.Power.EntitySystems; using Content.Shared.Interaction; +using Content.Shared.Popups; using Robust.Shared.Player; using Robust.Shared.Random; @@ -31,7 +32,7 @@ public sealed class SeedExtractorSystem : EntitySystem return; _popupSystem.PopupCursor(Loc.GetString("seed-extractor-component-interact-message",("name", args.Used)), - Filter.Entities(args.User)); + Filter.Entities(args.User), PopupType.Medium); QueueDel(args.Used); diff --git a/Content.Server/Chemistry/ReagentEffects/PopupMessage.cs b/Content.Server/Chemistry/ReagentEffects/PopupMessage.cs index 2b67cef1ba..0b445be564 100644 --- a/Content.Server/Chemistry/ReagentEffects/PopupMessage.cs +++ b/Content.Server/Chemistry/ReagentEffects/PopupMessage.cs @@ -11,7 +11,10 @@ namespace Content.Server.Chemistry.ReagentEffects public string[] Messages = default!; [DataField("type")] - public PopupType Type = PopupType.Local; + public PopupRecipients Type = PopupRecipients.Local; + + [DataField("visualType")] + public PopupType VisualType = PopupType.Small; public override void Effect(ReagentEffectArgs args) { @@ -19,14 +22,14 @@ namespace Content.Server.Chemistry.ReagentEffects var random = IoCManager.Resolve(); var msg = random.Pick(Messages); - if (Type == PopupType.Local) - popupSys.PopupEntity(Loc.GetString(msg), args.SolutionEntity, Filter.Entities(args.SolutionEntity)); - else if (Type == PopupType.Pvs) - popupSys.PopupEntity(Loc.GetString(msg), args.SolutionEntity, Filter.Pvs(args.SolutionEntity)); + if (Type == PopupRecipients.Local) + popupSys.PopupEntity(Loc.GetString(msg), args.SolutionEntity, Filter.Entities(args.SolutionEntity), VisualType); + else if (Type == PopupRecipients.Pvs) + popupSys.PopupEntity(Loc.GetString(msg), args.SolutionEntity, Filter.Pvs(args.SolutionEntity), VisualType); } } - public enum PopupType + public enum PopupRecipients { Pvs, Local diff --git a/Content.Server/Communications/CommunicationsConsoleSystem.cs b/Content.Server/Communications/CommunicationsConsoleSystem.cs index af270af9ab..b56c342f71 100644 --- a/Content.Server/Communications/CommunicationsConsoleSystem.cs +++ b/Content.Server/Communications/CommunicationsConsoleSystem.cs @@ -14,6 +14,7 @@ using Content.Shared.Access.Systems; using Content.Shared.CCVar; using Content.Shared.Communications; using Content.Shared.Examine; +using Content.Shared.Popups; using Robust.Server.GameObjects; using Robust.Shared.Configuration; using Robust.Shared.Player; @@ -204,7 +205,7 @@ namespace Content.Server.Communications if (message.Session.AttachedEntity is not {Valid: true} mob) return; if (!CanUse(mob, uid)) { - _popupSystem.PopupCursor(Loc.GetString("comms-console-permission-denied"), Filter.Entities(mob)); + _popupSystem.PopupCursor(Loc.GetString("comms-console-permission-denied"), Filter.Entities(mob), PopupType.Medium); return; } diff --git a/Content.Server/DeviceNetwork/Systems/NetworkConfiguratorSystem.cs b/Content.Server/DeviceNetwork/Systems/NetworkConfiguratorSystem.cs index c6bc1b49cc..fc76b70f12 100644 --- a/Content.Server/DeviceNetwork/Systems/NetworkConfiguratorSystem.cs +++ b/Content.Server/DeviceNetwork/Systems/NetworkConfiguratorSystem.cs @@ -91,7 +91,7 @@ public sealed class NetworkConfiguratorSystem : EntitySystem configurator.Devices.Add(device.Address, targetUid.Value); _popupSystem.PopupCursor(Loc.GetString("network-configurator-device-saved", ("address", device.Address), ("device", targetUid)), - Filter.Entities(userUid)); + Filter.Entities(userUid), PopupType.Medium); UpdateUiState(configurator.Owner, configurator); } diff --git a/Content.Server/Disease/Effects/DiseasePopUp.cs b/Content.Server/Disease/Effects/DiseasePopUp.cs index beee93c52e..3de3adfccb 100644 --- a/Content.Server/Disease/Effects/DiseasePopUp.cs +++ b/Content.Server/Disease/Effects/DiseasePopUp.cs @@ -17,20 +17,24 @@ namespace Content.Server.Disease.Effects public string Message = "disease-sick-generic"; [DataField("type")] - public PopupType Type = PopupType.Local; + public PopupRecipients Type = PopupRecipients.Local; + + [DataField("visualType")] + public PopupType VisualType = PopupType.Small; + public override void Effect(DiseaseEffectArgs args) { var popupSys = EntitySystem.Get(); - if (Type == PopupType.Local) - popupSys.PopupEntity(Loc.GetString(Message), args.DiseasedEntity, Filter.Entities(args.DiseasedEntity)); - else if (Type == PopupType.Pvs) - popupSys.PopupEntity(Loc.GetString(Message, ("person", args.DiseasedEntity)), args.DiseasedEntity, Filter.Pvs(args.DiseasedEntity)); + if (Type == PopupRecipients.Local) + popupSys.PopupEntity(Loc.GetString(Message), args.DiseasedEntity, Filter.Entities(args.DiseasedEntity), VisualType); + else if (Type == PopupRecipients.Pvs) + popupSys.PopupEntity(Loc.GetString(Message, ("person", args.DiseasedEntity)), args.DiseasedEntity, Filter.Pvs(args.DiseasedEntity), VisualType); } } - public enum PopupType + public enum PopupRecipients { Pvs, Local diff --git a/Content.Server/Drone/DroneSystem.cs b/Content.Server/Drone/DroneSystem.cs index ccdde784ab..66eeb2728c 100644 --- a/Content.Server/Drone/DroneSystem.cs +++ b/Content.Server/Drone/DroneSystem.cs @@ -20,6 +20,7 @@ using Content.Server.Hands.Components; using Content.Server.UserInterface; using Robust.Shared.Player; using Content.Shared.Hands.EntitySystems; +using Content.Shared.Popups; using Content.Shared.Storage; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -111,7 +112,8 @@ namespace Content.Server.Drone private void OnMindAdded(EntityUid uid, DroneComponent drone, MindAddedMessage args) { UpdateDroneAppearance(uid, DroneStatus.On); - _popupSystem.PopupEntity(Loc.GetString("drone-activated"), uid, Filter.Pvs(uid)); + _popupSystem.PopupEntity(Loc.GetString("drone-activated"), uid, + Filter.Pvs(uid), PopupType.Large); if (drone.AlreadyAwoken == false) { diff --git a/Content.Server/Emag/EmagSystem.cs b/Content.Server/Emag/EmagSystem.cs index 9a9f56a402..194e5b5014 100644 --- a/Content.Server/Emag/EmagSystem.cs +++ b/Content.Server/Emag/EmagSystem.cs @@ -65,7 +65,8 @@ namespace Content.Server.Emag RaiseLocalEvent(args.Target.Value, emaggedEvent, false); if (emaggedEvent.Handled) { - _popupSystem.PopupEntity(Loc.GetString("emag-success", ("target", args.Target)), args.User, Filter.Entities(args.User)); + _popupSystem.PopupEntity(Loc.GetString("emag-success", ("target", args.Target)), args.User, + Filter.Entities(args.User), PopupType.Medium); _adminLogger.Add(LogType.Emag, LogImpact.High, $"{ToPrettyString(args.User):player} emagged {ToPrettyString(args.Target.Value):target}"); component.Charges--; return; diff --git a/Content.Server/Guardian/GuardianSystem.cs b/Content.Server/Guardian/GuardianSystem.cs index 2e162faeb6..8f9a4bcb8f 100644 --- a/Content.Server/Guardian/GuardianSystem.cs +++ b/Content.Server/Guardian/GuardianSystem.cs @@ -8,6 +8,7 @@ using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction; using Content.Shared.Interaction.Events; using Content.Shared.MobState; +using Content.Shared.Popups; using Robust.Server.GameObjects; using Robust.Shared.Audio; using Robust.Shared.Containers; @@ -98,7 +99,7 @@ namespace Content.Server.Guardian if (args.Cancelled || args.Target != component.Host) return; - _popupSystem.PopupCursor(Loc.GetString("guardian-attack-host"), Filter.Entities(uid)); + _popupSystem.PopupCursor(Loc.GetString("guardian-attack-host"), Filter.Entities(uid), PopupType.Large); args.Cancel(); } diff --git a/Content.Server/ImmovableRod/ImmovableRodSystem.cs b/Content.Server/ImmovableRod/ImmovableRodSystem.cs index b7072be80e..149a7f977e 100644 --- a/Content.Server/ImmovableRod/ImmovableRodSystem.cs +++ b/Content.Server/ImmovableRod/ImmovableRodSystem.cs @@ -1,6 +1,7 @@ using Content.Server.Body.Components; using Content.Server.Popups; using Content.Shared.Examine; +using Content.Shared.Popups; using Robust.Shared.Audio; using Robust.Shared.Map; using Robust.Shared.Physics.Dynamics; @@ -84,7 +85,8 @@ public sealed class ImmovableRodSystem : EntitySystem { // oh god. var coords = Transform(uid).Coordinates; - _popup.PopupCoordinates(Loc.GetString("immovable-rod-collided-rod-not-good"), coords, Filter.Pvs(uid)); + _popup.PopupCoordinates(Loc.GetString("immovable-rod-collided-rod-not-good"), coords, + Filter.Pvs(uid), PopupType.Critical); Del(uid); Del(ent); @@ -98,7 +100,8 @@ public sealed class ImmovableRodSystem : EntitySystem { component.MobCount++; - _popup.PopupEntity(Loc.GetString("immovable-rod-penetrated-mob", ("rod", uid), ("mob", ent)), uid, Filter.Pvs(uid)); + _popup.PopupEntity(Loc.GetString("immovable-rod-penetrated-mob", ("rod", uid), ("mob", ent)), uid, + Filter.Pvs(uid), PopupType.Critical); body.Gib(); } diff --git a/Content.Server/Kitchen/EntitySystems/KitchenSpikeSystem.cs b/Content.Server/Kitchen/EntitySystems/KitchenSpikeSystem.cs index 2ac1300ab5..af76a9260a 100644 --- a/Content.Server/Kitchen/EntitySystems/KitchenSpikeSystem.cs +++ b/Content.Server/Kitchen/EntitySystems/KitchenSpikeSystem.cs @@ -123,7 +123,8 @@ namespace Content.Server.Kitchen.EntitySystems UpdateAppearance(uid, null, component); - _popupSystem.PopupEntity(Loc.GetString("comp-kitchen-spike-kill", ("user", userUid), ("victim", victimUid)), uid, Filter.Pvs(userUid)); + _popupSystem.PopupEntity(Loc.GetString("comp-kitchen-spike-kill", ("user", userUid), ("victim", victimUid)), uid, + Filter.Pvs(userUid), PopupType.Critical); // THE WHAT? // TODO: Need to be able to leave them on the spike to do DoT, see ss13. @@ -152,12 +153,12 @@ namespace Content.Server.Kitchen.EntitySystems if (component.PrototypesToSpawn.Count != 0) { - _popupSystem.PopupEntity(component.MeatSource1p, uid, Filter.Entities(user)); + _popupSystem.PopupEntity(component.MeatSource1p, uid, Filter.Entities(user), PopupType.Medium); } else { UpdateAppearance(uid, null, component); - _popupSystem.PopupEntity(component.MeatSource0, uid, Filter.Entities(user)); + _popupSystem.PopupEntity(component.MeatSource0, uid, Filter.Entities(user), PopupType.Medium); } return true; @@ -221,7 +222,8 @@ namespace Content.Server.Kitchen.EntitySystems if (userUid != victimUid) { - _popupSystem.PopupEntity(Loc.GetString("comp-kitchen-spike-begin-hook-victim", ("user", userUid), ("this", uid)), victimUid, Filter.Entities(victimUid)); + _popupSystem.PopupEntity(Loc.GetString("comp-kitchen-spike-begin-hook-victim", ("user", userUid), ("this", uid)), victimUid, + Filter.Entities(victimUid), PopupType.Large); } // TODO: make it work when SuicideEvent is implemented // else diff --git a/Content.Server/Kitchen/EntitySystems/SharpSystem.cs b/Content.Server/Kitchen/EntitySystems/SharpSystem.cs index 918370c949..4b01377210 100644 --- a/Content.Server/Kitchen/EntitySystems/SharpSystem.cs +++ b/Content.Server/Kitchen/EntitySystems/SharpSystem.cs @@ -88,7 +88,7 @@ public sealed class SharpSystem : EntitySystem } _popupSystem.PopupEntity(Loc.GetString("butcherable-knife-butchered-success", ("target", ev.Entity), ("knife", ev.Sharp)), - popupEnt, Filter.Entities(ev.User)); + popupEnt, Filter.Entities(ev.User), PopupType.Large); if (TryComp(ev.Entity, out var body)) { diff --git a/Content.Server/LandMines/LandMineSystem.cs b/Content.Server/LandMines/LandMineSystem.cs index a19ad44775..a151b217e7 100644 --- a/Content.Server/LandMines/LandMineSystem.cs +++ b/Content.Server/LandMines/LandMineSystem.cs @@ -32,7 +32,8 @@ public sealed class LandMineSystem : EntitySystem _popupSystem.PopupCoordinates( Loc.GetString("land-mine-triggered", ("mine", uid)), Transform(uid).Coordinates, - Filter.Entities(args.Tripper)); + Filter.Entities(args.Tripper), + PopupType.Critical); } if (component.DeleteOnActivate) diff --git a/Content.Server/Light/EntitySystems/LightReplacerSystem.cs b/Content.Server/Light/EntitySystems/LightReplacerSystem.cs index 5fef1809d0..24c0791865 100644 --- a/Content.Server/Light/EntitySystems/LightReplacerSystem.cs +++ b/Content.Server/Light/EntitySystems/LightReplacerSystem.cs @@ -169,7 +169,7 @@ namespace Content.Server.Light.EntitySystems { var msg = Loc.GetString("comp-light-replacer-insert-light", ("light-replacer", replacer.Owner), ("bulb", bulb.Owner)); - _popupSystem.PopupEntity(msg, replacerUid, Filter.Entities(userUid.Value)); + _popupSystem.PopupEntity(msg, replacerUid, Filter.Entities(userUid.Value), PopupType.Medium); } return hasInsert; @@ -208,7 +208,7 @@ namespace Content.Server.Light.EntitySystems if (insertedBulbs > 0 && userUid != null) { var msg = Loc.GetString("comp-light-replacer-refill-from-storage", ("light-replacer", storage.Owner)); - _popupSystem.PopupEntity(msg, replacerUid, Filter.Entities(userUid.Value)); + _popupSystem.PopupEntity(msg, replacerUid, Filter.Entities(userUid.Value), PopupType.Medium); } return insertedBulbs > 0; diff --git a/Content.Server/MachineLinking/System/SignalLinkerSystem.cs b/Content.Server/MachineLinking/System/SignalLinkerSystem.cs index d7c479c20e..7e5cb04108 100644 --- a/Content.Server/MachineLinking/System/SignalLinkerSystem.cs +++ b/Content.Server/MachineLinking/System/SignalLinkerSystem.cs @@ -209,7 +209,7 @@ namespace Content.Server.MachineLinking.System if (!TryComp(linker.SavedReceiver, out SignalReceiverComponent? receiver)) { _popupSystem.PopupCursor(Loc.GetString("signal-linker-component-saved", ("machine", uid)), - Filter.Entities(args.User)); + Filter.Entities(args.User), PopupType.Medium); args.Handled = true; return; } @@ -235,7 +235,7 @@ namespace Content.Server.MachineLinking.System if (!TryComp(linker.SavedTransmitter, out SignalTransmitterComponent? transmitter)) { _popupSystem.PopupCursor(Loc.GetString("signal-linker-component-saved", ("machine", uid)), - Filter.Entities(args.User)); + Filter.Entities(args.User), PopupType.Medium); args.Handled = true; return; } @@ -324,7 +324,7 @@ namespace Content.Server.MachineLinking.System _popupSystem.PopupCursor(Loc.GetString("signal-linker-component-linked-port", ("machine1", transmitter.Owner), ("port1", PortName(args.TransmitterPort)), ("machine2", receiver.Owner), ("port2", PortName(args.ReceiverPort))), - Filter.Entities(user)); + Filter.Entities(user), PopupType.Medium); return true; } @@ -351,7 +351,7 @@ namespace Content.Server.MachineLinking.System _popupSystem.PopupCursor(Loc.GetString("signal-linker-component-unlinked-port", ("machine1", transmitter.Owner), ("port1", PortName(args.TransmitterPort)), ("machine2", receiver.Owner), ("port2", PortName(args.ReceiverPort))), - Filter.Entities(attached)); + Filter.Entities(attached), PopupType.Medium); } else { // something weird happened diff --git a/Content.Server/Morgue/MorgueSystem.cs b/Content.Server/Morgue/MorgueSystem.cs index 22ecd7e910..03b739f87d 100644 --- a/Content.Server/Morgue/MorgueSystem.cs +++ b/Content.Server/Morgue/MorgueSystem.cs @@ -9,6 +9,7 @@ using Robust.Server.GameObjects; using Content.Server.Players; using Content.Server.GameTicking; using Content.Server.Popups; +using Content.Shared.Popups; using Content.Shared.Standing; using Robust.Shared.Player; @@ -44,7 +45,8 @@ namespace Content.Server.Morgue if (mind.OwnedEntity is { Valid: true } entity) { - _popup.PopupEntity(Loc.GetString("crematorium-entity-storage-component-suicide-message"), entity, Filter.Pvs(entity, entityManager: EntityManager)); + _popup.PopupEntity(Loc.GetString("crematorium-entity-storage-component-suicide-message"), entity, + Filter.Pvs(entity, entityManager: EntityManager), PopupType.Critical); } } diff --git a/Content.Server/Nuke/NukeSystem.cs b/Content.Server/Nuke/NukeSystem.cs index 22c7e279ac..c78489bf32 100644 --- a/Content.Server/Nuke/NukeSystem.cs +++ b/Content.Server/Nuke/NukeSystem.cs @@ -13,6 +13,7 @@ using Content.Shared.Audio; using Content.Shared.Construction.Components; using Content.Shared.Containers.ItemSlots; using Content.Shared.Nuke; +using Content.Shared.Popups; using Content.Shared.Sound; using Robust.Shared.Audio; using Robust.Shared.Containers; @@ -540,7 +541,8 @@ namespace Content.Server.Nuke }; _doAfterSystem.DoAfter(doafter); - _popups.PopupEntity(Loc.GetString("nuke-component-doafter-warning"), user, Filter.Entities(user)); + _popups.PopupEntity(Loc.GetString("nuke-component-doafter-warning"), user, + Filter.Entities(user), PopupType.Large); } private void NukeArmedAudio(NukeComponent component) diff --git a/Content.Server/PAI/PAISystem.cs b/Content.Server/PAI/PAISystem.cs index e3537a97a4..20476d549e 100644 --- a/Content.Server/PAI/PAISystem.cs +++ b/Content.Server/PAI/PAISystem.cs @@ -8,6 +8,7 @@ using Content.Server.Mind.Components; using Robust.Server.GameObjects; using Robust.Shared.Player; using Content.Shared.Interaction.Events; +using Content.Shared.Popups; namespace Content.Server.PAI { @@ -58,7 +59,7 @@ namespace Content.Server.PAI // Check for pAI activation if (EntityManager.TryGetComponent(uid, out var mind) && mind.HasMind) { - _popupSystem.PopupEntity(Loc.GetString("pai-system-pai-installed"), uid, Filter.Entities(args.User)); + _popupSystem.PopupEntity(Loc.GetString("pai-system-pai-installed"), uid, Filter.Entities(args.User), PopupType.Large); return; } else if (EntityManager.HasComponent(uid)) @@ -141,7 +142,7 @@ namespace Content.Server.PAI if (EntityManager.HasComponent(uid)) { EntityManager.RemoveComponent(uid); - _popupSystem.PopupEntity(Loc.GetString("pai-system-wiped-device"), uid, Filter.Entities(args.User)); + _popupSystem.PopupEntity(Loc.GetString("pai-system-wiped-device"), uid, Filter.Entities(args.User), PopupType.Large); PAITurningOff(uid); } }; diff --git a/Content.Server/Popups/PopupSystem.cs b/Content.Server/Popups/PopupSystem.cs index 7bf7d3789e..877d1dc417 100644 --- a/Content.Server/Popups/PopupSystem.cs +++ b/Content.Server/Popups/PopupSystem.cs @@ -6,19 +6,19 @@ namespace Content.Server.Popups { public sealed class PopupSystem : SharedPopupSystem { - public override void PopupCursor(string message, Filter filter) + public override void PopupCursor(string message, Filter filter, PopupType type=PopupType.Small) { - RaiseNetworkEvent(new PopupCursorEvent(message), filter); + RaiseNetworkEvent(new PopupCursorEvent(message, type), filter); } - public override void PopupCoordinates(string message, EntityCoordinates coordinates, Filter filter) + public override void PopupCoordinates(string message, EntityCoordinates coordinates, Filter filter, PopupType type=PopupType.Small) { - RaiseNetworkEvent(new PopupCoordinatesEvent(message, coordinates), filter); + RaiseNetworkEvent(new PopupCoordinatesEvent(message, type, coordinates), filter); } - public override void PopupEntity(string message, EntityUid uid, Filter filter) + public override void PopupEntity(string message, EntityUid uid, Filter filter, PopupType type=PopupType.Small) { - RaiseNetworkEvent(new PopupEntityEvent(message, uid), filter); + RaiseNetworkEvent(new PopupEntityEvent(message, type, uid), filter); } } } diff --git a/Content.Server/Power/EntitySystems/ApcSystem.cs b/Content.Server/Power/EntitySystems/ApcSystem.cs index 6d02e18131..72341c3270 100644 --- a/Content.Server/Power/EntitySystems/ApcSystem.cs +++ b/Content.Server/Power/EntitySystems/ApcSystem.cs @@ -4,6 +4,7 @@ using Content.Shared.Access.Components; using Content.Shared.Access.Systems; using Content.Shared.APC; using Content.Shared.Emag.Systems; +using Content.Shared.Popups; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Shared.Audio; @@ -55,7 +56,7 @@ namespace Content.Server.Power.EntitySystems else { _popupSystem.PopupCursor(Loc.GetString("apc-component-insufficient-access"), - Filter.Entities(args.Session.AttachedEntity.Value)); + Filter.Entities(args.Session.AttachedEntity.Value), PopupType.Medium); } } diff --git a/Content.Server/Resist/ResistLockerSystem.cs b/Content.Server/Resist/ResistLockerSystem.cs index 8506d3c3a3..303eada916 100644 --- a/Content.Server/Resist/ResistLockerSystem.cs +++ b/Content.Server/Resist/ResistLockerSystem.cs @@ -6,6 +6,7 @@ using Robust.Shared.Player; using Robust.Shared.Containers; using Content.Server.Popups; using Content.Shared.Movement.Events; +using Content.Shared.Popups; namespace Content.Server.Resist; @@ -56,7 +57,7 @@ public sealed class ResistLockerSystem : EntitySystem }; resistLockerComponent.IsResisting = true; - _popupSystem.PopupEntity(Loc.GetString("resist-locker-component-start-resisting"), user, Filter.Entities(user)); + _popupSystem.PopupEntity(Loc.GetString("resist-locker-component-start-resisting"), user, Filter.Entities(user), PopupType.Large); _doAfterSystem.DoAfter(doAfterEventArgs); } @@ -81,7 +82,7 @@ public sealed class ResistLockerSystem : EntitySystem { component.IsResisting = false; component.CancelToken = null; - _popupSystem.PopupEntity(Loc.GetString("resist-locker-component-resist-interrupted"), ev.User, Filter.Entities(ev.User)); + _popupSystem.PopupEntity(Loc.GetString("resist-locker-component-resist-interrupted"), ev.User, Filter.Entities(ev.User), PopupType.Medium); } private void OnRemovedFromContainer(EntityUid uid, ResistLockerComponent component, EntRemovedFromContainerMessage message) diff --git a/Content.Server/Shuttles/Systems/ShuttleSystem.EmergencyConsole.cs b/Content.Server/Shuttles/Systems/ShuttleSystem.EmergencyConsole.cs index 9ec39c8f0c..6da8b212c5 100644 --- a/Content.Server/Shuttles/Systems/ShuttleSystem.EmergencyConsole.cs +++ b/Content.Server/Shuttles/Systems/ShuttleSystem.EmergencyConsole.cs @@ -8,6 +8,7 @@ using Content.Server.Station.Components; using Content.Shared.Access.Systems; using Content.Shared.CCVar; using Content.Shared.Database; +using Content.Shared.Popups; using Content.Shared.Shuttles.BUIStates; using Content.Shared.Shuttles.Events; using Content.Shared.Shuttles.Systems; @@ -149,7 +150,7 @@ public sealed partial class ShuttleSystem if (!_reader.FindAccessTags(player.Value).Contains(EmergencyRepealAllAccess)) { - _popup.PopupCursor(Loc.GetString("emergency-shuttle-console-denied"), Filter.Entities(player.Value)); + _popup.PopupCursor(Loc.GetString("emergency-shuttle-console-denied"), Filter.Entities(player.Value), PopupType.Medium); return; } @@ -168,7 +169,7 @@ public sealed partial class ShuttleSystem if (!_idSystem.TryFindIdCard(player.Value, out var idCard) || !_reader.IsAllowed(idCard.Owner, uid)) { - _popup.PopupCursor(Loc.GetString("emergency-shuttle-console-denied"), Filter.Entities(player.Value)); + _popup.PopupCursor(Loc.GetString("emergency-shuttle-console-denied"), Filter.Entities(player.Value), PopupType.Medium); return; } @@ -189,7 +190,7 @@ public sealed partial class ShuttleSystem if (!_idSystem.TryFindIdCard(player.Value, out var idCard) || !_reader.IsAllowed(idCard.Owner, uid)) { - _popup.PopupCursor(Loc.GetString("emergency-shuttle-console-denied"), Filter.Entities(player.Value)); + _popup.PopupCursor(Loc.GetString("emergency-shuttle-console-denied"), Filter.Entities(player.Value), PopupType.Medium); return; } diff --git a/Content.Server/Stack/StackSystem.cs b/Content.Server/Stack/StackSystem.cs index e3ef06d343..11a4026629 100644 --- a/Content.Server/Stack/StackSystem.cs +++ b/Content.Server/Stack/StackSystem.cs @@ -1,3 +1,4 @@ +using Content.Shared.Popups; using Content.Shared.Stacks; using Content.Shared.Verbs; using JetBrains.Annotations; @@ -129,7 +130,7 @@ namespace Content.Server.Stack if (amount <= 0) { - PopupSystem.PopupCursor(Loc.GetString("comp-stack-split-too-small"), Filter.Entities(userUid)); + PopupSystem.PopupCursor(Loc.GetString("comp-stack-split-too-small"), Filter.Entities(userUid), PopupType.Medium); return; } diff --git a/Content.Server/Strip/StrippableSystem.cs b/Content.Server/Strip/StrippableSystem.cs index a9cd8ff2ae..e90de452a4 100644 --- a/Content.Server/Strip/StrippableSystem.cs +++ b/Content.Server/Strip/StrippableSystem.cs @@ -306,7 +306,8 @@ namespace Content.Server.Strip { if (userHands.ActiveHandEntity != null) { - _popupSystem.PopupEntity(Loc.GetString("strippable-component-alert-owner-insert", ("user", user), ("item", userHands.ActiveHandEntity)), component.Owner, Filter.Entities(component.Owner)); + _popupSystem.PopupEntity(Loc.GetString("strippable-component-alert-owner-insert", ("user", user), ("item", userHands.ActiveHandEntity)), component.Owner, + Filter.Entities(component.Owner), PopupType.Large); } } @@ -368,7 +369,8 @@ namespace Content.Server.Strip { if (handSlot.HeldEntity != null) { - _popupSystem.PopupEntity(Loc.GetString("strippable-component-alert-owner-insert", ("user", user), ("item", handSlot.HeldEntity)), component.Owner, Filter.Entities(component.Owner)); + _popupSystem.PopupEntity(Loc.GetString("strippable-component-alert-owner-insert", ("user", user), ("item", handSlot.HeldEntity)), component.Owner, + Filter.Entities(component.Owner), PopupType.Large); } } @@ -430,11 +432,13 @@ namespace Content.Server.Strip if (Check()) { if (slotDef.StripHidden && !ev.Stealth) - _popupSystem.PopupEntity(Loc.GetString("strippable-component-alert-owner-hidden", ("slot", slot)), component.Owner, Filter.Entities(component.Owner)); + _popupSystem.PopupEntity(Loc.GetString("strippable-component-alert-owner-hidden", ("slot", slot)), component.Owner, + Filter.Entities(component.Owner), PopupType.Large); else { if (_inventorySystem.TryGetSlotEntity(component.Owner, slot, out var slotItem)) - _popupSystem.PopupEntity(Loc.GetString("strippable-component-alert-owner", ("user", user), ("item", slotItem)), component.Owner, Filter.Entities(component.Owner)); + _popupSystem.PopupEntity(Loc.GetString("strippable-component-alert-owner", ("user", user), ("item", slotItem)), component.Owner, + Filter.Entities(component.Owner), PopupType.Large); } } diff --git a/Content.Server/Toilet/ToiletSystem.cs b/Content.Server/Toilet/ToiletSystem.cs index bc0a600f30..982715c2b2 100644 --- a/Content.Server/Toilet/ToiletSystem.cs +++ b/Content.Server/Toilet/ToiletSystem.cs @@ -9,6 +9,7 @@ using Content.Shared.Body.Part; using Content.Shared.Examine; using Content.Shared.Interaction; using Content.Shared.Interaction.Events; +using Content.Shared.Popups; using Content.Shared.Toilet; using Content.Shared.Tools.Components; using Robust.Shared.Audio; @@ -47,11 +48,11 @@ namespace Content.Server.Toilet { var othersMessage = Loc.GetString("toilet-component-suicide-head-message-others", ("victim", args.Victim), ("owner", uid)); - _popupSystem.PopupEntity(othersMessage, uid, Filter.Pvs(args.Victim).RemoveWhereAttachedEntity(puid => puid == args.Victim)); + _popupSystem.PopupEntity(othersMessage, uid, Filter.PvsExcept(args.Victim), PopupType.Critical); var selfMessage = Loc.GetString("toilet-component-suicide-head-message", ("owner", uid)); - _popupSystem.PopupEntity(selfMessage, uid, Filter.Entities(args.Victim)); + _popupSystem.PopupEntity(selfMessage, uid, Filter.Entities(args.Victim), PopupType.Critical); args.SetHandled(SuicideKind.Asphyxiation); } @@ -59,11 +60,11 @@ namespace Content.Server.Toilet { var othersMessage = Loc.GetString("toilet-component-suicide-message-others", ("victim", args.Victim), ("owner", uid)); - _popupSystem.PopupEntity(othersMessage, uid, Filter.Pvs(uid).RemoveWhereAttachedEntity(puid => puid == args.Victim)); + _popupSystem.PopupEntity(othersMessage, uid, Filter.PvsExcept(uid), PopupType.Critical); var selfMessage = Loc.GetString("toilet-component-suicide-message", ("owner", uid)); - _popupSystem.PopupEntity(selfMessage, uid, Filter.Entities(args.Victim)); + _popupSystem.PopupEntity(selfMessage, uid, Filter.Entities(args.Victim), PopupType.Critical); args.SetHandled(SuicideKind.Blunt); } diff --git a/Content.Shared/Popups/SharedPopupSystem.cs b/Content.Shared/Popups/SharedPopupSystem.cs index 53b8a2fa90..1247a36fb3 100644 --- a/Content.Shared/Popups/SharedPopupSystem.cs +++ b/Content.Shared/Popups/SharedPopupSystem.cs @@ -14,7 +14,8 @@ namespace Content.Shared.Popups /// /// The message to display. /// Filter for the players that will see the popup. - public abstract void PopupCursor(string message, Filter filter); + /// Used to customize how this popup should appear visually. + public abstract void PopupCursor(string message, Filter filter, PopupType type=PopupType.Small); /// /// Shows a popup at a world location. @@ -22,7 +23,8 @@ namespace Content.Shared.Popups /// The message to display. /// The coordinates where to display the message. /// Filter for the players that will see the popup. - public abstract void PopupCoordinates(string message, EntityCoordinates coordinates, Filter filter); + /// Used to customize how this popup should appear visually. + public abstract void PopupCoordinates(string message, EntityCoordinates coordinates, Filter filter, PopupType type=PopupType.Small); /// /// Shows a popup above an entity. @@ -30,7 +32,8 @@ namespace Content.Shared.Popups /// The message to display. /// The UID of the entity. /// Filter for the players that will see the popup. - public abstract void PopupEntity(string message, EntityUid uid, Filter filter); + /// Used to customize how this popup should appear visually. + public abstract void PopupEntity(string message, EntityUid uid, Filter filter, PopupType type=PopupType.Small); } /// @@ -41,9 +44,12 @@ namespace Content.Shared.Popups { public string Message { get; } - protected PopupEvent(string message) + public PopupType Type { get; } + + protected PopupEvent(string message, PopupType type) { Message = message; + Type = type; } } @@ -53,7 +59,7 @@ namespace Content.Shared.Popups [Serializable, NetSerializable] public sealed class PopupCursorEvent : PopupEvent { - public PopupCursorEvent(string message) : base(message) + public PopupCursorEvent(string message, PopupType type) : base(message, type) { } } @@ -66,7 +72,7 @@ namespace Content.Shared.Popups { public EntityCoordinates Coordinates { get; } - public PopupCoordinatesEvent(string message, EntityCoordinates coordinates) : base(message) + public PopupCoordinatesEvent(string message, PopupType type, EntityCoordinates coordinates) : base(message, type) { Coordinates = coordinates; } @@ -80,9 +86,41 @@ namespace Content.Shared.Popups { public EntityUid Uid { get; } - public PopupEntityEvent(string message, EntityUid uid) : base(message) + public PopupEntityEvent(string message, PopupType type, EntityUid uid) : base(message, type) { Uid = uid; } } + + /// + /// Used to determine how a popup should appear visually to the client. + /// + /// + /// Actions which can fail or succeed should use a smaller popup for failure and a larger popup for success. + /// Actions which have different popups for the user vs. others should use a larger popup for the user and a smaller popup for others. + /// Actions which result in immediate death for a user should almost always show as critical to all parties, such as suicides or smites. + /// + [Serializable, NetSerializable] + public enum PopupType : byte + { + /// + /// Small popups are the default, and denote actions that may be spammable or are otherwise unimportant. + /// + Small, + /// + /// Medium popups should be used for actions which are not spammable but may not be particularly important. + /// + Medium, + /// + /// Large popups should be used for actions which may be important or very important to one or more users, + /// but is not life-threatening. + /// + Large, + /// + /// Critical popups should be used very sparingly, should not be used on anything that is spammable, + /// and should primarily be used when showing popups to one user. Critical popups denote actions which + /// may be directly life-threatening. + /// + Critical + } } diff --git a/Resources/Prototypes/Diseases/infectious.yml b/Resources/Prototypes/Diseases/infectious.yml index 73ef5e2c00..2a6cc73b45 100644 --- a/Resources/Prototypes/Diseases/infectious.yml +++ b/Resources/Prototypes/Diseases/infectious.yml @@ -30,6 +30,7 @@ - !type:DiseasePopUp probability: 0.025 message: generic-reagent-effect-burning-insides + visualType: Medium - !type:DiseaseSnough probability: 0.025 snoughMessage: disease-cough @@ -122,9 +123,11 @@ probability: 0.015 type: Pvs message: disease-beat-chest-compulsion + visualType: Medium - !type:DiseasePopUp probability: 0.03 message: disease-banana-compulsion + visualType: Medium - !type:DiseaseSnough probability: 0.02 snoughMessage: disease-screech @@ -160,6 +163,7 @@ - !type:DiseasePopUp probability: 0.05 message: disease-eaten-inside + visualType: Medium cures: - !type:DiseaseJustWaitCure maxLength: 900 diff --git a/Resources/Prototypes/Entities/Mobs/Species/slime.yml b/Resources/Prototypes/Entities/Mobs/Species/slime.yml index b1e6825e3a..2c464a9c67 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/slime.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/slime.yml @@ -140,6 +140,7 @@ Heat: 2 - !type:PopupMessage type: Local + visualType: Large messages: [ "slime-hurt-by-water-popup" ] probability: 0.25 - type: Butcherable diff --git a/Resources/Prototypes/Reagents/cleaning.yml b/Resources/Prototypes/Reagents/cleaning.yml index e5b08a194f..749e647eb2 100644 --- a/Resources/Prototypes/Reagents/cleaning.yml +++ b/Resources/Prototypes/Reagents/cleaning.yml @@ -15,6 +15,7 @@ Poison: 3 - !type:PopupMessage type: Local + visualType: Critical messages: [ "generic-reagent-effect-burning-insides" ] probability: 0.33 diff --git a/Resources/Prototypes/Reagents/fun.yml b/Resources/Prototypes/Reagents/fun.yml index 929a6fc3a3..5e8dbe82c8 100644 --- a/Resources/Prototypes/Reagents/fun.yml +++ b/Resources/Prototypes/Reagents/fun.yml @@ -55,6 +55,7 @@ effects: - !type:PopupMessage type: Local + visualType: Critical messages: - "buzzochloricbees-effect-oh-god-bees" - "buzzochloricbees-effect-its-the-bees" @@ -71,6 +72,7 @@ tag: Bee - !type:PopupMessage type: Local + visualType: Medium messages: - "buzzochloricbees-effect-histamine-bee-allergy" - "buzzochloricbees-effect-histamine-swells" @@ -87,6 +89,7 @@ tag: Bee - !type:PopupMessage type: Local + visualType: Medium messages: - "buzzochloricbees-effect-licoxide-electrifying" - "buzzochloricbees-effect-licoxide-shocked-by-bee-facts" diff --git a/Resources/Prototypes/Reagents/gases.yml b/Resources/Prototypes/Reagents/gases.yml index 82d5c57175..c49c17b562 100644 --- a/Resources/Prototypes/Reagents/gases.yml +++ b/Resources/Prototypes/Reagents/gases.yml @@ -194,6 +194,7 @@ min: 0.8 - !type:PopupMessage type: Local + visualType: Medium messages: [ "miasma-smell" ] probability: 0.1 conditions: diff --git a/Resources/Prototypes/Reagents/medicine.yml b/Resources/Prototypes/Reagents/medicine.yml index d89a6e26be..9ccbd2aa4e 100644 --- a/Resources/Prototypes/Reagents/medicine.yml +++ b/Resources/Prototypes/Reagents/medicine.yml @@ -380,6 +380,7 @@ amount: -10000 - !type:PopupMessage type: Local + visualType: Medium messages: [ "leporazine-effect-temperature-adjusting" ] probability: 0.2 @@ -417,6 +418,7 @@ probability: 0.2 - !type:PopupMessage type: Local + visualType: Large messages: [ "barozine-effect-skin-burning", "barozine-effect-muscle-contract" ] probability: 0.1 diff --git a/Resources/Prototypes/Reagents/narcotics.yml b/Resources/Prototypes/Reagents/narcotics.yml index 17099952dd..be32afe89d 100644 --- a/Resources/Prototypes/Reagents/narcotics.yml +++ b/Resources/Prototypes/Reagents/narcotics.yml @@ -73,6 +73,7 @@ time: 1 type: Remove - !type:PopupMessage + visualType: Medium messages: ["ephedrine-effect-tight-pain", "ephedrine-effect-heart-pounds"] type: Local probability: 0.05 diff --git a/Resources/Prototypes/Reagents/pyrotechnic.yml b/Resources/Prototypes/Reagents/pyrotechnic.yml index cc5b88d208..c8ca9f5b86 100644 --- a/Resources/Prototypes/Reagents/pyrotechnic.yml +++ b/Resources/Prototypes/Reagents/pyrotechnic.yml @@ -116,6 +116,7 @@ probability: 0.2 - !type:PopupMessage messages: [ "clf3-it-burns", "clf3-get-away" ] + visualType: Critical probability: 0.3 type: Local diff --git a/Resources/Prototypes/Reagents/toxins.yml b/Resources/Prototypes/Reagents/toxins.yml index eb60f3ea27..b675b59b0a 100644 --- a/Resources/Prototypes/Reagents/toxins.yml +++ b/Resources/Prototypes/Reagents/toxins.yml @@ -39,6 +39,7 @@ Poison: 4 - !type:PopupMessage type: Local + visualType: Critical messages: [ "generic-reagent-effect-burning-insides" ] probability: 0.33 @@ -106,6 +107,7 @@ Caustic: 2 - !type:PopupMessage type: Local + visualType: Large messages: [ "generic-reagent-effect-burning-insides" ] probability: 0.33 @@ -139,6 +141,7 @@ Caustic: 2 - !type:PopupMessage type: Local + visualType: Large messages: [ "generic-reagent-effect-burning-insides" ] probability: 0.33 @@ -179,6 +182,7 @@ Poison: 2 - !type:PopupMessage type: Local + visualType: Large messages: [ "generic-reagent-effect-burning-insides" ] probability: 0.33 @@ -281,6 +285,7 @@ - !type:ReagentThreshold min: 45 type: Local + visualType: Medium messages: [ "histamine-effect-heavy-itchiness" ] probability: 0.2 diff --git a/Resources/Prototypes/Recipes/Reactions/pyrotechnic.yml b/Resources/Prototypes/Recipes/Reactions/pyrotechnic.yml index 4112b9994c..392ba6c91a 100644 --- a/Resources/Prototypes/Recipes/Reactions/pyrotechnic.yml +++ b/Resources/Prototypes/Recipes/Reactions/pyrotechnic.yml @@ -23,6 +23,7 @@ - !type:CreateGas gas: Plasma - !type:PopupMessage + visualType: Critical messages: [ "phlogiston-plasma-created" ] type: Pvs products: @@ -47,5 +48,6 @@ - !type:PopupMessage messages: [ "clf3-explosion" ] type: Pvs + visualType: Critical products: ChlorineTrifluoride: 4 diff --git a/SpaceStation14.sln.DotSettings b/SpaceStation14.sln.DotSettings index 21399c2074..52e8e3b3ac 100644 --- a/SpaceStation14.sln.DotSettings +++ b/SpaceStation14.sln.DotSettings @@ -534,6 +534,7 @@ public sealed class $CLASS$ : Shared$CLASS$ { True True True + True True True True