public override void HandleLeave(GameLevel gameLevel, SkyPlayer player) { base.HandleLeave(gameLevel, player); if (((MurderLevel)gameLevel).Murderer == player) { //Re-select murderer List <SkyPlayer> players = gameLevel.GetPlayersInTeam(MurderTeam.Innocent); int murdererIdx = Random.Next(players.Count); int i = 0; foreach (SkyPlayer gamePlayer in players) { if (++i == murdererIdx) { gameLevel.SetPlayerTeam(gamePlayer, MurderTeam.Murderer); InitializeMurderer(gamePlayer); gameLevel.DoForAllPlayers(playerLoop => { if (playerLoop == gamePlayer) { return; } TitleUtil.SendCenteredSubtitle(playerLoop, "§fA new §c§lMurderer\n§fhas been selected"); }); break; } } } }
public void InitializeMurderer(SkyPlayer player) { TitleUtil.SendCenteredSubtitle(player, "§c§l Murderer§r\n§7Kill all innocent players!"); player.Inventory.SetInventorySlot(0, new ItemMurderKnife()); player.Inventory.SetInventorySlot(8, new ItemGunParts()); player.Inventory.SetHeldItemSlot(1); //Avoid holding the knife on spawn/select player.HungerManager.Hunger = 20; //Set food to 'able to run' level. player.SendUpdateAttributes(); //PlayerAmmoCounts[player.Username] = 3; //Throwing Knives }
public override void EnterState(GameLevel gameLevel) { base.EnterState(gameLevel); gameLevel.DoForAllPlayers(player => { player.Inventory.Clear(); player.AddExperience(-1000, true); //Reset gun cooldowns }); //MurderVictoryType victoryType; SkyPlayer murderer = ((MurderLevel)gameLevel).Murderer; //Innocents Win (Murderer Dead) if (gameLevel.GetPlayersInTeam(MurderTeam.Murderer).Count == 0) { //victoryType = MurderVictoryType.MURDERER_DEAD; gameLevel.DoForAllPlayers(player => { TitleUtil.SendCenteredSubtitle(player, $"§a§lInnocents §r§7§lWin§r\n§7{murderer?.Username ?? "An Unknown Player"} §fwas the Murderer!"); }); } //Murderer Wins (Innocents + Detective Dead) else if (gameLevel.GetPlayersInTeam(MurderTeam.Innocent, MurderTeam.Detective).Count == 0) { //victoryType = MurderVictoryType.CONQUEST; gameLevel.DoForAllPlayers(player => { TitleUtil.SendCenteredSubtitle(player, $"§c§lMurderer §r§7§lWins§r\n§7{murderer?.Username ?? "An Unknown Player"} §fwas the Murderer!"); }); } //Innocents Win (Timeout) else { //victoryType = MurderVictoryType.TIMEOUT; gameLevel.DoForAllPlayers(player => { TitleUtil.SendCenteredSubtitle(player, $"§a§lInnocents §r§7Win\n§7{murderer?.Username ?? "An Unknown Player"} §fwas the Murderer!"); }); } }
public void AddPlayer(SkyPlayer player) { InstanceInfo bestGameInstance = null; GameInfo bestAvailableGame = null; //SkyUtil.log($"Checking available games from all instances for {GameName} ({_gameInstances.Count} total instances to search)"); //Check current instance first if (_gameInstances.ContainsKey("local") && !SkyCoreAPI.IsRebootQueued) //Avoid moving players to this server if it's about to reboot { InstanceInfo instanceInfo = _gameInstances["local"]; string currentGameId = null; if (player.Level is GameLevel level) { currentGameId = level.GameId; } GameInfo nextBestGame = null; foreach (GameInfo gameInfo in instanceInfo.AvailableGames) { //SkyUtil.log($"Checking {gameInfo.GameId} on {instanceInfo.HostAddress}"); if ((bestAvailableGame == null || gameInfo.CurrentPlayers > bestAvailableGame.CurrentPlayers)) { //Try to avoid placing the player in the game they just came from. //Use this game as a fallback to avoid moving players off this instance. if (currentGameId != null && currentGameId.Equals(gameInfo.GameId)) { bestGameInstance = instanceInfo; nextBestGame = gameInfo; continue; } //SkyUtil.log("Found best game!"); bestGameInstance = instanceInfo; bestAvailableGame = gameInfo; } } if (bestAvailableGame == null) { bestAvailableGame = nextBestGame; } } if (bestAvailableGame == null) { foreach (InstanceInfo instanceInfo in _gameInstances.Values) { //SkyUtil.log($"Checking instance {instanceInfo.HostAddress} Available Servers: {instanceInfo.AvailableGames.Count}"); foreach (GameInfo gameInfo in instanceInfo.AvailableGames) { //SkyUtil.log($"Checking {gameInfo.GameId} on {instanceInfo.HostAddress}"); if (bestAvailableGame == null || gameInfo.CurrentPlayers > bestAvailableGame.CurrentPlayers) { //SkyUtil.log("Found best game!"); bestGameInstance = instanceInfo; bestAvailableGame = gameInfo; } } } } if (bestAvailableGame == null) { player.Freeze(false); //Unfreeze TitleUtil.SendCenteredSubtitle(player, $"§c§lGAME {(GetCurrentPlayers() > 0 ? "FULL" : "UNAVAILABLE")}§r\n§7Try joining again soon!", false); } else { if (player.Level is GameLevel level) { if (player.Level.LevelId.Equals(bestAvailableGame.GameId)) { return; //Cannot change game into current game. } //Remove player from level to avoid issues level.RemovePlayer(player); } if (bestGameInstance.HostAddress.Equals("local")) { SkyCoreAPI.Instance.GameModes[GameName].InstantQueuePlayer(player, bestAvailableGame); } else { ExternalGameHandler.RedisPool.GetSubscriber().PublishAsync($"{GameName}_join", $"{player.Username}:{GameName}:{bestAvailableGame.GameId}"); McpeTransfer transferPacket = new McpeTransfer { serverAddress = bestGameInstance.HostAddress, port = bestGameInstance.HostPort }; player.SendPackage(transferPacket); MiNET.Worlds.Level playerLevel = player.Level; RunnableTask.RunTaskLater(() => { if (playerLevel.Players.ContainsKey(player.EntityId)) { if (playerLevel is GameLevel gameLevel) { gameLevel.RemovePlayer(player); } playerLevel.RemoveEntity(player); playerLevel.Players.TryRemove(player.EntityId, out _); } }, 1000); } } }
public override void OnTick(GameLevel gameLevel, int currentTick, out int outTick) { base.OnTick(gameLevel, currentTick, out outTick); int secondsLeft; if (EndTick == -1) { secondsLeft = 0; //Trigger a initial refresh } else { secondsLeft = (EndTick - currentTick) / 2; } if (secondsLeft > MaxVoteTime / 2) { return; //Ignore until the ticker has finished } if (secondsLeft == 0) { //Can't execute first run if (_currentVotingPlayer != null) { //Tally up votes int currentVoteCount = 0; gameLevel.DoForAllPlayers(player => { switch (player.Inventory.InHandSlot) { case 2: currentVoteCount += 1; break; case 3: currentVoteCount += 2; break; case 4: currentVoteCount += 3; break; case 5: currentVoteCount += 4; break; case 6: currentVoteCount += 5; break; default: if (player.Inventory.InHandSlot < 2) { currentVoteCount += 1; //2 } else if (player.Inventory.InHandSlot > 6) { currentVoteCount += 5; } break; } }); _voteTally.TryAdd(_currentVotingPlayer, currentVoteCount); } else { //Reset gamemode during voting phase gameLevel.DoForAllPlayers(player => { //player.UseCreativeInventory = false; player.UpdateGameMode(GameMode.Adventure, true); }); } //Pick another player, or end the phase if all voting has finished BuildBattleLevel buildLevel = (BuildBattleLevel)gameLevel; SkyPlayer nextVotePlayer = null; do { var gameTeam = buildLevel.BuildTeams[++_currentVotingTeam]; List <SkyPlayer> teamPlayer = buildLevel.GetPlayersInTeam(gameTeam); if (teamPlayer.Count > 0) { nextVotePlayer = teamPlayer[0]; } } while (nextVotePlayer == null && _currentVotingTeam < buildLevel.BuildTeams.Count - 1); if (nextVotePlayer == null) { gameLevel.UpdateGameState(GetNextGameState(gameLevel)); return; } _currentVotingPlayer = nextVotePlayer; EndTick = gameLevel.Tick + MaxVoteTime; List <PlayerLocation> voteLocations = ((BuildBattleLevel)gameLevel).GetVoteLocations((BuildBattleTeam)_currentVotingPlayer.GameTeam); int i = -1; gameLevel.DoForAllPlayers(player => { player.SetAllowFly(true); player.IsFlying = true; player.SendAdventureSettings(); if (player == _currentVotingPlayer) { player.Inventory.Clear(); //Remove voting possibility PlayerLocation teleportLocation = (PlayerLocation)((BuildBattleTeam)player.GameTeam).SpawnLocation.Clone(); teleportLocation.Y += 10; player.Teleport(teleportLocation); } else { i++; for (int j = 1; j < 6; j++) { player.Inventory.SetInventorySlot(1 + j, new ItemVote(j, _currentVotingPlayer.Username)); } player.Inventory.SetHeldItemSlot(4); //Default to middle rating if AFK PlayerLocation voteSpawnLocation = voteLocations[i]; BlockCoordinates voteSpawnCoordinates = voteSpawnLocation.GetCoordinates3D(); while (!player.Level.IsAir(voteSpawnCoordinates)) { voteSpawnCoordinates.Y++; } voteSpawnLocation = new PlayerLocation(voteSpawnCoordinates.X, voteSpawnCoordinates.Y, voteSpawnCoordinates.Z, voteSpawnLocation.HeadYaw, voteSpawnLocation.Yaw, voteSpawnLocation.Pitch); player.Teleport(voteSpawnLocation); } TitleUtil.SendCenteredSubtitle(player, $"§d§lVoting for:\n§7{nextVotePlayer.Username}"); }); } gameLevel.DoForAllPlayers(player => { SendTickableMessage(gameLevel, player, GetTickableInformation(_currentVotingPlayer)); }); }
public override void EnterState(GameLevel gameLevel) { base.EnterState(gameLevel); gameLevel.DoForAllPlayers(player => { player.Inventory.Clear(); }); SkyPlayer winningPlayer = null; List <KeyValuePair <SkyPlayer, int> > topPlayers = null; if (_voteTally != null) { topPlayers = new List <KeyValuePair <SkyPlayer, int> >(); foreach (SkyPlayer player in _voteTally.Keys) { topPlayers.Add(new KeyValuePair <SkyPlayer, int>(player, _voteTally[player])); } topPlayers.Sort((x, y) => 0 - x.Value.CompareTo(y.Value)); int i = 0; foreach (KeyValuePair <SkyPlayer, int> topPlayer in topPlayers) { if (++i > 1) //Top 1 Player for now { break; } //If the player has left, skip them. if (!gameLevel.PlayerTeamDict.ContainsKey(topPlayer.Key.Username)) { i = 0; } else { winningPlayer = topPlayer.Key; } } } string winningPlayerName = winningPlayer == null ? "Unknown..." : winningPlayer.Username; List <PlayerLocation> podiumLocations; if (winningPlayer == null) { BuildBattleTeam podiumCentre; if (topPlayers == null || topPlayers.Count == 0) { //Pick a random team podiumCentre = ((BuildBattleLevel)gameLevel).BuildTeams[0]; } else { //Pick a random player podiumCentre = (BuildBattleTeam)topPlayers[0].Key.GameTeam; } podiumLocations = ((BuildBattleLevel)gameLevel).GetVoteLocations(podiumCentre); } else { podiumLocations = ((BuildBattleLevel)gameLevel).GetVoteLocations((BuildBattleTeam)winningPlayer.GameTeam); } int j = 0; gameLevel.DoForAllPlayers(player => { player.SetAllowFly(true); player.IsFlying = true; player.SendAdventureSettings(); player.Inventory.Clear(); TitleUtil.SendCenteredSubtitle(player, $"§a§lWinning Builder\n§7{winningPlayerName}"); if (player == winningPlayer) { PlayerLocation teleportLocation = (PlayerLocation)((BuildBattleTeam)player.GameTeam).SpawnLocation.Clone(); teleportLocation.Y += 10; player.Teleport(teleportLocation); } else { player.Teleport(podiumLocations[j]); j++; } }); RunnableTask.RunTaskLater(() => { gameLevel.UpdateGameState(GetNextGameState(gameLevel)); }, 5000); }
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); } }
public override void EnterState(GameLevel gameLevel) { EndTick = gameLevel.Tick + MaxGameTime + PreStartTime; RunnableTask.RunTask(() => { ICollection <MiNET.Player> players = new List <MiNET.Player>(gameLevel.Players.Values); foreach (BuildBattleTeam gameTeam in ((BuildBattleLevel)gameLevel).BuildTeams) { foreach (SkyPlayer player in gameLevel.GetPlayersInTeam(gameTeam)) { player.IsWorldImmutable = true; //Prevent Breaking //player.IsWorldBuilder = false; player.Teleport(gameTeam.SpawnLocation); player.SetAllowFly(true); player.IsFlying = true; player.SendAdventureSettings(); player.UseCreativeInventory = true; player.UpdateGameMode(GameMode.Creative, false); player.SetNameTagVisibility(false); } } List <BuildBattleTheme> categoryRotation = ((BuildBattleLevel)gameLevel).ThemeList; { int initialTheme = Random.Next(categoryRotation.Count); for (int i = initialTheme; i < (initialTheme + 12); i++) { BuildBattleTheme category = categoryRotation[i % categoryRotation.Count]; foreach (MiNET.Player player in players) { TitleUtil.SendCenteredSubtitle(player, category.ThemeName); } Thread.Sleep(250); } } SelectedCategory = categoryRotation[Random.Next(categoryRotation.Count)]; gameLevel.DoForAllPlayers(player => { player.IsWorldImmutable = true; //Allow breaking //player.IsWorldBuilder = false; player.SendAdventureSettings(); player.UpdateGameMode(GameMode.Creative, true); string secondLine = "§fYou have §75 minutes§f, let's go!"; TitleUtil.SendCenteredSubtitle(player, $"{SelectedCategory.ThemeName}\n{secondLine}"); player.Inventory.Clear(); for (int i = 0; i < SelectedCategory.TemplateItems.Count; i++) { player.Inventory.SetInventorySlot(i, SelectedCategory.TemplateItems[i].GetItem()); } //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); } }); gameLevel.AllowBreak = true; gameLevel.AllowBuild = true; }); }