Merge branch 'master' of github.com:space-wizards/space-station-14

This commit is contained in:
juliangiebel
2020-08-16 23:57:49 +02:00
45 changed files with 944 additions and 180 deletions

View File

@@ -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);

View File

@@ -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<MsgTickerLobbyInfo>(nameof(MsgTickerLobbyInfo), LobbyInfo);
_netManager.RegisterNetMessage<MsgTickerLobbyCountdown>(nameof(MsgTickerLobbyCountdown), LobbyCountdown);
_netManager.RegisterNetMessage<MsgRoundEndMessage>(nameof(MsgRoundEndMessage), RoundEnd);
_netManager.RegisterNetMessage<MsgRequestWindowAttention>(nameof(MsgRequestWindowAttention), msg =>
{
IoCManager.Resolve<IClyde>().RequestWindowAttention();
});
_initialized = true;
}

View File

@@ -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);

View File

@@ -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();
}
}
}
}

View File

@@ -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<Direction>();
var amtEligibleAdj = 0;
var eligibleDirections = ArrayPool<Direction>.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<Direction>.Shared.Return(eligibleDirections);
}
giverTilesLength = 0;
@@ -446,7 +454,7 @@ namespace Content.Server.Atmos
}
}
ArrayPool<TileAtmosphere>.Shared.Return(queue, true);
ArrayPool<TileAtmosphere>.Shared.Return(queue);
}
else
{
@@ -516,7 +524,7 @@ namespace Content.Server.Atmos
}
}
ArrayPool<TileAtmosphere>.Shared.Return(queue, true);
ArrayPool<TileAtmosphere>.Shared.Return(queue);
}
for (var i = 0; i < tileCount; i++)
@@ -537,9 +545,9 @@ namespace Content.Server.Atmos
}
}
ArrayPool<TileAtmosphere>.Shared.Return(tiles, true);
ArrayPool<TileAtmosphere>.Shared.Return(giverTiles, true);
ArrayPool<TileAtmosphere>.Shared.Return(takerTiles, true);
ArrayPool<TileAtmosphere>.Shared.Return(tiles);
ArrayPool<TileAtmosphere>.Shared.Return(giverTiles);
ArrayPool<TileAtmosphere>.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<TileAtmosphere>();
var spaceTiles = new List<TileAtmosphere>();
tiles.Add(this);
var tiles = ArrayPool<TileAtmosphere>.Shared.Rent(limit);
var spaceTiles = ArrayPool<TileAtmosphere>.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<TileAtmosphere>();
foreach (var tile in spaceTiles)
var progressionOrder = ArrayPool<TileAtmosphere>.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<TileAtmosphere>.Shared.Return(tiles);
ArrayPool<TileAtmosphere>.Shared.Return(spaceTiles);
ArrayPool<TileAtmosphere>.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()

View File

@@ -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<string>());
}
}
}

View File

@@ -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<IMoverComponent>(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)
{

View File

@@ -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<ItemComponent>();
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
/// <returns>
/// True if there is an item in the slot and it can be dropped, false otherwise.
/// </returns>
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<ICollidableComponent>();
var controller = PulledObject!.EnsureController<PullController>();
controller!.StartPull(Owner.GetComponent<ICollidableComponent>());
AddPullingStatuses();
var controller = PulledObject.EnsureController<PullController>();
controller.StartPull(Owner.GetComponent<ICollidableComponent>());
}
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<MoveEvent>(EventSource.Local, this, MoveEvent);
AddPullingStatuses(msg.Pulled.Owner);
break;
case PullStoppedMessage msg:
Owner.EntityManager.EventBus.UnsubscribeEvent<MoveEvent>(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)

View File

@@ -173,9 +173,10 @@ namespace Content.Server.GameObjects.Components.GUI
/// </remarks>
/// <param name="slot">The slot to put the item in.</param>
/// <param name="item">The item to insert into the slot.</param>
/// <param name="mobCheck">Whether to perform an ActionBlocker check to the entity.</param>
/// <param name="reason">The translated reason why the item cannot be equipped, if this function returns false. Can be null.</param>
/// <returns>True if the item was successfully inserted, false otherwise.</returns>
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<ItemComponent>());
public bool Equip(Slots slot, IEntity entity, bool mobCheck = true) => Equip(slot, entity.GetComponent<ItemComponent>(), mobCheck);
/// <summary>
/// Checks whether an item can be put in the specified slot.
@@ -214,12 +215,12 @@ namespace Content.Server.GameObjects.Components.GUI
/// <param name="item">The item to check for.</param>
/// <param name="reason">The translated reason why the item cannot be equiped, if this function returns false. Can be null.</param>
/// <returns>True if the item can be inserted into the specified slot.</returns>
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<ItemComponent>());
public bool CanEquip(Slots slot, IEntity entity, bool mobCheck = true) => CanEquip(slot, entity.GetComponent<ItemComponent>(), mobCheck);
/// <summary>
/// Drops the item in a slot.
/// </summary>
/// <param name="slot">The slot to drop the item from.</param>
/// <returns>True if an item was dropped, false otherwise.</returns>
public bool Unequip(Slots slot)
/// <param name="mobCheck">Whether to perform an ActionBlocker check to the entity.</param>
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.
/// </summary>
/// <param name="slot">The slot to check for.</param>
/// <param name="mobCheck">Whether to perform an ActionBlocker check to the entity.</param>
/// <returns>
/// True if there is an item in the slot and it can be dropped, false otherwise.
/// </returns>
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);
}
/// <summary>
@@ -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<Slots, (EntityUid entity, bool fits)>(msg.Inventoryslot, (activeHand.Owner.Uid, canEquip));
Dirty();

View File

@@ -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;
}
}
}

View File

@@ -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);

View File

@@ -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]");
}
}
}

View File

@@ -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<SuspicionTraitorRole>();
}
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);
}
}
}

View File

@@ -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;

View File

@@ -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<VisibilityComponent>();
arrowVisibility.Layer = playerVisibility.Layer;
}
string selfMessage;
string viewerMessage;

View File

@@ -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)

View File

@@ -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<IPlayerSession>(readyPlayers);
var prefList = new List<IPlayerSession>();
@@ -54,6 +61,8 @@ namespace Content.Server.GameTicking.GamePresets
{
prefList.Add(player);
}
player.AttachedEntity?.EnsureComponent<SuspicionRoleComponent>();
}
var numTraitors = FloatMath.Clamp(readyPlayers.Count % PlayersPerTraitor,

View File

@@ -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<MobDamageStateChangedMessage>(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<MindComponent>(out var mind))
return;
if (!mind.HasMind)
return;
message.Species.Owner.Description +=
mind.Mind.HasRole<SuspicionTraitorRole>() ? "\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<SuspicionTraitorRole>())
traitorsAlive++;
else

View File

@@ -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<MsgTickerLobbyInfo>(nameof(MsgTickerLobbyInfo));
_netManager.RegisterNetMessage<MsgTickerLobbyCountdown>(nameof(MsgTickerLobbyCountdown));
_netManager.RegisterNetMessage<MsgRoundEndMessage>(nameof(MsgRoundEndMessage));
_netManager.RegisterNetMessage<MsgRequestWindowAttention>(nameof(MsgRequestWindowAttention));
SetStartPreset(_configurationManager.GetCVar<string>("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<IGameTiming>().RealTime;
_sendStatusToAll();
ReqWindowAttentionAll();
}
private void SendServerMessage(string message)

View File

@@ -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;

View File

@@ -61,8 +61,9 @@ namespace Content.Server.Interfaces.GameObjects.Components.Items
/// Puts an item into any empty hand, preferring the active hand.
/// </summary>
/// <param name="item">The item to put in a hand.</param>
/// <param name="mobCheck">Whether to perform an ActionBlocker check to the entity.</param>
/// <returns>True if the item was inserted, false otherwise.</returns>
bool PutInHand(ItemComponent item);
bool PutInHand(ItemComponent item, bool mobCheck = true);
/// <summary>
/// Puts an item into a specific hand.
@@ -71,24 +72,27 @@ namespace Content.Server.Interfaces.GameObjects.Components.Items
/// <param name="index">The name of the hand to put the item into.</param>
/// <param name="fallback">
/// If true and the provided hand is full, the method will fall back to <see cref="PutInHand(ItemComponent)" />
/// <param name="mobCheck">Whether to perform an ActionBlocker check to the entity.</param>
/// </param>
/// <returns>True if the item was inserted into a hand, false otherwise.</returns>
bool PutInHand(ItemComponent item, string index, bool fallback=true);
bool PutInHand(ItemComponent item, string index, bool fallback=true, bool mobCheck = true);
/// <summary>
/// Checks to see if an item can be put in any hand.
/// </summary>
/// <param name="item">The item to check for.</param>
/// <param name="mobCheck">Whether to perform an ActionBlocker check to the entity.</param>
/// <returns>True if the item can be inserted, false otherwise.</returns>
bool CanPutInHand(ItemComponent item);
bool CanPutInHand(ItemComponent item, bool mobCheck = true);
/// <summary>
/// Checks to see if an item can be put in the specified hand.
/// </summary>
/// <param name="item">The item to check for.</param>
/// <param name="index">The name for the hand to check for.</param>
/// <param name="mobCheck">Whether to perform an ActionBlocker check to the entity.</param>
/// <returns>True if the item can be inserted, false otherwise.</returns>
bool CanPutInHand(ItemComponent item, string index);
bool CanPutInHand(ItemComponent item, string index, bool mobCheck = true);
/// <summary>
/// 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.
/// </summary>
/// <param name="slot">The slot of which to drop to drop the item.</param>
/// <param name="doMobChecks">Whether to check the <see cref="ActionBlockerSystem.CanDrop()"/> for the mob or not.</param>
/// <param name="mobChecks">Whether to check the <see cref="ActionBlockerSystem.CanDrop()"/> for the mob or not.</param>
/// <returns>True on success, false if something blocked the drop.</returns>
bool Drop(string slot, bool doMobChecks = true);
bool Drop(string slot, bool mobChecks = true);
/// <summary>
/// Drops an item held by one of our hand slots to the same position as our owning entity.
/// </summary>
/// <param name="entity">The item to drop.</param>
/// <param name="doMobChecks">Whether to check the <see cref="ActionBlockerSystem.CanDrop()"/> for the mob or not.</param>
/// <param name="mobChecks">Whether to check the <see cref="ActionBlockerSystem.CanDrop()"/> for the mob or not.</param>
/// <returns>True on success, false if something blocked the drop.</returns>
/// <exception cref="ArgumentNullException">
/// Thrown if <see cref="entity"/> is null.
@@ -123,7 +127,7 @@ namespace Content.Server.Interfaces.GameObjects.Components.Items
/// <exception cref="ArgumentException">
/// Thrown if <see cref="entity"/> is not actually held in any hand.
/// </exception>
bool Drop(IEntity entity, bool doMobChecks = true);
bool Drop(IEntity entity, bool mobChecks = true);
/// <summary>
/// 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.
/// </summary>
/// <param name="name">The hand to check for.</param>
/// <param name="mobCheck">Whether to perform an ActionBlocker check to the entity.</param>
/// <returns>
/// True if the item can be dropped, false if the hand is empty or the item in the hand cannot be dropped.
/// </returns>
bool CanDrop(string name);
bool CanDrop(string name, bool mobCheck = true);
/// <summary>
/// Adds a new hand to this hands component.

View File

@@ -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<GhostComponent>())

View File

@@ -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<MsgRequestWindowAttention>();
session.ConnectedClient.SendMessage(msg);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;

View File

@@ -23,6 +23,7 @@ namespace Content.Shared.GameObjects.Verbs
/// <summary>
/// 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
/// </summary>
public virtual bool BlockedByContainers => true;

View File

@@ -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
}
}
}

View File

@@ -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<PullController>();
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<PullController>();
}
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<ISharedHandsComponent>().StopPull();
StopPull();
}
else if (_movingTo.HasValue)
{

View File

@@ -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;
}
}
}

View File

@@ -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)
{
}
}
}

View File

@@ -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)
{
}
}
}

View File

@@ -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<RoundEndPlayerInfo> 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<RoundEndPlayerInfo>();
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);

View File

@@ -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
...

View File

@@ -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

View File

@@ -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": [

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 469 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 663 B

After

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -51,6 +51,7 @@
<s:String x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue">&lt;data&gt;&lt;IncludeFilters /&gt;&lt;ExcludeFilters&gt;&lt;Filter ModuleMask="Lidgren.Network" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;/ExcludeFilters&gt;&lt;/data&gt;</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Collidable/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Cooldowns/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=firelocks/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=flashable/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Fluidsynth/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=freepats/@EntryIndexedValue">True</s:Boolean>