diff --git a/Content.Client/Commands/DebugCommands.cs b/Content.Client/Commands/DebugCommands.cs new file mode 100644 index 0000000000..b76fe8b948 --- /dev/null +++ b/Content.Client/Commands/DebugCommands.cs @@ -0,0 +1,39 @@ +using Content.Shared.GameObjects.Components.Markers; +using SS14.Client.Interfaces.Console; +using SS14.Client.Interfaces.GameObjects.Components; +using SS14.Shared.GameObjects; +using SS14.Shared.Interfaces.GameObjects; +using SS14.Shared.IoC; + +namespace Content.Client.Commands +{ + internal sealed class ShowMarkersCommand : IConsoleCommand + { + // ReSharper disable once StringLiteralTypo + public string Command => "togglemarkers"; + public string Description => "Toggles visibility of markers such as spawn points."; + public string Help => ""; + + public bool Execute(IDebugConsole console, params string[] args) + { + bool? whichToSet = null; + foreach (var entity in IoCManager.Resolve() + .GetEntities(new TypeEntityQuery(typeof(SharedSpawnPointComponent)))) + { + if (!entity.TryGetComponent(out ISpriteComponent sprite)) + { + continue; + } + + if (!whichToSet.HasValue) + { + whichToSet = !sprite.Visible; + } + + sprite.Visible = whichToSet.Value; + } + + return false; + } + } +} diff --git a/Content.Client/Content.Client.csproj b/Content.Client/Content.Client.csproj index 4a730db0b9..eb6b73f8fc 100644 --- a/Content.Client/Content.Client.csproj +++ b/Content.Client/Content.Client.csproj @@ -71,6 +71,7 @@ + diff --git a/Content.Client/EntryPoint.cs b/Content.Client/EntryPoint.cs index fbdce82919..e293421bc4 100644 --- a/Content.Client/EntryPoint.cs +++ b/Content.Client/EntryPoint.cs @@ -26,6 +26,7 @@ using SS14.Shared.IoC; using SS14.Shared.Prototypes; using System; using Content.Client.UserInterface; +using Content.Shared.GameObjects.Components.Markers; using SS14.Client.Interfaces.UserInterface; using SS14.Shared.Log; @@ -97,6 +98,8 @@ namespace Content.Client factory.RegisterIgnore("PowerCell"); + factory.Register(); + IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); diff --git a/Content.Server/Content.Server.csproj b/Content.Server/Content.Server.csproj index b51ba01b2f..c99c18b184 100644 --- a/Content.Server/Content.Server.csproj +++ b/Content.Server/Content.Server.csproj @@ -80,6 +80,7 @@ + diff --git a/Content.Server/EntryPoint.cs b/Content.Server/EntryPoint.cs index 9478b5a2e1..c708ab73dd 100644 --- a/Content.Server/EntryPoint.cs +++ b/Content.Server/EntryPoint.cs @@ -34,11 +34,13 @@ using Content.Server.GameObjects.EntitySystems; using Content.Server.Mobs; using Content.Server.Players; using Content.Server.GameObjects.Components.Interactable; +using Content.Server.GameObjects.Components.Markers; using Content.Server.GameObjects.Components.Weapon.Ranged; using Content.Server.GameTicking; using Content.Server.Interfaces; using Content.Server.Interfaces.GameTicking; using Content.Shared.GameObjects.Components.Inventory; +using Content.Shared.GameObjects.Components.Markers; using Content.Shared.Interfaces; using SS14.Server.Interfaces.ServerStatus; using SS14.Shared.Timing; @@ -119,6 +121,9 @@ namespace Content.Server factory.Register(); factory.Register(); + factory.Register(); + factory.RegisterReference(); + IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); diff --git a/Content.Server/GameObjects/Components/Markers/SpawnPointComponent.cs b/Content.Server/GameObjects/Components/Markers/SpawnPointComponent.cs new file mode 100644 index 0000000000..cb3397f262 --- /dev/null +++ b/Content.Server/GameObjects/Components/Markers/SpawnPointComponent.cs @@ -0,0 +1,28 @@ +using System; +using Content.Shared.GameObjects.Components.Markers; +using SS14.Shared.GameObjects; +using SS14.Shared.Serialization; +using SS14.Shared.ViewVariables; + +namespace Content.Server.GameObjects.Components.Markers +{ + public sealed class SpawnPointComponent : SharedSpawnPointComponent + { + private SpawnPointType _spawnType; + [ViewVariables] + public SpawnPointType SpawnType => _spawnType; + + public override void ExposeData(ObjectSerializer serializer) + { + base.ExposeData(serializer); + + serializer.DataField(ref _spawnType, "spawn_type", SpawnPointType.Unset); + } + } + + public enum SpawnPointType + { + Unset = 0, + LateJoin, + } +} diff --git a/Content.Server/GameTicking/GameTicker.cs b/Content.Server/GameTicking/GameTicker.cs index 2a172f432f..64525cfe49 100644 --- a/Content.Server/GameTicking/GameTicker.cs +++ b/Content.Server/GameTicking/GameTicker.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using Content.Server.GameObjects; +using Content.Server.GameObjects.Components.Markers; using Content.Server.GameTicking.GamePresets; using Content.Server.Interfaces.GameTicking; using Content.Server.Mobs; @@ -16,6 +17,7 @@ using SS14.Server.Player; using SS14.Shared.Configuration; using SS14.Shared.Console; using SS14.Shared.Enums; +using SS14.Shared.GameObjects; using SS14.Shared.Interfaces.Configuration; using SS14.Shared.Interfaces.GameObjects; using SS14.Shared.Interfaces.Map; @@ -75,6 +77,8 @@ namespace Content.Server.GameTicking [ViewVariables] private bool _roundStartCountdownHasNotStartedYetDueToNoPlayers; private DateTime _roundStartTimeUtc; + private readonly Random _spawnRandom = new Random(); + #pragma warning disable 649 [Dependency] private IEntityManager _entityManager; [Dependency] private IMapManager _mapManager; @@ -217,7 +221,7 @@ namespace Content.Server.GameTicking private IEntity _spawnPlayerMob() { - var entity = _entityManager.ForceSpawnEntityAt(PlayerPrototypeName, _spawnPoint); + var entity = _entityManager.ForceSpawnEntityAt(PlayerPrototypeName, _getLateJoinSpawnPoint()); var shoes = _entityManager.SpawnEntity("ShoesItem"); var uniform = _entityManager.SpawnEntity("UniformAssistant"); if (entity.TryGetComponent(out InventoryComponent inventory)) @@ -231,7 +235,29 @@ namespace Content.Server.GameTicking private IEntity _spawnObserverMob() { - return _entityManager.ForceSpawnEntityAt(ObserverPrototypeName, _spawnPoint); + return _entityManager.ForceSpawnEntityAt(ObserverPrototypeName, _getLateJoinSpawnPoint()); + } + + private GridCoordinates _getLateJoinSpawnPoint() + { + var location = _spawnPoint; + + var possiblePoints = new List(); + foreach (var entity in _entityManager.GetEntities(new TypeEntityQuery(typeof(SpawnPointComponent)))) + { + var point = entity.GetComponent(); + if (point.SpawnType == SpawnPointType.LateJoin) + { + possiblePoints.Add(entity.Transform.GridPosition); + } + } + + if (possiblePoints.Count != 0) + { + location = _spawnRandom.Pick(possiblePoints); + } + + return location; } /// diff --git a/Content.Shared/Content.Shared.csproj b/Content.Shared/Content.Shared.csproj index efa29c505e..2ef69f42e4 100644 --- a/Content.Shared/Content.Shared.csproj +++ b/Content.Shared/Content.Shared.csproj @@ -68,6 +68,7 @@ + diff --git a/Content.Shared/GameObjects/Components/Markers/SharedSpawnPointComponent.cs b/Content.Shared/GameObjects/Components/Markers/SharedSpawnPointComponent.cs new file mode 100644 index 0000000000..1347eed344 --- /dev/null +++ b/Content.Shared/GameObjects/Components/Markers/SharedSpawnPointComponent.cs @@ -0,0 +1,9 @@ +using SS14.Shared.GameObjects; + +namespace Content.Shared.GameObjects.Components.Markers +{ + public class SharedSpawnPointComponent : Component + { + public sealed override string Name => "SpawnPoint"; + } +} diff --git a/Resources/Prototypes/Entities/markers/spawn_points.yml b/Resources/Prototypes/Entities/markers/spawn_points.yml new file mode 100644 index 0000000000..391d054c80 --- /dev/null +++ b/Resources/Prototypes/Entities/markers/spawn_points.yml @@ -0,0 +1,31 @@ +- type: entity + name: Spawn Point + id: spawn_point + abstract: true + components: + - type: Sprite + netsync: false + visible: false + sprite: Objects/markers.rsi + + - type: Icon + sprite: Objects/markers.rsi + + - type: SpawnPoint + + placement: + mode: SnapgridCenter + +- type: entity + name: LateJoin Spawn Point + id: spawn_point_latejoin + parent: spawn_point + components: + - type: Sprite + state: cross_red + + - type: SpawnPoint + spawn_type: LateJoin + + - type: Icon + state: cross_red diff --git a/Resources/Textures/Objects/markers.rsi/cross_blue.png b/Resources/Textures/Objects/markers.rsi/cross_blue.png new file mode 100644 index 0000000000..7932e64aec Binary files /dev/null and b/Resources/Textures/Objects/markers.rsi/cross_blue.png differ diff --git a/Resources/Textures/Objects/markers.rsi/cross_green.png b/Resources/Textures/Objects/markers.rsi/cross_green.png new file mode 100644 index 0000000000..0becfdb0c5 Binary files /dev/null and b/Resources/Textures/Objects/markers.rsi/cross_green.png differ diff --git a/Resources/Textures/Objects/markers.rsi/cross_red.png b/Resources/Textures/Objects/markers.rsi/cross_red.png new file mode 100644 index 0000000000..063f341d36 Binary files /dev/null and b/Resources/Textures/Objects/markers.rsi/cross_red.png differ diff --git a/Resources/Textures/Objects/markers.rsi/meta.json b/Resources/Textures/Objects/markers.rsi/meta.json new file mode 100644 index 0000000000..625c447fa3 --- /dev/null +++ b/Resources/Textures/Objects/markers.rsi/meta.json @@ -0,0 +1 @@ +{"version": 1, "size": {"x": 32, "y": 32}, "license": "CC-BY-SA-3.0", "copyright": "Taken from https://github.com/vgstation-coders/vgstation13/blob/e71d6c4fba5a51f99b81c295dcaec4fc2f58fb19/icons/mob/screen1.dmi", "states": [{"name": "cross_blue", "directions": 1, "delays": [[1.0]]}, {"name": "cross_green", "directions": 1, "delays": [[1.0]]}, {"name": "cross_red", "directions": 1, "delays": [[1.0]]}]} \ No newline at end of file