diff --git a/Content.Client/Chat/ChatManager.cs b/Content.Client/Chat/ChatManager.cs index 1cf96367a6..21be7769ae 100644 --- a/Content.Client/Chat/ChatManager.cs +++ b/Content.Client/Chat/ChatManager.cs @@ -323,8 +323,6 @@ namespace Content.Client.Chat private void _onChatMessage(MsgChatMessage msg) { - Logger.Debug($"{msg.Channel}: {msg.Message}"); - // Log all incoming chat to repopulate when filter is un-toggled var storedMessage = new StoredChatMessage(msg); filteredHistory.Add(storedMessage); diff --git a/Content.Client/GameTicking/ClientGameTicker.cs b/Content.Client/GameTicking/ClientGameTicker.cs index a80f606215..cab0608a93 100644 --- a/Content.Client/GameTicking/ClientGameTicker.cs +++ b/Content.Client/GameTicking/ClientGameTicker.cs @@ -3,6 +3,8 @@ using Content.Client.Interfaces; using Content.Client.State; using Content.Client.UserInterface; using Content.Shared; +using Content.Shared.Network.NetMessages; +using Robust.Client.Interfaces.Graphics; using Robust.Client.Interfaces.State; using Robust.Shared.Interfaces.Network; using Robust.Shared.IoC; @@ -39,6 +41,10 @@ namespace Content.Client.GameTicking _netManager.RegisterNetMessage(nameof(MsgTickerLobbyInfo), LobbyInfo); _netManager.RegisterNetMessage(nameof(MsgTickerLobbyCountdown), LobbyCountdown); _netManager.RegisterNetMessage(nameof(MsgRoundEndMessage), RoundEnd); + _netManager.RegisterNetMessage(nameof(MsgRequestWindowAttention), msg => + { + IoCManager.Resolve().RequestWindowAttention(); + }); _initialized = true; } diff --git a/Content.Client/Input/ContentContexts.cs b/Content.Client/Input/ContentContexts.cs index 1250627a4f..89ddd64268 100644 --- a/Content.Client/Input/ContentContexts.cs +++ b/Content.Client/Input/ContentContexts.cs @@ -19,6 +19,7 @@ namespace Content.Client.Input common.AddFunction(ContentKeyFunctions.OpenTutorial); common.AddFunction(ContentKeyFunctions.TakeScreenshot); common.AddFunction(ContentKeyFunctions.TakeScreenshotNoUI); + common.AddFunction(ContentKeyFunctions.Point); var human = contexts.GetContext("human"); human.AddFunction(ContentKeyFunctions.SwapHands); @@ -37,9 +38,6 @@ namespace Content.Client.Input human.AddFunction(ContentKeyFunctions.MouseMiddle); human.AddFunction(ContentKeyFunctions.ToggleCombatMode); human.AddFunction(ContentKeyFunctions.WideAttack); - human.AddFunction(ContentKeyFunctions.Point); - human.AddFunction(ContentKeyFunctions.TryPullObject); - human.AddFunction(ContentKeyFunctions.MovePulledObject); var ghost = contexts.New("ghost", "common"); ghost.AddFunction(EngineKeyFunctions.MoveUp); diff --git a/Content.Client/State/GameScreenBase.cs b/Content.Client/State/GameScreenBase.cs index 1372dacce5..64e62d2b16 100644 --- a/Content.Client/State/GameScreenBase.cs +++ b/Content.Client/State/GameScreenBase.cs @@ -226,7 +226,10 @@ namespace Content.Client.State // client side command handlers will always be sent the local player session. var session = PlayerManager.LocalPlayer.Session; - inputSys.HandleInputCommand(session, func, message); + if (inputSys.HandleInputCommand(session, func, message)) + { + args.Handle(); + } } } } diff --git a/Content.Server/Atmos/TileAtmosphere.cs b/Content.Server/Atmos/TileAtmosphere.cs index 8e634a1c7d..cddfc3ee96 100644 --- a/Content.Server/Atmos/TileAtmosphere.cs +++ b/Content.Server/Atmos/TileAtmosphere.cs @@ -332,32 +332,40 @@ namespace Content.Server.Atmos var tile = tiles[i]; tile._tileAtmosInfo.FastDone = true; if (!(tile._tileAtmosInfo.MoleDelta > 0)) continue; - var eligibleDirections = new List(); - var amtEligibleAdj = 0; + var eligibleDirections = ArrayPool.Shared.Rent(4); + var eligibleDirectionCount = 0; foreach (var direction in Cardinal) { if (!tile._adjacentTiles.TryGetValue(direction, out var tile2)) continue; - // skip anything that isn't part of our current processing block. Original one didn't do this unfortunately, which probably cause some massive lag. + // skip anything that isn't part of our current processing block. if (tile2._tileAtmosInfo.FastDone || tile2._tileAtmosInfo.LastQueueCycle != queueCycle) continue; - eligibleDirections.Add(direction); - amtEligibleAdj++; + eligibleDirections[eligibleDirectionCount++] = direction; } - if (amtEligibleAdj <= 0) + if (eligibleDirectionCount <= 0) continue; // Oof we've painted ourselves into a corner. Bad luck. Next part will handle this. - var molesToMove = tile._tileAtmosInfo.MoleDelta / amtEligibleAdj; + var molesToMove = tile._tileAtmosInfo.MoleDelta / eligibleDirectionCount; foreach (var direction in Cardinal) { - if (eligibleDirections.Contains(direction) || - !tile._adjacentTiles.TryGetValue(direction, out var tile2)) continue; + var hasDirection = false; + for (var j = 0; j < eligibleDirectionCount; j++) + { + if (eligibleDirections[j] != direction) continue; + hasDirection = true; + break; + } + + if (hasDirection || !tile._adjacentTiles.TryGetValue(direction, out var tile2)) continue; tile.AdjustEqMovement(direction, molesToMove); tile._tileAtmosInfo.MoleDelta -= molesToMove; tile2._tileAtmosInfo.MoleDelta += molesToMove; } + + ArrayPool.Shared.Return(eligibleDirections); } giverTilesLength = 0; @@ -446,7 +454,7 @@ namespace Content.Server.Atmos } } - ArrayPool.Shared.Return(queue, true); + ArrayPool.Shared.Return(queue); } else { @@ -516,7 +524,7 @@ namespace Content.Server.Atmos } } - ArrayPool.Shared.Return(queue, true); + ArrayPool.Shared.Return(queue); } for (var i = 0; i < tileCount; i++) @@ -537,9 +545,9 @@ namespace Content.Server.Atmos } } - ArrayPool.Shared.Return(tiles, true); - ArrayPool.Shared.Return(giverTiles, true); - ArrayPool.Shared.Return(takerTiles, true); + ArrayPool.Shared.Return(tiles); + ArrayPool.Shared.Return(giverTiles); + ArrayPool.Shared.Return(takerTiles); } } @@ -925,16 +933,22 @@ namespace Content.Server.Atmos public void ExplosivelyDepressurize(int cycleNum) { if (Air == null) return; + + const int limit = Atmospherics.ZumosTileLimit; + var totalGasesRemoved = 0f; var queueCycle = ++_gridAtmosphereComponent.EqualizationQueueCycleControl; - var tiles = new List(); - var spaceTiles = new List(); - tiles.Add(this); + var tiles = ArrayPool.Shared.Rent(limit); + var spaceTiles = ArrayPool.Shared.Rent(limit); + + var tileCount = 0; + var spaceTileCount = 0; + + tiles[tileCount++] = this; ResetTileAtmosInfo(); _tileAtmosInfo.LastQueueCycle = queueCycle; - var tileCount = 1; for (var i = 0; i < tileCount; i++) { var tile = tiles[i]; @@ -942,40 +956,44 @@ namespace Content.Server.Atmos tile._tileAtmosInfo.CurrentTransferDirection = Direction.Invalid; if (tile.Air.Immutable) { - spaceTiles.Add(tile); + spaceTiles[spaceTileCount++] = tile; tile.PressureSpecificTarget = tile; } else { - if (i > Atmospherics.ZumosTileLimit) continue; foreach (var direction in Cardinal) { if (!tile._adjacentTiles.TryGetValue(direction, out var tile2)) continue; - if (tile2?.Air == null) continue; + if (tile2.Air == null) continue; if (tile2._tileAtmosInfo.LastQueueCycle == queueCycle) continue; + tile.ConsiderFirelocks(tile2); - if (tile._adjacentTiles[direction]?.Air != null) - { - tile2.ResetTileAtmosInfo(); - tile2._tileAtmosInfo.LastQueueCycle = queueCycle; - tiles.Add(tile2); - tileCount++; - } + + // The firelocks might have closed on us. + if (tile._adjacentTiles[direction]?.Air == null) continue; + tile2.ResetTileAtmosInfo(); + tile2._tileAtmosInfo.LastQueueCycle = queueCycle; + tiles[tileCount++] = tile2; } } + + if (tileCount >= limit || spaceTileCount >= limit) + break; } var queueCycleSlow = ++_gridAtmosphereComponent.EqualizationQueueCycleControl; - var progressionOrder = new List(); - foreach (var tile in spaceTiles) + var progressionOrder = ArrayPool.Shared.Rent(limit * 2); + var progressionCount = 0; + + for (var i = 0; i < spaceTileCount; i++) { - progressionOrder.Add(tile); + var tile = spaceTiles[i]; + progressionOrder[progressionCount++] = tile; tile._tileAtmosInfo.LastSlowQueueCycle = queueCycleSlow; tile._tileAtmosInfo.CurrentTransferDirection = Direction.Invalid; } - var progressionCount = progressionOrder.Count; - for (int i = 0; i < progressionCount; i++) + for (var i = 0; i < progressionCount; i++) { var tile = progressionOrder[i]; foreach (var direction in Cardinal) @@ -988,8 +1006,7 @@ namespace Content.Server.Atmos tile2._tileAtmosInfo.CurrentTransferAmount = 0; tile2.PressureSpecificTarget = tile.PressureSpecificTarget; tile2._tileAtmosInfo.LastSlowQueueCycle = queueCycleSlow; - progressionOrder.Add(tile2); - progressionCount++; + progressionOrder[progressionCount++] = tile2; } } @@ -1017,6 +1034,10 @@ namespace Content.Server.Atmos tile.UpdateVisuals(); tile.HandleDecompressionFloorRip(sum); } + + ArrayPool.Shared.Return(tiles); + ArrayPool.Shared.Return(spaceTiles); + ArrayPool.Shared.Return(progressionOrder); } private void HandleDecompressionFloorRip(float sum) @@ -1029,7 +1050,6 @@ namespace Content.Server.Atmos private void ConsiderFirelocks(TileAtmosphere other) { // TODO ATMOS firelocks! - //throw new NotImplementedException(); } private void React() diff --git a/Content.Server/Chat/ChatCommands.cs b/Content.Server/Chat/ChatCommands.cs index 9d3ff7c995..a6c5404f59 100644 --- a/Content.Server/Chat/ChatCommands.cs +++ b/Content.Server/Chat/ChatCommands.cs @@ -1,10 +1,12 @@ -using System.Linq; +using System; +using System.Linq; using Content.Server.GameObjects.Components.Damage; using Content.Server.GameObjects.Components.GUI; using Content.Server.GameObjects.Components.Items.Storage; using Content.Server.GameObjects.Components.Observer; using Content.Server.Interfaces.Chat; using Content.Server.Interfaces.GameObjects; +using Content.Server.Observer; using Content.Server.Players; using Content.Shared.GameObjects.Components.Damage; using Robust.Server.Interfaces.Console; @@ -168,6 +170,10 @@ namespace Content.Server.Chat // Default suicide, bite your tongue chat.EntityMe(owner, Loc.GetString("is attempting to bite {0:their} own tongue, looks like {0:theyre} trying to commit suicide!", owner)); //TODO: theyre macro dmgComponent.TakeDamage(DamageType.Brute, 500, owner, owner); //TODO: dmg value needs to be a max damage of some sorts + + // Prevent the player from returning to the body. Yes, this is an ugly hack. + var ghost = new Ghost(){CanReturn = false}; + ghost.Execute(shell, player, Array.Empty()); } } } diff --git a/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs b/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs index bcd49e5c89..7f4228b272 100644 --- a/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs +++ b/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs @@ -58,8 +58,7 @@ namespace Content.Server.GameObjects.Components.Doors private const float DoorStunTime = 5f; protected bool Safety = true; - [ViewVariables] - private bool _occludes; + [ViewVariables] private bool _occludes; public override void ExposeData(ObjectSerializer serializer) { @@ -111,18 +110,25 @@ namespace Content.Server.GameObjects.Components.Doors { return; } + + // Disabled because it makes it suck hard to walk through double doors. + if (entity.HasComponent(typeof(SpeciesComponent))) { if (!entity.TryGetComponent(out var mover)) return; + /* // TODO: temporary hack to fix the physics system raising collision events akwardly. // E.g. when moving parallel to a door by going off the side of a wall. var (walking, sprinting) = mover.VelocityDir; // Also TODO: walking and sprint dir are added together here // instead of calculating their contribution correctly. var dotProduct = Vector2.Dot((sprinting + walking).Normalized, (entity.Transform.WorldPosition - Owner.Transform.WorldPosition).Normalized); - if (dotProduct <= -0.9f) + if (dotProduct <= -0.85f) TryOpen(entity); + */ + + TryOpen(entity); } } @@ -144,6 +150,7 @@ namespace Content.Server.GameObjects.Components.Doors { return true; } + return accessReader.IsAllowed(user); } @@ -204,6 +211,7 @@ namespace Content.Server.GameObjects.Components.Doors { return true; } + return accessReader.IsAllowed(user); } @@ -214,6 +222,7 @@ namespace Content.Server.GameObjects.Components.Doors Deny(); return; } + Close(); } @@ -242,6 +251,7 @@ namespace Content.Server.GameObjects.Components.Doors stun.Paralyze(DoorStunTime); hitSomeone = true; } + // If we hit someone, open up after stun (opens right when stun ends) if (hitSomeone) { diff --git a/Content.Server/GameObjects/Components/GUI/HandsComponent.cs b/Content.Server/GameObjects/Components/GUI/HandsComponent.cs index ea75c7f382..6336845970 100644 --- a/Content.Server/GameObjects/Components/GUI/HandsComponent.cs +++ b/Content.Server/GameObjects/Components/GUI/HandsComponent.cs @@ -11,14 +11,16 @@ using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces.GameObjects.Components.Items; using Content.Shared.GameObjects.Components.Items; using Content.Shared.GameObjects.Components.Mobs; +using Content.Shared.GameObjects.EntitySystems; using Content.Shared.Health.BodySystem; -using Content.Shared.Physics; +using Content.Shared.Physics.Pull; using Robust.Server.GameObjects; using Robust.Server.GameObjects.Components.Container; using Robust.Server.GameObjects.EntitySystemMessages; using Robust.Shared.Containers; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Components; +using Robust.Shared.GameObjects.Components.Transform; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Network; using Robust.Shared.IoC; @@ -140,11 +142,11 @@ namespace Content.Server.GameObjects.Components.GUI } } - public bool PutInHand(ItemComponent item) + public bool PutInHand(ItemComponent item, bool mobCheck = true) { foreach (var hand in ActivePriorityEnumerable()) { - if (PutInHand(item, hand, false)) + if (PutInHand(item, hand, false, mobCheck)) { OnItemChanged?.Invoke(); @@ -155,10 +157,10 @@ namespace Content.Server.GameObjects.Components.GUI return false; } - public bool PutInHand(ItemComponent item, string index, bool fallback = true) + public bool PutInHand(ItemComponent item, string index, bool fallback = true, bool mobChecks = true) { var hand = GetHand(index); - if (!CanPutInHand(item, index) || hand == null) + if (!CanPutInHand(item, index, mobChecks) || hand == null) { return fallback && PutInHand(item); } @@ -176,19 +178,23 @@ namespace Content.Server.GameObjects.Components.GUI return success; } - public void PutInHandOrDrop(ItemComponent item) + public void PutInHandOrDrop(ItemComponent item, bool mobCheck = true) { - if (!PutInHand(item)) + if (!PutInHand(item, mobCheck)) { item.Owner.Transform.GridPosition = Owner.Transform.GridPosition; } } - public bool CanPutInHand(ItemComponent item) + public bool CanPutInHand(ItemComponent item, bool mobCheck = true) { + if (mobCheck && !ActionBlockerSystem.CanPickup(Owner)) + return false; + foreach (var handName in ActivePriorityEnumerable()) { - if (CanPutInHand(item, handName)) + // We already did a mobCheck, so let's not waste cycles. + if (CanPutInHand(item, handName, false)) { return true; } @@ -197,8 +203,11 @@ namespace Content.Server.GameObjects.Components.GUI return false; } - public bool CanPutInHand(ItemComponent item, string index) + public bool CanPutInHand(ItemComponent item, string index, bool mobCheck = true) { + if (mobCheck && !ActionBlockerSystem.CanPickup(Owner)) + return false; + return GetHand(index)?.Container.CanInsert(item.Owner) == true; } @@ -284,17 +293,17 @@ namespace Content.Server.GameObjects.Components.GUI return Drop(slot, coords, doMobChecks); } - public bool Drop(string slot, bool doMobChecks = true) + public bool Drop(string slot, bool mobChecks = true) { var hand = GetHand(slot); - if (!CanDrop(slot) || hand?.Entity == null) + if (!CanDrop(slot, mobChecks) || hand?.Entity == null) { return false; } var item = hand.Entity.GetComponent(); - if (!DroppedInteraction(item, doMobChecks)) + if (!DroppedInteraction(item, mobChecks)) return false; if (!hand.Container.Remove(hand.Entity)) @@ -321,7 +330,7 @@ namespace Content.Server.GameObjects.Components.GUI return true; } - public bool Drop(IEntity entity, bool doMobChecks = true) + public bool Drop(IEntity entity, bool mobChecks = true) { if (entity == null) { @@ -333,7 +342,7 @@ namespace Content.Server.GameObjects.Components.GUI throw new ArgumentException("Entity must be held in one of our hands.", nameof(entity)); } - return Drop(slot, doMobChecks); + return Drop(slot, mobChecks); } public bool Drop(string slot, BaseContainer targetContainer, bool doMobChecks = true) @@ -409,13 +418,15 @@ namespace Content.Server.GameObjects.Components.GUI /// /// True if there is an item in the slot and it can be dropped, false otherwise. /// - public bool CanDrop(string name) + public bool CanDrop(string name, bool mobCheck = true) { var hand = GetHand(name); - if (hand?.Entity == null) - { + + if (mobCheck && !ActionBlockerSystem.CanDrop(Owner)) + return false; + + if (hand?.Entity == null) return false; - } return hand.Container.CanRemove(hand.Entity); } @@ -537,15 +548,9 @@ namespace Content.Server.GameObjects.Components.GUI return; } - var isOwnerContained = ContainerHelpers.TryGetContainer(Owner, out var ownerContainer); - var isPullableContained = ContainerHelpers.TryGetContainer(pullable.Owner, out var pullableContainer); - - if (isOwnerContained || isPullableContained) + if (!Owner.IsInSameOrNoContainer(pullable.Owner)) { - if (ownerContainer != pullableContainer) - { - return; - } + return; } if (IsPulling) @@ -554,10 +559,8 @@ namespace Content.Server.GameObjects.Components.GUI } PulledObject = pullable.Owner.GetComponent(); - var controller = PulledObject!.EnsureController(); - controller!.StartPull(Owner.GetComponent()); - - AddPullingStatuses(); + var controller = PulledObject.EnsureController(); + controller.StartPull(Owner.GetComponent()); } public void MovePulledObject(GridCoordinates puller, GridCoordinates to) @@ -569,6 +572,46 @@ namespace Content.Server.GameObjects.Components.GUI } } + private void MoveEvent(MoveEvent moveEvent) + { + if (moveEvent.Sender != Owner) + { + return; + } + + if (!IsPulling) + { + return; + } + + PulledObject!.WakeBody(); + } + + public override void HandleMessage(ComponentMessage message, IComponent? component) + { + base.HandleMessage(message, component); + + if (!(message is PullMessage pullMessage) || + pullMessage.Puller.Owner != Owner) + { + return; + } + + switch (message) + { + case PullStartedMessage msg: + Owner.EntityManager.EventBus.SubscribeEvent(EventSource.Local, this, MoveEvent); + + AddPullingStatuses(msg.Pulled.Owner); + break; + case PullStoppedMessage msg: + Owner.EntityManager.EventBus.UnsubscribeEvent(EventSource.Local, this); + + RemovePullingStatuses(msg.Pulled.Owner); + break; + } + } + public override void HandleNetworkMessage(ComponentMessage message, INetChannel channel, ICommonSession? session = null) { base.HandleNetworkMessage(message, channel, session); @@ -679,10 +722,9 @@ namespace Content.Server.GameObjects.Components.GUI } } - private void AddPullingStatuses() + private void AddPullingStatuses(IEntity pulled) { - if (PulledObject?.Owner != null && - PulledObject.Owner.TryGetComponent(out ServerStatusEffectsComponent pulledStatus)) + if (pulled.TryGetComponent(out ServerStatusEffectsComponent pulledStatus)) { pulledStatus.ChangeStatusEffectIcon(StatusEffect.Pulled, "/Textures/Interface/StatusEffects/Pull/pulled.png"); @@ -695,10 +737,9 @@ namespace Content.Server.GameObjects.Components.GUI } } - private void RemovePullingStatuses() + private void RemovePullingStatuses(IEntity pulled) { - if (PulledObject?.Owner != null && - PulledObject.Owner.TryGetComponent(out ServerStatusEffectsComponent pulledStatus)) + if (pulled.TryGetComponent(out ServerStatusEffectsComponent pulledStatus)) { pulledStatus.RemoveStatusEffect(StatusEffect.Pulled); } @@ -709,12 +750,6 @@ namespace Content.Server.GameObjects.Components.GUI } } - public override void StopPull() - { - RemovePullingStatuses(); - base.StopPull(); - } - void IBodyPartAdded.BodyPartAdded(BodyPartAddedEventArgs eventArgs) { if (eventArgs.Part.PartType != BodyPartType.Hand) diff --git a/Content.Server/GameObjects/Components/GUI/InventoryComponent.cs b/Content.Server/GameObjects/Components/GUI/InventoryComponent.cs index 1d1e52b6a2..57ab715eb5 100644 --- a/Content.Server/GameObjects/Components/GUI/InventoryComponent.cs +++ b/Content.Server/GameObjects/Components/GUI/InventoryComponent.cs @@ -173,9 +173,10 @@ namespace Content.Server.GameObjects.Components.GUI /// /// The slot to put the item in. /// The item to insert into the slot. + /// Whether to perform an ActionBlocker check to the entity. /// The translated reason why the item cannot be equipped, if this function returns false. Can be null. /// True if the item was successfully inserted, false otherwise. - public bool Equip(Slots slot, ItemComponent item, out string reason) + public bool Equip(Slots slot, ItemComponent item, bool mobCheck, out string reason) { if (item == null) { @@ -183,7 +184,7 @@ namespace Content.Server.GameObjects.Components.GUI "Clothing must be passed here. To remove some clothing from a slot, use Unequip()"); } - if (!CanEquip(slot, item, out reason)) + if (!CanEquip(slot, item, mobCheck, out reason)) { return false; } @@ -203,9 +204,9 @@ namespace Content.Server.GameObjects.Components.GUI return true; } - public bool Equip(Slots slot, ItemComponent item) => Equip(slot, item, out var _); + public bool Equip(Slots slot, ItemComponent item, bool mobCheck = true) => Equip(slot, item, mobCheck, out var _); - public bool Equip(Slots slot, IEntity entity) => Equip(slot, entity.GetComponent()); + public bool Equip(Slots slot, IEntity entity, bool mobCheck = true) => Equip(slot, entity.GetComponent(), mobCheck); /// /// Checks whether an item can be put in the specified slot. @@ -214,12 +215,12 @@ namespace Content.Server.GameObjects.Components.GUI /// The item to check for. /// The translated reason why the item cannot be equiped, if this function returns false. Can be null. /// True if the item can be inserted into the specified slot. - public bool CanEquip(Slots slot, ItemComponent item, out string reason) + public bool CanEquip(Slots slot, ItemComponent item, bool mobCheck, out string reason) { var pass = false; reason = null; - if (!ActionBlockerSystem.CanEquip(Owner)) + if (mobCheck && !ActionBlockerSystem.CanEquip(Owner)) return false; if (item is ClothingComponent clothing) @@ -248,18 +249,19 @@ namespace Content.Server.GameObjects.Components.GUI return pass && _slotContainers[slot].CanInsert(item.Owner); } - public bool CanEquip(Slots slot, ItemComponent item) => CanEquip(slot, item, out var _); + public bool CanEquip(Slots slot, ItemComponent item, bool mobCheck = true) => CanEquip(slot, item, mobCheck, out var _); - public bool CanEquip(Slots slot, IEntity entity) => CanEquip(slot, entity.GetComponent()); + public bool CanEquip(Slots slot, IEntity entity, bool mobCheck = true) => CanEquip(slot, entity.GetComponent(), mobCheck); /// /// Drops the item in a slot. /// /// The slot to drop the item from. /// True if an item was dropped, false otherwise. - public bool Unequip(Slots slot) + /// Whether to perform an ActionBlocker check to the entity. + public bool Unequip(Slots slot, bool mobCheck = true) { - if (!CanUnequip(slot)) + if (!CanUnequip(slot, mobCheck)) { return false; } @@ -288,16 +290,17 @@ namespace Content.Server.GameObjects.Components.GUI /// Checks whether an item can be dropped from the specified slot. /// /// The slot to check for. + /// Whether to perform an ActionBlocker check to the entity. /// /// True if there is an item in the slot and it can be dropped, false otherwise. /// - public bool CanUnequip(Slots slot) + public bool CanUnequip(Slots slot, bool mobCheck = true) { - if (!ActionBlockerSystem.CanUnequip(Owner)) + if (mobCheck && !ActionBlockerSystem.CanUnequip(Owner)) return false; - var InventorySlot = _slotContainers[slot]; - return InventorySlot.ContainedEntity != null && InventorySlot.CanRemove(InventorySlot.ContainedEntity); + var inventorySlot = _slotContainers[slot]; + return inventorySlot.ContainedEntity != null && inventorySlot.CanRemove(inventorySlot.ContainedEntity); } /// @@ -398,7 +401,7 @@ namespace Content.Server.GameObjects.Components.GUI if (activeHand != null && activeHand.Owner.TryGetComponent(out ItemComponent clothing)) { hands.Drop(hands.ActiveHand); - if (!Equip(msg.Inventoryslot, clothing, out var reason)) + if (!Equip(msg.Inventoryslot, clothing, true, out var reason)) { hands.PutInHand(clothing); @@ -434,7 +437,7 @@ namespace Content.Server.GameObjects.Components.GUI var activeHand = hands.GetActiveHand; if (activeHand != null && GetSlotItem(msg.Inventoryslot) == null) { - var canEquip = CanEquip(msg.Inventoryslot, activeHand, out var reason); + var canEquip = CanEquip(msg.Inventoryslot, activeHand, true, out var reason); _hoverEntity = new KeyValuePair(msg.Inventoryslot, (activeHand.Owner.Uid, canEquip)); Dirty(); diff --git a/Content.Server/GameObjects/Components/GUI/StrippableComponent.cs b/Content.Server/GameObjects/Components/GUI/StrippableComponent.cs index e045fd2b5a..0363fee424 100644 --- a/Content.Server/GameObjects/Components/GUI/StrippableComponent.cs +++ b/Content.Server/GameObjects/Components/GUI/StrippableComponent.cs @@ -137,7 +137,7 @@ namespace Content.Server.GameObjects.Components.GUI return false; } - if (!inventory.CanEquip(slot, item)) + if (!inventory.CanEquip(slot, item, false)) { _notifyManager.PopupMessageCursor(user, Loc.GetString("{0:They} cannot equip that there!", Owner)); return false; @@ -162,7 +162,7 @@ namespace Content.Server.GameObjects.Components.GUI if (result != DoAfterStatus.Finished) return; userHands.Drop(item!.Owner, false); - inventory.Equip(slot, item!.Owner); + inventory.Equip(slot, item!.Owner, false); UpdateSubscribed(); } @@ -202,7 +202,7 @@ namespace Content.Server.GameObjects.Components.GUI return false; } - if (!hands.CanPutInHand(item, hand)) + if (!hands.CanPutInHand(item, hand, false)) { _notifyManager.PopupMessageCursor(user, Loc.GetString("{0:They} cannot put that there!", Owner)); return false; @@ -227,7 +227,7 @@ namespace Content.Server.GameObjects.Components.GUI if (result != DoAfterStatus.Finished) return; userHands.Drop(hand, false); - hands.PutInHand(item, hand, false); + hands.PutInHand(item!, hand, false, false); UpdateSubscribed(); } @@ -253,7 +253,7 @@ namespace Content.Server.GameObjects.Components.GUI return false; } - if (!inventory.CanUnequip(slot)) + if (!inventory.CanUnequip(slot, false)) { _notifyManager.PopupMessageCursor(user, Loc.GetString("{0:They} cannot unequip that!", Owner)); return false; @@ -277,7 +277,7 @@ namespace Content.Server.GameObjects.Components.GUI if (result != DoAfterStatus.Finished) return; var item = inventory.GetSlotItem(slot); - inventory.Unequip(slot); + inventory.Unequip(slot, false); userHands.PutInHandOrDrop(item); UpdateSubscribed(); } @@ -304,7 +304,7 @@ namespace Content.Server.GameObjects.Components.GUI return false; } - if (!hands.CanDrop(hand)) + if (!hands.CanDrop(hand, false)) { _notifyManager.PopupMessageCursor(user, Loc.GetString("{0:They} cannot drop that!", Owner)); return false; @@ -329,7 +329,7 @@ namespace Content.Server.GameObjects.Components.GUI var item = hands.GetItem(hand); hands.Drop(hand, false); - userHands.PutInHandOrDrop(item); + userHands.PutInHandOrDrop(item!); UpdateSubscribed(); } @@ -364,8 +364,6 @@ namespace Content.Server.GameObjects.Components.GUI else TakeItemFromHands(user, handMessage.Hand); break; - default: - break; } } } diff --git a/Content.Server/GameObjects/Components/Items/Clothing/ClothingComponent.cs b/Content.Server/GameObjects/Components/Items/Clothing/ClothingComponent.cs index a94c5982bc..7de3236ec9 100644 --- a/Content.Server/GameObjects/Components/Items/Clothing/ClothingComponent.cs +++ b/Content.Server/GameObjects/Components/Items/Clothing/ClothingComponent.cs @@ -112,7 +112,7 @@ namespace Content.Server.GameObjects.Components.Items.Clothing private bool TryEquip(InventoryComponent inv, Slots slot, IEntity user) { - if (!inv.Equip(slot, this, out var reason)) + if (!inv.Equip(slot, this, true, out var reason)) { if (reason != null) _serverNotifyManager.PopupMessage(Owner, user, reason); diff --git a/Content.Server/GameObjects/Components/Mobs/MindComponent.cs b/Content.Server/GameObjects/Components/Mobs/MindComponent.cs index d148490bd9..fe033e2231 100644 --- a/Content.Server/GameObjects/Components/Mobs/MindComponent.cs +++ b/Content.Server/GameObjects/Components/Mobs/MindComponent.cs @@ -137,7 +137,8 @@ namespace Content.Server.GameObjects.Components.Mobs } else if (Mind?.Session == null) { - message.AddMarkup("[color=yellow]" + Loc.GetString("{0:They} {0:have} a blank, absent-minded stare and appears completely unresponsive to anything. {0:They} may snap out of it soon.", Owner) + "[/color]"); + if(!dead) + message.AddMarkup("[color=yellow]" + Loc.GetString("{0:They} {0:have} a blank, absent-minded stare and appears completely unresponsive to anything. {0:They} may snap out of it soon.", Owner) + "[/color]"); } } } diff --git a/Content.Server/GameObjects/Components/Suspicion/SuspicionRoleComponent.cs b/Content.Server/GameObjects/Components/Suspicion/SuspicionRoleComponent.cs new file mode 100644 index 0000000000..833169a223 --- /dev/null +++ b/Content.Server/GameObjects/Components/Suspicion/SuspicionRoleComponent.cs @@ -0,0 +1,42 @@ +using Content.Server.GameObjects.Components.Mobs; +using Content.Server.Mobs.Roles; +using Content.Shared.GameObjects.EntitySystems; +using Robust.Shared.GameObjects; +using Robust.Shared.Localization; +using Robust.Shared.Utility; + +namespace Content.Server.GameObjects.Components.Suspicion +{ + [RegisterComponent] + public class SuspicionRoleComponent : Component, IExamine + { + public override string Name => "SuspicionRole"; + + public bool IsDead() + { + return Owner.TryGetComponent(out SpeciesComponent species) && + species.CurrentDamageState is DeadState; + } + + public bool IsTraitor() + { + return Owner.TryGetComponent(out MindComponent mind) && + mind.HasMind && + mind.Mind!.HasRole(); + } + + void IExamine.Examine(FormattedMessage message, bool inDetailsRange) + { + if (!IsDead()) + { + return; + } + + var tooltip = IsTraitor() + ? Loc.GetString($"They were a [color=red]traitor[/color]!") + : Loc.GetString($"They were an [color=green]innocent[/color]!"); + + message.AddMarkup(tooltip); + } + } +} diff --git a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs index fd73d86a3a..8c6e8f1912 100644 --- a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs @@ -12,6 +12,7 @@ using Content.Shared.GameObjects.EntitySystems; using Content.Shared.Input; using Content.Shared.Interfaces.GameObjects.Components; using Content.Shared.Physics; +using Content.Shared.Physics.Pull; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Server.Interfaces.Player; diff --git a/Content.Server/GameObjects/EntitySystems/PointingSystem.cs b/Content.Server/GameObjects/EntitySystems/PointingSystem.cs index 898ed90475..d27857954f 100644 --- a/Content.Server/GameObjects/EntitySystems/PointingSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/PointingSystem.cs @@ -6,6 +6,7 @@ using Content.Shared.GameObjects.EntitySystems; using Content.Shared.Input; using Content.Shared.Interfaces; using JetBrains.Annotations; +using Robust.Server.GameObjects.Components; using Robust.Server.Interfaces.Player; using Robust.Server.Player; using Robust.Shared.Enums; @@ -113,7 +114,13 @@ namespace Content.Server.GameObjects.EntitySystems var viewers = _playerManager.GetPlayersInRange(player.Transform.GridPosition, 15); - EntityManager.SpawnEntity("pointingarrow", coords); + var arrow = EntityManager.SpawnEntity("pointingarrow", coords); + + if (player.TryGetComponent(out VisibilityComponent playerVisibility)) + { + var arrowVisibility = arrow.EnsureComponent(); + arrowVisibility.Layer = playerVisibility.Layer; + } string selfMessage; string viewerMessage; diff --git a/Content.Server/GameObjects/EntitySystems/VerbSystem.cs b/Content.Server/GameObjects/EntitySystems/VerbSystem.cs index 6de086226a..761681b1ac 100644 --- a/Content.Server/GameObjects/EntitySystems/VerbSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/VerbSystem.cs @@ -113,8 +113,17 @@ namespace Content.Server.GameObjects.EntitySystems if (verb.RequireInteractionRange && !VerbUtility.InVerbUseRange(userEntity, entity)) continue; - if (verb.BlockedByContainers && !userEntity.IsInSameOrNoContainer(entity)) - continue; + if (verb.BlockedByContainers) + { + if (!userEntity.IsInSameOrNoContainer(entity)) + { + if (!ContainerHelpers.TryGetContainer(entity, out var container) || + container.Owner != userEntity) + { + continue; + } + } + } var verbData = verb.GetData(userEntity, component); if (verbData.IsInvisible) diff --git a/Content.Server/GameTicking/GamePresets/PresetSuspicion.cs b/Content.Server/GameTicking/GamePresets/PresetSuspicion.cs index bd2f43a13d..fc09cc14a3 100644 --- a/Content.Server/GameTicking/GamePresets/PresetSuspicion.cs +++ b/Content.Server/GameTicking/GamePresets/PresetSuspicion.cs @@ -10,11 +10,12 @@ using Robust.Shared.Prototypes; using Robust.Shared.Random; using System.Collections.Generic; using System.Linq; +using Content.Server.GameObjects.Components.Suspicion; using Content.Shared.Roles; +using Robust.Shared.GameObjects; using Robust.Shared.Log; using Robust.Shared.Maths; - namespace Content.Server.GameTicking.GamePresets { public class PresetSuspicion : GamePreset @@ -40,6 +41,12 @@ namespace Content.Server.GameTicking.GamePresets return false; } + if (readyPlayers.Count == 0) + { + _chatManager.DispatchServerAnnouncement($"No players readied up! Can't start Suspicion."); + return false; + } + var list = new List(readyPlayers); var prefList = new List(); @@ -54,6 +61,8 @@ namespace Content.Server.GameTicking.GamePresets { prefList.Add(player); } + + player.AttachedEntity?.EnsureComponent(); } var numTraitors = FloatMath.Clamp(readyPlayers.Count % PlayersPerTraitor, diff --git a/Content.Server/GameTicking/GameRules/RuleSuspicion.cs b/Content.Server/GameTicking/GameRules/RuleSuspicion.cs index 34ddc50f78..a3d830412e 100644 --- a/Content.Server/GameTicking/GameRules/RuleSuspicion.cs +++ b/Content.Server/GameTicking/GameRules/RuleSuspicion.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading; using Content.Server.GameObjects.Components.Mobs; using Content.Server.Interfaces.Chat; @@ -7,7 +7,6 @@ using Content.Server.Mobs.Roles; using Content.Server.Players; using Robust.Server.Interfaces.Player; using Robust.Shared.GameObjects; -using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.IoC; using Timer = Robust.Shared.Timers.Timer; @@ -24,7 +23,6 @@ namespace Content.Server.GameTicking.GameRules #pragma warning disable 649 [Dependency] private readonly IPlayerManager _playerManager; [Dependency] private readonly IChatManager _chatManager; - [Dependency] private readonly IEntityManager _entityManager; [Dependency] private readonly IGameTicker _gameTicker; #pragma warning restore 649 @@ -32,28 +30,9 @@ namespace Content.Server.GameTicking.GameRules public override void Added() { - _entityManager.EventBus.SubscribeEvent(EventSource.Local, this, _onMobDamageStateChanged); - Timer.SpawnRepeating(DeadCheckDelay, _checkWinConditions, _checkTimerCancel.Token); } - private void _onMobDamageStateChanged(MobDamageStateChangedMessage message) - { - var owner = message.Species.Owner; - - if (!(message.Species.CurrentDamageState is DeadState)) - return; - - if (!owner.TryGetComponent(out var mind)) - return; - - if (!mind.HasMind) - return; - - message.Species.Owner.Description += - mind.Mind.HasRole() ? "\nThey were a traitor!" : "\nThey were an innocent!"; - } - public override void Removed() { base.Removed(); @@ -78,6 +57,7 @@ namespace Content.Server.GameTicking.GameRules { continue; } + if (playerSession.ContentData().Mind.HasRole()) traitorsAlive++; else diff --git a/Content.Server/GameTicking/GameTicker.cs b/Content.Server/GameTicking/GameTicker.cs index bef68e027d..42bd24d44c 100644 --- a/Content.Server/GameTicking/GameTicker.cs +++ b/Content.Server/GameTicking/GameTicker.cs @@ -24,6 +24,7 @@ using Content.Server.Players; using Content.Shared; using Content.Shared.Chat; using Content.Shared.GameObjects.Components.PDA; +using Content.Shared.Network.NetMessages; using Content.Shared.Preferences; using Content.Shared.Roles; using Prometheus; @@ -137,6 +138,7 @@ namespace Content.Server.GameTicking _netManager.RegisterNetMessage(nameof(MsgTickerLobbyInfo)); _netManager.RegisterNetMessage(nameof(MsgTickerLobbyCountdown)); _netManager.RegisterNetMessage(nameof(MsgRoundEndMessage)); + _netManager.RegisterNetMessage(nameof(MsgRequestWindowAttention)); SetStartPreset(_configurationManager.GetCVar("game.defaultpreset")); @@ -206,6 +208,16 @@ namespace Content.Server.GameTicking _roundStartTimeUtc = DateTime.UtcNow + LobbyDuration; _sendStatusToAll(); + + ReqWindowAttentionAll(); + } + } + + private void ReqWindowAttentionAll() + { + foreach (var player in _playerManager.GetAllPlayers()) + { + player.RequestWindowAttention(); } } @@ -284,6 +296,7 @@ namespace Content.Server.GameTicking _roundStartTimeSpan = IoCManager.Resolve().RealTime; _sendStatusToAll(); + ReqWindowAttentionAll(); } private void SendServerMessage(string message) diff --git a/Content.Server/GlobalVerbs/PullingVerb.cs b/Content.Server/GlobalVerbs/PullingVerb.cs index 0b864eb075..6213d443a5 100644 --- a/Content.Server/GlobalVerbs/PullingVerb.cs +++ b/Content.Server/GlobalVerbs/PullingVerb.cs @@ -4,6 +4,7 @@ using Content.Shared.GameObjects.Components.Items; using Content.Shared.GameObjects.EntitySystems; using Content.Shared.GameObjects.Verbs; using Content.Shared.Physics; +using Content.Shared.Physics.Pull; using Robust.Server.Interfaces.GameObjects; using Robust.Shared.GameObjects.Components; using Robust.Shared.Interfaces.GameObjects; diff --git a/Content.Server/Interfaces/GameObjects/Components/Items/IHandsComponent.cs b/Content.Server/Interfaces/GameObjects/Components/Items/IHandsComponent.cs index e716533285..5765098531 100644 --- a/Content.Server/Interfaces/GameObjects/Components/Items/IHandsComponent.cs +++ b/Content.Server/Interfaces/GameObjects/Components/Items/IHandsComponent.cs @@ -61,8 +61,9 @@ namespace Content.Server.Interfaces.GameObjects.Components.Items /// Puts an item into any empty hand, preferring the active hand. /// /// The item to put in a hand. + /// Whether to perform an ActionBlocker check to the entity. /// True if the item was inserted, false otherwise. - bool PutInHand(ItemComponent item); + bool PutInHand(ItemComponent item, bool mobCheck = true); /// /// Puts an item into a specific hand. @@ -71,24 +72,27 @@ namespace Content.Server.Interfaces.GameObjects.Components.Items /// The name of the hand to put the item into. /// /// If true and the provided hand is full, the method will fall back to + /// Whether to perform an ActionBlocker check to the entity. /// /// True if the item was inserted into a hand, false otherwise. - bool PutInHand(ItemComponent item, string index, bool fallback=true); + bool PutInHand(ItemComponent item, string index, bool fallback=true, bool mobCheck = true); /// /// Checks to see if an item can be put in any hand. /// /// The item to check for. + /// Whether to perform an ActionBlocker check to the entity. /// True if the item can be inserted, false otherwise. - bool CanPutInHand(ItemComponent item); + bool CanPutInHand(ItemComponent item, bool mobCheck = true); /// /// Checks to see if an item can be put in the specified hand. /// /// The item to check for. /// The name for the hand to check for. + /// Whether to perform an ActionBlocker check to the entity. /// True if the item can be inserted, false otherwise. - bool CanPutInHand(ItemComponent item, string index); + bool CanPutInHand(ItemComponent item, string index, bool mobCheck = true); /// /// Finds the hand slot holding the specified entity, if any. @@ -107,15 +111,15 @@ namespace Content.Server.Interfaces.GameObjects.Components.Items /// Drops the item contained in the slot to the same position as our entity. /// /// The slot of which to drop to drop the item. - /// Whether to check the for the mob or not. + /// Whether to check the for the mob or not. /// True on success, false if something blocked the drop. - bool Drop(string slot, bool doMobChecks = true); + bool Drop(string slot, bool mobChecks = true); /// /// Drops an item held by one of our hand slots to the same position as our owning entity. /// /// The item to drop. - /// Whether to check the for the mob or not. + /// Whether to check the for the mob or not. /// True on success, false if something blocked the drop. /// /// Thrown if is null. @@ -123,7 +127,7 @@ namespace Content.Server.Interfaces.GameObjects.Components.Items /// /// Thrown if is not actually held in any hand. /// - bool Drop(IEntity entity, bool doMobChecks = true); + bool Drop(IEntity entity, bool mobChecks = true); /// /// Drops the item in a slot. @@ -194,10 +198,11 @@ namespace Content.Server.Interfaces.GameObjects.Components.Items /// Checks whether the item in the specified hand can be dropped. /// /// The hand to check for. + /// Whether to perform an ActionBlocker check to the entity. /// /// True if the item can be dropped, false if the hand is empty or the item in the hand cannot be dropped. /// - bool CanDrop(string name); + bool CanDrop(string name, bool mobCheck = true); /// /// Adds a new hand to this hands component. diff --git a/Content.Server/Observer/Ghost.cs b/Content.Server/Observer/Ghost.cs index 80480b958a..004f5951ee 100644 --- a/Content.Server/Observer/Ghost.cs +++ b/Content.Server/Observer/Ghost.cs @@ -17,6 +17,7 @@ namespace Content.Server.Observer public string Command => "ghost"; public string Description => "Give up on life and become a ghost."; public string Help => "ghost"; + public bool CanReturn { get; set; } = true; public void Execute(IConsoleShell shell, IPlayerSession player, string[] args) { @@ -27,7 +28,7 @@ namespace Content.Server.Observer } var mind = player.ContentData().Mind; - var canReturn = player.AttachedEntity != null; + var canReturn = player.AttachedEntity != null && CanReturn; var name = player.AttachedEntity?.Name ?? player.Name; if (player.AttachedEntity != null && player.AttachedEntity.HasComponent()) diff --git a/Content.Server/Players/PlayerSessionExt.cs b/Content.Server/Players/PlayerSessionExt.cs new file mode 100644 index 0000000000..3b06788869 --- /dev/null +++ b/Content.Server/Players/PlayerSessionExt.cs @@ -0,0 +1,14 @@ +using Content.Shared.Network.NetMessages; +using Robust.Server.Interfaces.Player; + +namespace Content.Server.Players +{ + public static class PlayerSessionExt + { + public static void RequestWindowAttention(this IPlayerSession session) + { + var msg = session.ConnectedClient.CreateNetMessage(); + session.ConnectedClient.SendMessage(msg); + } + } +} diff --git a/Content.Shared/GameObjects/Components/Items/SharedHandsComponent.cs b/Content.Shared/GameObjects/Components/Items/SharedHandsComponent.cs index 47a15e5f10..02919bcf8e 100644 --- a/Content.Shared/GameObjects/Components/Items/SharedHandsComponent.cs +++ b/Content.Shared/GameObjects/Components/Items/SharedHandsComponent.cs @@ -1,8 +1,9 @@ #nullable enable using System; -using Content.Shared.Physics; +using Content.Shared.Physics.Pull; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Components; +using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -26,8 +27,27 @@ namespace Content.Shared.GameObjects.Components.Items { controller.StopPull(); } + } - PulledObject = null; + public override void HandleMessage(ComponentMessage message, IComponent? component) + { + base.HandleMessage(message, component); + + if (!(message is PullMessage pullMessage) || + pullMessage.Puller.Owner != Owner) + { + return; + } + + switch (message) + { + case PullStartedMessage msg: + PulledObject = msg.Pulled; + break; + case PullStoppedMessage _: + PulledObject = null; + break; + } } } diff --git a/Content.Shared/GameObjects/EntitySystems/SharedMoverSystem.cs b/Content.Shared/GameObjects/EntitySystems/SharedMoverSystem.cs index 7c9a4537a2..49f77ad735 100644 --- a/Content.Shared/GameObjects/EntitySystems/SharedMoverSystem.cs +++ b/Content.Shared/GameObjects/EntitySystems/SharedMoverSystem.cs @@ -3,6 +3,7 @@ using System.Diagnostics.CodeAnalysis; using Content.Shared.GameObjects.Components.Items; using Content.Shared.GameObjects.Components.Movement; using Content.Shared.Physics; +using Content.Shared.Physics.Pull; using Robust.Shared.Configuration; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Components; diff --git a/Content.Shared/GameObjects/Verbs/Verb.cs b/Content.Shared/GameObjects/Verbs/Verb.cs index 99cf50b24d..723f90f1f3 100644 --- a/Content.Shared/GameObjects/Verbs/Verb.cs +++ b/Content.Shared/GameObjects/Verbs/Verb.cs @@ -23,6 +23,7 @@ namespace Content.Shared.GameObjects.Verbs /// /// If true, this verb requires both the user and the entity on which /// this verb resides to be in the same container or no container. + /// OR the user can be the entity's container /// public virtual bool BlockedByContainers => true; diff --git a/Content.Shared/Network/NetMessages/MsgRequestWindowAttention.cs b/Content.Shared/Network/NetMessages/MsgRequestWindowAttention.cs new file mode 100644 index 0000000000..e14ca862e5 --- /dev/null +++ b/Content.Shared/Network/NetMessages/MsgRequestWindowAttention.cs @@ -0,0 +1,27 @@ +using Lidgren.Network; +using Robust.Shared.Interfaces.Network; +using Robust.Shared.Network; + +namespace Content.Shared.Network.NetMessages +{ + public sealed class MsgRequestWindowAttention : NetMessage + { + #region REQUIRED + + public const MsgGroups GROUP = MsgGroups.Command; + public const string NAME = nameof(MsgRequestWindowAttention); + public MsgRequestWindowAttention(INetChannel channel) : base(NAME, GROUP) { } + + #endregion + + public override void ReadFromBuffer(NetIncomingMessage buffer) + { + // Nothing + } + + public override void WriteToBuffer(NetOutgoingMessage buffer) + { + // Nothing + } + } +} diff --git a/Content.Shared/Physics/PullController.cs b/Content.Shared/Physics/Pull/PullController.cs similarity index 66% rename from Content.Shared/Physics/PullController.cs rename to Content.Shared/Physics/Pull/PullController.cs index c0ea728571..8bb76473be 100644 --- a/Content.Shared/Physics/PullController.cs +++ b/Content.Shared/Physics/Pull/PullController.cs @@ -1,15 +1,16 @@ #nullable enable using System; -using Content.Shared.GameObjects.Components.Items; using Content.Shared.GameObjects.EntitySystems; +using Robust.Shared.Containers; using Robust.Shared.GameObjects.Components; using Robust.Shared.Interfaces.Map; using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.Shared.Maths; using Robust.Shared.Physics; +using Robust.Shared.Utility; -namespace Content.Shared.Physics +namespace Content.Shared.Physics.Pull { public class PullController : VirtualController { @@ -25,15 +26,54 @@ namespace Content.Shared.Physics public ICollidableComponent? Puller => _puller; - public void StartPull(ICollidableComponent? pull) + public void StartPull(ICollidableComponent puller) { - _puller = pull; + DebugTools.AssertNotNull(puller); + + if (_puller == puller) + { + return; + } + + _puller = puller; + + if (ControlledComponent == null) + { + return; + } + + ControlledComponent.WakeBody(); + + var message = new PullStartedMessage(this, _puller, ControlledComponent); + + _puller.Owner.SendMessage(null, message); + ControlledComponent.Owner.SendMessage(null, message); } public void StopPull() { + var oldPuller = _puller; + + if (oldPuller == null) + { + return; + } + _puller = null; - ControlledComponent?.TryRemoveController(); + + if (ControlledComponent == null) + { + return; + } + + ControlledComponent.WakeBody(); + + var message = new PullStoppedMessage(this, oldPuller, ControlledComponent); + + oldPuller.Owner.SendMessage(null, message); + ControlledComponent.Owner.SendMessage(null, message); + + ControlledComponent.TryRemoveController(); } public void TryMoveTo(GridCoordinates from, GridCoordinates to) @@ -50,6 +90,8 @@ namespace Content.Shared.Physics return; } + ControlledComponent.WakeBody(); + var dist = _puller.Owner.Transform.GridPosition.Position - to.Position; if (Math.Sqrt(dist.LengthSquared) > DistBeforeStopPull || @@ -68,12 +110,18 @@ namespace Content.Shared.Physics return; } + if (!_puller.Owner.IsInSameOrNoContainer(ControlledComponent.Owner)) + { + StopPull(); + return; + } + // Are we outside of pulling range? var dist = _puller.Owner.Transform.WorldPosition - ControlledComponent.Owner.Transform.WorldPosition; if (dist.Length > DistBeforeStopPull) { - _puller.Owner.GetComponent().StopPull(); + StopPull(); } else if (_movingTo.HasValue) { diff --git a/Content.Shared/Physics/Pull/PullMessage.cs b/Content.Shared/Physics/Pull/PullMessage.cs new file mode 100644 index 0000000000..811eae404e --- /dev/null +++ b/Content.Shared/Physics/Pull/PullMessage.cs @@ -0,0 +1,19 @@ +using Robust.Shared.GameObjects; +using Robust.Shared.GameObjects.Components; + +namespace Content.Shared.Physics.Pull +{ + public class PullMessage : ComponentMessage + { + public readonly PullController Controller; + public readonly ICollidableComponent Puller; + public readonly ICollidableComponent Pulled; + + protected PullMessage(PullController controller, ICollidableComponent puller, ICollidableComponent pulled) + { + Controller = controller; + Puller = puller; + Pulled = pulled; + } + } +} diff --git a/Content.Shared/Physics/Pull/PullStartedMessage.cs b/Content.Shared/Physics/Pull/PullStartedMessage.cs new file mode 100644 index 0000000000..263c0b8db1 --- /dev/null +++ b/Content.Shared/Physics/Pull/PullStartedMessage.cs @@ -0,0 +1,12 @@ +using Robust.Shared.GameObjects.Components; + +namespace Content.Shared.Physics.Pull +{ + public class PullStartedMessage : PullMessage + { + public PullStartedMessage(PullController controller, ICollidableComponent puller, ICollidableComponent pulled) : + base(controller, puller, pulled) + { + } + } +} diff --git a/Content.Shared/Physics/Pull/PullStoppedMessage.cs b/Content.Shared/Physics/Pull/PullStoppedMessage.cs new file mode 100644 index 0000000000..c018558341 --- /dev/null +++ b/Content.Shared/Physics/Pull/PullStoppedMessage.cs @@ -0,0 +1,12 @@ +using Robust.Shared.GameObjects.Components; + +namespace Content.Shared.Physics.Pull +{ + public class PullStoppedMessage : PullMessage + { + public PullStoppedMessage(PullController controller, ICollidableComponent puller, ICollidableComponent pulled) : + base(controller, puller, pulled) + { + } + } +} diff --git a/Content.Shared/SharedGameTicker.cs b/Content.Shared/SharedGameTicker.cs index cd16b79191..669a6acb93 100644 --- a/Content.Shared/SharedGameTicker.cs +++ b/Content.Shared/SharedGameTicker.cs @@ -152,6 +152,7 @@ namespace Content.Shared } } + public struct RoundEndPlayerInfo { public string PlayerOOCName; @@ -176,7 +177,7 @@ namespace Content.Shared public TimeSpan RoundDuration; - public uint PlayerCount; + public int PlayerCount; public List AllPlayersEndInfo; @@ -189,9 +190,9 @@ namespace Content.Shared var seconds = buffer.ReadInt32(); RoundDuration = new TimeSpan(hours, mins, seconds); - PlayerCount = buffer.ReadUInt32(); + PlayerCount = buffer.ReadInt32(); AllPlayersEndInfo = new List(); - for(var i = 0; i < PlayerCount + 1; i++) + for(var i = 0; i < PlayerCount; i++) { var readPlayerData = new RoundEndPlayerInfo { @@ -214,7 +215,7 @@ namespace Content.Shared buffer.Write(RoundDuration.Seconds); - buffer.Write(PlayerCount); + buffer.Write(AllPlayersEndInfo.Count); foreach(var playerEndInfo in AllPlayersEndInfo) { buffer.Write(playerEndInfo.PlayerOOCName); diff --git a/Resources/Maps/saltern.yml b/Resources/Maps/saltern.yml index e387f022c3..f3ccd2b9b1 100644 --- a/Resources/Maps/saltern.yml +++ b/Resources/Maps/saltern.yml @@ -33466,10 +33466,10 @@ entities: rot: -1.5707963267948966 rad type: Transform - uid: 2877 - type: TrashSpawner + type: SuspicionPistolMagazineSpawner components: - parent: 15 - pos: -21.5,-12.5 + pos: -35.5,0.5 rot: -1.5707963267948966 rad type: Transform - uid: 2878 @@ -37344,7 +37344,6 @@ entities: pos: -13.672081,21.719378 rot: -1.5707963267948966 rad type: Transform - - type: BatteryBarrel - anchored: False type: Collidable - containers: @@ -37371,7 +37370,6 @@ entities: pos: -14.515831,21.735003 rot: -1.5707963267948966 rad type: Transform - - type: BatteryBarrel - anchored: False type: Collidable - containers: @@ -37840,10 +37838,10 @@ entities: type: Robust.Server.GameObjects.Components.Container.Container type: ContainerContainer - uid: 3282 - type: metal_wall + type: SuspicionPistolSpawner components: - parent: 15 - pos: 13.293709,-8.309891 + pos: 8.5,-4.5 rot: -1.5707963267948966 rad type: Transform - uid: 3283 @@ -38099,4 +38097,312 @@ entities: type: Transform - anchored: False type: Collidable +- uid: 3310 + type: SuspicionShotgunMagazineSpawner + components: + - parent: 15 + pos: -6.5,-3.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3311 + type: SuspicionShotgunMagazineSpawner + components: + - parent: 15 + pos: -7.5,-3.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3312 + type: SuspicionShotgunSpawner + components: + - parent: 15 + pos: -7.5,-6.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3313 + type: SuspicionSniperSpawner + components: + - parent: 15 + pos: -8.5,-12.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3314 + type: SuspicionRifleMagazineSpawner + components: + - parent: 15 + pos: -13.5,-6.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3315 + type: SuspicionGrenadesSpawner + components: + - parent: 15 + pos: 15.5,-0.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3316 + type: SuspicionGrenadesSpawner + components: + - parent: 15 + pos: 18.5,1.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3317 + type: SuspicionHitscanSpawner + components: + - parent: 15 + pos: 25.5,0.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3318 + type: SuspicionGrenadesSpawner + components: + - parent: 15 + pos: 0.5,-15.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3319 + type: SuspicionGrenadesSpawner + components: + - parent: 15 + pos: -8.5,-17.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3320 + type: SuspicionMagnumMagazineSpawner + components: + - parent: 15 + pos: 14.5,-2.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3321 + type: SuspicionRevolverSpawner + components: + - parent: 15 + pos: 15.5,-3.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3322 + type: SuspicionMagnumMagazineSpawner + components: + - parent: 15 + pos: 16.5,7.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3323 + type: SuspicionSMGSpawner + components: + - parent: 15 + pos: -7.5,8.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3324 + type: SuspicionRifleMagazineSpawner + components: + - parent: 15 + pos: -7.5,7.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3325 + type: SuspicionShotgunSpawner + components: + - parent: 15 + pos: -29.5,-5.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3326 + type: SuspicionShotgunMagazineSpawner + components: + - parent: 15 + pos: -30.5,-4.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3327 + type: SuspicionShotgunMagazineSpawner + components: + - parent: 15 + pos: -29.5,-4.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3328 + type: SuspicionPistolMagazineSpawner + components: + - parent: 15 + pos: -3.5,0.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3329 + type: SuspicionPistolMagazineSpawner + components: + - parent: 15 + pos: -10.5,1.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3330 + type: SuspicionPistolMagazineSpawner + components: + - parent: 15 + pos: -9.5,6.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3331 + type: SuspicionPistolMagazineSpawner + components: + - parent: 15 + pos: -29.5,9.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3332 + type: SuspicionPistolMagazineSpawner + components: + - parent: 15 + pos: -31.5,13.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3333 + type: SuspicionPistolSpawner + components: + - parent: 15 + pos: -5.5,24.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3334 + type: SuspicionPistolSpawner + components: + - parent: 15 + pos: -10.5,-0.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3335 + type: SuspicionHitscanSpawner + components: + - parent: 15 + pos: -14.5,18.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3336 + type: SuspicionRevolverSpawner + components: + - parent: 15 + pos: -14.5,19.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3337 + type: SuspicionPistolSpawner + components: + - parent: 15 + pos: -13.5,18.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3338 + type: SuspicionRifleSpawner + components: + - parent: 15 + pos: -13.5,19.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3339 + type: SuspicionSMGSpawner + components: + - parent: 15 + pos: -13.5,20.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3340 + type: SuspicionShotgunSpawner + components: + - parent: 15 + pos: -12.5,20.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3341 + type: SuspicionSniperSpawner + components: + - parent: 15 + pos: -12.5,19.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3342 + type: SuspicionLaunchersSpawner + components: + - parent: 15 + pos: -12.5,18.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3343 + type: SuspicionGrenadesSpawner + components: + - parent: 15 + pos: -11.5,20.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3344 + type: SuspicionGrenadesSpawner + components: + - parent: 15 + pos: -11.5,19.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3345 + type: SuspicionGrenadesSpawner + components: + - parent: 15 + pos: -11.5,18.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3346 + type: SuspicionShotgunMagazineSpawner + components: + - parent: 15 + pos: -35.5,-7.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3347 + type: SuspicionShotgunMagazineSpawner + components: + - parent: 15 + pos: -35.5,-6.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3348 + type: SuspicionRifleMagazineSpawner + components: + - parent: 15 + pos: -35.5,-4.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3349 + type: SuspicionRifleMagazineSpawner + components: + - parent: 15 + pos: -35.5,-3.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3350 + type: SuspicionPistolMagazineSpawner + components: + - parent: 15 + pos: -35.5,-0.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3351 + type: SuspicionShotgunMagazineSpawner + components: + - parent: 15 + pos: -23.5,-13.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3352 + type: SuspicionShotgunSpawner + components: + - parent: 15 + pos: -15.5,-14.5 + rot: -1.5707963267948966 rad + type: Transform +- uid: 3353 + type: SuspicionHitscanSpawner + components: + - parent: 15 + pos: -15.5,-11.5 + rot: -1.5707963267948966 rad + type: Transform ... diff --git a/Resources/Prototypes/Entities/Effects/Markers/gamemode_conditional_spawners.yml b/Resources/Prototypes/Entities/Effects/Markers/gamemode_conditional_spawners.yml index f5a840c392..1fe1cb94e2 100644 --- a/Resources/Prototypes/Entities/Effects/Markers/gamemode_conditional_spawners.yml +++ b/Resources/Prototypes/Entities/Effects/Markers/gamemode_conditional_spawners.yml @@ -71,7 +71,7 @@ - PistolMolly - PistolOlivaw - PistolPaco - chance: 0.75 + chance: 0.95 gameRules: - RuleSuspicion @@ -96,7 +96,7 @@ - ToolboxEmergency - CrowbarRed - Stunbaton - chance: 0.75 + chance: 0.95 gameRules: - RuleSuspicion @@ -118,7 +118,7 @@ - RevolverDeckard - RevolverInspector - RevolverMateba - chance: 0.75 + chance: 0.95 gameRules: - RuleSuspicion @@ -144,7 +144,7 @@ - ShotgunRegulator - ShotgunPump - ShotgunSawn - chance: 0.75 + chance: 0.95 gameRules: - RuleSuspicion @@ -169,7 +169,7 @@ - SmgStraylight - SmgWt550 - SmgZoric - chance: 0.75 + chance: 0.95 gameRules: - RuleSuspicion @@ -191,7 +191,7 @@ - SniperBoltGun - SniperBoltGunWood - SniperHeavy - chance: 0.75 + chance: 0.95 gameRules: - RuleSuspicion @@ -217,7 +217,7 @@ - LaserCannon - XrayCannon - TaserGun - chance: 0.75 + chance: 0.85 gameRules: - RuleSuspicion @@ -260,6 +260,117 @@ - ExGrenade - GrenadeFlashBang - SyndieMiniBomb + - GrenadeFlash + - GrenadeBlast + - GrenadeFrag + - GrenadeBaton chance: 0.75 gameRules: - RuleSuspicion + +- type: entity + name: Suspicion Rifle Ammo Spawner + id: SuspicionRifleMagazineSpawner + parent: BaseConditionalSpawner + components: + - type: Sprite + netsync: false + visible: false + sprite: Interface/Misc/markers.rsi + state: spawner_rifle_ammo + - type: Icon + sprite: Interface/Misc/markers.rsi + state: spawner_rifle_ammo + - type: ConditionalSpawner + prototypes: + - MagazineSRifle + - MagazineClRifle + - MagazineLRifle + chance: 0.95 + gameRules: + - RuleSuspicion + +- type: entity + name: Suspicion Shotgun Ammo Spawner + id: SuspicionShotgunMagazineSpawner + parent: BaseConditionalSpawner + components: + - type: Sprite + netsync: false + visible: false + sprite: Interface/Misc/markers.rsi + state: spawner_shotgun_ammo + - type: Icon + sprite: Interface/Misc/markers.rsi + state: spawner_shotgun_ammo + - type: ConditionalSpawner + prototypes: + - MagazineShotgun + chance: 0.95 + gameRules: + - RuleSuspicion + +- type: entity + name: Suspicion Pistol Ammo Spawner + id: SuspicionPistolMagazineSpawner + parent: BaseConditionalSpawner + components: + - type: Sprite + netsync: false + visible: false + sprite: Interface/Misc/markers.rsi + state: spawner_pistol_ammo + - type: Icon + sprite: Interface/Misc/markers.rsi + state: spawner_pistol_ammo + - type: ConditionalSpawner + prototypes: + - MagazinePistol + - MagazineHCPistol + - MagazinePistolSmg + - MagazineClRiflePistol + chance: 0.95 + gameRules: + - RuleSuspicion + +- type: entity + name: Suspicion Magnum Ammo Spawner + id: SuspicionMagnumMagazineSpawner + parent: BaseConditionalSpawner + components: + - type: Sprite + netsync: false + visible: false + sprite: Interface/Misc/markers.rsi + state: spawner_magnum_ammo + - type: Icon + sprite: Interface/Misc/markers.rsi + state: spawner_magnum_ammo + - type: ConditionalSpawner + prototypes: + - MagazineMagnum + - MagazineMagnumSmg + chance: 0.95 + gameRules: + - RuleSuspicion + +- type: entity + name: Suspicion Launcher Ammo Spawner + id: SuspicionLauncherAmmoSpawner + parent: BaseConditionalSpawner + components: + - type: Sprite + netsync: false + visible: false + sprite: Interface/Misc/markers.rsi + state: spawner_launcher_ammo + - type: Icon + sprite: Interface/Misc/markers.rsi + state: spawner_launcher_ammo + - type: ConditionalSpawner + prototypes: + - RocketAmmo + - GrenadeFrag + chance: 0.95 + gameRules: + - RuleSuspicion diff --git a/Resources/Textures/Interface/Misc/markers.rsi/meta.json b/Resources/Textures/Interface/Misc/markers.rsi/meta.json index a1fa3f2b53..3c58904297 100644 --- a/Resources/Textures/Interface/Misc/markers.rsi/meta.json +++ b/Resources/Textures/Interface/Misc/markers.rsi/meta.json @@ -403,6 +403,24 @@ ] ] }, + { + "name": "spawner_launcher_ammo", + "directions": 1, + "delays": [ + [ + 1.0 + ] + ] + }, + { + "name": "spawner_magnum_ammo", + "directions": 1, + "delays": [ + [ + 1.0 + ] + ] + }, { "name": "spawner_melee", "directions": 1, @@ -421,6 +439,15 @@ ] ] }, + { + "name": "spawner_pistol_ammo", + "directions": 1, + "delays": [ + [ + 1.0 + ] + ] + }, { "name": "spawner_revolver", "directions": 1, @@ -439,6 +466,15 @@ ] ] }, + { + "name": "spawner_rifle_ammo", + "directions": 1, + "delays": [ + [ + 1.0 + ] + ] + }, { "name": "spawner_shotgun", "directions": 1, @@ -448,6 +484,15 @@ ] ] }, + { + "name": "spawner_shotgun_ammo", + "directions": 1, + "delays": [ + [ + 1.0 + ] + ] + }, { "name": "spawner_smg", "directions": 1, @@ -466,7 +511,7 @@ ] ] }, - { + { "name": "spawner_trash", "directions": 1, "delays": [ diff --git a/Resources/Textures/Interface/Misc/markers.rsi/spawner_ai.png b/Resources/Textures/Interface/Misc/markers.rsi/spawner_ai.png index c9d18bf907..6e7304d762 100644 Binary files a/Resources/Textures/Interface/Misc/markers.rsi/spawner_ai.png and b/Resources/Textures/Interface/Misc/markers.rsi/spawner_ai.png differ diff --git a/Resources/Textures/Interface/Misc/markers.rsi/spawner_launcher_ammo.png b/Resources/Textures/Interface/Misc/markers.rsi/spawner_launcher_ammo.png new file mode 100644 index 0000000000..b7cffe180e Binary files /dev/null and b/Resources/Textures/Interface/Misc/markers.rsi/spawner_launcher_ammo.png differ diff --git a/Resources/Textures/Interface/Misc/markers.rsi/spawner_magnum_ammo.png b/Resources/Textures/Interface/Misc/markers.rsi/spawner_magnum_ammo.png new file mode 100644 index 0000000000..3b59a3ca46 Binary files /dev/null and b/Resources/Textures/Interface/Misc/markers.rsi/spawner_magnum_ammo.png differ diff --git a/Resources/Textures/Interface/Misc/markers.rsi/spawner_pistol_ammo.png b/Resources/Textures/Interface/Misc/markers.rsi/spawner_pistol_ammo.png new file mode 100644 index 0000000000..1e5330cfe2 Binary files /dev/null and b/Resources/Textures/Interface/Misc/markers.rsi/spawner_pistol_ammo.png differ diff --git a/Resources/Textures/Interface/Misc/markers.rsi/spawner_rifle_ammo.png b/Resources/Textures/Interface/Misc/markers.rsi/spawner_rifle_ammo.png new file mode 100644 index 0000000000..1c9372e9ea Binary files /dev/null and b/Resources/Textures/Interface/Misc/markers.rsi/spawner_rifle_ammo.png differ diff --git a/Resources/Textures/Interface/Misc/markers.rsi/spawner_shotgun_ammo.png b/Resources/Textures/Interface/Misc/markers.rsi/spawner_shotgun_ammo.png new file mode 100644 index 0000000000..2c341f2218 Binary files /dev/null and b/Resources/Textures/Interface/Misc/markers.rsi/spawner_shotgun_ammo.png differ diff --git a/Resources/Textures/Interface/Misc/markers.rsi/spawner_trash.png b/Resources/Textures/Interface/Misc/markers.rsi/spawner_trash.png index b92ba56c3d..0a685dc041 100644 Binary files a/Resources/Textures/Interface/Misc/markers.rsi/spawner_trash.png and b/Resources/Textures/Interface/Misc/markers.rsi/spawner_trash.png differ diff --git a/Resources/Textures/Interface/Misc/markers.rsi/spawner_xenoai.png b/Resources/Textures/Interface/Misc/markers.rsi/spawner_xenoai.png index 7b0db41b65..4f64d33046 100644 Binary files a/Resources/Textures/Interface/Misc/markers.rsi/spawner_xenoai.png and b/Resources/Textures/Interface/Misc/markers.rsi/spawner_xenoai.png differ diff --git a/RobustToolbox b/RobustToolbox index 1934428c95..c72ea7194e 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit 1934428c95d44210cfc9c155c7d15405d4a374c4 +Subproject commit c72ea7194e08bba42371a06e353bcd79f5a7c7cc diff --git a/SpaceStation14.sln.DotSettings b/SpaceStation14.sln.DotSettings index c93412bf8d..14abc1df09 100644 --- a/SpaceStation14.sln.DotSettings +++ b/SpaceStation14.sln.DotSettings @@ -51,6 +51,7 @@ <data><IncludeFilters /><ExcludeFilters><Filter ModuleMask="Lidgren.Network" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /></ExcludeFilters></data> True True + True True True True