diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java index 183b32313..67403386f 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java @@ -168,8 +168,10 @@ public class UtilAlg public static T Random(List list) { - if (list.isEmpty()) + if (list == null || list.isEmpty()) + { return null; + } return list.get(UtilMath.r(list.size())); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/game/nano/NanoFavourite.java b/Plugins/Mineplex.Core/src/mineplex/core/game/nano/NanoFavourite.java index a020e65a3..a44bac9e1 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/game/nano/NanoFavourite.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/game/nano/NanoFavourite.java @@ -50,6 +50,14 @@ public class NanoFavourite extends MiniDbClientPlugin> while (resultSet.next()) { + // To fix an issue where players could set more than 3 by being on EU and US at the same time + if (games.size() >= MAX_FAVOURITES) + { + _repository.clearFavourites(accountId); + games.clear(); + return; + } + NanoDisplay display = NanoDisplay.getFromId(resultSet.getInt("gameId")); if (display == null) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/game/nano/NanoRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/game/nano/NanoRepository.java index 051531c49..7c9e00619 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/game/nano/NanoRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/game/nano/NanoRepository.java @@ -9,14 +9,20 @@ public class NanoRepository extends RepositoryBase private static final String ADD_FAVOURITE = "INSERT INTO accountFavouriteNano VALUES (?,?);"; private static final String REMOVE_FAVOURITE = "DELETE FROM accountFavouriteNano WHERE accountId=? AND gameId=?;"; + private static final String CLEAR_FAVOURITES = "DELETE FROM accountFavouriteNano WHERE accountId=?;"; NanoRepository() { super(DBPool.getAccount()); } - public void setFavourite(int accountId, int gameId, boolean favourite) + void setFavourite(int accountId, int gameId, boolean favourite) { executeInsert(favourite ? ADD_FAVOURITE : REMOVE_FAVOURITE, null, new ColumnInt("accountId", accountId), new ColumnInt("gameId", gameId)); } + + void clearFavourites(int accountId) + { + executeUpdate(CLEAR_FAVOURITES, new ColumnInt("accountId", accountId)); + } } diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/components/currency/GameCurrencyManager.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/components/currency/GameCurrencyManager.java index 34aa54463..6e2d3fe57 100644 --- a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/components/currency/GameCurrencyManager.java +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/components/currency/GameCurrencyManager.java @@ -186,12 +186,14 @@ public class GameCurrencyManager extends GameManager implements CurrencyComponen if (_manager.getServerGroup().getRewardStats()) { + int gamesPlayed = (int) Math.floor(data.Games / 5D); + // TODO enable game specific stats after beta _manager.getStatsManager().incrementStat(player, "Global.GemsEarned", gems); //_manager.getStatsManager().incrementStat(player, gameName + ".GemsEarned", gems); _manager.getStatsManager().incrementStat(player, "Global.ExpEarned", exp); //_manager.getStatsManager().incrementStat(player, gameName + ".ExpEarned", exp); - _manager.getStatsManager().incrementStat(player, "Global.GamesPlayed", data.Games); + _manager.getStatsManager().incrementStat(player, "Global.GamesPlayed", gamesPlayed); //_manager.getStatsManager().incrementStat(player, gameName + ".GamesPlayed", data.Games); require(TrackManager.class).getTrack(GemCollectorTrack.class).earnedGems(player, gems); } diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/components/player/DoubleJumpComponent.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/components/player/DoubleJumpComponent.java new file mode 100644 index 000000000..eefdbbb84 --- /dev/null +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/components/player/DoubleJumpComponent.java @@ -0,0 +1,80 @@ +package mineplex.game.nano.game.components.player; + +import org.bukkit.Effect; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerToggleFlightEvent; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.nano.game.Game; +import mineplex.game.nano.game.Game.GameState; +import mineplex.game.nano.game.GameComponent; + +public class DoubleJumpComponent extends GameComponent +{ + + private double _magnitude = 1.2; + + public DoubleJumpComponent(Game game) + { + super(game, GameState.Live); + } + + @Override + public void disable() + { + + } + + public DoubleJumpComponent setMagnitude(double magnitude) + { + _magnitude = magnitude; + return this; + } + + @EventHandler(priority = EventPriority.HIGH) + public void updateJump(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + for (Player player : getGame().getAlivePlayers()) + { + if (player.getAllowFlight()) + { + continue; + } + + if (UtilEnt.isGrounded(player)) + { + player.setAllowFlight(true); + } + } + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void toggleFlight(PlayerToggleFlightEvent event) + { + Player player = event.getPlayer(); + + if (!event.isFlying() || !getGame().isAlive(player)) + { + return; + } + + Vector velocity = player.getLocation().getDirection(); + velocity.setY(velocity.getY() + 0.2).multiply(_magnitude); + + UtilAction.velocity(player, velocity); + event.setCancelled(true); + player.setAllowFlight(false); + player.playEffect(player.getLocation(), Effect.BLAZE_SHOOT, 8); + } +} diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/dropper/Dropper.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/dropper/Dropper.java index 8bf2e9007..adbe79154 100644 --- a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/dropper/Dropper.java +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/dropper/Dropper.java @@ -12,6 +12,8 @@ import org.bukkit.event.EventHandler; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; +import com.mineplex.anticheat.checks.move.Glide; + import mineplex.core.common.util.C; import mineplex.core.common.util.F; import mineplex.core.common.util.MapUtil; @@ -80,6 +82,9 @@ public class Dropper extends SoloGame scoreboard.draw(); }); + + // Temporary fix to fix rubber banding + _manager.getAntiHack().addIgnoredCheck(Glide.class); } @Override @@ -106,7 +111,7 @@ public class Dropper extends SoloGame @Override public boolean endGame() { - return false; + return getAlivePlayers().isEmpty(); } @Override @@ -141,6 +146,11 @@ public class Dropper extends SoloGame @EventHandler public void npcInteract(NPCInteractEvent event) { + if (!isLive()) + { + return; + } + Player player = event.getPlayer(); if (!event.getNpc().getMetadata().equals(getGameType().getName()) || !isAlive(player)) diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/kingslime/KingSlime.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/kingslime/KingSlime.java index 5a6e9bd04..13c575b30 100644 --- a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/kingslime/KingSlime.java +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/kingslime/KingSlime.java @@ -31,13 +31,14 @@ import mineplex.core.updater.event.UpdateEvent; import mineplex.game.nano.NanoManager; import mineplex.game.nano.game.GameType; import mineplex.game.nano.game.ScoredSoloGame; +import mineplex.game.nano.game.components.player.DoubleJumpComponent; import mineplex.game.nano.game.event.GameStateChangeEvent; import mineplex.minecraft.game.core.damage.CustomDamageEvent; public class KingSlime extends ScoredSoloGame { - private static final int MAX_SLIMES = 30; + private static final int MAX_SLIMES = 40; private static final int MAX_BALLS = 10; private static final String SLIME_NAME = "Big Brian"; @@ -61,12 +62,15 @@ public class KingSlime extends ScoredSoloGame _prepareComponent.setPrepareFreeze(false); - _damageComponent.setPvp(false); - _damageComponent.setFall(false); + _damageComponent + .setPvp(false) + .setFall(false); _spectatorComponent.setDeathOut(false); - _endComponent.setTimeout(TimeUnit.SECONDS.toMillis(90)); + _endComponent.setTimeout(TimeUnit.SECONDS.toMillis(80)); + + new DoubleJumpComponent(this); } @Override diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/microbattle/components/MapCourruptionComponent.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/microbattle/components/MapCourruptionComponent.java index 9ece927ea..f1d8ea9bf 100644 --- a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/microbattle/components/MapCourruptionComponent.java +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/microbattle/components/MapCourruptionComponent.java @@ -14,6 +14,7 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockPhysicsEvent; import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntityChangeBlockEvent; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import mineplex.core.common.Pair; @@ -229,6 +230,12 @@ public class MapCourruptionComponent extends GameComponent addWorldBlock(event.getBlock()); } + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void entityChangeBlock(EntityChangeBlockEvent event) + { + addWorldBlock(event.getBlock()); + } + @EventHandler public void corruptionDamage(UpdateEvent event) { diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/Challenge.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/Challenge.java index a82ad404e..1d69175fc 100644 --- a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/Challenge.java +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/Challenge.java @@ -40,6 +40,7 @@ public abstract class Challenge extends ListenerComponent implements Lifetimed, protected List _players; protected long _startTime; protected long _timeout = TimeUnit.SECONDS.toMillis(10); + private int _startingPlayers; private boolean _playerWon; protected boolean _pvp; @@ -58,6 +59,7 @@ public abstract class Challenge extends ListenerComponent implements Lifetimed, { _startTime = System.currentTimeMillis(); _players = _game.getAlivePlayers(); + _startingPlayers = _players.size(); _lifetime.start(); _players.forEach(player -> _game.respawnPlayer(player, _game.getPlayersTeam())); @@ -181,7 +183,7 @@ public abstract class Challenge extends ListenerComponent implements Lifetimed, } else if (event.getType() == UpdateType.FASTER) { - if (_players.isEmpty() || UtilTime.elapsed(_startTime, _timeout) || (_winConditions.isLastOne() && _players.size() == 1)) + if (_players.isEmpty() || UtilTime.elapsed(_startTime, _timeout) || (_winConditions.isLastOne() && _players.size() == 1) || (_winConditions.isLastThree() && _players.size() <= getPlayersToEnd())) { end(); } @@ -213,6 +215,11 @@ public abstract class Challenge extends ListenerComponent implements Lifetimed, } } + private int getPlayersToEnd() + { + return _startingPlayers > 5 ? 3 : 1; + } + boolean isPvp() { return _pvp; diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/ChallengeType.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/ChallengeType.java index 320b46f6f..1e3c0cd7c 100644 --- a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/ChallengeType.java +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/ChallengeType.java @@ -8,12 +8,18 @@ import mineplex.game.nano.game.games.quick.challenges.ChallengeEnchantItem; import mineplex.game.nano.game.games.quick.challenges.ChallengeFood; import mineplex.game.nano.game.games.quick.challenges.ChallengeIgniteTNT; import mineplex.game.nano.game.games.quick.challenges.ChallengeIntoVoid; +import mineplex.game.nano.game.games.quick.challenges.ChallengeMaths; +import mineplex.game.nano.game.games.quick.challenges.ChallengeMilkCow; +import mineplex.game.nano.game.games.quick.challenges.ChallengePickASide; import mineplex.game.nano.game.games.quick.challenges.ChallengePlatform; +import mineplex.game.nano.game.games.quick.challenges.ChallengePlayMusic; import mineplex.game.nano.game.games.quick.challenges.ChallengePole; import mineplex.game.nano.game.games.quick.challenges.ChallengePunchAPig; import mineplex.game.nano.game.games.quick.challenges.ChallengeRedBlocks; +import mineplex.game.nano.game.games.quick.challenges.ChallengeReverseRunner; import mineplex.game.nano.game.games.quick.challenges.ChallengeSlimeJump; import mineplex.game.nano.game.games.quick.challenges.ChallengeSpeedBridge; +import mineplex.game.nano.game.games.quick.challenges.ChallengeSpin; import mineplex.game.nano.game.games.quick.challenges.ChallengeSpleef; import mineplex.game.nano.game.games.quick.challenges.ChallengeStandStill; import mineplex.game.nano.game.games.quick.challenges.ChallengeSumo; @@ -27,7 +33,7 @@ public enum ChallengeType INTO_VOID(ChallengeIntoVoid.class, "Jump into the Void!"), SUMO(ChallengeSumo.class, "Knock other players off the platform!"), CRAFT_ITEM(ChallengeCraftItem.class, "Craft the item shown!"), - ENCHANT_ITEM(ChallengeEnchantItem.class, "Enchant a sword"), + ENCHANT_ITEM(ChallengeEnchantItem.class, "Enchant a sword!"), RED_BLOCKS(ChallengeRedBlocks.class, "Don't fall into the void!"), POLE(ChallengePole.class, "Get as high as you can!"), CROUCH(ChallengeCrouch.class, "Crouch/Sneak!"), @@ -42,7 +48,12 @@ public enum ChallengeType SLIME_JUMP(ChallengeSlimeJump.class, "Get on the emerald blocks!"), PUNCH_A_PIG(ChallengePunchAPig.class, "Punch 5 Pigs!"), IGNITE_TNT(ChallengeIgniteTNT.class, "Ignite the TNT!"), - + SPIN(ChallengeSpin.class, "Spin around has fast as you can!"), + PLAY_MUSIC(ChallengePlayMusic.class, "Play a song on the noteblocks!"), + MATHS_QUESTION(ChallengeMaths.class, "Get ready! Solve this math equation..."), + MILK_A_COW(ChallengeMilkCow.class, "Drink the milk from one of the cows!"), + PICK_A_SIDE(ChallengePickASide.class, "Stand on the side with the least players."), + REVERSE_RUNNER(ChallengeReverseRunner.class, "Reverse Runner, Avoid the falling blocks!") ; diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/ChallengeWinConditions.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/ChallengeWinConditions.java index f50a706fa..62d37045f 100644 --- a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/ChallengeWinConditions.java +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/ChallengeWinConditions.java @@ -3,7 +3,7 @@ package mineplex.game.nano.game.games.quick; public class ChallengeWinConditions { - private boolean _lastOne, _timeoutWin; + private boolean _lastOne, _lastThree, _timeoutWin; private boolean _timeoutAfterFirst; public ChallengeWinConditions setLastOne(boolean lastOne) @@ -18,6 +18,18 @@ public class ChallengeWinConditions return _lastOne; } + public ChallengeWinConditions setLastThree(boolean lastThree) + { + setTimeoutWin(true); + _lastThree = lastThree; + return this; + } + + public boolean isLastThree() + { + return _lastThree; + } + public ChallengeWinConditions setTimeoutWin(boolean timeoutWin) { _timeoutWin = timeoutWin; diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/Quick.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/Quick.java index f73fdb832..103154e0d 100644 --- a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/Quick.java +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/Quick.java @@ -31,6 +31,8 @@ import mineplex.game.nano.game.GameType; import mineplex.game.nano.game.ScoredSoloGame; import mineplex.game.nano.game.components.player.NightVisionComponent; import mineplex.game.nano.game.event.PlayerDeathOutEvent; +import mineplex.minecraft.game.core.combat.DeathMessageType; +import mineplex.minecraft.game.core.combat.event.CombatDeathEvent; public class Quick extends ScoredSoloGame { @@ -247,6 +249,12 @@ public class Quick extends ScoredSoloGame event.setShouldRespawn(true); } + @EventHandler + public void combatDeath(CombatDeathEvent event) + { + event.SetBroadcastType(DeathMessageType.Simple); + } + @EventHandler(priority = EventPriority.HIGHEST) public void playerJoin(PlayerJoinEvent event) { diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeIgniteTNT.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeIgniteTNT.java index d98ae803b..8e6c3fa9f 100644 --- a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeIgniteTNT.java +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeIgniteTNT.java @@ -22,6 +22,8 @@ import mineplex.game.nano.game.games.quick.Quick; public class ChallengeIgniteTNT extends Challenge { + private int _tnt; + public ChallengeIgniteTNT(Quick game) { super(game, ChallengeType.IGNITE_TNT); @@ -32,9 +34,9 @@ public class ChallengeIgniteTNT extends Challenge { List corners = _game.getOrangePoints(); List blocks = UtilBlock.getInBoundingBox(corners.get(0), corners.get(1), false); - int max = Math.min(20, _players.size() / 2); + _tnt = Math.min(20, _players.size() / 2); - for (int i = 0; i < max; i++) + for (int i = 0; i < _tnt; i++) { Block block = UtilAlg.Random(blocks); @@ -51,6 +53,7 @@ public class ChallengeIgniteTNT extends Challenge for (Player player : _players) { player.getInventory().addItem(itemStack); + player.getInventory().setHeldItemSlot(0); player.setGameMode(GameMode.SURVIVAL); } } @@ -83,6 +86,15 @@ public class ChallengeIgniteTNT extends Challenge return; } - _game.getManager().runSyncLater(() -> completePlayer(player, true), 0); + + _game.getManager().runSyncLater(() -> + { + completePlayer(player, true); + + if (--_tnt <= 0) + { + end(); + } + }, 0); } } diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeMaths.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeMaths.java new file mode 100644 index 000000000..8753e95e5 --- /dev/null +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeMaths.java @@ -0,0 +1,66 @@ +package mineplex.game.nano.game.games.quick.challenges; + +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.AsyncPlayerChatEvent; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.game.nano.game.games.quick.Challenge; +import mineplex.game.nano.game.games.quick.ChallengeType; +import mineplex.game.nano.game.games.quick.Quick; + +public class ChallengeMaths extends Challenge +{ + + private int _solution; + + public ChallengeMaths(Quick game) + { + super(game, ChallengeType.MATHS_QUESTION); + } + + @Override + public void challengeSelect() + { + _game.getManager().runSyncLater(() -> + { + int a = UtilMath.rRange(3, 10), b = UtilMath.rRange(3, 10); + _solution = a * b; + + UtilTextMiddle.display(C.cYellow + a + " x " + b, "Type your answer in chat!", 0, 80, 0, UtilServer.getPlayers()); + _game.announce(F.main(_game.getManager().getName(), "Solve " + F.elem(a + " x " + b) + "!"), Sound.NOTE_SNARE_DRUM); + }, 40); + } + + @Override + public void disable() + { + + } + + @EventHandler + public void playerChat(AsyncPlayerChatEvent event) + { + if (_solution == 0) + { + return; + } + + Player player = event.getPlayer(); + + if (event.getMessage().equals(String.valueOf(_solution))) + { + completePlayer(player, false); + event.setCancelled(true); + } + else + { + failPlayer(player, false); + } + } +} diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeMilkCow.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeMilkCow.java new file mode 100644 index 000000000..b21968d46 --- /dev/null +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeMilkCow.java @@ -0,0 +1,70 @@ +package mineplex.game.nano.game.games.quick.challenges; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Cow; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerItemConsumeEvent; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilEnt; +import mineplex.game.nano.game.games.quick.Challenge; +import mineplex.game.nano.game.games.quick.ChallengeType; +import mineplex.game.nano.game.games.quick.Quick; + +public class ChallengeMilkCow extends Challenge +{ + + public ChallengeMilkCow(Quick game) + { + super(game, ChallengeType.MILK_A_COW); + + _winConditions.setTimeoutAfterFirst(true); + } + + @Override + public void challengeSelect() + { + _game.getWorldComponent().setCreatureAllowOverride(true); + + _game.getGreenPoints().forEach(location -> + { + Location spawn = location.clone(); + + spawn.setYaw(UtilAlg.GetYaw(UtilAlg.getTrajectory(_game.getSpectatorLocation(), spawn))); + + Cow cow = spawn.getWorld().spawn(spawn, Cow.class); + + UtilEnt.vegetate(cow); + UtilEnt.ghost(cow, true, false); + UtilEnt.setFakeHead(cow, true); + }); + + _game.getWorldComponent().setCreatureAllowOverride(false); + + ItemStack itemStack = new ItemStack(Material.BUCKET); + + for (Player player : _players) + { + player.getInventory().addItem(itemStack); + player.getInventory().setHeldItemSlot(0); + } + } + + @Override + public void disable() + { + + } + + @EventHandler + public void playerItemConsume(PlayerItemConsumeEvent event) + { + if (event.getItem().getType() == Material.MILK_BUCKET) + { + completePlayer(event.getPlayer(), false); + } + } +} diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengePickASide.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengePickASide.java new file mode 100644 index 000000000..6fedd5a56 --- /dev/null +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengePickASide.java @@ -0,0 +1,102 @@ +package mineplex.game.nano.game.games.quick.challenges; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import mineplex.core.common.util.MapUtil; +import mineplex.core.common.util.UtilBlock; +import mineplex.game.nano.game.games.quick.Challenge; +import mineplex.game.nano.game.games.quick.ChallengeType; +import mineplex.game.nano.game.games.quick.Quick; + +public class ChallengePickASide extends Challenge +{ + + private int _middleZ; + + public ChallengePickASide(Quick game) + { + super(game, ChallengeType.PICK_A_SIDE); + } + + @Override + public void challengeSelect() + { + _middleZ = _game.getMineplexWorld().getIronLocation("LIGHT_BLUE").getBlockZ(); + + List corners = _game.getOrangePoints(); + UtilBlock.getInBoundingBox(corners.get(0), corners.get(1), false).forEach(block -> + { + int z = block.getZ(); + byte data = 0; + + if (z > _middleZ) + { + data = 14; + } + else if (z < _middleZ) + { + data = 11; + } + + MapUtil.QuickChangeBlockAt(block.getLocation(), Material.STAINED_CLAY, data); + }); + } + + @Override + public void disable() + { + + } + + @Override + protected void completeRemaining() + { + List total = _game.getAlivePlayers(); + List redSide = new ArrayList<>(); + + for (Player player : total) + { + int z = player.getLocation().getBlockZ(); + + if (z == _middleZ) + { + failPlayer(player, true); + } + else if (z > _middleZ) + { + redSide.add(player); + } + } + + int redPlayers = redSide.size(), bluePlayers = total.size() - redSide.size(); + + if (redPlayers == bluePlayers) + { + for (Player player : total) + { + completePlayer(player, true); + } + } + else + { + boolean containsWin = redPlayers < bluePlayers; + + for (Player player : total) + { + if ((containsWin && redSide.contains(player)) || (!containsWin && !redSide.contains(player))) + { + completePlayer(player, true); + } + else + { + failPlayer(player, true); + } + } + } + } +} diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengePlayMusic.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengePlayMusic.java new file mode 100644 index 000000000..d8581e3ac --- /dev/null +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengePlayMusic.java @@ -0,0 +1,112 @@ +package mineplex.game.nano.game.games.quick.challenges; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerInteractEvent; + +import mineplex.core.common.util.MapUtil; +import mineplex.core.common.util.UtilEvent; +import mineplex.core.common.util.UtilEvent.ActionType; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.noteblock.NBSReader; +import mineplex.core.noteblock.Note; +import mineplex.core.noteblock.NoteSong; +import mineplex.core.noteblock.UtilNote; +import mineplex.game.nano.game.games.quick.Challenge; +import mineplex.game.nano.game.games.quick.ChallengeType; +import mineplex.game.nano.game.games.quick.Quick; + +public class ChallengePlayMusic extends Challenge +{ + + private final NoteSong _song; + private final Map _songTick; + + public ChallengePlayMusic(Quick game) + { + super(game, ChallengeType.PLAY_MUSIC); + + NoteSong song; + + try + { + song = NBSReader.loadSong(".." + File.separator + ".." + File.separator + "update" + File.separator + "songs" + File.separator + "bebop.nbs"); + } + catch (FileNotFoundException e) + { + song = null; + e.printStackTrace(); + } + + _song = song; + _songTick = new HashMap<>(); + } + + @Override + public void challengeSelect() + { + _game.getGreenPoints().forEach(location -> MapUtil.QuickChangeBlockAt(location, Material.NOTE_BLOCK)); + } + + @Override + public void disable() + { + _songTick.clear(); + } + + @EventHandler + public void playerInteract(PlayerInteractEvent event) + { + if (!UtilEvent.isAction(event, ActionType.R_BLOCK)) + { + return; + } + + Player player = event.getPlayer(); + Block block = event.getClickedBlock(); + + if (block.getType() != Material.NOTE_BLOCK) + { + return; + } + + event.setCancelled(true); + + Location location = block.getLocation().add(0.5, 1.2, 0.5); + + UtilParticle.PlayParticle(ParticleType.NOTE, location, null, 0.1F, 1, ViewDist.NORMAL, player); + + int tick = _songTick.getOrDefault(player, 0); + _songTick.put(player, tick + 1); + + _song.getLayers().forEach(layer -> + { + Note note = layer.getNote(tick); + + if (note != null) + { + Sound sound = UtilNote.getInstrumentSound(note.getInstrument()); + float volume = layer.getVolume() / 100F; + float pitch = (float) UtilNote.getPitch(note.getNote() - 33); + + player.playSound(location, sound, volume, pitch); + } + }); + + if (tick == 10) + { + completePlayer(player, false); + } + } +} diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeReverseRunner.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeReverseRunner.java new file mode 100644 index 000000000..3671e1afd --- /dev/null +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeReverseRunner.java @@ -0,0 +1,75 @@ +package mineplex.game.nano.game.games.quick.challenges; + +import java.util.concurrent.TimeUnit; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import mineplex.core.common.util.UtilTime; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.nano.game.games.quick.Challenge; +import mineplex.game.nano.game.games.quick.ChallengeType; +import mineplex.game.nano.game.games.quick.Quick; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class ChallengeReverseRunner extends Challenge +{ + + public ChallengeReverseRunner(Quick game) + { + super(game, ChallengeType.REVERSE_RUNNER); + + _timeout = TimeUnit.MINUTES.toMillis(1); + + _winConditions.setLastThree(true); + } + + @Override + public void challengeSelect() + { + + } + + @Override + public void disable() + { + + } + + @EventHandler + public void updateBlocks(UpdateEvent event) + { + if (event.getType() != UpdateType.FASTER || !UtilTime.elapsed(_startTime, 2000)) + { + return; + } + + for (Player player : _players) + { + Location location = player.getLocation().add(0, 10, 0).getBlock().getLocation().add(0.5, 0, 0.5); + + if (!inArena(location)) + { + continue; + } + + FallingBlock fallingBlock = location.getWorld().spawnFallingBlock(location, Material.STAINED_CLAY, (byte) 14); + fallingBlock.setHurtEntities(true); + fallingBlock.setDropItem(false); + } + } + + @EventHandler(ignoreCancelled = true) + public void damage(CustomDamageEvent event) + { + if (event.GetCause() == DamageCause.SUFFOCATION) + { + event.AddMod("Falling Block", 4); + } + } +} diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeSlimeJump.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeSlimeJump.java index 99cd9b938..48097b6b2 100644 --- a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeSlimeJump.java +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeSlimeJump.java @@ -71,7 +71,7 @@ public class ChallengeSlimeJump extends Challenge { for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { - if (player.getLocation().subtract(x, 0.5, z).getBlock().getType() == Material.EMERALD_BLOCK) + if (player.getLocation().add(x, -0.5, z).getBlock().getType() == Material.EMERALD_BLOCK) { completePlayer(player, true); continue playerLoop; diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeSpin.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeSpin.java new file mode 100644 index 000000000..b7825e63d --- /dev/null +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeSpin.java @@ -0,0 +1,69 @@ +package mineplex.game.nano.game.games.quick.challenges; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.nano.game.games.quick.Challenge; +import mineplex.game.nano.game.games.quick.ChallengeType; +import mineplex.game.nano.game.games.quick.Quick; + +public class ChallengeSpin extends Challenge +{ + + private final Map _yaw; + + public ChallengeSpin(Quick game) + { + super(game, ChallengeType.SPIN); + + _yaw = new HashMap<>(); + + _timeout = TimeUnit.SECONDS.toMillis(5); + } + + @Override + public void challengeSelect() + { + for (Player player : _players) + { + _yaw.put(player, player.getLocation().getYaw()); + } + } + + @Override + public void disable() + { + _yaw.clear(); + } + + @EventHandler + public void updateSpin(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + { + return; + } + + _yaw.entrySet().forEach(entry -> + { + Player player = entry.getKey(); + float newYaw = player.getLocation().getYaw(); + float lastYaw = entry.getValue(); + + if (Math.abs(newYaw - lastYaw) > 180) + { + completePlayer(player, false); + } + else + { + entry.setValue(newYaw); + } + }); + } +} diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeSpleef.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeSpleef.java index 7a8ab67ee..ef3991512 100644 --- a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeSpleef.java +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeSpleef.java @@ -4,20 +4,26 @@ import java.util.List; import java.util.concurrent.TimeUnit; import org.bukkit.Effect; +import org.bukkit.EntityEffect; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.block.BlockDamageEvent; import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; import mineplex.core.common.util.MapUtil; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; import mineplex.core.common.util.UtilBlock; import mineplex.game.nano.game.games.quick.Challenge; import mineplex.game.nano.game.games.quick.ChallengeType; import mineplex.game.nano.game.games.quick.Quick; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; public class ChallengeSpleef extends Challenge { @@ -45,6 +51,26 @@ public class ChallengeSpleef extends Challenge } }, 20); + ItemStack snowball = new ItemStack(Material.SNOW_BALL); + + _game.getManager().runSyncTimer(new BukkitRunnable() + { + @Override + public void run() + { + if (!isRunning()) + { + cancel(); + return; + } + + for (Player player : _players) + { + player.getInventory().addItem(snowball); + } + } + }, 15 * 20, 15); + List corners = _game.getOrangePoints(); UtilBlock.getInBoundingBox(corners.get(0), corners.get(1), false).forEach(block -> MapUtil.QuickChangeBlockAt(block.getLocation(), Material.SNOW_BLOCK)); } @@ -79,4 +105,16 @@ public class ChallengeSpleef extends Challenge location.getWorld().playEffect(location, Effect.STEP_SOUND, block.getType()); MapUtil.QuickChangeBlockAt(location, Material.AIR); } + + @EventHandler + public void snowballDamage(CustomDamageEvent event) + { + if (event.GetProjectile() != null) + { + LivingEntity damagee = event.GetDamageeEntity(); + + damagee.playEffect(EntityEffect.HURT); + UtilAction.velocity(damagee, UtilAlg.getTrajectory2d(event.GetProjectile(), damagee).setY(0.4)); + } + } } diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeSumo.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeSumo.java index f7361b699..f595937b9 100644 --- a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeSumo.java +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeSumo.java @@ -33,7 +33,7 @@ public class ChallengeSumo extends Challenge _timeout = TimeUnit.MINUTES.toMillis(1); _pvp = true; - _winConditions.setLastOne(true); + _winConditions.setLastThree(true); } @Override diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeThrowEggs.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeThrowEggs.java index 03af7a77b..16cc15531 100644 --- a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeThrowEggs.java +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/quick/challenges/ChallengeThrowEggs.java @@ -3,6 +3,7 @@ package mineplex.game.nano.game.games.quick.challenges; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; import mineplex.core.updater.UpdateType; @@ -56,4 +57,10 @@ public class ChallengeThrowEggs extends Challenge completePlayer(player, false); } } + + @EventHandler + public void inventoryClick(InventoryClickEvent event) + { + event.setCancelled(true); + } }