Extremely basic game ticker. (#126)
You can theoretically restart the round (resetting the map) now, but it breaks very badly if a client is connected due to various edge cases/race conditions.
This commit is contained in:
committed by
GitHub
parent
744af3be3e
commit
574512f1bf
@@ -123,6 +123,11 @@ namespace Content.Client.GameObjects.Components.Storage
|
|||||||
if(!spriteComp.Running)
|
if(!spriteComp.Running)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (spriteComp.BaseRSI == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var baseName = spriteComp.LayerGetState(0).Name;
|
var baseName = spriteComp.LayerGetState(0).Name;
|
||||||
|
|
||||||
var stateId = open ? $"{baseName}_open" : $"{baseName}_door";
|
var stateId = open ? $"{baseName}_open" : $"{baseName}_door";
|
||||||
|
|||||||
@@ -108,6 +108,9 @@
|
|||||||
<Compile Include="GameObjects\EntitySystems\StorageSystem.cs" />
|
<Compile Include="GameObjects\EntitySystems\StorageSystem.cs" />
|
||||||
<Compile Include="GameObjects\EntitySystems\WelderSystem.cs" />
|
<Compile Include="GameObjects\EntitySystems\WelderSystem.cs" />
|
||||||
<Compile Include="GameObjects\EntitySystems\TemperatureSystem.cs" />
|
<Compile Include="GameObjects\EntitySystems\TemperatureSystem.cs" />
|
||||||
|
<Compile Include="GameTicking\GamePreset.cs" />
|
||||||
|
<Compile Include="GameTicking\GamePresets\PresetTraitor.cs" />
|
||||||
|
<Compile Include="GameTicking\GameTicker.cs" />
|
||||||
<Compile Include="Interfaces\GameObjects\Components\Items\IHandsComponent.cs" />
|
<Compile Include="Interfaces\GameObjects\Components\Items\IHandsComponent.cs" />
|
||||||
<Compile Include="GameObjects\Components\GUI\ServerHandsComponent.cs" />
|
<Compile Include="GameObjects\Components\GUI\ServerHandsComponent.cs" />
|
||||||
<Compile Include="GameObjects\Components\GUI\InventoryComponent.cs" />
|
<Compile Include="GameObjects\Components\GUI\InventoryComponent.cs" />
|
||||||
@@ -116,6 +119,7 @@
|
|||||||
<Compile Include="GameObjects\Components\Damage\ResistanceSet.cs" />
|
<Compile Include="GameObjects\Components\Damage\ResistanceSet.cs" />
|
||||||
<Compile Include="GameObjects\Components\Temperature\TemperatureComponent.cs" />
|
<Compile Include="GameObjects\Components\Temperature\TemperatureComponent.cs" />
|
||||||
<Compile Include="Interfaces\GameObjects\IOnDamageBehavior.cs" />
|
<Compile Include="Interfaces\GameObjects\IOnDamageBehavior.cs" />
|
||||||
|
<Compile Include="Interfaces\GameTicking\IGameTicker.cs" />
|
||||||
<Compile Include="Interfaces\IServerNotifyManager.cs" />
|
<Compile Include="Interfaces\IServerNotifyManager.cs" />
|
||||||
<Compile Include="Mobs\Commands.cs" />
|
<Compile Include="Mobs\Commands.cs" />
|
||||||
<Compile Include="Mobs\Mind.cs" />
|
<Compile Include="Mobs\Mind.cs" />
|
||||||
@@ -171,4 +175,4 @@
|
|||||||
<Compile Include="GameObjects\Components\Construction\ConstructorComponent.cs" />
|
<Compile Include="GameObjects\Components\Construction\ConstructorComponent.cs" />
|
||||||
<Compile Include="GameObjects\Components\Construction\ConstructionComponent.cs" />
|
<Compile Include="GameObjects\Components\Construction\ConstructionComponent.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -34,24 +34,21 @@ using Content.Server.GameObjects.EntitySystems;
|
|||||||
using Content.Server.Mobs;
|
using Content.Server.Mobs;
|
||||||
using Content.Server.Players;
|
using Content.Server.Players;
|
||||||
using Content.Server.GameObjects.Components.Interactable;
|
using Content.Server.GameObjects.Components.Interactable;
|
||||||
|
using Content.Server.GameTicking;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
|
using Content.Server.Interfaces.GameTicking;
|
||||||
using Content.Shared.GameObjects.Components.Inventory;
|
using Content.Shared.GameObjects.Components.Inventory;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
|
using SS14.Shared.Timing;
|
||||||
|
|
||||||
namespace Content.Server
|
namespace Content.Server
|
||||||
{
|
{
|
||||||
public class EntryPoint : GameServer
|
public class EntryPoint : GameServer
|
||||||
{
|
{
|
||||||
const string PlayerPrototypeName = "HumanMob_Content";
|
|
||||||
|
|
||||||
private IBaseServer _server;
|
private IBaseServer _server;
|
||||||
private IPlayerManager _players;
|
private IPlayerManager _players;
|
||||||
private IEntityManager entityManager;
|
|
||||||
private IChatManager chatManager;
|
private IChatManager chatManager;
|
||||||
|
private IGameTicker _gameTicker;
|
||||||
private bool _countdownStarted;
|
|
||||||
|
|
||||||
private GridLocalCoordinates SpawnPoint;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Init()
|
public override void Init()
|
||||||
@@ -60,7 +57,6 @@ namespace Content.Server
|
|||||||
|
|
||||||
_server = IoCManager.Resolve<IBaseServer>();
|
_server = IoCManager.Resolve<IBaseServer>();
|
||||||
_players = IoCManager.Resolve<IPlayerManager>();
|
_players = IoCManager.Resolve<IPlayerManager>();
|
||||||
entityManager = IoCManager.Resolve<IEntityManager>();
|
|
||||||
chatManager = IoCManager.Resolve<IChatManager>();
|
chatManager = IoCManager.Resolve<IChatManager>();
|
||||||
|
|
||||||
_players.PlayerStatusChanged += HandlePlayerStatusChanged;
|
_players.PlayerStatusChanged += HandlePlayerStatusChanged;
|
||||||
@@ -129,8 +125,11 @@ namespace Content.Server
|
|||||||
|
|
||||||
IoCManager.Register<ISharedNotifyManager, ServerNotifyManager>();
|
IoCManager.Register<ISharedNotifyManager, ServerNotifyManager>();
|
||||||
IoCManager.Register<IServerNotifyManager, ServerNotifyManager>();
|
IoCManager.Register<IServerNotifyManager, ServerNotifyManager>();
|
||||||
|
IoCManager.Register<IGameTicker, GameTicker>();
|
||||||
IoCManager.BuildGraph();
|
IoCManager.BuildGraph();
|
||||||
|
|
||||||
|
_gameTicker = IoCManager.Resolve<IGameTicker>();
|
||||||
|
|
||||||
IoCManager.Resolve<IServerNotifyManager>().Initialize();
|
IoCManager.Resolve<IServerNotifyManager>().Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,18 +137,7 @@ namespace Content.Server
|
|||||||
{
|
{
|
||||||
base.PostInit();
|
base.PostInit();
|
||||||
|
|
||||||
var timing = IoCManager.Resolve<IGameTiming>();
|
_gameTicker.Initialize();
|
||||||
var mapLoader = IoCManager.Resolve<IMapLoader>();
|
|
||||||
var mapMan = IoCManager.Resolve<IMapManager>();
|
|
||||||
|
|
||||||
var newMap = mapMan.CreateMap();
|
|
||||||
var grid = mapLoader.LoadBlueprint(newMap, "Maps/stationstation.yml");
|
|
||||||
|
|
||||||
SpawnPoint = new GridLocalCoordinates(Vector2.Zero, grid);
|
|
||||||
|
|
||||||
var startTime = timing.RealTime;
|
|
||||||
var timeSpan = timing.RealTime - startTime;
|
|
||||||
Logger.Info($"Loaded map in {timeSpan.TotalMilliseconds:N2}ms.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -163,6 +151,13 @@ namespace Content.Server
|
|||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Update(AssemblyLoader.UpdateLevel level, float frameTime)
|
||||||
|
{
|
||||||
|
base.Update(level, frameTime);
|
||||||
|
|
||||||
|
_gameTicker.Update(new FrameEventArgs(frameTime));
|
||||||
|
}
|
||||||
|
|
||||||
private void HandlePlayerStatusChanged(object sender, SessionStatusEventArgs args)
|
private void HandlePlayerStatusChanged(object sender, SessionStatusEventArgs args)
|
||||||
{
|
{
|
||||||
var session = args.Session;
|
var session = args.Session;
|
||||||
@@ -170,67 +165,60 @@ namespace Content.Server
|
|||||||
switch (args.NewStatus)
|
switch (args.NewStatus)
|
||||||
{
|
{
|
||||||
case SessionStatus.Connected:
|
case SessionStatus.Connected:
|
||||||
|
{
|
||||||
|
if (session.Data.ContentDataUncast == null)
|
||||||
{
|
{
|
||||||
if (session.Data.ContentDataUncast == null)
|
session.Data.ContentDataUncast = new PlayerData(session.SessionId);
|
||||||
{
|
|
||||||
session.Data.ContentDataUncast = new PlayerData(session.SessionId);
|
|
||||||
}
|
|
||||||
// timer time must be > tick length
|
|
||||||
Timer.Spawn(0, args.Session.JoinLobby);
|
|
||||||
|
|
||||||
chatManager.DispatchMessage(ChatChannel.Server, "Gamemode: Player joined server!", args.Session.SessionId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// timer time must be > tick length
|
||||||
|
Timer.Spawn(0, args.Session.JoinLobby);
|
||||||
|
|
||||||
|
chatManager.DispatchMessage(ChatChannel.Server, "Gamemode: Player joined server!",
|
||||||
|
args.Session.SessionId);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SessionStatus.InLobby:
|
case SessionStatus.InLobby:
|
||||||
{
|
{
|
||||||
chatManager.DispatchMessage(ChatChannel.Server, "Gamemode: Player joined Lobby!", args.Session.SessionId);
|
chatManager.DispatchMessage(ChatChannel.Server, "Gamemode: Player joined Lobby!",
|
||||||
}
|
args.Session.SessionId);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SessionStatus.InGame:
|
case SessionStatus.InGame:
|
||||||
|
{
|
||||||
|
//TODO: Check for existing mob and re-attach
|
||||||
|
var data = session.ContentData();
|
||||||
|
if (data.Mind == null)
|
||||||
{
|
{
|
||||||
//TODO: Check for existing mob and re-attach
|
// No mind yet (new session), make a new one.
|
||||||
var data = session.ContentData();
|
data.Mind = new Mind(session.SessionId);
|
||||||
if (data.Mind == null)
|
var mob = _gameTicker.SpawnPlayerMob();
|
||||||
|
data.Mind.TransferTo(mob);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (data.Mind.CurrentEntity == null)
|
||||||
{
|
{
|
||||||
// No mind yet (new session), make a new one.
|
var mob = _gameTicker.SpawnPlayerMob();
|
||||||
data.Mind = new Mind(session.SessionId);
|
|
||||||
var mob = SpawnPlayerMob();
|
|
||||||
data.Mind.TransferTo(mob);
|
data.Mind.TransferTo(mob);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
session.AttachToEntity(data.Mind.CurrentEntity);
|
||||||
if (data.Mind.CurrentEntity == null)
|
|
||||||
{
|
|
||||||
var mob = SpawnPlayerMob();
|
|
||||||
data.Mind.TransferTo(mob);
|
|
||||||
}
|
|
||||||
session.AttachToEntity(data.Mind.CurrentEntity);
|
|
||||||
}
|
|
||||||
chatManager.DispatchMessage(ChatChannel.Server, "Gamemode: Player joined Game!", args.Session.SessionId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chatManager.DispatchMessage(ChatChannel.Server, "Gamemode: Player joined Game!",
|
||||||
|
args.Session.SessionId);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SessionStatus.Disconnected:
|
case SessionStatus.Disconnected:
|
||||||
{
|
{
|
||||||
chatManager.DispatchMessage(ChatChannel.Server, "Gamemode: Player left!", args.Session.SessionId);
|
chatManager.DispatchMessage(ChatChannel.Server, "Gamemode: Player left!", args.Session.SessionId);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IEntity SpawnPlayerMob()
|
|
||||||
{
|
|
||||||
var entity = entityManager.ForceSpawnEntityAt(PlayerPrototypeName, SpawnPoint);
|
|
||||||
var shoes = entityManager.SpawnEntity("ShoesItem");
|
|
||||||
var uniform = entityManager.SpawnEntity("UniformAssistant");
|
|
||||||
if (entity.TryGetComponent(out InventoryComponent inventory))
|
|
||||||
{
|
|
||||||
inventory.Equip(EquipmentSlotDefines.Slots.INNERCLOTHING, uniform.GetComponent<ClothingComponent>());
|
|
||||||
inventory.Equip(EquipmentSlotDefines.Slots.SHOES, shoes.GetComponent<ClothingComponent>());
|
|
||||||
}
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
Content.Server/GameTicking/GamePreset.cs
Normal file
10
Content.Server/GameTicking/GamePreset.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Content.Server.GameTicking
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A round-start setup preset, such as which antagonists to spawn.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class GamePreset
|
||||||
|
{
|
||||||
|
public abstract void Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
12
Content.Server/GameTicking/GamePresets/PresetTraitor.cs
Normal file
12
Content.Server/GameTicking/GamePresets/PresetTraitor.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using SS14.Shared.Log;
|
||||||
|
|
||||||
|
namespace Content.Server.GameTicking.GamePresets
|
||||||
|
{
|
||||||
|
public class PresetTraitor : GamePreset
|
||||||
|
{
|
||||||
|
public override void Start()
|
||||||
|
{
|
||||||
|
Logger.DebugS("ticker.preset", "Current preset is traitor.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
238
Content.Server/GameTicking/GameTicker.cs
Normal file
238
Content.Server/GameTicking/GameTicker.cs
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Content.Server.GameObjects;
|
||||||
|
using Content.Server.GameTicking.GamePresets;
|
||||||
|
using Content.Server.Interfaces.GameTicking;
|
||||||
|
using Content.Shared.GameObjects.Components.Inventory;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using SS14.Server.Interfaces;
|
||||||
|
using SS14.Server.Interfaces.Console;
|
||||||
|
using SS14.Server.Interfaces.Maps;
|
||||||
|
using SS14.Server.Interfaces.Player;
|
||||||
|
using SS14.Shared.Configuration;
|
||||||
|
using SS14.Shared.Interfaces.Configuration;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.Map;
|
||||||
|
using SS14.Shared.Interfaces.Timing;
|
||||||
|
using SS14.Shared.IoC;
|
||||||
|
using SS14.Shared.Log;
|
||||||
|
using SS14.Shared.Map;
|
||||||
|
using SS14.Shared.Maths;
|
||||||
|
using SS14.Shared.Timing;
|
||||||
|
using SS14.Shared.Utility;
|
||||||
|
using SS14.Shared.ViewVariables;
|
||||||
|
|
||||||
|
namespace Content.Server.GameTicking
|
||||||
|
{
|
||||||
|
public class GameTicker : IGameTicker
|
||||||
|
{
|
||||||
|
[ViewVariables]
|
||||||
|
public GameRunLevel RunLevel
|
||||||
|
{
|
||||||
|
get => _runLevel;
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
if (_runLevel == value)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var old = _runLevel;
|
||||||
|
_runLevel = value;
|
||||||
|
|
||||||
|
OnRunLevelChanged?.Invoke(new GameRunLevelChangedEventArgs(old, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private const string PlayerPrototypeName = "HumanMob_Content";
|
||||||
|
private const string MapFile = "Maps/stationstation.yml";
|
||||||
|
|
||||||
|
private bool _initialized;
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)] private GridLocalCoordinates _spawnPoint;
|
||||||
|
|
||||||
|
#pragma warning disable 649
|
||||||
|
[Dependency] private IEntityManager _entityManager;
|
||||||
|
[Dependency] private IMapManager _mapManager;
|
||||||
|
[Dependency] private IMapLoader _mapLoader;
|
||||||
|
[Dependency] private IGameTiming _gameTiming;
|
||||||
|
[Dependency] private IConfigurationManager _configurationManager;
|
||||||
|
#pragma warning restore 649
|
||||||
|
|
||||||
|
public Action<GameRunLevelChangedEventArgs> OnRunLevelChanged;
|
||||||
|
private GameRunLevel _runLevel;
|
||||||
|
|
||||||
|
public void Initialize()
|
||||||
|
{
|
||||||
|
DebugTools.Assert(!_initialized);
|
||||||
|
|
||||||
|
_configurationManager.RegisterCVar("game.lobbyenabled", false, CVar.ARCHIVE);
|
||||||
|
|
||||||
|
RestartRound();
|
||||||
|
|
||||||
|
_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(FrameEventArgs frameEventArgs)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RestartRound()
|
||||||
|
{
|
||||||
|
Logger.InfoS("ticker", "Restarting round!");
|
||||||
|
|
||||||
|
RunLevel = GameRunLevel.PreRoundLobby;
|
||||||
|
_resettingCleanup();
|
||||||
|
_preRoundSetup();
|
||||||
|
|
||||||
|
if (_configurationManager.GetCVar<bool>("game.lobbyenabled"))
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
StartRound();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartRound()
|
||||||
|
{
|
||||||
|
DebugTools.Assert(RunLevel == GameRunLevel.PreRoundLobby);
|
||||||
|
Logger.InfoS("ticker", "Starting round!");
|
||||||
|
|
||||||
|
RunLevel = GameRunLevel.InRound;
|
||||||
|
|
||||||
|
// TODO: Allow other presets to be selected.
|
||||||
|
var preset = new PresetTraitor();
|
||||||
|
preset.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EndRound()
|
||||||
|
{
|
||||||
|
DebugTools.Assert(RunLevel == GameRunLevel.InRound);
|
||||||
|
Logger.InfoS("ticker", "Ending round!");
|
||||||
|
|
||||||
|
RunLevel = GameRunLevel.PostRound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEntity SpawnPlayerMob()
|
||||||
|
{
|
||||||
|
var entity = _entityManager.ForceSpawnEntityAt(PlayerPrototypeName, _spawnPoint);
|
||||||
|
var shoes = _entityManager.SpawnEntity("ShoesItem");
|
||||||
|
var uniform = _entityManager.SpawnEntity("UniformAssistant");
|
||||||
|
if (entity.TryGetComponent(out InventoryComponent inventory))
|
||||||
|
{
|
||||||
|
inventory.Equip(EquipmentSlotDefines.Slots.INNERCLOTHING, uniform.GetComponent<ClothingComponent>());
|
||||||
|
inventory.Equip(EquipmentSlotDefines.Slots.SHOES, shoes.GetComponent<ClothingComponent>());
|
||||||
|
}
|
||||||
|
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cleanup that has to run to clear up anything from the previous round.
|
||||||
|
/// Stuff like wiping the previous map clean.
|
||||||
|
/// </summary>
|
||||||
|
private void _resettingCleanup()
|
||||||
|
{
|
||||||
|
// Delete all entities.
|
||||||
|
foreach (var entity in _entityManager.GetEntities().ToList())
|
||||||
|
{
|
||||||
|
// TODO: Maybe something less naive here?
|
||||||
|
// FIXME: Actually, definitely.
|
||||||
|
entity.Delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete all maps outside of nullspace.
|
||||||
|
foreach (var map in _mapManager.GetAllMaps().ToList())
|
||||||
|
{
|
||||||
|
// TODO: Maybe something less naive here?
|
||||||
|
if (map.Index != MapId.Nullspace)
|
||||||
|
{
|
||||||
|
_mapManager.DeleteMap(map.Index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _preRoundSetup()
|
||||||
|
{
|
||||||
|
var newMap = _mapManager.CreateMap();
|
||||||
|
var startTime = _gameTiming.RealTime;
|
||||||
|
var grid = _mapLoader.LoadBlueprint(newMap, MapFile);
|
||||||
|
|
||||||
|
_spawnPoint = new GridLocalCoordinates(Vector2.Zero, grid);
|
||||||
|
|
||||||
|
var timeSpan = _gameTiming.RealTime - startTime;
|
||||||
|
Logger.InfoS("ticker", $"Loaded map in {timeSpan.TotalMilliseconds:N2}ms.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum GameRunLevel
|
||||||
|
{
|
||||||
|
PreRoundLobby = 0,
|
||||||
|
InRound,
|
||||||
|
PostRound
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GameRunLevelChangedEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public GameRunLevel OldRunLevel { get; }
|
||||||
|
public GameRunLevel NewRunLevel { get; }
|
||||||
|
|
||||||
|
public GameRunLevelChangedEventArgs(GameRunLevel oldRunLevel, GameRunLevel newRunLevel)
|
||||||
|
{
|
||||||
|
OldRunLevel = oldRunLevel;
|
||||||
|
NewRunLevel = newRunLevel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class StartRoundCommand : IClientCommand
|
||||||
|
{
|
||||||
|
public string Command => "startround";
|
||||||
|
public string Description => "Ends PreRoundLobby state and starts the round.";
|
||||||
|
public string Help => String.Empty;
|
||||||
|
|
||||||
|
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
|
||||||
|
{
|
||||||
|
var ticker = IoCManager.Resolve<IGameTicker>();
|
||||||
|
|
||||||
|
if (ticker.RunLevel != GameRunLevel.PreRoundLobby)
|
||||||
|
{
|
||||||
|
shell.SendText(player, "This can only be executed while the game is in the pre-round lobby.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ticker.StartRound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EndRoundCommand : IClientCommand
|
||||||
|
{
|
||||||
|
public string Command => "endround";
|
||||||
|
public string Description => "Ends the round and moves the server to PostRound.";
|
||||||
|
public string Help => String.Empty;
|
||||||
|
|
||||||
|
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
|
||||||
|
{
|
||||||
|
var ticker = IoCManager.Resolve<IGameTicker>();
|
||||||
|
|
||||||
|
if (ticker.RunLevel != GameRunLevel.InRound)
|
||||||
|
{
|
||||||
|
shell.SendText(player, "This can only be executed while the game is in a round.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ticker.EndRound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NewRoundCommand : IClientCommand
|
||||||
|
{
|
||||||
|
public string Command => "restartround";
|
||||||
|
public string Description => "Moves the server from PostRound to a new PreRoundLobby.";
|
||||||
|
public string Help => String.Empty;
|
||||||
|
|
||||||
|
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
|
||||||
|
{
|
||||||
|
var ticker = IoCManager.Resolve<IGameTicker>();
|
||||||
|
ticker.RestartRound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
Content.Server/Interfaces/GameTicking/IGameTicker.cs
Normal file
23
Content.Server/Interfaces/GameTicking/IGameTicker.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using Content.Server.GameTicking;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.Timing;
|
||||||
|
|
||||||
|
namespace Content.Server.Interfaces.GameTicking
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The game ticker is responsible for managing the round-by-round system of the game.
|
||||||
|
/// </summary>
|
||||||
|
public interface IGameTicker
|
||||||
|
{
|
||||||
|
GameRunLevel RunLevel { get; }
|
||||||
|
|
||||||
|
void Initialize();
|
||||||
|
void Update(FrameEventArgs frameEventArgs);
|
||||||
|
|
||||||
|
void RestartRound();
|
||||||
|
void StartRound();
|
||||||
|
void EndRound();
|
||||||
|
|
||||||
|
IEntity SpawnPlayerMob();
|
||||||
|
}
|
||||||
|
}
|
||||||
2
engine
2
engine
Submodule engine updated: fcc405e6b6...8320339ab0
Reference in New Issue
Block a user