using Content.Server.GameObjects; using Content.Server.GameObjects.Components.Power; using Content.Server.GameObjects.Components.Interactable.Tools; using Content.Server.Interfaces.GameObjects; using Content.Server.Placement; using SS14.Server; using SS14.Server.Interfaces; using SS14.Server.Interfaces.Chat; using SS14.Server.Interfaces.Maps; using SS14.Server.Interfaces.Player; using SS14.Server.Player; using SS14.Shared.Console; using SS14.Shared.ContentPack; using SS14.Shared.Enums; using SS14.Shared.Interfaces.GameObjects; using SS14.Shared.Interfaces.Map; using SS14.Shared.Interfaces.Timers; using SS14.Shared.IoC; using SS14.Shared.Log; using SS14.Shared.Map; using SS14.Shared.Timers; using SS14.Shared.Interfaces.Timing; using SS14.Shared.Maths; using Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan; using Content.Server.GameObjects.Components.Weapon.Ranged.Projectile; using Content.Server.GameObjects.Components.Projectiles; using Content.Server.GameObjects.Components.Weapon.Melee; using Content.Server.GameObjects.Components.Materials; using Content.Server.GameObjects.Components.Stack; using Content.Server.GameObjects.Components.Construction; using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.EntitySystems; using Content.Server.Mobs; using Content.Server.Players; using Content.Server.GameObjects.Components.Interactable; using Content.Shared.GameObjects.Components.Inventory; namespace Content.Server { public class EntryPoint : GameServer { const string PlayerPrototypeName = "HumanMob_Content"; private IBaseServer _server; private IPlayerManager _players; private IEntityManager entityManager; private IChatManager chatManager; private bool _countdownStarted; private GridLocalCoordinates SpawnPoint; /// public override void Init() { base.Init(); _server = IoCManager.Resolve(); _players = IoCManager.Resolve(); entityManager = IoCManager.Resolve(); chatManager = IoCManager.Resolve(); _server.RunLevelChanged += HandleRunLevelChanged; _players.PlayerStatusChanged += HandlePlayerStatusChanged; var factory = IoCManager.Resolve(); factory.Register(); factory.RegisterReference(); factory.Register(); factory.Register(); factory.Register(); factory.RegisterReference(); factory.Register(); factory.RegisterReference(); factory.Register(); factory.Register(); factory.Register(); factory.Register(); //Power Components factory.Register(); factory.Register(); factory.RegisterReference(); factory.Register(); factory.Register(); factory.RegisterReference(); factory.Register(); factory.RegisterReference(); factory.Register(); factory.Register(); //Tools factory.Register(); factory.Register(); factory.Register(); factory.Register(); factory.Register(); factory.Register(); factory.Register(); factory.Register(); factory.Register(); factory.Register(); factory.Register(); factory.Register(); factory.RegisterReference(); factory.Register(); factory.Register(); factory.Register(); factory.Register(); factory.Register(); factory.Register(); factory.Register(); factory.Register(); factory.RegisterIgnore("ConstructionGhost"); factory.Register(); } /// protected override void Dispose(bool disposing) { if (disposing) { _server.RunLevelChanged -= HandleRunLevelChanged; _players.PlayerStatusChanged -= HandlePlayerStatusChanged; } base.Dispose(disposing); } private void HandleRunLevelChanged(object sender, RunLevelChangedEventArgs args) { switch (args.NewLevel) { case ServerRunLevel.PreGame: var timing = IoCManager.Resolve(); var mapLoader = IoCManager.Resolve(); var mapMan = IoCManager.Resolve(); 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."); chatManager.DispatchMessage(ChatChannel.Server, "Gamemode: Round loaded!"); break; case ServerRunLevel.Game: _players.SendJoinGameToAll(); chatManager.DispatchMessage(ChatChannel.Server, "Gamemode: Round started!"); break; case ServerRunLevel.PostGame: chatManager.DispatchMessage(ChatChannel.Server, "Gamemode: Round over!"); break; } } private void HandlePlayerStatusChanged(object sender, SessionStatusEventArgs args) { var session = args.Session; switch (args.NewStatus) { case SessionStatus.Connected: { if (session.Data.ContentDataUncast == null) { session.Data.ContentDataUncast = new PlayerData(session.SessionId); } // timer time must be > tick length Timer.Spawn(250, args.Session.JoinLobby); chatManager.DispatchMessage(ChatChannel.Server, "Gamemode: Player joined server!", args.Session.SessionId); } break; case SessionStatus.InLobby: { // auto start game when first player joins if (_server.RunLevel == ServerRunLevel.PreGame && !_countdownStarted) { _countdownStarted = true; Timer.Spawn(2000, () => { _server.RunLevel = ServerRunLevel.Game; _countdownStarted = false; }); } chatManager.DispatchMessage(ChatChannel.Server, "Gamemode: Player joined Lobby!", args.Session.SessionId); } break; case SessionStatus.InGame: { //TODO: Check for existing mob and re-attach var data = session.ContentData(); if (data.Mind == null) { // No mind yet (new session), make a new one. data.Mind = new Mind(session.SessionId); var mob = SpawnPlayerMob(); data.Mind.TransferTo(mob); } else { 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); } break; case SessionStatus.Disconnected: { chatManager.DispatchMessage(ChatChannel.Server, "Gamemode: Player left!", args.Session.SessionId); } 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()); inventory.Equip(EquipmentSlotDefines.Slots.SHOES, shoes.GetComponent()); } return entity; } } }