public override void OnTick(GameLevel gameLevel, int currentTick, out int outTick) { outTick = currentTick; if (TimeRemaining-- >= 0) { string message; if (TimeRemaining == 0) { message = "§r§f §r"; } else { int timeRemaining = TimeRemaining / 2; message = $"§d§lGame Ended:§r §fNext Game in §7{timeRemaining} §fSecond{(timeRemaining != 1 ? "s" : "")}..."; } gameLevel.DoForAllPlayers(player => { player.BarHandler.AddMajorLine(message, 4, 3); }); } else { List <SkyPlayer> remainingPlayers = gameLevel.GetAllPlayers(); if (remainingPlayers.Count > 0) { foreach (SkyPlayer player in remainingPlayers) { gameLevel.RemovePlayer(player); if (SkyCoreAPI.IsRebootQueued) { player.BarHandler.AddMajorLine(("§d§lGame Ending: §r§fMoving to Network Lobby..."), 20, 7); ExternalGameHandler.AddPlayer(player, "hub"); } else { ExternalGameHandler.AddPlayer(player, gameLevel.GameType); } } } Thread.Sleep(5000); gameLevel.UpdateGameState(new VoidGameState()); } }
public override void EnterState(GameLevel gameLevel) { base.EnterState(gameLevel); GunPartLocations.Clear(); PlayerSpawnLocations.Clear(); GunPartLocations.AddRange(((MurderLevelInfo)((MurderLevel)gameLevel).GameLevelInfo).GunPartLocations); PlayerSpawnLocations.AddRange(((MurderLevelInfo)((MurderLevel)gameLevel).GameLevelInfo).PlayerSpawnLocations); while (PlayerSpawnLocations.Count < gameLevel.GetMaxPlayers()) { PlayerSpawnLocations.Add(((MurderLevelInfo)((MurderLevel)gameLevel).GameLevelInfo).PlayerSpawnLocations[0]); } EndTick = gameLevel.Tick + MaxGameTime + PreStartTime; try { RunnableTask.RunTask(() => { //Create new collection due to iterating over a live list ICollection <SkyPlayer> players = gameLevel.GetAllPlayers(); foreach (SkyPlayer player in players) { player.SetEffect(new Blindness { Duration = 80, Particles = false }); //Should be 3 seconds? player.SetHideNameTag(true); player.IsAlwaysShowName = false; player.SetNameTagVisibility(false); } List <PlayerLocation> usedSpawnLocations = new List <PlayerLocation>(); gameLevel.DoForAllPlayers(player => { //Pre-add all players to the map to avoid any unnecessary contains if (PlayerAmmoCounts.ContainsKey(player.Username)) { PlayerAmmoCounts[player.Username] = 0; } else { PlayerAmmoCounts.Add(player.Username, 0); } if (PlayerGunPartCounts.ContainsKey(player.Username)) { PlayerGunPartCounts[player.Username] = 0; } else { PlayerGunPartCounts.Add(player.Username, 0); } player.SetGameMode(GameMode.Adventure); //Avoid spawning two players in the same location PlayerLocation spawnLocation; while (usedSpawnLocations.Contains((spawnLocation = PlayerSpawnLocations[Random.Next(PlayerSpawnLocations.Count)]))) { // } usedSpawnLocations.Add(spawnLocation); //Mark spawn position for AFK Check player.SpawnPosition = spawnLocation; player.Teleport(spawnLocation); player.SetHideNameTag(true); player.IsAlwaysShowName = false; player.SetNameTagVisibility(false); player.Freeze(true); player.HungerManager.Hunger = 6; //Set food to 'unable to run' level. player.SendUpdateAttributes(); //TODO: Not required? Or is this required for Hunger }); List <MurderTeam> teamRotation = new List <MurderTeam> { MurderTeam.Murderer, MurderTeam.Detective, MurderTeam.Innocent }; int offset = Random.Next(teamRotation.Count); for (int i = 0; i < 12; i++) { MurderTeam team = teamRotation[(offset + i) % 3]; foreach (SkyPlayer player in players) { TitleUtil.SendCenteredSubtitle(player, team.TeamPrefix + "§l" + team.TeamName); //Poorly enforce speed if (i == 0 || i == 11) { player.Freeze(true); player.SetHideNameTag(true); player.IsAlwaysShowName = false; player.SetNameTagVisibility(false); } } //SkyUtil.log($"Printed scroll {i}/12, with {team.TeamPrefix + "§l" + team.TeamName}"); Thread.Sleep(250); } int murdererIdx = Random.Next(players.Count), detectiveIdx = 0; int idx = 0; while (++idx < 50 && (detectiveIdx = Random.Next(players.Count)) == murdererIdx) { // } //Console.WriteLine($"Rolled Murderer as {murdererIdx} Detective as {detectiveIdx} with 0-{players.Count - 1} possible indexes"); idx = 0; foreach (SkyPlayer player in players) { if (idx == murdererIdx) { gameLevel.SetPlayerTeam(player, MurderTeam.Murderer); } else if (idx == detectiveIdx) { gameLevel.SetPlayerTeam(player, MurderTeam.Detective); } else { gameLevel.SetPlayerTeam(player, MurderTeam.Innocent); } idx++; } //Workaround for one player (single murderer) if (((MurderLevel)gameLevel).Detective == null) { ((MurderLevel)gameLevel).Detective = ((MurderLevel)gameLevel).Murderer; } gameLevel.DoForPlayersIn(player => { TitleUtil.SendCenteredSubtitle(player, "§a§lInnocent §r\n§7Track down the murderer!"); }, MurderTeam.Innocent); gameLevel.DoForPlayersIn(player => { TitleUtil.SendCenteredSubtitle(player, "§9§lDetective §r\n§7Track down the murderer!"); player.Inventory.SetInventorySlot(0, new ItemInnocentGun()); //SkyUtil.log($"In Slot 0 = {player.Inventory.GetSlots()[0].GetType().FullName}"); player.Inventory.SetInventorySlot(9, new ItemArrow()); PlayerAmmoCounts[player.Username] = int.MaxValue; }, MurderTeam.Detective); gameLevel.DoForPlayersIn(InitializeMurderer, MurderTeam.Murderer); gameLevel.DoForAllPlayers(player => { player.SendAdventureSettings(); player.Freeze(false); //Ensure this player is at the correct spawn location if (gameLevel.GetBlock(player.KnownPosition).Id != 0) { PlayerLocation newLocation = (PlayerLocation)player.KnownPosition.Clone(); newLocation.Y++; player.Teleport(newLocation); } }); }); } catch (Exception e) { BugSnagUtil.ReportBug(e, this, gameLevel); } }