diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/api/ApiHost.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/api/ApiHost.java index a6dd1cbae..b1593c552 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/api/ApiHost.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/api/ApiHost.java @@ -71,6 +71,11 @@ public class ApiHost return getAPIHost("ENDERCHEST"); } + public static ApiHost getBanner() + { + return getAPIHost("BANNER"); + } + private String _host; private int _port; diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/shape/ShapeWings.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/shape/ShapeWings.java index a1ec02bb5..3c9a78a56 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/shape/ShapeWings.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/shape/ShapeWings.java @@ -3,6 +3,7 @@ package mineplex.core.common.shape; import java.awt.Color; import org.bukkit.Location; +import org.bukkit.entity.Player; import org.bukkit.util.Vector; import mineplex.core.common.util.UtilParticle; @@ -276,41 +277,111 @@ public class ShapeWings extends ShapeGrid implements CosmeticShape rotateOnXAxis(xRotation); } + /** + * Displays the wing + * @param location The location to display the visual at + */ @Override - public void display(Location loc) + public void display(Location location) { Shape clone = clone(); - clone.rotateOnYAxis(Math.toRadians(loc.getYaw())); + clone.rotateOnYAxis(Math.toRadians(location.getYaw())); for (Vector v : clone.getPoints()) { - Location ploc = loc.clone().add(v); - displayParticle(ploc); + Location particleLocation = location.clone().add(v); + displayParticle(particleLocation); } } - public void displayColored(Location loc, Color color) + /** + * Displays the wing for the given player + * @param location The location to display the visual at + * @param player The player + */ + public void display(Location location, Player player) { Shape clone = clone(); - clone.rotateOnYAxis(Math.toRadians(loc.getYaw())); + clone.rotateOnYAxis(Math.toRadians(location.getYaw())); for (Vector v : clone.getPoints()) { - Location ploc = loc.clone().add(v); - displayColoredParticle(ploc, color); + Location particleLocation = location.clone().add(v); + displayParticle(particleLocation, player); } } - + + /** + * Displays the colored wing + * @param location The location to display the visual at + * @param color The color of the particles + */ + public void displayColored(Location location, Color color) + { + Shape clone = clone(); + clone.rotateOnYAxis(Math.toRadians(location.getYaw())); + for (Vector v : clone.getPoints()) + { + Location particleLocation = location.clone().add(v); + displayColoredParticle(particleLocation, color); + } + } + + /** + * Displays the colored wing for the given player + * @param location The location to display the visual at + * @param color The color of the particles + * @param player The player + */ + public void displayColored(Location location, Color color, Player player) + { + Shape clone = clone(); + clone.rotateOnYAxis(Math.toRadians(location.getYaw())); + for (Vector v : clone.getPoints()) + { + Location particleLocation = location.clone().add(v); + displayColoredParticle(particleLocation, color, player); + } + } + /** * Display a single particle of the type provided to this shape at the given location. + * @param location The location */ - public void displayParticle(Location loc) + public void displayParticle(Location location) { - UtilParticle.PlayParticleToAll(_particle, loc, _offsetData, _speed, _count, ViewDist.NORMAL); + UtilParticle.PlayParticleToAll(_particle, location, _offsetData, _speed, _count, ViewDist.NORMAL); } - public void displayColoredParticle(Location loc, Color color) + /** + * Display a single particle of the type provided to this shape at the given location for the given player + * @param location The location + * @param player The player + */ + public void displayParticle(Location location, Player player) { - ColoredParticle coloredParticle = new ColoredParticle(ParticleType.RED_DUST, new DustSpellColor(color), loc); + UtilParticle.PlayParticle(_particle, location, (float) _offsetData.getX(), (float) _offsetData.getY(), (float) _offsetData.getZ(), _speed, _count, ViewDist.NORMAL, player); + } + + /** + * Display a single colored particle of the type provided to this shape at the given location. + * @param location The location + * @param color The color + */ + public void displayColoredParticle(Location location, Color color) + { + ColoredParticle coloredParticle = new ColoredParticle(ParticleType.RED_DUST, new DustSpellColor(color), location); coloredParticle.display(ViewDist.NORMAL); } + /** + * Displays a single colored particle of the type provided to this shape at the given location for the given player + * @param location The location + * @param color The color + * @param player The player + */ + public void displayColoredParticle(Location location, Color color, Player player) + { + ColoredParticle coloredParticle = new ColoredParticle(ParticleType.RED_DUST, new DustSpellColor(color), location); + coloredParticle.display(ViewDist.NORMAL, player); + } + } diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java index bfc5e4ec8..19b7b6059 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java @@ -1,5 +1,6 @@ package mineplex.core.common.util; +import java.net.InetAddress; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -1145,6 +1146,11 @@ public class UtilPlayer return entityPlayer.activeContainer != entityPlayer.defaultContainer; } + public static String getIp(Player player) + { + return player.getAddress().getAddress().getHostAddress(); + } + /* * Returns whether the UUID belongs to a slim skin */ diff --git a/Plugins/Mineplex.Core/src/mineplex/core/achievement/Achievement.java b/Plugins/Mineplex.Core/src/mineplex/core/achievement/Achievement.java index 419b8b977..17b03158f 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/achievement/Achievement.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/achievement/Achievement.java @@ -373,7 +373,7 @@ public enum Achievement new String[]{"Win 30 games of Master Builders"}, new int[]{30}, AchievementCategory.MASTER_BUILDERS), - + //Castle Siege CASTLE_SIEGE_WINS("FOR THE KING!", 600, new String[]{"Castle Siege.ForTheKing"}, @@ -398,6 +398,70 @@ public enum Achievement new String[]{"Do 50% or more of the damage to the king"}, new int[]{1}, AchievementCategory.CASTLE_SIEGE), + + //Castle Assault + CASTLE_ASSAULT_KILL_STREAK("Kill Streak", 0, + new String[]{"Castle Assault.KillStreak", "Castle Assault TDM.KillStreak"}, + new String[]{"Earn Kill Streak Rewards"}, + new int[][]{new int[]{0, 50, 500}, new int[]{0, 100, 750}, new int[]{0, 150, 1000}, new int[]{0, 200, 1500}, new int[]{0, 400, 2000}, new int[]{0, 500, 2500}, new int[]{0, 1000, 3000}, new int[]{0, 1500, 3500}, new int[]{0, 2000, 4000}, new int[]{0, 5000, 100000}}, + new int[]{10, 20, 50, 100, 200, 250, 500, 750, 1000, 2000}, + "Novice I", + new String[]{"Novice II", "Novice III", "Novice IV", "Novice V", "Master I", "Master II", "Master III", "Master IV", "GRANDMASTER"}, + AchievementCategory.CASTLE_ASSAULT), + + CASTLE_ASSAULT_FIRST_BLOOD("First Blood", 0, + new String[]{"Castle Assault.FirstBlood", "Castle Assault TDM.FirstBlood"}, + new String[]{"Obtain the first kill in a Match"}, + new int[][]{new int[]{0, 100, 100}, new int[]{0, 150, 200}, new int[]{0, 200, 300}, new int[]{0, 250, 400}, new int[]{0, 500, 500}}, + new int[]{2, 5, 10, 25, 50}, + "Novice I", + new String[]{"Novice II", "Novice III", "Novice IV", "Novice V"}, + AchievementCategory.CASTLE_ASSAULT), + + CASTLE_ASSAULT_FIGHTER_KIT("Fighter", 0, + new String[]{"Castle Assault.FighterKitKills", "Castle Assault TDM.FighterKitKills"}, + new String[]{"Kill opponents while wearing the Fighter Kit"}, + new int[][]{new int[]{0, 100, 500}, new int[]{0, 150, 750}, new int[]{0, 250, 1000}, new int[]{0, 500, 1500}, new int[]{0, 1000, 2500}, new int[]{0, 1500, 3500}, new int[]{0, 2000, 4500}, new int[]{0, 3000, 6000}, new int[]{0, 5000, 10000}, new int[]{0, 10000, 100000}}, + new int[]{50, 100, 250, 500, 1000, 1500, 3000, 5000, 10000, 20000}, + "Novice I", + new String[]{"Novice II", "Novice III", "Novice IV", "Novice V", "Master I", "Master II", "Master III", "Master IV", "GRANDMASTER"}, + AchievementCategory.CASTLE_ASSAULT), + + CASTLE_ASSAULT_TANK_KIT("Tank", 0, + new String[]{"Castle Assault.TankKitKills", "Castle Assault TDM.TankKitKills"}, + new String[]{"Kill opponents while wearing the Tank Kit"}, + new int[][]{new int[]{0, 100, 500}, new int[]{0, 150, 750}, new int[]{0, 250, 1000}, new int[]{0, 500, 1500}, new int[]{0, 1000, 2500}, new int[]{0, 1500, 3500}, new int[]{0, 2000, 4500}, new int[]{0, 3000, 6000}, new int[]{0, 5000, 10000}, new int[]{0, 10000, 100000}}, + new int[]{50, 100, 250, 500, 1000, 1500, 3000, 5000, 10000, 20000}, + "Novice I", + new String[]{"Novice II", "Novice III", "Novice IV", "Novice V", "Master I", "Master II", "Master III", "Master IV", "GRANDMASTER"}, + AchievementCategory.CASTLE_ASSAULT), + + CASTLE_ASSAULT_ARCHER_KIT("Archer", 0, + new String[]{"Castle Assault.ArcherKitKills", "Castle Assault TDM.ArcherKitKills"}, + new String[]{"Kill opponents while wearing the Archer Kit"}, + new int[][]{new int[]{0, 100, 500}, new int[]{0, 150, 750}, new int[]{0, 250, 1000}, new int[]{0, 500, 1500}, new int[]{0, 1000, 2500}, new int[]{0, 1500, 3500}, new int[]{0, 2000, 4500}, new int[]{0, 3000, 6000}, new int[]{0, 5000, 10000}, new int[]{0, 10000, 100000}}, + new int[]{50, 100, 250, 500, 1000, 1500, 3000, 5000, 10000, 20000}, + "Novice I", + new String[]{"Novice II", "Novice III", "Novice IV", "Novice V", "Master I", "Master II", "Master III", "Master IV", "GRANDMASTER"}, + AchievementCategory.CASTLE_ASSAULT), + + CASTLE_ASSAULT_DEMOLITIONIST_KIT("Demolitionist", 0, + new String[]{"Castle Assault.DemolitionistKitKills", "Castle Assault TDM.DemolitionistKitKills"}, + new String[]{"Kill opponents while wearing the Demolitionist Kit"}, + new int[][]{new int[]{0, 100, 500}, new int[]{0, 150, 750}, new int[]{0, 250, 1000}, new int[]{0, 500, 1500}, new int[]{0, 1000, 2500}, new int[]{0, 1500, 3500}, new int[]{0, 2000, 4500}, new int[]{0, 3000, 6000}, new int[]{0, 5000, 10000}, new int[]{0, 10000, 100000}}, + new int[]{50, 100, 250, 500, 1000, 1500, 3000, 5000, 10000, 20000}, + "Novice I", + new String[]{"Novice II", "Novice III", "Novice IV", "Novice V", "Master I", "Master II", "Master III", "Master IV", "GRANDMASTER"}, + AchievementCategory.CASTLE_ASSAULT), + + CASTLE_ASSAULT_WINNER("Assault", 0, + new String[]{"Castle Assault.Wins", "Castle Assault TDM.Wins"}, + new String[]{"Win games of Castle Assault"}, + new int[][]{new int[]{0, 100, 500}, new int[]{0, 150, 750}, new int[]{0, 250, 1000}, new int[]{0, 500, 1500}, new int[]{0, 1000, 2500}, new int[]{0, 1500, 3500}, new int[]{0, 2000, 4500}, new int[]{0, 3000, 6000}, new int[]{0, 5000, 10000}, new int[]{0, 10000, 100000}}, + new int[]{2, 5, 25, 50, 100, 150, 250, 500, 1000, 2000}, + "Novice I", + new String[]{"Novice II", "Novice III", "Novice IV", "Novice V", "Master I", "Master II", "Master III", "Master IV", "GRANDMASTER"}, + AchievementCategory.CASTLE_ASSAULT), //Champions CHAMPIONS_WINS("Champion", 600, @@ -1135,17 +1199,36 @@ public enum Achievement private String _name; private String[] _desc; private String[] _stats; + private int[][] _levelUpRewards; private int[] _levels; + private String _defaultLevelName; + private String[] _levelNames; private int _gems; private AchievementCategory _category; + Achievement(String name, int gems, String[] stats, String[] desc, int[][] levelUpRewards, int[] levels, String defaultLevelName, String[] levelNames, AchievementCategory category) + { + _name = name; + _gems = gems; + _desc = desc; + _stats = stats; + _levelUpRewards = levelUpRewards; + _levels = levels; + _defaultLevelName = defaultLevelName; + _levelNames = levelNames; + _category = category; + } + Achievement(String name, int gems, String[] stats, String[] desc, int[] levels, AchievementCategory category) { _name = name; _gems = gems; _desc = desc; _stats = stats; + _levelUpRewards = new int[][] {}; _levels = levels; + _levelNames = new String[] {}; + _defaultLevelName = ""; _category = category; } @@ -1228,11 +1311,26 @@ public enum Achievement { return _stats; } + + public int[][] getLevelUpRewards() + { + return _levelUpRewards; + } public int[] getLevels() { return _levels; } + + public String getDefaultLevelName() + { + return _defaultLevelName; + } + + public String[] getLevelNames() + { + return _levelNames; + } public int getMaxLevel() { @@ -1248,6 +1346,11 @@ public enum Achievement { return _levels.length == 1; } + + public boolean hasLevelNames() + { + return _levelNames.length > 0; + } public AchievementCategory getCategory() { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementCategory.java b/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementCategory.java index 37805a3be..3a2d752df 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementCategory.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementCategory.java @@ -84,7 +84,11 @@ public enum AchievementCategory WIZARDS("Wizards", null, new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED }, Material.BLAZE_ROD, 0, GameCategory.SURVIVAL, "Witch Doctor Kit", false, GameDisplay.Wizards.getGameId()), - + + CASTLE_ASSAULT("Castle Assault", new String[] {"Castle Assault", "Castle Assault TDM"}, + new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.CROWNS_EARNED }, + Material.DIAMOND_CHESTPLATE, 0, GameCategory.CLASSICS, null, false, GameDisplay.CastleAssault.getGameId(), GameDisplay.CastleAssaultTDM.getGameId()), + CASTLE_SIEGE("Castle Siege", null, new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, new StatDisplay("Kills as Defenders"), new StatDisplay("Deaths as Defenders"), new StatDisplay("Kills as Undead"), new StatDisplay("Deaths as Undead"), StatDisplay.GEMS_EARNED }, diff --git a/Plugins/Mineplex.Core/src/mineplex/core/achievement/StatDisplay.java b/Plugins/Mineplex.Core/src/mineplex/core/achievement/StatDisplay.java index a4dc577ed..8609bb12a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/achievement/StatDisplay.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/achievement/StatDisplay.java @@ -89,6 +89,7 @@ public class StatDisplay public static final StatDisplay KILLS = new StatDisplay("Kills"); public static final StatDisplay DEATHS = new StatDisplay("Deaths"); public static final StatDisplay GEMS_EARNED = new StatDisplay("Gems Earned", "GemsEarned"); + public static final StatDisplay CROWNS_EARNED = new StatDisplay("Crowns Earned", "CrownsEarned"); public static final StatDisplay TIME_IN_GAME = new StatDisplay("Time In Game", "TimeInGame"); public static final StatDisplay GAMES_PLAYED = new StatDisplay("Games Played", "Wins", "Losses"); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/achievement/ui/page/AchievementMainPage.java b/Plugins/Mineplex.Core/src/mineplex/core/achievement/ui/page/AchievementMainPage.java index e2825bfde..0ff566c82 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/achievement/ui/page/AchievementMainPage.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/achievement/ui/page/AchievementMainPage.java @@ -107,6 +107,14 @@ public class AchievementMainPage extends ShopPageBase 1) continue; @@ -121,6 +129,8 @@ public class AchievementMainPage extends ShopPageBase 0) + { lore.add(" "); + } } -} +} \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/achievement/ui/page/AchievementPage.java b/Plugins/Mineplex.Core/src/mineplex/core/achievement/ui/page/AchievementPage.java index b0912addd..3915059e8 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/achievement/ui/page/AchievementPage.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/achievement/ui/page/AchievementPage.java @@ -3,6 +3,15 @@ package mineplex.core.achievement.ui.page; import java.util.ArrayList; import java.util.List; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + import mineplex.core.account.CoreClientManager; import mineplex.core.achievement.Achievement; import mineplex.core.achievement.AchievementCategory; @@ -20,14 +29,6 @@ import mineplex.core.shop.page.ShopPageBase; import mineplex.core.stats.PlayerStats; import mineplex.core.stats.StatsManager; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - public class AchievementPage extends ShopPageBase { private static int ACHIEVEMENT_MIDDLE_INDEX = 31; @@ -68,6 +69,7 @@ public class AchievementPage extends ShopPageBase= achievement.getMaxLevel(); if (!hasUnlocked) @@ -80,7 +82,16 @@ public class AchievementPage extends ShopPageBase lore = new ArrayList(); lore.add(" "); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java index b59982c6f..525351b5a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java @@ -68,6 +68,7 @@ import mineplex.core.antihack.commands.AnticheatOnCommand; import mineplex.core.antihack.commands.DetailedMessagesCommand; import mineplex.core.antihack.commands.GetVlsCommand; import mineplex.core.antihack.commands.TestBanCommand; +import mineplex.core.antihack.compedaccount.CompromisedAccountManager; import mineplex.core.antihack.gep.GwenExtremePrejudice; import mineplex.core.antihack.guardians.GuardianManager; import mineplex.core.antihack.logging.AntihackLogger; @@ -80,6 +81,8 @@ import mineplex.core.preferences.Preference; import mineplex.core.preferences.PreferencesManager; import mineplex.core.punish.Category; import mineplex.core.punish.Punish; +import mineplex.core.punish.PunishClient; +import mineplex.core.punish.Punishment; import mineplex.core.punish.PunishmentResponse; import mineplex.serverdata.commands.ServerCommandManager; @@ -147,6 +150,8 @@ public class AntiHack extends MiniPlugin private BanWaveManager _banWaveManager; + private final CompromisedAccountManager _compromisedAccountManager; + private AntiHack() { super("AntiHack"); @@ -155,6 +160,7 @@ public class AntiHack extends MiniPlugin require(GuardianManager.class); _banWaveManager = require(BanWaveManager.class); + _compromisedAccountManager = require(CompromisedAccountManager.class); Bukkit.getServicesManager().register(MineplexLink.class, new MineplexLinkImpl(), this._plugin, ServicePriority.Normal); @@ -208,7 +214,7 @@ public class AntiHack extends MiniPlugin CoreClient coreClient = _clientManager.Get(player); String id = generateId(); - String finalMessage = "[GWEN] " + id; + String finalMessage = "[GWEN Cheat Detection]\n\nToken: " + id; JsonObject custom = new JsonObject(); custom.addProperty("ban-reason", CheckManager.getCheckSimpleName(cause)); if (gep) @@ -225,7 +231,9 @@ public class AntiHack extends MiniPlugin new GwenBanNotification(_thisServer, player.getName(), player.getUniqueId().toString(), coreClient.GetRank().name(), CheckManager.getCheckSimpleName(cause), id, gep).publish(); }); - _punish.AddPunishment(coreClient.getName(), Category.Hacking, finalMessage, AntiHack.NAME, 3, true, -1, true, after); + _compromisedAccountManager.submitImmediateBan(player); + + _punish.AddPunishment(coreClient.getName(), Category.Hacking, finalMessage, AntiHack.NAME, 3, true, getDaysBanned(player, cause), true, after); }; if (coreClient.GetRank().has(Rank.TWITCH)) @@ -264,7 +272,7 @@ public class AntiHack extends MiniPlugin Consumer> doPunish = after -> { - _punish.AddPunishment(coreClient.getName(), Category.Hacking, info.getMessage(), AntiHack.NAME, 3, true, -1, true, after); + _punish.AddPunishment(coreClient.getName(), Category.Hacking, info.getMessage(), AntiHack.NAME, 3, true, getDaysBanned(player, CheckManager.getCheckBySimpleName(info.getHackType())), true, after); }; if (coreClient.GetRank().has(Rank.TWITCH)) @@ -340,6 +348,60 @@ public class AntiHack extends MiniPlugin event.setCancelled(true); } + public int getPunishments(Player player) + { + PunishClient punishClient = require(Punish.class).GetClient(player.getName()); + + int totalPunishments = 0; + + if (punishClient.GetPunishments().containsKey(Category.Hacking)) + { + for (Punishment punishment : punishClient.GetPunishments().get(Category.Hacking)) + { + if (punishment.GetAdmin().equalsIgnoreCase(NAME) && punishment.GetReason().contains("[GWEN]")) + { + totalPunishments++; + } + } + } + + return totalPunishments; + } + + public int getDaysBanned(Player player, Class check) + { + if (check == null) // old banwaves + { + switch (getPunishments(player)) + { + case 0: + return 5; + case 1: + return 14; + case 2: + return 30; + default: + return -1; + } + } + + switch (check.getSimpleName()) + { + default: + switch (getPunishments(player)) + { + case 0: + return 5; + case 1: + return 14; + case 2: + return 30; + default: + return -1; + } + } + } + public void announceBan(Player player) { Bukkit.getServer().broadcastMessage(String.format(USER_HAS_BEEN_BANNED, player.getName())); @@ -427,7 +489,7 @@ public class AntiHack extends MiniPlugin .append("A").color(ChatColor.AQUA).obfuscated(true) .append(" GWEN > ", ComponentBuilder.FormatRetention.NONE).color(ChatColor.RED).bold(true) .append(violation.getPlayerName(), ComponentBuilder.FormatRetention.NONE).color(ChatColor.GOLD) - .append(" failed " + violation.getHackType() + " VL" + violation.getViolations() + " in server", ComponentBuilder.FormatRetention.NONE).color(ChatColor.YELLOW) + .append(" failed " + violation.getHackType() + " VL" + violation.getViolations() + " in server ", ComponentBuilder.FormatRetention.NONE).color(ChatColor.YELLOW) .append(violation.getOriginatingServer(), ComponentBuilder.FormatRetention.NONE).color(ChatColor.YELLOW) .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/server " + violation.getOriginatingServer())) .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveManager.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveManager.java index 668c60db2..3eb4506b0 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveManager.java @@ -5,6 +5,7 @@ import mineplex.core.ReflectivelyCreateMiniPlugin; import mineplex.core.account.CoreClient; import mineplex.core.account.CoreClientManager; import mineplex.core.antihack.AntiHack; +import mineplex.core.antihack.compedaccount.CompromisedAccountManager; import mineplex.core.antihack.logging.AntihackLogger; import mineplex.core.antihack.redisnotifications.GwenBanwaveNotification; import mineplex.core.common.util.UtilServer; @@ -60,7 +61,7 @@ public class BanWaveManager extends MiniPlugin runAsync(() -> { String id = AntiHack.generateId(); - String newMessage = "[GWEN] [BanWave] " + id; + String newMessage = "[GWEN Cheat Detection]\n\nToken: " + id; CoreClient client = _clientManager.Get(player); @@ -74,6 +75,7 @@ public class BanWaveManager extends MiniPlugin JsonObject custom = new JsonObject(); custom.addProperty("is-banwave", true); + require(CompromisedAccountManager.class).submitPendingDelayedBan(player); require(AntihackLogger.class).saveMetadata(player, id, after, custom); } }); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/CompromisedAccountManager.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/CompromisedAccountManager.java new file mode 100644 index 000000000..48f092b2e --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/CompromisedAccountManager.java @@ -0,0 +1,94 @@ +package mineplex.core.antihack.compedaccount; + +import java.util.logging.Level; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; + +import com.google.gson.JsonObject; + +import mineplex.core.MiniPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.account.CoreClient; +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.api.ApiHost; +import mineplex.core.common.api.ApiWebCall; +import mineplex.core.common.util.UtilPlayer; + +@ReflectivelyCreateMiniPlugin +public class CompromisedAccountManager extends MiniPlugin +{ + private final CompromisedAccountRepository _repository = new CompromisedAccountRepository(); + + private final CoreClientManager _clientManager = require(CoreClientManager.class); + + private final ApiWebCall _apiCall; + + private CompromisedAccountManager() + { + super("CompedAccount"); + + String url = "http://" + ApiHost.getBanner().getHost() + ":" + ApiHost.getBanner().getPort() + "/"; + _apiCall = new ApiWebCall(url); + } + + public void submitImmediateBan(Player player) + { + _repository.insertPunishment(_clientManager.getAccountId(player), UtilPlayer.getIp(player), "immediate").whenComplete((res, err) -> + { + if (err != null) + { + getPlugin().getLogger().log(Level.SEVERE, "An unexpected error occurred while submitting immediate ban of " + player.getName(), err); + } + }); + } + + public void submitPendingDelayedBan(Player player) + { + _repository.insertPunishment(_clientManager.getAccountId(player), UtilPlayer.getIp(player), "predelayed").whenComplete((res, err) -> + { + if (err != null) + { + getPlugin().getLogger().log(Level.SEVERE, "An unexpected error occurred while submitting delayed ban of " + player.getName(), err); + } + }); + } + + @EventHandler + public void onJoin(PlayerJoinEvent event) + { + runAsync(() -> + { + JsonObject response = _apiCall.post("api/server/login/" + event.getPlayer().getName(), JsonObject.class, getPlayerInfo(event.getPlayer())); + if (response != null && response.get("error") != null) + { + getPlugin().getLogger().log(Level.SEVERE, "Response from Banner: " + response); + } + }); + } + + public void triggerPriorityBan(Player player, PriorityCause cause) + { + runAsync(() -> + { + JsonObject response = _apiCall.post("api/banner/trigger/" + player.getName(), JsonObject.class, new TriggerPriorityInfo(getPlayerInfo(player), cause)); + if (response != null && response.get("error") != null) + { + getPlugin().getLogger().log(Level.SEVERE, "Response from Banner: " + response); + } + }); + } + + private PlayerInfo getPlayerInfo(Player player) + { + CoreClient coreClient = _clientManager.Get(player); + return new PlayerInfo( + player.getName(), + coreClient.getName(), + player.getUniqueId(), + coreClient.getAccountId(), + UtilPlayer.getIp(player) + ); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/CompromisedAccountRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/CompromisedAccountRepository.java new file mode 100644 index 000000000..c9af4fa35 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/CompromisedAccountRepository.java @@ -0,0 +1,46 @@ +package mineplex.core.antihack.compedaccount; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.concurrent.CompletableFuture; + +import mineplex.core.common.util.UtilServer; +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.database.RepositoryBase; + +public class CompromisedAccountRepository extends RepositoryBase +{ + private static final String INSERT_BAN = "INSERT INTO gwenPunishments (accountId, ip, type) VALUES (?, ?, ?)"; + + public CompromisedAccountRepository() + { + super(DBPool.getAccount()); + } + + public CompletableFuture insertPunishment(int accountId, String ip, String type) + { + CompletableFuture future = new CompletableFuture<>(); + + CompletableFuture.runAsync(() -> { + try (Connection connection = getConnection()) + { + try (PreparedStatement preparedStatement = connection.prepareStatement(INSERT_BAN)) + { + preparedStatement.setInt(1, accountId); + preparedStatement.setString(2, ip); + preparedStatement.setString(3, type); + preparedStatement.executeUpdate(); + } + } + catch (SQLException ex) + { + future.completeExceptionally(ex); + return; + } + future.complete(null); + }); + + return future; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/PlayerInfo.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/PlayerInfo.java new file mode 100644 index 000000000..d80ccf5b9 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/PlayerInfo.java @@ -0,0 +1,62 @@ +package mineplex.core.antihack.compedaccount; + +import java.util.Objects; +import java.util.UUID; + +public class PlayerInfo +{ + private final String _name; + private final String _realName; + private final UUID _uuid; + private final int _accountId; + private final String _ip; + + public PlayerInfo(String name, String realName, UUID uuid, int accountId, String ip) + { + _name = name; + _realName = realName; + _uuid = uuid; + _accountId = accountId; + _ip = ip; + } + + public String getName() + { + return _name; + } + + public String getRealName() + { + return _realName; + } + + public UUID getUuid() + { + return _uuid; + } + + public int getAccountId() + { + return _accountId; + } + + public String getIp() + { + return _ip; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof PlayerInfo)) return false; + PlayerInfo that = (PlayerInfo) o; + return _accountId == that._accountId; + } + + @Override + public int hashCode() + { + return Objects.hash(_accountId); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/PriorityCause.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/PriorityCause.java new file mode 100644 index 000000000..697432b38 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/PriorityCause.java @@ -0,0 +1,7 @@ +package mineplex.core.antihack.compedaccount; + +public enum PriorityCause +{ + JOIN_GAME, + CHAT +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/TriggerPriorityInfo.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/TriggerPriorityInfo.java new file mode 100644 index 000000000..aea9654e2 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/compedaccount/TriggerPriorityInfo.java @@ -0,0 +1,23 @@ +package mineplex.core.antihack.compedaccount; + +public class TriggerPriorityInfo +{ + private final PlayerInfo _target; + private final PriorityCause _cause; + + public TriggerPriorityInfo(PlayerInfo target, PriorityCause cause) + { + _target = target; + _cause = cause; + } + + public PlayerInfo getTarget() + { + return _target; + } + + public PriorityCause getCause() + { + return _cause; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/button/open/OpenKitSelector.java b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/button/open/OpenKitSelector.java new file mode 100644 index 000000000..cb0c3f34a --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/button/open/OpenKitSelector.java @@ -0,0 +1,21 @@ +package mineplex.core.cosmetic.ui.button.open; + +import org.bukkit.entity.Player; + +import mineplex.core.cosmetic.ui.page.Menu; +import mineplex.core.cosmetic.ui.page.KitSelectorPage; +import mineplex.core.gadget.types.Gadget; + +public class OpenKitSelector extends OpenPageButton +{ + public OpenKitSelector(Menu menu, Gadget active) + { + super(menu, active); + } + + @Override + protected void leftClick(Player player) + { + getMenu().getShop().openPageForPlayer(player, new KitSelectorPage(getMenu().getPlugin(), getMenu().getShop(), getMenu().getClientManager(), getMenu().getDonationManager(), "Rank Selector Particles", player)); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/GadgetPage.java b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/GadgetPage.java index 3d8aedbb7..657d98b30 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/GadgetPage.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/GadgetPage.java @@ -78,6 +78,11 @@ public class GadgetPage extends ShopPageBase } protected void addGadget(Gadget gadget, int slot) + { + addGadget(gadget, slot, false); + } + + protected void addGadget(Gadget gadget, int slot, boolean locked) { List itemLore = new ArrayList(); @@ -102,7 +107,7 @@ public class GadgetPage extends ShopPageBase itemLore.add(" " + (gadget.getSet().isActive(getPlayer()) ? C.cGreen : C.cGray) + bonus); } - if (!gadget.ownsGadget(getPlayer())) + if (!gadget.ownsGadget(getPlayer()) || locked) { if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) == -1) { @@ -261,7 +266,7 @@ public class GadgetPage extends ShopPageBase ItemMeta im = item.getItemMeta(); im.setDisplayName(C.cGreen + C.Bold + gadget.getName()); - if (gadget.ownsGadget(getPlayer())) + if (gadget.ownsGadget(getPlayer()) && !locked) { if (gadget.getActive().contains(getPlayer())) { @@ -320,7 +325,7 @@ public class GadgetPage extends ShopPageBase } //Standard - if (gadget.ownsGadget(getPlayer())) + if (gadget.ownsGadget(getPlayer()) && !locked) { ItemStack gadgetItemStack; /*if (gadget instanceof MorphWitch) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/KitSelectorPage.java b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/KitSelectorPage.java new file mode 100644 index 000000000..26b399783 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/KitSelectorPage.java @@ -0,0 +1,50 @@ +package mineplex.core.cosmetic.ui.page; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.C; +import mineplex.core.cosmetic.CosmeticManager; +import mineplex.core.cosmetic.ui.CosmeticShop; +import mineplex.core.donation.DonationManager; +import mineplex.core.gadget.types.Gadget; +import mineplex.core.gadget.types.GadgetType; +import mineplex.core.shop.item.IButton; +import mineplex.core.shop.item.ShopItem; + +public class KitSelectorPage extends GadgetPage +{ + public KitSelectorPage(CosmeticManager plugin, CosmeticShop shop, CoreClientManager clientManager, DonationManager donationManager, String name, Player player) + { + super(plugin, shop, clientManager, donationManager, name, player); + } + + @Override + protected void buildPage() + { + int slot = 10; + + for (Gadget gadget : getPlugin().getGadgetManager().getGadgets(GadgetType.KIT_SELECTOR)) + { + addGadget(gadget, slot); + + if (getPlugin().getGadgetManager().getActive(getPlayer(), GadgetType.KIT_SELECTOR) == gadget) + addGlow(slot); + + slot++; + + if (slot == 17 || slot == 26 || slot == 35) + slot += 2; + } + + addButton(4, new ShopItem(Material.BED, C.cGray + " \u21FD Go Back", new String[]{}, 1, false), new IButton() + { + public void onClick(Player player, ClickType clickType) + { + getShop().openPageForPlayer(getPlayer(), new Menu(getPlugin(), getShop(), getClientManager(), getDonationManager(), player)); + } + }); + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/Menu.java b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/Menu.java index 37d7190f4..8a27df36e 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/Menu.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/Menu.java @@ -30,6 +30,7 @@ import mineplex.core.cosmetic.ui.button.open.OpenMounts; import mineplex.core.cosmetic.ui.button.open.OpenMusic; import mineplex.core.cosmetic.ui.button.open.OpenParticles; import mineplex.core.cosmetic.ui.button.open.OpenPets; +import mineplex.core.cosmetic.ui.button.open.OpenKitSelector; import mineplex.core.cosmetic.ui.button.open.OpenTaunts; import mineplex.core.cosmetic.ui.button.open.OpenWinEffect; import mineplex.core.donation.DonationManager; @@ -46,6 +47,7 @@ public class Menu extends ShopPageBase private static final String VISIBILITY_HUB = "Usable in Lobbies"; private static final String VISIBILITY_EVERYWHERE = "Visible Everywhere"; private static final String VISIBILITY_GAMES = "Visible in Games"; + private static final String VISIBILITY_GAME_HUB = "Visible in Game Lobbies"; public Menu(CosmeticManager plugin, CosmeticShop shop, CoreClientManager clientManager, DonationManager donationManager, Player player) { @@ -66,10 +68,9 @@ public class Menu extends ShopPageBase shardLore.add(C.cGray + "handy. Maybe I can collect more!"); ShopItem shards = new ShopItem(Material.PRISMARINE_SHARD, C.cAqua + C.Bold + treasureShards + " Treasure Shards", shardLore.toArray(new String[0]), 0, false); - addItem(4, shards); // Cosmetic Items - int[] slots = UtilUI.getIndicesFor(15, 1, 5, 1); + int[] slots = UtilUI.getIndicesFor(15, 0, 5, 1); /*int particleSlot = 9;//slots[0]; int arrowSlot = 11;//slots[1]; int jumpSlot = 13;//slots[2]; @@ -88,11 +89,14 @@ public class Menu extends ShopPageBase deathSlot = slots[3], gadgetSlot = slots[4], morphSlot = slots[5], mountSlot = slots[6], petSlot = slots[7], hatSlot = slots[8], costumeSlot = slots[9], musicSlot = slots[10], tauntSlot = slots[11], - winEffectSlot = slots[12], gameModifierSlot = slots[13], balloonsSlot = slots[14]; + winEffectSlot = slots[12], gameModifierSlot = slots[13], balloonsSlot = slots[14], + kitSelectorSlot = balloonsSlot + 4; - EnumMap ownedCount = new EnumMap(GadgetType.class); - EnumMap maxCount = new EnumMap(GadgetType.class); - EnumMap enabled = new EnumMap(GadgetType.class); + addItem(kitSelectorSlot + 2, shards); + + EnumMap ownedCount = new EnumMap<>(GadgetType.class); + EnumMap maxCount = new EnumMap<>(GadgetType.class); + EnumMap enabled = new EnumMap<>(GadgetType.class); for(GadgetType type : GadgetType.values()) { @@ -218,6 +222,11 @@ public class Menu extends ShopPageBase lore = getLore(ownedCount.get(type), maxCount.get(type), "Balloons are collectibles that you can float above your head as you wander the lobby. You can have up to 10 balloons in your hand at one time.", VISIBILITY_HUB, enabled.get(type)); addButton(balloonsSlot, new ShopItem(Material.LEASH, "Balloons", lore, 1, false), new OpenBalloons(this, enabled.get(type))); if (enabled.containsKey(type)) addGlow(balloonsSlot); + + type = GadgetType.KIT_SELECTOR; + lore = getLore(ownedCount.get(type), maxCount.get(type), "Click here to select different particles to indicate which kit you have selected!", VISIBILITY_GAME_HUB, enabled.get(type)); + addButton(kitSelectorSlot, new ShopItem(Material.LEVER, "Kit Selector Particles", lore, 1, false), new OpenKitSelector(this, enabled.get(type))); + if (enabled.containsKey(type)) addGlow(kitSelectorSlot); } private String[] getLore(int ownedCount, int maxCount, String info, String visibility, Gadget enabled) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/WinEffectPage.java b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/WinEffectPage.java index 3236de2fb..cc116cbac 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/WinEffectPage.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/WinEffectPage.java @@ -9,6 +9,7 @@ import mineplex.core.common.util.C; import mineplex.core.cosmetic.CosmeticManager; import mineplex.core.cosmetic.ui.CosmeticShop; import mineplex.core.donation.DonationManager; +import mineplex.core.gadget.gadgets.wineffect.rankrooms.WinEffectRankBased; import mineplex.core.gadget.types.Gadget; import mineplex.core.gadget.types.GadgetType; import mineplex.core.shop.item.IButton; @@ -30,14 +31,29 @@ public class WinEffectPage extends GadgetPage for (Gadget gadget : getPlugin().getGadgetManager().getGadgets(GadgetType.WIN_EFFECT)) { - addGadget(gadget, slot); + if (gadget instanceof WinEffectRankBased) + { + WinEffectRankBased rankBased = (WinEffectRankBased) gadget; + if (getClientManager().Get(getPlayer()).GetRank().has(rankBased.getRank())) + { + addGadget(gadget, slot); + } + else + { + addGadget(gadget, slot, true); + } + } + else + { + addGadget(gadget, slot); + } if (getPlugin().getGadgetManager().getActive(getPlayer(), GadgetType.WIN_EFFECT) == gadget) addGlow(slot); slot++; - if (slot == 17) + if (slot == 17 || slot == 26) slot += 2; } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/donation/DonationManager.java b/Plugins/Mineplex.Core/src/mineplex/core/donation/DonationManager.java index 9b1934c9c..8ef17f337 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/donation/DonationManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/donation/DonationManager.java @@ -1,9 +1,12 @@ package mineplex.core.donation; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Consumer; import org.bukkit.entity.Player; @@ -15,10 +18,14 @@ import mineplex.core.MiniClientPlugin; import mineplex.core.ReflectivelyCreateMiniPlugin; import mineplex.core.account.CoreClient; import mineplex.core.account.CoreClientManager; +import mineplex.core.account.ILoginProcessor; +import mineplex.core.account.event.ClientUnloadEvent; import mineplex.core.account.event.ClientWebResponseEvent; import mineplex.core.common.currency.GlobalCurrency; +import mineplex.core.donation.command.CrownCommand; import mineplex.core.donation.command.GemCommand; import mineplex.core.donation.command.ShardCommand; +import mineplex.core.donation.crown.CrownRepository; import mineplex.core.donation.gold.GoldRepository; import mineplex.core.donation.repository.DonationRepository; import mineplex.core.donation.repository.token.DonorTokenWrapper; @@ -40,7 +47,10 @@ public class DonationManager extends MiniClientPlugin private static final Gson GSON = new Gson(); private final Map> _attemptUntilSuccess = new HashMap<>(); - + + private final Map _crownBalance = new ConcurrentHashMap<>(); + private final CrownRepository _crownRepository; + private final CoreClientManager _clientManager = require(CoreClientManager.class); private final DonationRepository _repository; @@ -52,6 +62,36 @@ public class DonationManager extends MiniClientPlugin _repository = new DonationRepository(); _goldRepository = new GoldRepository(); + + _crownRepository = new CrownRepository(); + _clientManager.addStoredProcedureLoginProcessor(new ILoginProcessor() + { + @Override + public String getName() + { + return "crown-balance-loader"; + } + + @Override + public void processLoginResultSet(String playerName, UUID uuid, int accountId, ResultSet resultSet) throws SQLException + { + boolean hasRow = resultSet.next(); + if (hasRow) + { + _crownBalance.put(uuid, resultSet.getInt(1)); + } + else + { + _crownBalance.put(uuid, 0); + } + } + + @Override + public String getQuery(int accountId, String uuid, String name) + { + return "SELECT crownCount FROM accountCrowns WHERE accountId=" + accountId + ";"; + } + }); UtilScheduler.runEvery(UpdateType.FAST, this::processCoinAttemptQueue); } @@ -61,6 +101,7 @@ public class DonationManager extends MiniClientPlugin { addCommand(new GemCommand(this)); addCommand(new ShardCommand(this)); + addCommand(new CrownCommand(this)); } @EventHandler @@ -75,6 +116,88 @@ public class DonationManager extends MiniClientPlugin { return _goldRepository; } + + public int getCrowns(Player player) + { + return getCrowns(player.getUniqueId()); + } + + public int getCrowns(UUID uuid) + { + return _crownBalance.computeIfAbsent(uuid, key -> 0); + } + + /** + * Adds an unknown sales package to the specified {@link Player} + * + * @param callback The callback which will be called on the main thread. Possible responses are: + * {@link TransactionResponse#InsufficientFunds}, when the player does not have enough of the currency + * {@link TransactionResponse#Success}, when everything worked fine + * {@link TransactionResponse#Failed}, when an known exception occured + * {@link TransactionResponse#AlreadyOwns}, when the player already owns the package + */ + public void purchaseUnknownSalesPackageCrown(Player player, String packageName, int cost, boolean oneTimePurchase, Consumer callback) + { + purchaseUnknownSalesPackageCrown(_clientManager.Get(player), packageName, cost, oneTimePurchase, callback); + } + + /** + * Adds an unknown sales package to the specified {@link CoreClient} + * + * @param callback The callback which will be called on the main thread. Possible responses are: + * {@link TransactionResponse#InsufficientFunds}, when the player does not have enough of the currency + * {@link TransactionResponse#Success}, when everything worked fine + * {@link TransactionResponse#Failed}, when an known exception occured + * {@link TransactionResponse#AlreadyOwns}, when the player already owns the package + */ + public void purchaseUnknownSalesPackageCrown(CoreClient client, String packageName, int cost, boolean oneTimePurchase, Consumer callback) + { + Donor donor = Get(client.getUniqueId()); + + if (donor != null) + { + if (oneTimePurchase && donor.ownsUnknownSalesPackage(packageName)) + { + if (callback != null) + { + callback.accept(TransactionResponse.AlreadyOwns); + } + + return; + } + } + + _crownRepository.consumeCrowns(result -> + { + if (result == TransactionResponse.Success) + { + if (_crownBalance.containsKey(client.getUniqueId())) + { + _crownBalance.put(client.getUniqueId(), _crownBalance.get(client.getUniqueId()) - cost); + } + _repository.purchaseUnknownSalesPackage(client.getName(), packageName, GlobalCurrency.GEM, 0, response -> + { + if (response == TransactionResponse.Success) + { + if (donor != null) + { + donor.addOwnedUnknownSalesPackage(packageName); + donor.addBalance(GlobalCurrency.GEM, 0); + } + } + + if (callback != null) + { + callback.accept(response); + } + }); + } + else if (callback != null) + { + callback.accept(result); + } + }, client.getAccountId(), cost); + } /** * Adds an unknown sales package to the specified {@link Player} @@ -187,6 +310,26 @@ public class DonationManager extends MiniClientPlugin callback.accept(response); }); } + + public void rewardCrowns(int crowns, Player player) + { + rewardCrowns(crowns, player, null); + } + + public void rewardCrowns(int crowns, Player player, Consumer completed) + { + _crownRepository.rewardCrowns(success -> + { + if (success) + { + _crownBalance.merge(player.getUniqueId(), crowns, Integer::sum); + } + if (completed != null) + { + completed.accept(success); + } + }, _clientManager.Get(player).getAccountId(), crowns); + } /** * Rewards the specified {@link Player} with {@code amount} of {@code currency} because of {@code reason} @@ -405,4 +548,10 @@ public class DonationManager extends MiniClientPlugin { return _clientManager; } + + @EventHandler + public void unloadCrownBalance(ClientUnloadEvent event) + { + _crownBalance.remove(event.getUniqueId()); + } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/donation/command/CrownCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/donation/command/CrownCommand.java new file mode 100644 index 000000000..72800e748 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/donation/command/CrownCommand.java @@ -0,0 +1,91 @@ +package mineplex.core.donation.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.Rank; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.donation.DonationManager; + +public class CrownCommand extends CommandBase +{ + public CrownCommand(DonationManager plugin) + { + super(plugin, Rank.ADMIN, "crown"); + } + + @Override + public void Execute(final Player caller, String[] args) + { + if (args.length < 2) + { + UtilPlayer.message(caller, F.main("Crown", "Missing Args: " + F.elem("/crown "))); + return; + } + + String targetName = args[0]; + + int amount; + + try + { + amount = Integer.parseInt(args[1]); + } + catch (NumberFormatException ex) + { + UtilPlayer.message(caller, F.main("Crown", "Invalid crown Amount")); + return; + } + + if (targetName.equalsIgnoreCase("@a")) + { + rewardAllCrowns(caller, amount); + } + else + { + Player target = UtilPlayer.searchExact(targetName); + if (target != null) + { + rewardCrowns(caller, target, amount); + } + else + { + UtilPlayer.message(caller, F.main("Crown", "Could not find player " + F.name(targetName))); + } + } + } + + private void rewardAllCrowns(Player caller, int crowns) + { + if (crowns > 1000) + { + UtilPlayer.message(caller, F.main("Crown", "You can only give everybody 1000 crowns at a time.")); + return; + } + + for (Player player : UtilServer.getPlayers()) + { + Plugin.rewardCrowns(crowns, player); + } + + UtilPlayer.message(caller, F.main("Crown", "Gave everyone " + F.elem(crowns + " crowns"))); + } + + private void rewardCrowns(Player caller, Player target, int crowns) + { + Plugin.rewardCrowns(crowns, target, completed -> + { + if (completed) + { + UtilPlayer.message(caller, F.main("Crown", "You gave " + F.elem(crowns + " crowns") + " to " + F.name(target.getName()) + ".")); + UtilPlayer.message(target, F.main("Crown", F.name(caller.getName()) + " gave you " + F.elem(crowns + " crowns") + ".")); + } + else + { + UtilPlayer.message(caller, F.main("Crown", "There was an error giving " + F.elem(crowns + " crowns") + " to " + F.name(target.getName()) + ".")); + } + }); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/donation/crown/CrownRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/donation/crown/CrownRepository.java new file mode 100644 index 000000000..49fd9364d --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/donation/crown/CrownRepository.java @@ -0,0 +1,117 @@ +package mineplex.core.donation.crown; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +import org.bukkit.Bukkit; + +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.UtilServer; +import mineplex.core.server.util.TransactionResponse; +import mineplex.serverdata.database.DBPool; + +public class CrownRepository +{ + private static final String CREATE_TABLE = "CREATE TABLE accountCrowns (accountId INT(11) NOT NULL, crownCount INT NOT NULL, PRIMARY KEY (accountId), FOREIGN KEY (accountId) REFERENCES accounts(id));"; + private static final String REWARD_ACCOUNT_CROWNS = "INSERT INTO accountCrowns (accountId, crownCount) VALUES (?, ?) ON DUPLICATE KEY UPDATE crownCount=crownCount+VALUES(crownCount);"; + private static final String CONSUME_ACCOUNT_CROWNS = "UPDATE accountCrowns SET crownCount=(crownCount - ?) WHERE accountId=? AND crownCount >= ?;"; + private static final String SET_ACCOUNT_CROWNS = "INSERT INTO accountCrowns (accountId, crownCount) VALUES (?, ?) ON DUPLICATE KEY UPDATE crownCount=VALUES(crownCount);"; + + public CrownRepository() {} + + public void rewardCrowns(final Callback callback, final int accountId, final int crowns) + { + Bukkit.getScheduler().runTaskAsynchronously(UtilServer.getPlugin(), () -> + { + try (Connection connection = DBPool.getAccount().getConnection()) + { + PreparedStatement statement = connection.prepareStatement(REWARD_ACCOUNT_CROWNS); + statement.setInt(1, accountId); + statement.setInt(2, crowns); + statement.executeUpdate(); + + if (callback != null) + { + Bukkit.getScheduler().runTask(UtilServer.getPlugin(), () -> callback.run(true)); + } + } + catch (SQLException e) + { + e.printStackTrace(); + + if (callback != null) + { + Bukkit.getScheduler().runTask(UtilServer.getPlugin(), () -> callback.run(false)); + } + } + }); + } + + public void consumeCrowns(final Callback callback, final int accountId, final int crowns) + { + Bukkit.getScheduler().runTaskAsynchronously(UtilServer.getPlugin(), () -> + { + try (Connection connection = DBPool.getAccount().getConnection()) + { + String baseStmt = "INSERT INTO accountCrowns (accountId, crownCount) VALUES (" + accountId + ", 0) ON DUPLICATE KEY UPDATE crownCount=crownCount;"; + PreparedStatement statement = connection.prepareStatement(baseStmt + CONSUME_ACCOUNT_CROWNS); + statement.setInt(1, crowns); + statement.setInt(2, accountId); + statement.setInt(3, crowns); + statement.execute(); + + statement.getMoreResults(); + + final TransactionResponse response = statement.getUpdateCount() > 0 ? TransactionResponse.Success : TransactionResponse.InsufficientFunds; + + if (callback != null) + { + Bukkit.getScheduler().runTask(UtilServer.getPlugin(), () -> callback.run(response)); + } + } + catch (SQLException e) + { + e.printStackTrace(); + + if (callback != null) + { + Bukkit.getScheduler().runTask(UtilServer.getPlugin(), () -> callback.run(TransactionResponse.Failed)); + } + } + }); + } + + public void setCrowns(final Callback callback, final int accountId, final int crowns) + { + if (crowns < 0) + { + throw new IllegalArgumentException("Crowns cannot be negative"); + } + + Bukkit.getScheduler().runTaskAsynchronously(UtilServer.getPlugin(), () -> + { + try (Connection connection = DBPool.getAccount().getConnection()) + { + PreparedStatement statement = connection.prepareStatement(SET_ACCOUNT_CROWNS); + statement.setInt(1, accountId); + statement.setInt(2, crowns); + statement.executeUpdate(); + + if (callback != null) + { + Bukkit.getScheduler().runTask(UtilServer.getPlugin(), () -> callback.run(true)); + } + } + catch (SQLException e) + { + e.printStackTrace(); + + if (callback != null) + { + Bukkit.getScheduler().runTask(UtilServer.getPlugin(), () -> callback.run(false)); + } + } + }); + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java index e1c7dbef9..e35168a9b 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java @@ -29,6 +29,7 @@ import mineplex.core.MiniPlugin; import mineplex.core.account.CoreClientManager; import mineplex.core.achievement.AchievementManager; import mineplex.core.blockrestore.BlockRestore; +import mineplex.core.common.Rank; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilEnt; import mineplex.core.common.util.UtilMath; @@ -45,12 +46,12 @@ import mineplex.core.gadget.event.GadgetCollideEntityEvent; import mineplex.core.gadget.event.GadgetEnableEvent; import mineplex.core.gadget.event.PlayerToggleSwimEvent; import mineplex.core.gadget.event.TauntCommandEvent; -import mineplex.core.gadget.gadgets.arrowtrail.halloween.ArrowTrailHalloween; import mineplex.core.gadget.gadgets.arrowtrail.candycane.ArrowTrailCandyCane; import mineplex.core.gadget.gadgets.arrowtrail.cupidslove.ArrowTrailCupid; import mineplex.core.gadget.gadgets.arrowtrail.emerald.ArrowTrailEmerald; import mineplex.core.gadget.gadgets.arrowtrail.freedom.ArrowTrailFreedom; import mineplex.core.gadget.gadgets.arrowtrail.frostlord.ArrowTrailFrostLord; +import mineplex.core.gadget.gadgets.arrowtrail.halloween.ArrowTrailHalloween; import mineplex.core.gadget.gadgets.arrowtrail.howlingwinds.ArrowTrailStorm; import mineplex.core.gadget.gadgets.arrowtrail.music.ArrowTrailMusic; import mineplex.core.gadget.gadgets.arrowtrail.party.ArrowTrailConfetti; @@ -75,12 +76,12 @@ import mineplex.core.gadget.gadgets.death.spring.DeathSpring; import mineplex.core.gadget.gadgets.death.titan.DeathTitan; import mineplex.core.gadget.gadgets.death.vampire.DeathBlood; import mineplex.core.gadget.gadgets.death.wisdom.DeathEnchant; -import mineplex.core.gadget.gadgets.doublejump.halloween.DoubleJumpHalloween; import mineplex.core.gadget.gadgets.doublejump.candycane.DoubleJumpCandyCane; import mineplex.core.gadget.gadgets.doublejump.cupidslove.DoubleJumpCupidsWings; import mineplex.core.gadget.gadgets.doublejump.emerald.DoubleJumpEmerald; import mineplex.core.gadget.gadgets.doublejump.freedom.DoubleJumpFreedom; import mineplex.core.gadget.gadgets.doublejump.frostlord.DoubleJumpFrostLord; +import mineplex.core.gadget.gadgets.doublejump.halloween.DoubleJumpHalloween; import mineplex.core.gadget.gadgets.doublejump.howlingwinds.DoubleJumpStorm; import mineplex.core.gadget.gadgets.doublejump.music.DoubleJumpMusic; import mineplex.core.gadget.gadgets.doublejump.party.DoubleJumpFirecracker; @@ -116,6 +117,12 @@ import mineplex.core.gadget.gadgets.item.ItemPaintbrush; import mineplex.core.gadget.gadgets.item.ItemPartyPopper; import mineplex.core.gadget.gadgets.item.ItemSnowball; import mineplex.core.gadget.gadgets.item.ItemTNT; +import mineplex.core.gadget.gadgets.kitselector.HaloKitSelector; +import mineplex.core.gadget.gadgets.kitselector.RainCloudKitSelector; +import mineplex.core.gadget.gadgets.kitselector.RainbowDanceKitSelector; +import mineplex.core.gadget.gadgets.kitselector.ShimmeringRingKitSelector; +import mineplex.core.gadget.gadgets.kitselector.SingleParticleKitSelector; +import mineplex.core.gadget.gadgets.kitselector.WaterWingsKitSelector; import mineplex.core.gadget.gadgets.morph.MorphAwkwardRabbit; import mineplex.core.gadget.gadgets.morph.MorphBat; import mineplex.core.gadget.gadgets.morph.MorphBlaze; @@ -170,7 +177,6 @@ import mineplex.core.gadget.gadgets.particle.ParticleFireRings; import mineplex.core.gadget.gadgets.particle.king.CastleManager; import mineplex.core.gadget.gadgets.particle.king.ParticleKing; import mineplex.core.gadget.gadgets.particle.ParticleLegend; -import mineplex.core.gadget.gadgets.particle.spring.ParticleSpringHalo; import mineplex.core.gadget.gadgets.particle.ParticleWingsAngel; import mineplex.core.gadget.gadgets.particle.ParticleWingsBee; import mineplex.core.gadget.gadgets.particle.ParticleWingsDemons; @@ -187,6 +193,7 @@ import mineplex.core.gadget.gadgets.particle.howlingwinds.ParticleRain; import mineplex.core.gadget.gadgets.particle.music.ParticleMusic; import mineplex.core.gadget.gadgets.particle.party.ParticlePartyTime; import mineplex.core.gadget.gadgets.particle.shadow.ParticleFoot; +import mineplex.core.gadget.gadgets.particle.spring.ParticleSpringHalo; import mineplex.core.gadget.gadgets.particle.titan.ParticleTitan; import mineplex.core.gadget.gadgets.particle.vampire.ParticleBlood; import mineplex.core.gadget.gadgets.particle.wisdom.ParticleEnchant; @@ -204,6 +211,12 @@ import mineplex.core.gadget.gadgets.wineffect.WinEffectPodium; import mineplex.core.gadget.gadgets.wineffect.WinEffectRiseOfTheElderGuardian; import mineplex.core.gadget.gadgets.wineffect.WinEffectSnowTrails; import mineplex.core.gadget.gadgets.wineffect.WinEffectWinterWarfare; +import mineplex.core.gadget.gadgets.wineffect.rankrooms.WinEffectRankBased; +import mineplex.core.gadget.gadgets.wineffect.rankrooms.rankwineffects.WinEffectRankEternal; +import mineplex.core.gadget.gadgets.wineffect.rankrooms.rankwineffects.WinEffectRankHero; +import mineplex.core.gadget.gadgets.wineffect.rankrooms.rankwineffects.WinEffectRankLegend; +import mineplex.core.gadget.gadgets.wineffect.rankrooms.rankwineffects.WinEffectRankTitan; +import mineplex.core.gadget.gadgets.wineffect.rankrooms.rankwineffects.WinEffectRankUltra; import mineplex.core.gadget.persistence.UserGadgetPersistence; import mineplex.core.gadget.set.SetCandyCane; import mineplex.core.gadget.set.SetCupidsLove; @@ -232,6 +245,7 @@ import mineplex.core.gadget.types.GadgetType; import mineplex.core.gadget.types.GameModifierGadget; import mineplex.core.gadget.types.HatGadget; import mineplex.core.gadget.types.ItemGadget; +import mineplex.core.gadget.types.KitSelectorGadget; import mineplex.core.gadget.types.MusicGadget; import mineplex.core.gadget.types.OutfitGadget; import mineplex.core.gadget.types.OutfitGadget.ArmorSlot; @@ -272,6 +286,8 @@ public class GadgetManager extends MiniPlugin private CastleManager _castleManager; private Map> _gadgets; + private Map _singleParticleSelectors; + private List _rankBasedWinEffects; private final Map _lastMove = new HashMap<>(); private final Map> _playerActiveGadgetMap = new HashMap<>(); @@ -354,6 +370,8 @@ public class GadgetManager extends MiniPlugin private void createGadgets() { _gadgets = new HashMap<>(); + _rankBasedWinEffects = new ArrayList<>(); + _singleParticleSelectors = new HashMap<>(); // Items addGadget(new ItemEtherealPearl(this)); @@ -534,6 +552,13 @@ public class GadgetManager extends MiniPlugin addGadget(new WinEffectWinterWarfare(this)); addGadget(new WinEffectLoveIsABattlefield(this)); + // Rank based win effects + addGadget(new WinEffectRankUltra(this)); + addGadget(new WinEffectRankHero(this)); + addGadget(new WinEffectRankLegend(this)); + addGadget(new WinEffectRankTitan(this)); + addGadget(new WinEffectRankEternal(this)); + // Music addGadget(new MusicGadget(this, "13 Disc", new String[] {""}, -2, 2256, 178000)); addGadget(new MusicGadget(this, "Cat Disc", new String[] {""}, -2, 2257, 185000)); @@ -598,6 +623,20 @@ public class GadgetManager extends MiniPlugin addGadget(new BlowAKissTaunt(this)); addGadget(new RainbowTaunt(this)); + // Kit Selectors + addGadget(new WaterWingsKitSelector(this)); + addGadget(new HaloKitSelector(this)); + addGadget(new RainbowDanceKitSelector(this)); + addGadget(new RainCloudKitSelector(this)); + addGadget(new ShimmeringRingKitSelector(this)); + + for(SingleParticleKitSelector.SingleParticleSelectors singleParticleSelectors : SingleParticleKitSelector.SingleParticleSelectors.values()) + { + Gadget gadget = singleParticleSelectors.getKitSelectorGadget(this); + addGadget(gadget); + _singleParticleSelectors.put(singleParticleSelectors, gadget); + } + // Gem Hunters Mounts for (MountType mount : MountType.values()) { @@ -653,6 +692,9 @@ public class GadgetManager extends MiniPlugin _gadgets.put(gadget.getGadgetType(), new ArrayList<>()); _gadgets.get(gadget.getGadgetType()).add(gadget); + + if (gadget instanceof WinEffectRankBased) + _rankBasedWinEffects.add((WinEffectRankBased) gadget); } @EventHandler @@ -799,6 +841,23 @@ public class GadgetManager extends MiniPlugin } return null; } + + public WinEffectRankBased getRankBasedWinEffect(WinEffectRankBased.WinEffectType winEffectType, Rank rank) + { + for (WinEffectRankBased winEffectRankBased : _rankBasedWinEffects) + { + if (winEffectRankBased.getWinEffectType().equals(winEffectType) && winEffectRankBased.getRank().equals(rank)) + { + return winEffectRankBased; + } + } + return null; + } + + public SingleParticleKitSelector getSingleParticleKitSelector(SingleParticleKitSelector.SingleParticleSelectors singleParticleSelectors) + { + return (SingleParticleKitSelector) _singleParticleSelectors.get(singleParticleSelectors); + } // Disallows two armor gadgets in same slot. public void removeOutfit(Player player, ArmorSlot slot) @@ -867,6 +926,9 @@ public class GadgetManager extends MiniPlugin if (gadget instanceof TauntGadget) continue; + + if (gadget instanceof KitSelectorGadget) + continue; for (Player player : UtilServer.getPlayers()) gadget.disable(player); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/kitselector/HaloKitSelector.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/kitselector/HaloKitSelector.java new file mode 100644 index 000000000..4d1069e00 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/kitselector/HaloKitSelector.java @@ -0,0 +1,98 @@ +package mineplex.core.gadget.gadgets.kitselector; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.LineFormat; +import mineplex.core.common.util.RGBData; +import mineplex.core.common.util.UtilColor; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilText; +import mineplex.core.common.util.particles.ColoredParticle; +import mineplex.core.common.util.particles.DustSpellColor; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.types.KitSelectorGadget; + +public class HaloKitSelector extends KitSelectorGadget +{ + + private static final int PARTICLES_PER_CIRCLE = 20; + private static final double RADIUS = 0.6; + + private List _colors; + private int _steps = 0; + + public HaloKitSelector(GadgetManager manager) + { + super(manager, "Halo", UtilText.splitLinesToArray(new String[]{C.cGray + "Fight like an Angel."}, LineFormat.LORE), + 0, Material.GOLD_HELMET, (byte) 0); + _colors = new ArrayList<>(); + } + + @Override + public void playParticle(Entity entity, Player playTo) + { + if (_colors.isEmpty()) + { + RGBData rgbData = UtilColor.hexToRgb(0xffd700); + _colors.add(new Color(rgbData.getFullRed(), rgbData.getFullGreen(), rgbData.getFullBlue())); + rgbData = UtilColor.hexToRgb(0xdaa520); + _colors.add(new Color(rgbData.getFullRed(), rgbData.getFullGreen(), rgbData.getFullBlue())); + } + + Location location = entity.getLocation().add(0, getEntityYOffset(entity), 0); + double increment = (2 * Math.PI) / PARTICLES_PER_CIRCLE; + double angle = _steps * increment; + Vector vector = new Vector(Math.cos(angle) * RADIUS, 0, Math.sin(angle) * RADIUS); + ColoredParticle coloredParticle = new ColoredParticle(UtilParticle.ParticleType.RED_DUST, new DustSpellColor(getNextColor()), location.add(vector)); + coloredParticle.display(UtilParticle.ViewDist.NORMAL, playTo); + _steps++; + } + + private Color getNextColor() + { + int r = UtilMath.random.nextInt(_colors.size()); + return _colors.get(r); + } + + /** + * Gets the right Y offset for that entity based on the type + * @param entity The entity + * @return The correct Y offset + */ + public double getEntityYOffset(Entity entity) + { + EntityType entityType = entity.getType(); + switch (entityType) + { + case SHEEP: + case PIG: + case BAT: + case MAGMA_CUBE: + case GUARDIAN: + case CHICKEN: + case SLIME: + case SQUID: + case WOLF: + case OCELOT: + return 1.3; + case SPIDER: + case CAVE_SPIDER: + return 0.75; + case ENDERMAN: + return 3.3; + } + return 2.3; + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/kitselector/RainCloudKitSelector.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/kitselector/RainCloudKitSelector.java new file mode 100644 index 000000000..55cb97461 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/kitselector/RainCloudKitSelector.java @@ -0,0 +1,36 @@ +package mineplex.core.gadget.gadgets.kitselector; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.LineFormat; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilText; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.types.KitSelectorGadget; + +public class RainCloudKitSelector extends KitSelectorGadget +{ + + public RainCloudKitSelector(GadgetManager manager) + { + super(manager, "Rain Cloud", UtilText.splitLinesToArray(new String[]{C.cGray + "The rain keeps falling, and the kit keeps calling."}, LineFormat.LORE), + 0, Material.POTION, (byte) 0); + } + + + @Override + public void playParticle(Entity entity, Player playTo) + { + Location loc = entity.getLocation().add(0, 3.5, 0); + UtilParticle.PlayParticle(UtilParticle.ParticleType.EXPLODE, loc, 0.6f, 0f, 0.6f, 0, 8, UtilParticle.ViewDist.NORMAL, playTo); + + UtilParticle.PlayParticle(UtilParticle.ParticleType.CLOUD, loc, 0.6f, 0.1f, 0.6f, 0, 8, UtilParticle.ViewDist.NORMAL, playTo); + + UtilParticle.PlayParticle(UtilParticle.ParticleType.DRIP_WATER, loc, 0.4f, 0.1f, 0.4f, 0, 2, UtilParticle.ViewDist.NORMAL, playTo); + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/kitselector/RainbowDanceKitSelector.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/kitselector/RainbowDanceKitSelector.java new file mode 100644 index 000000000..c4aed4e90 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/kitselector/RainbowDanceKitSelector.java @@ -0,0 +1,61 @@ +package mineplex.core.gadget.gadgets.kitselector; + +import java.awt.Color; + +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.LineFormat; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilText; +import mineplex.core.common.util.particles.ColoredParticle; +import mineplex.core.common.util.particles.DustSpellColor; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.types.KitSelectorGadget; + +public class RainbowDanceKitSelector extends KitSelectorGadget +{ + + private Color[] _rainbowColors = new Color[] + { + new Color(148, 0, 211), + new Color(75, 0, 130), + new Color(0, 0, 255), + new Color(0, 255, 0), + new Color(255, 255, 0), + new Color(255, 127, 0), + new Color(255, 0, 0) + }; + private int _colorCount = 0; + + public RainbowDanceKitSelector(GadgetManager manager) + { + super(manager, "Rainbow Dance", UtilText.splitLinesToArray(new String[]{C.cGray + "At the end of this Rainbow is the kit of your dreams."}, LineFormat.LORE), + 0, Material.WOOL, (byte) 6); + } + + @Override + public void playParticle(Entity entity, Player playTo) + { + int tick = entity.getTicksLived(); + + float x = (float) (Math.sin(tick / 7d) * 1f); + float z = (float) (Math.cos(tick / 7d) * 1f); + float y = (float) (Math.cos(tick / 17d) * 1f + 1f); + + ColoredParticle coloredParticle = new ColoredParticle(UtilParticle.ParticleType.RED_DUST, new DustSpellColor(getNextColor()), entity.getLocation().add(x, y, z)); + coloredParticle.display(UtilParticle.ViewDist.NORMAL, playTo); + } + + private Color getNextColor() + { + Color color = _rainbowColors[_colorCount]; + _colorCount++; + if (_colorCount == _rainbowColors.length) + _colorCount = 0; + return color; + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/kitselector/ShimmeringRingKitSelector.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/kitselector/ShimmeringRingKitSelector.java new file mode 100644 index 000000000..c94da1413 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/kitselector/ShimmeringRingKitSelector.java @@ -0,0 +1,82 @@ +package mineplex.core.gadget.gadgets.kitselector; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.LineFormat; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilText; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.types.KitSelectorGadget; + +public class ShimmeringRingKitSelector extends KitSelectorGadget +{ + + private static final int PARTICLES_PER_CIRCLE = 20; + + private double _circleHeight = 0.0; + private boolean _direction = true; + + public ShimmeringRingKitSelector(GadgetManager manager) + { + super(manager, "Shimmering Ring", UtilText.splitLinesToArray(new String[]{C.cGray + "Encaged in your golden rings, your kits weapon still sing."}, LineFormat.LORE), + 0, Material.WOOL, (byte) 4); + } + + @Override + public void playParticle(Entity entity, Player playTo) + { + + // Updates height and direction of particles + if (_circleHeight <= 0) + { + _direction = true; + } + else if (_circleHeight >= getEntityHeight(entity)) + { + _direction = false; + } + if (_direction) + _circleHeight += 0.2; + else + _circleHeight -= 0.2; + + for (int i = 0; i < PARTICLES_PER_CIRCLE; i++) + { + Location location = entity.getLocation().add(0, _circleHeight, 0); + double increment = (2 * Math.PI) / PARTICLES_PER_CIRCLE; + double angle = i * increment; + Vector vector = new Vector(Math.cos(angle), 0, Math.sin(angle)); + UtilParticle.PlayParticle(UtilParticle.ParticleType.FLAME, location.add(vector), 0, 0, 0, 0, 1, UtilParticle.ViewDist.NORMAL, playTo); + } + } + + private double getEntityHeight(Entity entity) + { + switch (entity.getType()) + { + case SHEEP: + case PIG: + case BAT: + case MAGMA_CUBE: + case GUARDIAN: + case CHICKEN: + case SLIME: + case SQUID: + case WOLF: + case OCELOT: + return 0.75; + case SPIDER: + case CAVE_SPIDER: + return 0.5; + case ENDERMAN: + return 3; + } + return 2; + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/kitselector/SingleParticleKitSelector.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/kitselector/SingleParticleKitSelector.java new file mode 100644 index 000000000..a2ec8e93b --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/kitselector/SingleParticleKitSelector.java @@ -0,0 +1,81 @@ +package mineplex.core.gadget.gadgets.kitselector; + +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.LineFormat; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilText; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.types.KitSelectorGadget; + +public class SingleParticleKitSelector extends KitSelectorGadget +{ + + private UtilParticle.ParticleType _particleType; + private int _particleCount; + + public SingleParticleKitSelector(GadgetManager manager, String name, String[] lore, int cost, Material mat, byte data, + UtilParticle.ParticleType particleType, int particleCount, String... alternativeSalesPackageNames) + { + super(manager, name, lore, cost, mat, data, alternativeSalesPackageNames); + _particleType = particleType; + _particleCount = particleCount; + } + + @Override + public void playParticle(Entity entity, Player playTo) + { + UtilParticle.PlayParticle(_particleType, entity.getLocation().add(0, 1, 0), 0.5f, 0.5f, 0.5f, 0, _particleCount, UtilParticle.ViewDist.NORMAL, playTo); + } + + public enum SingleParticleSelectors + { + FLAMES_OF_FURY("Flames Of Fury", UtilText.splitLinesToArray(new String[]{C.cGray + "Through the Fire and the Flames we will ride"}, LineFormat.LORE), + 0, Material.BLAZE_POWDER, (byte) 0, UtilParticle.ParticleType.FLAME), + EMBER("Ember", UtilText.splitLinesToArray(new String[]{C.cGray + "I'd like my kit well done."}, LineFormat.LORE), + 0, Material.COAL, (byte) 0, UtilParticle.ParticleType.SMOKE, 3), + LOVE("Kit Love", UtilText.splitLinesToArray(new String[]{C.cGray + "I think I LIKE this kit, if you know what I mean."}, LineFormat.LORE), + 0, Material.POTION, (byte) 8233, UtilParticle.ParticleType.HEART); + + private String _name; + private String[] _lore; + private int _cost; + private Material _material; + private byte _data; + private UtilParticle.ParticleType _particleType; + private int _particleCount = 1; + private String[] _alternativeSalesPackageNames; + + SingleParticleSelectors(String name, String[] lore, int cost, Material material, byte data, UtilParticle.ParticleType particleType, String... alternativeSalesPackageNames) + { + _name = name; + _lore = lore; + _cost = cost; + _material = material; + _data = data; + _particleType = particleType; + _alternativeSalesPackageNames = alternativeSalesPackageNames; + } + + SingleParticleSelectors(String name, String[] lore, int cost, Material material, byte data, UtilParticle.ParticleType particleType, int particleCount, String... alternativeSalesPackageNames) + { + _name = name; + _lore = lore; + _cost = cost; + _material = material; + _data = data; + _particleType = particleType; + _alternativeSalesPackageNames = alternativeSalesPackageNames; + _particleCount = particleCount; + } + + public KitSelectorGadget getKitSelectorGadget(GadgetManager manager) + { + return new SingleParticleKitSelector(manager, _name, _lore, _cost, _material, _data, _particleType, _particleCount, _alternativeSalesPackageNames); + } + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/kitselector/WaterWingsKitSelector.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/kitselector/WaterWingsKitSelector.java new file mode 100644 index 000000000..c776610f3 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/kitselector/WaterWingsKitSelector.java @@ -0,0 +1,86 @@ +package mineplex.core.gadget.gadgets.kitselector; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.util.Vector; + +import mineplex.core.common.shape.ShapeWings; +import mineplex.core.common.util.C; +import mineplex.core.common.util.LineFormat; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilText; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.types.KitSelectorGadget; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; + +public class WaterWingsKitSelector extends KitSelectorGadget +{ + + private ShapeWings _wings = new ShapeWings(UtilParticle.ParticleType.DRIP_WATER.particleName, new Vector(0.2,0.2,0.2), 1, 0, false, ShapeWings.DEFAULT_ROTATION, ShapeWings.ANGEL_WING_PATTERN); + private ShapeWings _wingsEdge = new ShapeWings(UtilParticle.ParticleType.DRIP_WATER.particleName, new Vector(0.1,0.1,0.1), 1, 0, true, ShapeWings.DEFAULT_ROTATION, ShapeWings.ANGEL_WING_PATTERN); + + private int _tick = 0; + private int _lastTick = 0; + + public WaterWingsKitSelector(GadgetManager manager) + { + super(manager, "Water Wings", UtilText.splitLinesToArray(new String[]{C.cGray + "These wings won't help you float or fly, but they look pretty sweet."}, LineFormat.LORE), + 0, Material.WATER_BUCKET, (byte) 0); + } + + @Override + public void playParticle(Entity entity, Player playTo) + { + if (_tick != _lastTick) + { + double offsetY = getEntityYOffset(entity); + Location loc = entity.getLocation().add(0, offsetY, 0).add(entity.getLocation().getDirection().multiply(-0.2)); + _wings.display(loc, playTo); + _wingsEdge.display(loc, playTo); + _lastTick = _tick; + } + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() == UpdateType.FASTEST) + _tick++; + } + + /** + * Gets the right Y offset for that entity based on the type + * @param entity The entity + * @return The correct Y offset + */ + public double getEntityYOffset(Entity entity) + { + EntityType entityType = entity.getType(); + switch (entityType) + { + case SHEEP: + case PIG: + case BAT: + case MAGMA_CUBE: + case GUARDIAN: + case CHICKEN: + case SLIME: + case SQUID: + case WOLF: + case OCELOT: + return 0.75; + case SPIDER: + case CAVE_SPIDER: + return 0.25; + case ENDERMAN: + return 1.5; + } + return 1.2; + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/rankrooms/WinEffectRankBased.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/rankrooms/WinEffectRankBased.java new file mode 100644 index 000000000..48381aafa --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/rankrooms/WinEffectRankBased.java @@ -0,0 +1,80 @@ +package mineplex.core.gadget.gadgets.wineffect.rankrooms; + +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import mineplex.core.Managers; +import mineplex.core.common.Rank; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.types.WinEffectGadget; + +/** + * Helper class to create win effects based on ranks + */ +public abstract class WinEffectRankBased extends WinEffectGadget +{ + + private Rank _rank; + private WinEffectType _winEffectType; + + /** + * @param manager The gadget manager + * @param rank The rank needed for the win room + * @param winEffectType The win effect type, used to display in menus + * @param alternativeSalepackageNames + */ + public WinEffectRankBased(GadgetManager manager, String name, String[] lore, Material material, byte data, Rank rank, WinEffectType winEffectType, String... alternativeSalepackageNames) + { + super(manager, name, lore, -1, material, data, true, alternativeSalepackageNames); + _rank = rank; + _winEffectType = winEffectType; + _schematicName = winEffectType.getSchematic().replace("%r%", rank.getRawTag()); + } + + public Rank getRank() + { + return _rank; + } + + public WinEffectType getWinEffectType() + { + return _winEffectType; + } + + /** + * Gets the highest possible rank for the player + * @param player The player + * @return The highest rank for that player or null if GadgetManager isn't loaded + */ + public static Rank getHighestRankForPlayer(Player player) + { + GadgetManager gadgetManager = Managers.get(GadgetManager.class); + if (gadgetManager != null) + { + Rank rank = gadgetManager.getClientManager().Get(player).GetRank(); + if (rank.has(Rank.ETERNAL)) + return Rank.ETERNAL; + else + return rank; + } + return null; + } + + public enum WinEffectType + { + RANK_WIN_EFFECT("WinRank%r%"); + + private String _schematic; + + WinEffectType(String schematic) + { + _schematic = schematic; + } + + public String getSchematic() + { + return _schematic; + } + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/rankrooms/rankwineffects/WinEffectRankEternal.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/rankrooms/rankwineffects/WinEffectRankEternal.java new file mode 100644 index 000000000..03ddfa4d5 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/rankrooms/rankwineffects/WinEffectRankEternal.java @@ -0,0 +1,153 @@ +package mineplex.core.gadget.gadgets.wineffect.rankrooms.rankwineffects; + +import java.util.Set; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.Guardian; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.EventHandler; +import org.bukkit.util.Vector; + +import mineplex.core.common.MaterialData; +import mineplex.core.common.Rank; +import mineplex.core.common.util.C; +import mineplex.core.common.util.LineFormat; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilText; +import mineplex.core.disguise.disguises.DisguisePlayer; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.gadgets.wineffect.rankrooms.WinEffectRankBased; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; + +public class WinEffectRankEternal extends WinEffectRankBased +{ + + private DisguisePlayer _npc; + private Guardian _guardian = null; + private int _step = 0; + + private static final int POINTS = 100; + private static final float RADIUS = 15F; + private static final int BLOCK_RADIUS = 5; + + public WinEffectRankEternal(GadgetManager manager) + { + super(manager, "Eternal Win Effect", + UtilText.splitLinesToArray(new String[]{C.cGray + "GWEN is ALWAYS watching."}, LineFormat.LORE), + Material.PRISMARINE_SHARD, (byte) 0, Rank.ETERNAL, WinEffectType.RANK_WIN_EFFECT); + } + + @Override + public void play() + { + Location loc = getBaseLocation(); + + loc.setDirection(_player.getLocation().subtract(loc).toVector().multiply(-1)); + + _npc = getNPC(getPlayer(), loc, true); + } + + @Override + public void finish() + { + if (_guardian != null) + { + _guardian.remove(); + _guardian = null; + } + _step = 0; + } + + @EventHandler + public void spawnGuardian(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + return; + + if (_guardian != null) + { + return; + } + + if (!isRunning()) + return; + + _step++; + + if (_step == 5) + { + Location npcLocation = _npc.getEntity().getBukkitEntity().getLocation(); + Manager.getPetManager().getCreatureModule().SetForce(true); + _guardian = npcLocation.getWorld().spawn(npcLocation, Guardian.class); + Manager.getPetManager().getCreatureModule().SetForce(false); + _step = 0; + } + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (!isRunning()) + return; + + if (event.getType() != UpdateType.FASTEST) + return; + + if (_guardian == null) + { + return; + } + + Location npcLocation = _npc.getEntity().getBukkitEntity().getLocation(); + + _step++; + + double increment = (2 * Math.PI) / POINTS; + double angle = _step * increment; + Vector vector = new Vector(Math.cos(angle) * RADIUS, 0, Math.sin(angle) * RADIUS); + _guardian.setVelocity(new Vector(0,0,0)); + _guardian.teleport(npcLocation.clone().subtract(vector)); + Vector direction = npcLocation.toVector().subtract(_guardian.getEyeLocation().toVector()); + Location enderLocation = _guardian.getLocation().setDirection(direction); + _guardian.teleport(enderLocation); + + if (_step % 2 == 0 && _step < 45) + zap(); + + if (_step == 45) + { + breakBlocks(); + } + } + + private void zap() + { + if (_guardian != null) + { + _guardian.setTarget((LivingEntity) _npc.getEntity().getBukkitEntity()); + } + } + + private void breakBlocks() + { + Set blocks = UtilBlock.getBlocksInRadius(_npc.getEntity().getBukkitEntity().getLocation(), BLOCK_RADIUS, BLOCK_RADIUS); + for (Block block : blocks) + { + MaterialData materialData = MaterialData.of(block.getType(), block.getData()); + block.setType(Material.AIR); + FallingBlock fallingBlock = block.getLocation().getWorld().spawnFallingBlock(block.getLocation(), materialData.getMaterial(), materialData.getData()); + fallingBlock.setDropItem(false); + UtilAction.velocity(fallingBlock, UtilAlg.getTrajectory(fallingBlock.getLocation(), _npc.getEntity().getBukkitEntity().getLocation()).multiply(-1), .75, true, 0.8, 0, 1.0, true); + } + ArmorStand armorStand = (ArmorStand) _npc.getEntity().getBukkitEntity(); + armorStand.setHealth(0); + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/rankrooms/rankwineffects/WinEffectRankHero.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/rankrooms/rankwineffects/WinEffectRankHero.java new file mode 100644 index 000000000..f71cf48b6 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/rankrooms/rankwineffects/WinEffectRankHero.java @@ -0,0 +1,133 @@ +package mineplex.core.gadget.gadgets.wineffect.rankrooms.rankwineffects; + +import java.util.Set; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEnderDragon; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.EnderDragon; +import org.bukkit.entity.FallingBlock; +import org.bukkit.event.EventHandler; +import org.bukkit.util.Vector; + +import mineplex.core.common.MaterialData; +import mineplex.core.common.Rank; +import mineplex.core.common.util.C; +import mineplex.core.common.util.LineFormat; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilText; +import mineplex.core.disguise.disguises.DisguisePlayer; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.gadgets.wineffect.rankrooms.WinEffectRankBased; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; + +public class WinEffectRankHero extends WinEffectRankBased +{ + + private DisguisePlayer _npc; + private EnderDragon _enderDragon = null; + private int _step = 0; + + private static final int POINTS = 100; + private static final float RADIUS = 15F; + private static final int BLOCK_RADIUS = 5; + + public WinEffectRankHero(GadgetManager manager) + { + super(manager, "Hero Win Effect", + UtilText.splitLinesToArray(new String[]{C.cGray + "To become a True Hero you must first defeat the Dragon."}, LineFormat.LORE), + Material.DRAGON_EGG, (byte) 0, Rank.HERO, WinEffectType.RANK_WIN_EFFECT); + } + + @Override + public void play() + { + Location loc = getBaseLocation(); + + loc.setDirection(_player.getLocation().subtract(loc).toVector().multiply(-1)); + + _npc = getNPC(getPlayer(), loc); + } + + @Override + public void finish() + { + if (_enderDragon != null) + { + _enderDragon.remove(); + _enderDragon = null; + } + _step = 0; + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (!isRunning()) + return; + + if (_step > 62) + return; + + if (_step == 62) + { + breakBlocks(); + } + + if (event.getType() != UpdateType.FASTEST) + return; + + Location npcLocation = _npc.getEntity().getBukkitEntity().getLocation(); + + _step++; + + if (_enderDragon == null) + { + Manager.getPetManager().getCreatureModule().SetForce(true); + _enderDragon = npcLocation.getWorld().spawn(npcLocation.add(0, 20, 0), EnderDragon.class); + Manager.getPetManager().getCreatureModule().SetForce(false); + _step = 0; + } + + if (_step < 50) + { + double increment = (2 * Math.PI) / POINTS; + double angle = _step * increment; + Vector vector = new Vector(Math.cos(angle) * RADIUS, 0, Math.sin(angle) * RADIUS); + _enderDragon.setVelocity(new Vector(0, 0, 0)); + _enderDragon.teleport(npcLocation.clone().subtract(vector)); + Vector direction = npcLocation.toVector().subtract(_enderDragon.getEyeLocation().toVector()).multiply(-1); + Location enderLocation = _enderDragon.getLocation().setDirection(direction); + _enderDragon.teleport(enderLocation); + } + + if (_step >= 50) + setTarget(); + } + + private void setTarget() + { + ((CraftEnderDragon) _enderDragon).getHandle().setTargetBlock(_baseLocation.getBlockX(), _baseLocation.getBlockY(), _baseLocation.getBlockZ()); + } + + private void breakBlocks() + { + Set blocks = UtilBlock.getBlocksInRadius(_baseLocation.add(0, 1, 0), BLOCK_RADIUS, BLOCK_RADIUS); + for (Block block : blocks) + { + MaterialData materialData = MaterialData.of(block.getType(), block.getData()); + block.setType(Material.AIR); + FallingBlock fallingBlock = block.getLocation().getWorld().spawnFallingBlock(block.getLocation(), materialData.getMaterial(), materialData.getData()); + fallingBlock.setDropItem(false); + UtilAction.velocity(fallingBlock, UtilAlg.getTrajectory(fallingBlock.getLocation(), _npc.getEntity().getBukkitEntity().getLocation()).multiply(-1), .75, true, 0.8, 0, 1.0, true); + } + ArmorStand armorStand = (ArmorStand) _npc.getEntity().getBukkitEntity(); + armorStand.setHealth(0); + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/rankrooms/rankwineffects/WinEffectRankLegend.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/rankrooms/rankwineffects/WinEffectRankLegend.java new file mode 100644 index 000000000..ab96a352c --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/rankrooms/rankwineffects/WinEffectRankLegend.java @@ -0,0 +1,128 @@ +package mineplex.core.gadget.gadgets.wineffect.rankrooms.rankwineffects; + +import java.util.Set; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.Wither; +import org.bukkit.entity.WitherSkull; +import org.bukkit.event.EventHandler; +import org.bukkit.util.Vector; + +import mineplex.core.common.MaterialData; +import mineplex.core.common.Rank; +import mineplex.core.common.util.C; +import mineplex.core.common.util.LineFormat; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilText; +import mineplex.core.disguise.disguises.DisguisePlayer; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.gadgets.wineffect.rankrooms.WinEffectRankBased; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; + +public class WinEffectRankLegend extends WinEffectRankBased +{ + + private DisguisePlayer _npc; + private Wither _wither = null; + private int _step = 0; + + private static final int POINTS = 100; + private static final float RADIUS = 15F; + private static final int BLOCK_RADIUS = 5; + + public WinEffectRankLegend(GadgetManager manager) + { + super(manager, "Legend Win Effect", + UtilText.splitLinesToArray(new String[]{C.cGray + "Can you weather this Withering Assault?"}, LineFormat.LORE), + Material.SKULL_ITEM, (byte) 1, Rank.LEGEND, WinEffectType.RANK_WIN_EFFECT); + } + + @Override + public void play() + { + Location loc = getBaseLocation(); + + loc.setDirection(_player.getLocation().subtract(loc).toVector().multiply(-1)); + + _npc = getNPC(getPlayer(), loc, true); + } + + @Override + public void finish() + { + if (_wither != null) + { + _wither.remove(); + _wither = null; + } + _step = 0; + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (!isRunning()) + return; + + if (event.getType() != UpdateType.FASTEST) + return; + + Location npcLocation = _npc.getEntity().getBukkitEntity().getLocation(); + + _step++; + + if (_wither == null) + { + Manager.getPetManager().getCreatureModule().SetForce(true); + _wither = npcLocation.getWorld().spawn(npcLocation.add(0, 20, 0), Wither.class); + Manager.getPetManager().getCreatureModule().SetForce(false); + } + + double increment = (2 * Math.PI) / POINTS; + + double angle = _step * increment; + Vector vector = new Vector(Math.cos(angle) * RADIUS, 0, Math.sin(angle) * RADIUS); + _wither.setVelocity(new Vector(0,0,0)); + _wither.teleport(npcLocation.clone().subtract(vector)); + Vector direction = npcLocation.toVector().subtract(_wither.getEyeLocation().toVector()); + Location enderLocation = _wither.getLocation().setDirection(direction); + _wither.teleport(enderLocation); + + if (_step % 5 == 0 && _step < 45) + spawnSkull(); + + if (_step == 45) + breakBlocks(); + } + + private void spawnSkull() + { + if (_wither != null) + { + _wither.launchProjectile(WitherSkull.class); + } + } + + private void breakBlocks() + { + Set blocks = UtilBlock.getBlocksInRadius(_npc.getEntity().getBukkitEntity().getLocation(), BLOCK_RADIUS, BLOCK_RADIUS); + for (Block block : blocks) + { + MaterialData materialData = MaterialData.of(block.getType(), block.getData()); + block.setType(Material.AIR); + FallingBlock fallingBlock = block.getLocation().getWorld().spawnFallingBlock(block.getLocation(), materialData.getMaterial(), materialData.getData()); + fallingBlock.setDropItem(false); + UtilAction.velocity(fallingBlock, UtilAlg.getTrajectory(fallingBlock.getLocation(), _npc.getEntity().getBukkitEntity().getLocation()).multiply(-1), .75, true, 0.8, 0, 1.0, true); + } + ArmorStand armorStand = (ArmorStand) _npc.getEntity().getBukkitEntity(); + armorStand.setHealth(0); + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/rankrooms/rankwineffects/WinEffectRankTitan.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/rankrooms/rankwineffects/WinEffectRankTitan.java new file mode 100644 index 000000000..93c508ae5 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/rankrooms/rankwineffects/WinEffectRankTitan.java @@ -0,0 +1,115 @@ +package mineplex.core.gadget.gadgets.wineffect.rankrooms.rankwineffects; + +import java.util.Set; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.Giant; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent; + +import mineplex.core.common.MaterialData; +import mineplex.core.common.Rank; +import mineplex.core.common.util.C; +import mineplex.core.common.util.LineFormat; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilText; +import mineplex.core.disguise.disguises.DisguisePlayer; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.gadgets.wineffect.rankrooms.WinEffectRankBased; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; + +public class WinEffectRankTitan extends WinEffectRankBased +{ + + private DisguisePlayer _npc; + private Giant _giant = null; + private int _step = 0; + + private static final int RADIUS = 5; + + public WinEffectRankTitan(GadgetManager manager) + { + super(manager, "Titan Win Effect", + UtilText.splitLinesToArray(new String[]{C.cGray + "Legend has it that the Titans were so powerful they towered over even the gods."}, LineFormat.LORE), + Material.ROTTEN_FLESH, (byte) 0, Rank.TITAN, WinEffectType.RANK_WIN_EFFECT); + } + + @Override + public void play() + { + Location loc = getBaseLocation(); + + loc.setDirection(_player.getLocation().subtract(loc).toVector().multiply(-1)); + + _npc = getNPC(getPlayer(), loc); + } + + @Override + public void finish() + { + if (_giant != null) + { + _giant.remove(); + _giant = null; + } + _step = 0; + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (!isRunning()) + return; + + if (event.getType() != UpdateType.FASTEST) + return; + + if (_giant == null && _step >= 5) + { + Location loc = getBaseLocation(); + + Manager.getPetManager().getCreatureModule().SetForce(true); + + _giant = loc.getWorld().spawn(loc.add(0, 20, 0), Giant.class); + + Manager.getPetManager().getCreatureModule().SetForce(false); + } + else + { + _step++; + } + } + + @EventHandler + public void onGiantFall(EntityDamageEvent event) + { + if (_giant == null) + return; + + if (event.getCause().equals(EntityDamageEvent.DamageCause.FALL)) + { + if (event.getEntity().equals(_giant)) + { + Set blocks = UtilBlock.getBlocksInRadius(_npc.getEntity().getBukkitEntity().getLocation(), RADIUS, RADIUS); + for (Block block : blocks) + { + MaterialData materialData = MaterialData.of(block.getType(), block.getData()); + block.setType(Material.AIR); + FallingBlock fallingBlock = block.getLocation().getWorld().spawnFallingBlock(block.getLocation(), materialData.getMaterial(), materialData.getData()); + fallingBlock.setDropItem(false); + UtilAction.velocity(fallingBlock, UtilAlg.getTrajectory(fallingBlock.getLocation(), _npc.getEntity().getBukkitEntity().getLocation()).multiply(-1), .75, true, 0.8, 0, 1.0, true); + } + ArmorStand armorStand = (ArmorStand) _npc.getEntity().getBukkitEntity(); + armorStand.setHealth(0); + } + } + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/rankrooms/rankwineffects/WinEffectRankUltra.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/rankrooms/rankwineffects/WinEffectRankUltra.java new file mode 100644 index 000000000..afb57433c --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/rankrooms/rankwineffects/WinEffectRankUltra.java @@ -0,0 +1,114 @@ +package mineplex.core.gadget.gadgets.wineffect.rankrooms.rankwineffects; + +import java.util.Set; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Creeper; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityExplodeEvent; + +import mineplex.core.common.MaterialData; +import mineplex.core.common.Rank; +import mineplex.core.common.util.C; +import mineplex.core.common.util.LineFormat; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilText; +import mineplex.core.disguise.disguises.DisguisePlayer; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.gadgets.wineffect.rankrooms.WinEffectRankBased; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; + +public class WinEffectRankUltra extends WinEffectRankBased +{ + + private static final int RADIUS = 5; + + private DisguisePlayer _npc; + private Creeper _creeper; + private int _step = 0; + + public WinEffectRankUltra(GadgetManager manager) + { + super(manager, "Ultra Win Effect", UtilText.splitLinesToArray(new String[]{C.cGray + "Always check behind you."}, LineFormat.LORE), + Material.SKULL_ITEM, (byte) 4, Rank.ULTRA, WinEffectType.RANK_WIN_EFFECT); + } + + @Override + public void play() + { + Location loc = getBaseLocation(); + + loc.setDirection(_player.getLocation().subtract(loc).toVector().multiply(-1)); + loc.setPitch(0); + loc.setYaw(0); + _npc = getNPC(getPlayer(), loc, true); + } + + @Override + public void finish() + { + if (_creeper != null) + { + _creeper.remove(); + _creeper = null; + } + _step = 0; + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (!isRunning()) + return; + + if (event.getType() != UpdateType.FASTEST) + return; + + if (_creeper == null && _step >= 5) + { + Location loc = getBaseLocation(); + + Manager.getPetManager().getCreatureModule().SetForce(true); + + _creeper = loc.getWorld().spawn(loc.add(0, 10, 0), Creeper.class); + + _creeper.teleport(loc.subtract(0, 0, 2)); + + _creeper.setTarget((LivingEntity) _npc.getEntity().getBukkitEntity()); + + Manager.getPetManager().getCreatureModule().SetForce(false); + } + else + { + _step++; + } + } + + @EventHandler + public void onEntityExplode(EntityExplodeEvent event) + { + if (event.getEntity().equals(_creeper)) + { + Set blocks = UtilBlock.getBlocksInRadius(_npc.getEntity().getBukkitEntity().getLocation(), RADIUS, RADIUS); + for (Block block : blocks) + { + MaterialData materialData = MaterialData.of(block.getType(), block.getData()); + block.setType(Material.AIR); + FallingBlock fallingBlock = block.getLocation().getWorld().spawnFallingBlock(block.getLocation(), materialData.getMaterial(), materialData.getData()); + fallingBlock.setDropItem(false); + UtilAction.velocity(fallingBlock, UtilAlg.getTrajectory(fallingBlock.getLocation(), _npc.getEntity().getBukkitEntity().getLocation()).multiply(-1), .75, true, 0.8, 0, 1.0, true); + } + ArmorStand armorStand = (ArmorStand) _npc.getEntity().getBukkitEntity(); + armorStand.setHealth(0); + } + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/Gadget.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/Gadget.java index 141885d0c..aab6e9c71 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/Gadget.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/Gadget.java @@ -141,8 +141,8 @@ public abstract class Gadget extends SalesPackageBase implements Listener return; } - Manager.setActive(player, this); enableCustom(player, message); + Manager.setActive(player, this); Bukkit.getServer().getPluginManager().callEvent(new GadgetAppliedEvent(player, this)); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/GadgetType.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/GadgetType.java index 6f06cb54c..edc823e6d 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/GadgetType.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/GadgetType.java @@ -17,7 +17,8 @@ public enum GadgetType TAUNT("Taunts", "activeTaunt"), WIN_EFFECT("Win Effects", "activeWinEffect"), GAME_MODIFIER("Game Modifiers", ""), - BALLOON("Balloons", ""); + BALLOON("Balloons", ""), + KIT_SELECTOR("Kit Selectors", "activeKitSelector"); private String _name; private String _databaseKey; diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/KitSelectorGadget.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/KitSelectorGadget.java new file mode 100644 index 000000000..b8dff0bd6 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/KitSelectorGadget.java @@ -0,0 +1,28 @@ +package mineplex.core.gadget.types; + +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import mineplex.core.gadget.GadgetManager; + +/** + * Handles custom particle effects for the arcade hub kit selectors + */ +public abstract class KitSelectorGadget extends Gadget +{ + + public KitSelectorGadget(GadgetManager gadgetManager, String name, String[] lore, int cost, Material mat, byte data, + String... alternativeSalesPackageNames) + { + super(gadgetManager, GadgetType.KIT_SELECTOR, name, lore, cost, mat, data, 1, alternativeSalesPackageNames); + } + + /** + * Plays the next particle for the selected entity + * @param entity The entity of the selected kit + * @param playTo The player that will receive the particles + */ + public abstract void playParticle(Entity entity, Player playTo); + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/WinEffectGadget.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/WinEffectGadget.java index 3b16c5c4a..faf54e131 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/WinEffectGadget.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/WinEffectGadget.java @@ -339,6 +339,28 @@ public abstract class WinEffectGadget extends Gadget Manager.getDisguiseManager().disguise(disguise); return disguise; } + + /** + * Get a disguised ArmorStand with the skin of the provided player at the provided location. The ArmorStand got 2048 health. + * @param player The player to create the disguise from + * @param loc The location to spawn the ArmorStand at + * @param gravity true if the armorstand should have gravity + * @return Returns a disguised ArmorStand at the given location + */ + public DisguisePlayer getNPC(Player player, Location loc, boolean gravity) { + ArmorStand stand = loc.getWorld().spawn(loc, ArmorStand.class); + + stand.setMaxHealth(2048); + stand.setHealth(2048); + stand.setGravity(gravity); + + GameProfile profile = new GameProfile(UUID.randomUUID(), player.getName()); + profile.getProperties().putAll(((CraftPlayer) player).getHandle().getProfile().getProperties()); + + DisguisePlayer disguise = new DisguisePlayer(stand, profile); + Manager.getDisguiseManager().disguise(disguise); + return disguise; + } /** * Paste a schematic relative to the base location diff --git a/Plugins/Mineplex.Core/src/mineplex/core/game/GameDisplay.java b/Plugins/Mineplex.Core/src/mineplex/core/game/GameDisplay.java index 430a198b7..cbeadcc64 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/game/GameDisplay.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/game/GameDisplay.java @@ -14,6 +14,8 @@ public enum GameDisplay Barbarians("A Barbarians Life", Material.WOOD_AXE, (byte)0, GameCategory.EXTRA, 2, false), BossBattles("Boss Battles", Material.SKULL_ITEM, (byte) 0, GameCategory.EVENT, 55, false), Bridge("The Bridges", Material.IRON_PICKAXE, (byte)0, GameCategory.SURVIVAL, 3, true), + CastleAssault("Castle Assault", Material.DIAMOND_CHESTPLATE, (byte)0, GameCategory.CLASSICS, 67, true), + CastleAssaultTDM("Castle Assault TDM", Material.DIAMOND_CHESTPLATE, (byte)0, GameCategory.CLASSICS, 68, false), CastleSiege("Castle Siege", Material.DIAMOND_CHESTPLATE, (byte)0, GameCategory.CLASSICS, 4, true), ChampionsDominate("Champions Domination", "Champions", Material.BEACON, (byte)0, GameCategory.CHAMPIONS, 6, true), ChampionsTDM("Champions TDM", "Champions", Material.GOLD_SWORD, (byte)0, GameCategory.CHAMPIONS, 5, true), diff --git a/Plugins/Mineplex.Core/src/mineplex/core/hologram/HologramManager.java b/Plugins/Mineplex.Core/src/mineplex/core/hologram/HologramManager.java index 618c30f44..a68ce5944 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/hologram/HologramManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/hologram/HologramManager.java @@ -4,6 +4,17 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.util.Vector; + +import mineplex.core.MiniPlugin; import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilTime; import mineplex.core.packethandler.IPacketHandler; @@ -14,24 +25,13 @@ import mineplex.core.updater.event.UpdateEvent; import net.minecraft.server.v1_8_R3.PacketPlayInUseEntity; import net.minecraft.server.v1_8_R3.PacketPlayInUseEntity.EnumEntityUseAction; -import org.bukkit.Bukkit; -import org.bukkit.World; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.util.Vector; - -public class HologramManager implements Listener, IPacketHandler +public class HologramManager extends MiniPlugin implements IPacketHandler { private ArrayList _activeHolograms = new ArrayList(); - public HologramManager(JavaPlugin arcadeManager, PacketHandler packetHandler) + public HologramManager(JavaPlugin plugin, PacketHandler packetHandler) { - Bukkit.getPluginManager().registerEvents(this, arcadeManager); + super("Hologram Manager", plugin); packetHandler.addPacketHandler(this, true, PacketPlayInUseEntity.class); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/itemstack/EnchantedBookBuilder.java b/Plugins/Mineplex.Core/src/mineplex/core/itemstack/EnchantedBookBuilder.java new file mode 100644 index 000000000..f4228e06d --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/itemstack/EnchantedBookBuilder.java @@ -0,0 +1,63 @@ +package mineplex.core.itemstack; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.EnchantmentStorageMeta;; + +public class EnchantedBookBuilder +{ + private Map _enchantments; + private int _amount; + + public EnchantedBookBuilder(int amount) + { + _enchantments = new HashMap<>(); + _amount = amount; + } + + public Map getEnchantments() + { + return _enchantments; + } + + public Integer getLevel(Enchantment enchantment) + { + return _enchantments.getOrDefault(enchantment, 0); + } + + public EnchantedBookBuilder setLevel(Enchantment enchantment, Integer level) + { + if (level <= 0) + { + _enchantments.remove(enchantment); + } + else + { + _enchantments.put(enchantment, level); + } + + return this; + } + + public EnchantedBookBuilder removeEnchantment(Enchantment enchantment) + { + _enchantments.remove(enchantment); + + return this; + } + + public ItemStack build() + { + ItemStack item = new ItemStack(Material.ENCHANTED_BOOK, _amount); + EnchantmentStorageMeta meta = (EnchantmentStorageMeta) item.getItemMeta(); + + _enchantments.entrySet().forEach(entry -> meta.addStoredEnchant(entry.getKey(), entry.getValue(), true)); + item.setItemMeta(meta); + + return item; + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/itemstack/ItemBuilder.java b/Plugins/Mineplex.Core/src/mineplex/core/itemstack/ItemBuilder.java index 14af0f28d..603f5e150 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/itemstack/ItemBuilder.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/itemstack/ItemBuilder.java @@ -8,8 +8,6 @@ import java.util.HashSet; import java.util.List; import java.util.Map; -import mineplex.core.common.util.UtilInput; -import mineplex.core.common.util.UtilInv; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Color; @@ -26,6 +24,7 @@ import org.bukkit.inventory.meta.LeatherArmorMeta; import org.bukkit.inventory.meta.SkullMeta; import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilInv; public class ItemBuilder { @@ -311,6 +310,18 @@ public class ItemBuilder // newBuilder.potion = potion; newBuilder.setDurability(_durability); + newBuilder.setData(_data); + + newBuilder.setAmount(_amount); + + newBuilder.setUnbreakable(_unbreakable); + + newBuilder.setGlow(_glow); + + newBuilder.setItemFlags(_itemFlags); + + newBuilder.setPlayerHead(_playerHeadName); + return newBuilder; } @@ -389,9 +400,14 @@ public class ItemBuilder public ItemBuilder setTitle(String title) { - _title = (title == null ? null - : (title.length() > 2 && ChatColor.getLastColors(title.substring(0, 2)).length() == 0 ? ChatColor.WHITE : "")) - + title; + if (title == null) + { + _title = null; + } + else + { + _title = ((title.length() > 2 && ChatColor.getLastColors(title.substring(0, 2)).length() == 0) ? ChatColor.WHITE : "") + title; + } return this; } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/Leaderboard.java b/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/Leaderboard.java new file mode 100644 index 000000000..c90639b66 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/Leaderboard.java @@ -0,0 +1,100 @@ +package mineplex.core.leaderboard; + +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.Location; + +import mineplex.core.Managers; +import mineplex.core.common.Pair; +import mineplex.core.common.util.C; +import mineplex.core.hologram.Hologram; +import mineplex.core.leaderboard.LeaderboardRepository.LeaderboardSQLType; + +public class Leaderboard +{ + private String _display; + private Pair _statDisplay; + private String[] _statNames; + private int[] _statIds; + private int _size, _start; + private LeaderboardSQLType _type; + private Location _loc; + private Hologram _holo; + + public Leaderboard(String display, Pair statDisplayNames, String[] statNames, LeaderboardSQLType type, Location displayLoc, int size) + { + this(display, statDisplayNames, statNames, type, displayLoc, size, 0); + } + + public Leaderboard(String display, Pair statDisplayNames, String[] statNames, LeaderboardSQLType type, Location displayLoc, int size, int start) + { + _display = display; + _statDisplay = statDisplayNames; + _statNames = statNames; + _statIds = new int[_statNames.length]; + _type = type; + _size = size; + _loc = displayLoc; + + update(new LinkedHashMap<>()); + } + + public int getSize() + { + return _size; + } + + public int getStart() + { + return _start; + } + + public String[] getStatNames() + { + return _statNames; + } + + public int[] getStatIds() + { + return _statIds; + } + + public LeaderboardSQLType getType() + { + return _type; + } + + public void update(Map names) + { + deconstruct(); + LinkedList display = new LinkedList<>(); + display.add(C.cAqua + _display); + display.add(C.cRed + " "); + int place = _start + 1; + for (Entry entry : names.entrySet()) + { + if (entry.getValue() == 1) + { + display.add(C.cGreen + "#" + place + " " + entry.getKey() + C.cRed + " " + entry.getValue() + " " + _statDisplay.getLeft()); + } + else + { + display.add(C.cGreen + "#" + place + " " + entry.getKey() + C.cRed + " " + entry.getValue() + " " + _statDisplay.getRight()); + } + place++; + } + _holo = new Hologram(Managers.get(LeaderboardManager.class).getHologramManager(), _loc, display.toArray(new String[display.size()])).start(); + } + + public void deconstruct() + { + if (_holo != null) + { + _holo.stop(); + _holo = null; + } + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/LeaderboardManager.java b/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/LeaderboardManager.java index 1ca8b9bc6..88a84c29d 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/LeaderboardManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/LeaderboardManager.java @@ -1,91 +1,136 @@ package mineplex.core.leaderboard; -import mineplex.core.MiniPlugin; -import mineplex.core.account.CoreClient; -import mineplex.core.account.CoreClientManager; -import mineplex.core.spawn.command.SpawnCommand; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; -/** - * Manages dynamic Leaderboard statistics. - * - * Used for recording stat events, retrieving customized leaderboards, etc. - * @author MrTwiggy - * - */ +import mineplex.core.Managers; +import mineplex.core.MiniPlugin; +import mineplex.core.command.CommandBase; +import mineplex.core.common.Rank; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilMath; +import mineplex.core.hologram.HologramManager; +import mineplex.core.stats.StatsManager; + public class LeaderboardManager extends MiniPlugin { + private final Map _leaderboards = new HashMap<>(); + private final long REFRESH_RATE; + private final LeaderboardRepository _repo; + private final Map _loading = new HashMap<>(); - private static LeaderboardManager _instance; // Singleton instance of Leaderboard Manager - private StatEventsRepository _statEvents; // 'statEvents' table repository. - private CoreClientManager _clientManager; - private String _serverGroup; - - /** - * Private class constructor to prevent non-singleton instances. - */ - public LeaderboardManager(JavaPlugin plugin, CoreClientManager clientManager) + public LeaderboardManager(JavaPlugin plugin) { super("Leaderboard Manager", plugin); - _instance = this; - _clientManager = clientManager; - _statEvents = new StatEventsRepository(plugin); - _serverGroup = _plugin.getConfig().getString("serverstatus.group"); - } - - /** - * Attempt to trigger a stat event. - * @param player - the player responsible for the statistic - * @param stat - the display name of the statistic to be added - * @param value - the counter value used to increment the statistic - * @return true, if a stat event was successfully triggered and logged, false otherwise. - */ - public boolean attemptStatEvent(Player player, String stat, int gamemode, int value) - { - StatType type = StatType.getType(stat); + _repo = new LeaderboardRepository(plugin); - return (type == null) ? false : onStatEvent(player, type, gamemode, value); - } - - /** - * Trigger a stat event to be recorded. - * @param player - the player responsible for the statistic - * @param type - the unique type id designating the statistic being recorded - * @param gamemode - the unique gamemode id associated with the stat event - * @param value - the counter value used to increment the statistic - * @return true, if the stat event was successfully triggered and logged, false otherwise. - */ - public boolean onStatEvent(final Player player, final StatType type, final int gamemode, final int value) - { - /* - // Asynchronously make DB call to insert stat event. - Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), new Runnable() + addCommand(new CommandBase(this, Rank.DEVELOPER, "cycleleaderboard") { - public void run() + @Override + public void Execute(Player caller, String[] args) { - _statEvents.insertStatEvent(player.getName(), gamemode, _serverGroup, type.getTypeId(), value); + caller.sendMessage(F.main(getName(), "Cycling leaderboards!")); + refreshBoards(); } }); - */ - return true; + REFRESH_RATE = 5 * 60 * 20 + ((UtilMath.r(5) + 1) * 60 * 20); + + runSyncTimer(() -> refreshBoards(), 0, REFRESH_RATE); + + runSyncTimer(() -> + { + Iterator> iterator = _loading.entrySet().iterator(); + while (iterator.hasNext()) + { + Entry entry = iterator.next(); + boolean registered = true; + for (int id : entry.getKey().getStatIds()) + { + if (id == 0) + { + registered = false; + } + } + if (registered) + { + entry.getValue().run(); + iterator.remove(); + } + } + }, 0, 20 * 2); } - @Override - public void addCommands() + private void refreshBoards() { - addCommand(new SetTournamentCommand(this)); + List leaderboards = new ArrayList<>(); + leaderboards.addAll(_leaderboards.values()); + _repo.loadLeaderboards(_leaderboards.values(), boards -> + { + for (int i = 0; i < boards.length && i < leaderboards.size(); i++) + { + leaderboards.get(i).update(boards[i]); + } + }); } - /** - * @return the singleton instance for {@link LeaderboardManager}. - */ - public static LeaderboardManager getInstance() + public HologramManager getHologramManager() { - return _instance; + return Managers.get(HologramManager.class); } -} + + public Leaderboard getLeaderboard(String identifier) + { + return _leaderboards.get(identifier); + } + + public void handleStatIncrease(Map> stats) + { + _repo.insertStats(stats); + } + + public void handleStatIncrease(int accountId, Map stats) + { + _repo.insertStats(accountId, stats); + } + + public void registerLeaderboard(String identifier, Leaderboard board) + { + if (_leaderboards.containsKey(identifier)) + { + board.deconstruct(); + return; + } + final Runnable postLoad = () -> + { + _leaderboards.put(identifier, board); + _repo.loadLeaderboard(board, board::update); + }; + _loading.put(board, postLoad); + for (int i = 0; i < board.getStatNames().length; i++) + { + final int index = i; + Managers.get(StatsManager.class).loadStatId(board.getStatNames()[index], id -> + { + board.getStatIds()[index] = id.intValue(); + }); + } + } + + public void unregisterLeaderboard(String boardIdentifier) + { + if (!_leaderboards.containsKey(boardIdentifier)) + { + return; + } + _leaderboards.remove(boardIdentifier).deconstruct(); + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/LeaderboardRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/LeaderboardRepository.java new file mode 100644 index 000000000..f9b286039 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/LeaderboardRepository.java @@ -0,0 +1,251 @@ +package mineplex.core.leaderboard; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.function.Consumer; + +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.common.util.UtilServer; +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.database.RepositoryBase; + +public class LeaderboardRepository extends RepositoryBase +{ + private static final String CREATE_TOTAL = "CREATE TABLE accountStatsAllTime (accountId INT NOT NULL, statId INT NOT NULL, value BIGINT NOT NULL, PRIMARY KEY (accountId, statId), INDEX valueIndex (value DESC), FOREIGN KEY (accountId) REFERENCES accounts(id), FOREIGN KEY (statId) REFERENCES stats(id));"; + private static final String CREATE_SEASONAL = "CREATE TABLE accountStatsSeasonal (accountId INT NOT NULL, statId INT NOT NULL, seasonId SMALLINT NOT NULL, value BIGINT NOT NULL, PRIMARY KEY (accountId, statId), INDEX valueIndex (value DESC), INDEX seasonIndex (seasonId), FOREIGN KEY (accountId) REFERENCES accounts(id), FOREIGN KEY (statId) REFERENCES stats(id), FOREIGN KEY (seasonId) REFERENCES statSeasons(id));"; + private static final String CREATE_YEARLY = "CREATE TABLE accountStatsYearly (accountId INT NOT NULL, statId INT NOT NULL, date DATE NOT NULL, value BIGINT NOT NULL, PRIMARY KEY (accountId, statId), INDEX valueIndex (value DESC), INDEX dateIndex (date), FOREIGN KEY (accountId) REFERENCES accounts(id), FOREIGN KEY (statId) REFERENCES stats(id));"; + private static final String CREATE_MONTHLY = "CREATE TABLE accountStatsMonthly (accountId INT NOT NULL, statId INT NOT NULL, date DATE NOT NULL, value BIGINT NOT NULL, PRIMARY KEY (accountId, statId), INDEX valueIndex (value DESC), INDEX dateIndex (date), FOREIGN KEY (accountId) REFERENCES accounts(id), FOREIGN KEY (statId) REFERENCES stats(id));"; + private static final String CREATE_WEEKLY = "CREATE TABLE accountStatsWeekly (accountId INT NOT NULL, statId INT NOT NULL, date DATE NOT NULL, value BIGINT NOT NULL, PRIMARY KEY (accountId, statId), INDEX valueIndex (value DESC), INDEX dateIndex (date), FOREIGN KEY (accountId) REFERENCES accounts(id), FOREIGN KEY (statId) REFERENCES stats(id));"; + private static final String CREATE_DAILY = "CREATE TABLE accountStatsDaily (accountId INT NOT NULL, statId INT NOT NULL, date DATE NOT NULL, value BIGINT NOT NULL, PRIMARY KEY (accountId, statId), INDEX valueIndex (value DESC), INDEX dateIndex (date), FOREIGN KEY (accountId) REFERENCES accounts(id), FOREIGN KEY (statId) REFERENCES stats(id));"; + private static final String CREATE_SEASON = "CREATE TABLE statSeasons (id SMALLINT NOT NULL, seasonName VARCHAR(50) NOT NULL, startDate TIMESTAMP NOT NULL DEFAULT '1969-12-31 18:00:01', endDate TIMESTAMP NOT NULL DEFAULT '1969-12-31 18:00:01', PRIMARY KEY (id), UNIQUE INDEX seasonIndex (seasonName), INDEX startIndex (startDate), INDEX endIndex (endDate));"; + + private static final String INSERT_STAT = "INSERT INTO accountStatsAllTime (accountId, statId, value) VALUES (?, ?, ?);"; + private static final String UPDATE_STAT = "UPDATE accountStatsAllTime SET value=value + ? WHERE accountId=? AND statId=?;"; + + private static final String FETCH_STAT_ALL = "SELECT a.name, sl.value FROM accountStatsAllTime AS sl INNER JOIN accounts AS a ON a.id=sl.accountId WHERE sl.statId=%STAT% ORDER BY sl.value DESC LIMIT %START%,%LIMIT%;"; + + private static final String FETCH_STAT_YEARLY = "SELECT a.name, sl.value FROM accountStatsYearly AS sl INNER JOIN accounts AS a ON a.id=sl.accountId WHERE YEAR(sl.date) = YEAR(CURDATE()) AND sl.statId=%STAT% ORDER BY sl.value DESC LIMIT %START%,%LIMIT%;"; + private static final String FETCH_STAT_MONTHLY = "SELECT a.name, sl.value FROM accountStatsMonthly AS sl INNER JOIN accounts AS a ON a.id=sl.accountId WHERE MONTH(sl.date) = MONTH(CURDATE()) AND YEAR(sl.date) = YEAR(CURDATE()) AND sl.statId=%STAT% ORDER BY sl.value DESC LIMIT %START%,%LIMIT%;"; + private static final String FETCH_STAT_WEEKLY = "SELECT a.name, sl.value FROM accountStatsWeekly AS sl INNER JOIN accounts AS a ON a.id=sl.accountId WHERE YEARWEEK(sl.date, 1) = YEARWEEK(CURDATE(), 1) AND sl.statId=%STAT% ORDER BY sl.value DESC LIMIT %START%,%LIMIT%;"; + private static final String FETCH_STAT_DAILY = "SELECT a.name, sl.value FROM accountStatsDaily AS sl INNER JOIN accounts AS a ON a.id=sl.accountId WHERE sl.date = CURDATE() AND sl.statId=%STAT% ORDER BY sl.value DESC LIMIT %START%,%LIMIT%;"; + + private static final String FETCH_STAT_ALL_SEASON = "SELECT a.name, sl.value FROM accountStatsSeasonal AS sl INNER JOIN accounts AS a ON a.id=sl.accountId WHERE sl.statId=%STAT% AND seasonId=(SELECT id FROM statSeasons WHERE now() BETWEEN startDate AND endDate LIMIT 1) ORDER BY sl.value DESC LIMIT %START%,%LIMIT%;"; + + public LeaderboardRepository(JavaPlugin plugin) + { + super(DBPool.getAccount()); + } + + public void insertStats(Map> stats) + { + UtilServer.runAsync(() -> + { + try ( + Connection c = getConnection(); + PreparedStatement updateStat = c.prepareStatement(UPDATE_STAT); + PreparedStatement insertStat = c.prepareStatement(INSERT_STAT); + ) + { + for (Integer accountId : stats.keySet()) + { + for (Integer statId : stats.get(accountId).keySet()) + { + updateStat.setLong(1, stats.get(accountId).get(statId)); + updateStat.setInt(2, accountId); + updateStat.setInt(3, statId); + updateStat.addBatch(); + } + } + int[] rowsAffected = updateStat.executeBatch(); + int i = 0; + for (Integer accountId : stats.keySet()) + { + for (Integer statId : stats.get(accountId).keySet()) + { + if (rowsAffected[i] < 1) + { + insertStat.setInt(1, accountId); + insertStat.setInt(2, statId); + insertStat.setLong(3, stats.get(accountId).get(statId)); + insertStat.addBatch(); + } + i++; + } + } + insertStat.executeBatch(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + }); + } + + public void insertStats(int accountId, Map stats) + { + try ( + Connection c = getConnection(); + PreparedStatement updateStat = c.prepareStatement(UPDATE_STAT); + PreparedStatement insertStat = c.prepareStatement(INSERT_STAT); + ) + { + for (Integer statId : stats.keySet()) + { + updateStat.setLong(1, stats.get(statId)); + updateStat.setInt(2, accountId); + updateStat.setInt(3, statId); + updateStat.addBatch(); + } + int[] rowsAffected = updateStat.executeBatch(); + int i = 0; + for (Integer statId : stats.keySet()) + { + if (rowsAffected[i] < 1) + { + insertStat.setInt(1, accountId); + insertStat.setInt(2, statId); + insertStat.setLong(3, stats.get(statId)); + insertStat.addBatch(); + } + i++; + } + insertStat.executeBatch(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + + public void loadLeaderboard(Leaderboard board, Consumer> leaderboard) + { + Map names = new LinkedHashMap<>(); + try ( + Connection c = getConnection(); + Statement s = c.createStatement(); + ) + { + s.execute(board.getType().getStatement(board.getStatIds(), board.getStart(), board.getSize())); + for (int i = 0; i < board.getStatIds().length; i++) + { + try (ResultSet rs = s.getResultSet()) + { + while (rs.next()) + { + names.merge(rs.getString("name"), rs.getInt("value"), Integer::sum); + } + + if (!s.getMoreResults()) + { + break; + } + } + } + } + catch (SQLException ex) + { + ex.printStackTrace(); + } + finally + { + UtilServer.runSync(() -> leaderboard.accept(names)); + } + } + + @SuppressWarnings("unchecked") + public void loadLeaderboards(Collection boards, Consumer[]> leaderboard) + { + UtilServer.runAsync(() -> + { + Map[] leaderboards = new Map[boards.size()]; + StringBuilder queryBuilder = new StringBuilder(); + { + int i = 0; + for (Leaderboard board : boards) + { + queryBuilder.append(board.getType().getStatement(board.getStatIds(), board.getStart(), board.getSize())); + leaderboards[i] = new LinkedHashMap<>(); + i++; + } + } + + if (queryBuilder.length() > 0) + { + try ( + Connection c = getConnection(); + Statement s = c.createStatement(); + ) + { + s.execute(queryBuilder.toString()); + int index = 0; + mainBoardLoop: for (Leaderboard board : boards) + { + for (int i = 0; i < board.getStatIds().length; i++) + { + try (ResultSet rs = s.getResultSet()) + { + while (rs.next()) + { + leaderboards[index].merge(rs.getString("name"), rs.getInt("value"), Integer::sum); + } + + if (!s.getMoreResults()) + { + break mainBoardLoop; + } + } + } + index++; + } + } + catch (SQLException ex) + { + ex.printStackTrace(); + } + finally + { + UtilServer.runSync(() -> leaderboard.accept(leaderboards)); + } + } + else + { + UtilServer.runSync(() -> leaderboard.accept(leaderboards)); + } + }); + } + + public static enum LeaderboardSQLType + { + DAILY(FETCH_STAT_DAILY), + WEEKLY(FETCH_STAT_WEEKLY), + MONTHLY(FETCH_STAT_MONTHLY), + YEARLY(FETCH_STAT_YEARLY), + ALL(FETCH_STAT_ALL), + ALL_SEASON(FETCH_STAT_ALL_SEASON) + ; + + private String _sql; + + private LeaderboardSQLType(String sql) + { + _sql = sql; + } + + public String getStatement(int[] statIds, int start, int limit) + { + StringBuilder statementBuilder = new StringBuilder(); + for (int id : statIds) + { + statementBuilder.append(_sql.replace("%STAT%", String.valueOf(id)).replace("%START%", String.valueOf(start)).replace("%LIMIT%", String.valueOf(limit))); + } + return statementBuilder.toString(); + } + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/SetTournamentCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/SetTournamentCommand.java deleted file mode 100644 index 7e25605bf..000000000 --- a/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/SetTournamentCommand.java +++ /dev/null @@ -1,27 +0,0 @@ -package mineplex.core.leaderboard; - -import mineplex.core.command.CommandBase; -import mineplex.core.common.Rank; - -import org.bukkit.entity.Player; - -public class SetTournamentCommand extends CommandBase -{ - public SetTournamentCommand(LeaderboardManager plugin) - { - super(plugin, Rank.ADMIN, "settournament", "set-tournament"); - } - - @Override - public void Execute(Player caller, String[] args) - { - // TODO: Implement set tournament command. - /*if (args.length == 3) - { - String statType = args[0]; - int gamemode = Integer.parseInt(args[1]); - int value = Integer.parseInt(args[2]); - LeaderboardManager.getInstance().attemptStatEvent(caller, statType, gamemode, value); - }*/ - } -} \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/StatEventsRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/StatEventsRepository.java deleted file mode 100644 index 3acf6a2f8..000000000 --- a/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/StatEventsRepository.java +++ /dev/null @@ -1,59 +0,0 @@ -package mineplex.core.leaderboard; - -import mineplex.core.database.MinecraftRepository; -import mineplex.serverdata.database.DBPool; -import mineplex.serverdata.database.RepositoryBase; -import mineplex.serverdata.database.column.ColumnInt; -import mineplex.serverdata.database.column.ColumnVarChar; - -import org.bukkit.plugin.java.JavaPlugin; - - -/** - * StatEventsRepository offers the ability to insert and log newly generated stat events. - * - * Intended for the purpose of statistical tracking of players. - * @author MrTwiggy - * - */ -public class StatEventsRepository extends RepositoryBase -{ - - // Insert or update stat events query - /*private static String INSERT_EVENT = - "INSERT INTO statEvents(accountId, gamemode, serverGroup, type, value, date) " - + "VALUES (?, ?, ?, ?, ?, CURRENT_DATE()) " - + "ON DUPLICATE KEY UPDATE value=value+";*/ - - private static String INSERT_EVENT = - "INSERT INTO statEvents(accountId, gamemode, serverGroup, type, value, date) " - + "SELECT accounts.id, ?, ?, ?, ?, CURRENT_DATE() " - + "FROM accounts WHERE name = ? " - + "ON DUPLICATE KEY UPDATE value=value+"; - - /** - * Class constructor - * @param plugin - the plugin responsible for instantiating this repository. - */ - public StatEventsRepository(JavaPlugin plugin) - { - super(DBPool.getAccount()); - } - - - /** - * Insert (or update) a new stat event record for today into the repository. - * @param accountId - the id of the account responsible for the stat event. - * @param gamemode - the id of the gamemode type at the time of the stat event. - * @param serverGroup - the server group id associated with the stat event. - * @param type - the type of stat event to be inserted (id of type). - * @param value - the integer based value denoting the actual statistic being logged. - */ - public void insertStatEvent(String playerName, int gamemode, String serverGroup, int type, int value) - { - // Hacky string concatanation - Don't judge me!! - // TODO: How to handle outside value block parameters - executeUpdate(INSERT_EVENT + value + ";", new ColumnInt("gamemode", gamemode), new ColumnVarChar("serverGroup", 100, serverGroup), - new ColumnInt("type", type), new ColumnInt("value", value), new ColumnVarChar("name", 100, playerName)); - } -} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/StatType.java b/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/StatType.java deleted file mode 100644 index 10663bae0..000000000 --- a/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/StatType.java +++ /dev/null @@ -1,48 +0,0 @@ -package mineplex.core.leaderboard; - -/** - * An enumeration delegating the various types of statistics to be dynamically tracked. - * @author MrTwiggy - * - */ -public enum StatType -{ - WIN(1), - LOSS(2), - KILL(3), - DEATH(4); - - private int _typeId; // Unique id for stat type - public int getTypeId() { return _typeId; } - - /** - * Private class constructor - * @param typeId - the unique identifying id for this {@link StatType} - */ - private StatType(int typeId) - { - _typeId = typeId; - } - - /** - * @param stat - the display name for the stat type - * @return the {@link StatType} corresponding to the passed in {@code stat}, if one exists, - * null otherwise. - */ - public static StatType getType(String stat) - { - switch(stat.toUpperCase().trim()) - { - case "WINS": - return WIN; - case "LOSSES": - return LOSS; - case "KILLS": - return KILL; - case "DEATHS": - return DEATH; - default: - return null; - } - } -} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/particleeffects/ColoredCircleEffect.java b/Plugins/Mineplex.Core/src/mineplex/core/particleeffects/ColoredCircleEffect.java index 51851e40b..21a4b2681 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/particleeffects/ColoredCircleEffect.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/particleeffects/ColoredCircleEffect.java @@ -7,6 +7,7 @@ import java.util.List; import org.bukkit.Location; import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.util.Vector; @@ -26,6 +27,7 @@ public class ColoredCircleEffect extends Effect private int _maxCircles = -1; private int _totalCircles = 0; private double _yOffset = 0.0; + private Player[] _players = null; private static final int PARTICLES_PER_CIRCLE = 20; @@ -38,6 +40,11 @@ public class ColoredCircleEffect extends Effect Collections.addAll(_colors, colors); } + public void setPlayers(Player... players) + { + _players = players; + } + public void setMaxCircles(int circles) { _maxCircles = circles; @@ -83,7 +90,10 @@ public class ColoredCircleEffect extends Effect double angle = _steps * increment; Vector vector = new Vector(Math.cos(angle) * _radius, 0, Math.sin(angle) * _radius); ColoredParticle coloredParticle = new ColoredParticle(UtilParticle.ParticleType.RED_DUST, new DustSpellColor(getNextColor()), location.add(vector)); - coloredParticle.display(); + if (_players != null) + coloredParticle.display(UtilParticle.ViewDist.NORMAL, _players); + else + coloredParticle.display(); _steps++; } stop(); @@ -103,7 +113,10 @@ public class ColoredCircleEffect extends Effect double angle = _steps * increment; Vector vector = new Vector(Math.cos(angle) * _radius, 0, Math.sin(angle) * _radius); ColoredParticle coloredParticle = new ColoredParticle(UtilParticle.ParticleType.RED_DUST, new DustSpellColor(getNextColor()), location.add(vector)); - coloredParticle.display(); + if (_players != null) + coloredParticle.display(UtilParticle.ViewDist.NORMAL, _players); + else + coloredParticle.display(); _steps++; if (_steps >= PARTICLES_PER_CIRCLE) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/manager/PartyJoinManager.java b/Plugins/Mineplex.Core/src/mineplex/core/party/manager/PartyJoinManager.java index 1dcd4c746..85f33fabc 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/party/manager/PartyJoinManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/manager/PartyJoinManager.java @@ -236,7 +236,7 @@ public class PartyJoinManager implements Listener requestServerJoin(best.getName(), party); } - @EventHandler + @EventHandler(ignoreCancelled = true) public void onTransfer(ServerTransferEvent event) { Player player = event.getPlayer(); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/preferences/ui/PreferenceMainMenu.java b/Plugins/Mineplex.Core/src/mineplex/core/preferences/ui/PreferenceMainMenu.java index ab07a6d8f..d8ee17525 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/preferences/ui/PreferenceMainMenu.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/preferences/ui/PreferenceMainMenu.java @@ -30,7 +30,7 @@ public class PreferenceMainMenu extends Menu protected Button[] setUp(Player player) { Rank rank = getPlugin().getClientManager().Get(player).GetRank(); - boolean exclusive = rank.has(Rank.HELPER) || rank == Rank.YOUTUBE_SMALL || rank == Rank.YOUTUBE || rank == Rank.TWITCH; + boolean exclusive = rank.has(Rank.MAPDEV) || rank == Rank.YOUTUBE_SMALL || rank == Rank.YOUTUBE || rank == Rank.TWITCH; Button[] buttons = new Button[exclusive ? INV_SIZE_MAX : INV_SIZE_MIN]; diff --git a/Plugins/Mineplex.Core/src/mineplex/core/progression/ProgressiveKit.java b/Plugins/Mineplex.Core/src/mineplex/core/progression/ProgressiveKit.java index 395bd428d..88a1a5180 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/progression/ProgressiveKit.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/progression/ProgressiveKit.java @@ -11,6 +11,10 @@ import org.bukkit.entity.Player; import mineplex.core.common.util.UtilParticle; import mineplex.core.common.util.UtilParticle.ParticleType; import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.types.Gadget; +import mineplex.core.gadget.types.GadgetType; +import mineplex.core.gadget.types.KitSelectorGadget; import mineplex.core.progression.math.Calculations; /** @@ -269,8 +273,15 @@ public interface ProgressiveKit return getUpgradeLevel(player) >= upgradeLevel; } - default void displaySelectedEffect(Entity kitHost, Player... displayTo) + default void displaySelectedEffect(Entity kitHost, GadgetManager gadgetManager, Player displayTo) { + Gadget gadget = gadgetManager.getActive(displayTo, GadgetType.KIT_SELECTOR); + if (gadget != null) + { + KitSelectorGadget kitSelectorGadget = (KitSelectorGadget) gadget; + kitSelectorGadget.playParticle(kitHost, displayTo); + return; + } for (int i = 0; i < 1; i++) { double lead = i * ((2d * Math.PI) / 2); @@ -285,4 +296,14 @@ public interface ProgressiveKit ViewDist.NORMAL, displayTo); } } + + default boolean usesXp() + { + return true; + } + + default boolean crownsEnabled() + { + return false; + } } \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/progression/data/KitUpgradeProcessor.java b/Plugins/Mineplex.Core/src/mineplex/core/progression/data/KitUpgradeProcessor.java index e8cff97ee..e090dae6b 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/progression/data/KitUpgradeProcessor.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/progression/data/KitUpgradeProcessor.java @@ -1,6 +1,6 @@ package mineplex.core.progression.data; -import mineplex.core.server.util.TransactionResponse; +import java.util.function.Consumer; import org.bukkit.Sound; import org.bukkit.entity.Player; @@ -11,6 +11,7 @@ import mineplex.core.common.util.F; import mineplex.core.progression.KitProgressionManager; import mineplex.core.progression.ProgressiveKit; import mineplex.core.progression.math.Calculations; +import mineplex.core.server.util.TransactionResponse; import mineplex.core.shop.confirmation.ConfirmationCallback; import mineplex.core.shop.confirmation.ConfirmationProcessor; @@ -39,27 +40,40 @@ public class KitUpgradeProcessor implements ConfirmationProcessor { String packageName = _kit.getInternalName() + "." + _upgradeLevel; int cost = Calculations.getGemsCost(_upgradeLevel); + if (!_kit.usesXp()) + { + cost = Calculations.getGemsCostXpLess(_upgradeLevel); + } + + Consumer handler = response -> + { + if (response == TransactionResponse.Success) + { + _kit.upgrade(_upgradeLevel, _player.getUniqueId()); + + _player.playSound(_player.getLocation(), Sound.CAT_MEOW, 5.0f, 1.0f); + _player.sendMessage(F.main("Kit Progression", "Purchased upgrades for " + _kit.getDisplayName() + " level " + _upgradeLevel)); + + callback.resolve("Success! You now own this upgrade!"); + } + else if (response == TransactionResponse.InsufficientFunds) + { + callback.reject("Insufficient funds!"); + } + else + { + callback.reject("There was an error processing your transaction. Try again later"); + } + }; + // Use UnknownPackages for this right now as it handles overspending gems properly - _manager.getDonationManager().purchaseUnknownSalesPackage(_player, packageName, GlobalCurrency.GEM, cost, false, - data -> - { - if (data == TransactionResponse.Success) - { - _kit.upgrade(_upgradeLevel, _player.getUniqueId()); - - _player.playSound(_player.getLocation(), Sound.CAT_MEOW, 5.0f, 1.0f); - _player.sendMessage(F.main("Kit Progression", "Purchased upgrades for " + _kit.getDisplayName() + " level " + _upgradeLevel)); - - callback.resolve("Success! You now own this upgrade!"); - } - else if (data == TransactionResponse.InsufficientFunds) - { - callback.reject("Insufficient funds!"); - } - else - { - callback.reject("There was an error processing your transaction. Try again later"); - } - }); + if (_kit.crownsEnabled()) + { + _manager.getDonationManager().purchaseUnknownSalesPackageCrown(_player, packageName, cost, false, handler); + } + else + { + _manager.getDonationManager().purchaseUnknownSalesPackage(_player, packageName, GlobalCurrency.GEM, cost, false, handler); + } } -} +} \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/progression/gui/buttons/KitUpgradeDetailsButton.java b/Plugins/Mineplex.Core/src/mineplex/core/progression/gui/buttons/KitUpgradeDetailsButton.java index 911a8087d..11a12c356 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/progression/gui/buttons/KitUpgradeDetailsButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/progression/gui/buttons/KitUpgradeDetailsButton.java @@ -1,14 +1,18 @@ package mineplex.core.progression.gui.buttons; +import java.util.List; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + import com.google.common.collect.Lists; + import mineplex.core.common.util.C; import mineplex.core.itemstack.ItemBuilder; import mineplex.core.menu.IconButton; +import mineplex.core.progression.ProgressiveKit; import mineplex.core.progression.math.Calculations; -import org.bukkit.Material; -import org.bukkit.inventory.ItemStack; - -import java.util.List; /** * Representing this kits Abilities in a GUI @@ -18,11 +22,13 @@ public class KitUpgradeDetailsButton extends IconButton private ItemStack _item; - public KitUpgradeDetailsButton(int level, List details) + public KitUpgradeDetailsButton(ProgressiveKit kit, Player player, int level, List details) { super(null); - - ItemBuilder builder = new ItemBuilder(Material.SLIME_BALL); + + int current = kit.getUpgradeLevel(player.getUniqueId()); + + ItemBuilder builder = new ItemBuilder(Material.STAINED_CLAY).setData((current >= level) ? (short)5 : (short)14); builder.setTitle(C.cYellow + "Level " + level + " upgrades"); @@ -34,7 +40,19 @@ public class KitUpgradeDetailsButton extends IconButton } lore.add(""); - lore.add(C.cGray + "Unlocks at kit level " + C.cGreen + Calculations.getLevelRequiredFor(level)); + if (kit.usesXp()) + { + lore.add(C.cGray + "Unlocks at kit level " + C.cGreen + Calculations.getLevelRequiredFor(level)); + } + else + { + String currency = C.cGreen + "%cost% Gems"; + if (kit.crownsEnabled()) + { + currency = C.cGold + "%cost% Crowns"; + } + lore.add(C.cGray + "Unlocks with " + currency.replace("%cost%", Calculations.getGemsCostXpLess(level) + "")); + } builder.setLore(lore.toArray(new String[lore.size()])); _item = builder.build(); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/progression/gui/buttons/KitUpgradeMenuButton.java b/Plugins/Mineplex.Core/src/mineplex/core/progression/gui/buttons/KitUpgradeMenuButton.java index 0bd36086c..263f69476 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/progression/gui/buttons/KitUpgradeMenuButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/progression/gui/buttons/KitUpgradeMenuButton.java @@ -1,5 +1,6 @@ package mineplex.core.progression.gui.buttons; +import mineplex.core.common.currency.GlobalCurrency; import mineplex.core.common.util.C; import mineplex.core.itemstack.ItemBuilder; import mineplex.core.progression.KitProgressionManager; @@ -47,14 +48,20 @@ public class KitUpgradeMenuButton extends KitButton //The difference between the players current level, and the next upgrade level int diff = nextUpgradeLevelPlayer - level; + int balance = plugin.getDonationManager().Get(player).getBalance(GlobalCurrency.GEM); + if (kit.crownsEnabled()) + { + balance = plugin.getDonationManager().getCrowns(player); + } + //This ONLY flashes if their next upgrade level isn't their same one. - _flash = Calculations.isUpgradeLevelEligible(level) && (nextUpgradeLevel > upgradeLevel); + _flash = (kit.usesXp() ? (Calculations.isUpgradeLevelEligible(level) && (nextUpgradeLevel > upgradeLevel)) : (Calculations.isUpgradeLevelEligibleXpLess(balance) && upgradeLevel < Calculations.getNextUpgradeLevelXpLess(upgradeLevel))); ChatColor color = Calculations.getColor(level, nextUpgradeLevelPlayer); - if(kit.showUpgrades()) + if (kit.showUpgrades()) { - ItemBuilder builder = lore(new ItemBuilder(Material.ENCHANTMENT_TABLE), upgradeLevel, color, diff); + ItemBuilder builder = kit.usesXp() ? lore(new ItemBuilder(Material.ENCHANTMENT_TABLE), upgradeLevel, color, diff) : lore(new ItemBuilder(Material.ENCHANTMENT_TABLE), upgradeLevel); builder.setTitle(C.cYellow + "Upgrade Level " + upgradeLevel); _item = builder.build(); } @@ -138,4 +145,13 @@ public class KitUpgradeMenuButton extends KitButton ChatColor.WHITE + "Click to view Upgrade and XP tracking"); return builder; } -} + + private ItemBuilder lore(ItemBuilder builder, int upgradeLevel) + { + builder.setLore(" ", + ChatColor.WHITE + "Upgrade Level: " + ChatColor.GREEN + upgradeLevel + " out of 5", + "", + ChatColor.WHITE + "Click to view Upgrades"); + return builder; + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/progression/gui/guis/KitDisplayMenu.java b/Plugins/Mineplex.Core/src/mineplex/core/progression/gui/guis/KitDisplayMenu.java index 2a9d73b67..e32104822 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/progression/gui/guis/KitDisplayMenu.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/progression/gui/guis/KitDisplayMenu.java @@ -63,8 +63,11 @@ public class KitDisplayMenu extends KitMenu */ private void setUpNextMenuButtons(Button[] buttons, Player player) { - buttons[48] = new KitXPButton(getKit(), player, getPlugin()); - buttons[50] = new KitUpgradeMenuButton(getKit(), player, getPlugin()); + if (getKit().usesXp()) + { + buttons[48] = new KitXPButton(getKit(), player, getPlugin()); + } + buttons[getKit().usesXp() ? 50 : 49] = new KitUpgradeMenuButton(getKit(), player, getPlugin()); } /** @@ -90,7 +93,7 @@ public class KitDisplayMenu extends KitMenu int index = 0; for(int i : UPGRADE_SLOTS) { - buttons[i] = new KitUpgradeDetailsButton(index + 1, details.get(index++)); + buttons[i] = new KitUpgradeDetailsButton(getKit(), player, index + 1, details.get(index++)); } return; } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/progression/gui/guis/KitInformationTrackerMenu.java b/Plugins/Mineplex.Core/src/mineplex/core/progression/gui/guis/KitInformationTrackerMenu.java index 42d1aa723..9a61c872f 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/progression/gui/guis/KitInformationTrackerMenu.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/progression/gui/guis/KitInformationTrackerMenu.java @@ -59,11 +59,13 @@ public class KitInformationTrackerMenu extends KitMenu Button[] buttons = new Button[52]; buttons[0] = new BackButton(new KitDisplayMenu(getKit(), getPlugin())); - - setUpXP(buttons, player); - - setUpLevel(buttons, player); - + + if (getKit().usesXp()) + { + setUpXP(buttons, player); + setUpLevel(buttons, player); + } + setUpUpgrade(buttons, player); return buttons; @@ -155,10 +157,10 @@ public class KitInformationTrackerMenu extends KitMenu Map> details = getKit().getUpgradeDetails(); int index = 0; - for(int i : UPGRADE_SLOTS) + for (int i : (getKit().usesXp() ? UPGRADE_SLOTS : LEVEL_SLOTS)) { List list = details.get(index++); - KitUpgradeDetailsButton detailsButton = new KitUpgradeDetailsButton(index, list); + KitUpgradeDetailsButton detailsButton = new KitUpgradeDetailsButton(getKit(), player, index, list); ItemBuilder itemStack = new ItemBuilder(detailsButton.getItemStack()); if (getKit().ownsUpgrade(player.getUniqueId(), index)) @@ -168,12 +170,18 @@ public class KitInformationTrackerMenu extends KitMenu else if (getKit().canPurchaseUpgrade(player.getUniqueId(), index)) { itemStack.setGlow(true); - itemStack.addLore("Costs " + C.cGreen + Calculations.getGemsCost(index) + C.cGray + " gems"); + if (getKit().usesXp()) + { + itemStack.addLore("Costs " + (getKit().crownsEnabled() ? C.cGold : C.cGreen) + Calculations.getGemsCost(index) + C.cGray + (getKit().crownsEnabled() ? " crowns" : " gems")); + } itemStack.addLore(C.cGreen + "Click to purchase this upgrade!"); } else { - itemStack.addLore("Costs " + C.cGreen + Calculations.getGemsCost(index) + C.cGray + " gems"); + if (getKit().usesXp()) + { + itemStack.addLore("Costs " + (getKit().crownsEnabled() ? C.cGold : C.cGreen) + Calculations.getGemsCost(index) + C.cGray + (getKit().crownsEnabled() ? " crowns" : " gems")); + } itemStack.addLore(C.cRed + "You cannot purchase this upgrade!"); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/progression/math/Calculations.java b/Plugins/Mineplex.Core/src/mineplex/core/progression/math/Calculations.java index b4a6ac726..51299c6d0 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/progression/math/Calculations.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/progression/math/Calculations.java @@ -1,10 +1,12 @@ package mineplex.core.progression.math; -import com.google.common.collect.Maps; -import net.md_5.bungee.api.ChatColor; - +import java.util.HashMap; import java.util.Map; +import com.google.common.collect.Maps; + +import net.md_5.bungee.api.ChatColor; + /** * This class handles all the math and static fields needed for Kit Progressions * You can find some util methods in here as well that relate to numbers @@ -15,6 +17,7 @@ public class Calculations private static final int[] LEVELS = new int[100]; private static final int[] UPGRADE_LEVELS = {5, 10, 30, 75, 100}; private static final Map GEMS_FOR_UPGRADE = Maps.newHashMap(); + private static final Map GEMS_FOR_XPLESS_UPGRADE = new HashMap<>(); static { @@ -23,6 +26,11 @@ public class Calculations { GEMS_FOR_UPGRADE.put(level, level * 1000); } + GEMS_FOR_XPLESS_UPGRADE.put(1, 1000); + GEMS_FOR_XPLESS_UPGRADE.put(2, 5000); + GEMS_FOR_XPLESS_UPGRADE.put(3, 15000); + GEMS_FOR_XPLESS_UPGRADE.put(4, 50000); + GEMS_FOR_XPLESS_UPGRADE.put(5, 100000); } /** @@ -79,6 +87,20 @@ public class Calculations { return GEMS_FOR_UPGRADE.containsKey(currentLevel); } + + public static boolean isUpgradeLevelEligibleXpLess(int gems) + { + boolean afford = false; + + for (int cost : GEMS_FOR_XPLESS_UPGRADE.values()) + { + if (cost <= gems) + { + afford = true; + } + } + return afford; + } /** * Determines if the players current level, and his gems, are what he needs to level up this upgrade @@ -91,6 +113,11 @@ public class Calculations { return GEMS_FOR_UPGRADE.containsKey(currentLevel) && GEMS_FOR_UPGRADE.get(currentLevel) <= gems; } + + public static boolean canUpgradeXpLess(int upgradeLevel, int gems) + { + return GEMS_FOR_XPLESS_UPGRADE.containsKey(upgradeLevel) && GEMS_FOR_XPLESS_UPGRADE.get(upgradeLevel) <= gems; + } /** * Get the XP required for the next level @@ -155,7 +182,7 @@ public class Calculations } /** - * Get the next integer upgrade level based of the players current leve; + * Get the next integer upgrade level based of the players current level * * @param currentLevel The players current level * @return The next upgrade level @@ -169,6 +196,20 @@ public class Calculations } return 5; } + + public static int getNextUpgradeLevelXpLess(int currentLevel) + { + int current = 5; + for (int level : GEMS_FOR_XPLESS_UPGRADE.keySet()) + { + if (level < current && level > currentLevel) + { + current = level; + } + } + + return current; + } /** * Get the next level the player needs to reach to unlock an upgrade @@ -215,4 +256,9 @@ public class Calculations { return GEMS_FOR_UPGRADE.get(getLevelRequiredFor(upgradeLevel)); } + + public static int getGemsCostXpLess(int upgradeLevel) + { + return GEMS_FOR_XPLESS_UPGRADE.get(upgradeLevel); + } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java index 171bfa55e..5f4e5fb16 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java @@ -70,6 +70,12 @@ import mineplex.core.gadget.gadgets.item.ItemPaintballGun; import mineplex.core.gadget.gadgets.item.ItemPartyPopper; import mineplex.core.gadget.gadgets.item.ItemSnowball; import mineplex.core.gadget.gadgets.item.ItemTNT; +import mineplex.core.gadget.gadgets.kitselector.HaloKitSelector; +import mineplex.core.gadget.gadgets.kitselector.RainCloudKitSelector; +import mineplex.core.gadget.gadgets.kitselector.RainbowDanceKitSelector; +import mineplex.core.gadget.gadgets.kitselector.ShimmeringRingKitSelector; +import mineplex.core.gadget.gadgets.kitselector.SingleParticleKitSelector; +import mineplex.core.gadget.gadgets.kitselector.WaterWingsKitSelector; import mineplex.core.gadget.gadgets.morph.MorphAwkwardRabbit; import mineplex.core.gadget.gadgets.morph.MorphBat; import mineplex.core.gadget.gadgets.morph.MorphBlock; @@ -609,6 +615,23 @@ public class RewardManager addGadget(Type.SPRING, getGadget(ArrowTrailSpring.class), rarity, 100); addGadget(Type.SPRING, getGadget(DeathSpring.class), rarity, 100); addGadget(Type.SPRING, getGadget(DoubleJumpSpring.class), rarity, 100); + + // KIT SELECTORS + addGadget(Type.OMEGA, getGadget(HaloKitSelector.class), rarity, 100); + addGadget(Type.ILLUMINATED, getGadget(HaloKitSelector.class), rarity, 100); + addGadget(Type.MYTHICAL, getGadget(HaloKitSelector.class), rarity, 100); + + addGadget(Type.OMEGA, getGadget(RainbowDanceKitSelector.class), rarity, 100); + addGadget(Type.ILLUMINATED, getGadget(RainbowDanceKitSelector.class), rarity, 100); + addGadget(Type.MYTHICAL, getGadget(RainbowDanceKitSelector.class), rarity, 100); + + addGadget(Type.OMEGA, getGadget(ShimmeringRingKitSelector.class), rarity, 150); + addGadget(Type.ILLUMINATED, getGadget(ShimmeringRingKitSelector.class), rarity, 150); + addGadget(Type.MYTHICAL, getGadget(ShimmeringRingKitSelector.class), rarity, 150); + + addGadget(Type.OMEGA, getSingleParticleKitSelector(SingleParticleKitSelector.SingleParticleSelectors.FLAMES_OF_FURY), rarity, 150); + addGadget(Type.ILLUMINATED, getSingleParticleKitSelector(SingleParticleKitSelector.SingleParticleSelectors.FLAMES_OF_FURY), rarity, 150); + addGadget(Type.MYTHICAL, getSingleParticleKitSelector(SingleParticleKitSelector.SingleParticleSelectors.FLAMES_OF_FURY), rarity, 150); } public void addLegendary() @@ -872,6 +895,23 @@ public class RewardManager addGadget(Type.SPRING, getGadget(MorphAwkwardRabbit.class), rarity, 25); addPetReward(Type.SPRING, PetType.KILLER_BUNNY, rarity, 50); + + // KIT SELECTORS + addGadget(Type.OMEGA, getGadget(RainCloudKitSelector.class), rarity, 100); + addGadget(Type.ILLUMINATED, getGadget(RainCloudKitSelector.class), rarity, 100); + addGadget(Type.MYTHICAL, getGadget(RainCloudKitSelector.class), rarity, 100); + + addGadget(Type.OMEGA, getGadget(WaterWingsKitSelector.class), rarity, 50); + addGadget(Type.ILLUMINATED, getGadget(WaterWingsKitSelector.class), rarity, 50); + addGadget(Type.MYTHICAL, getGadget(WaterWingsKitSelector.class), rarity, 50); + + addGadget(Type.OMEGA, getSingleParticleKitSelector(SingleParticleKitSelector.SingleParticleSelectors.EMBER), rarity, 100); + addGadget(Type.ILLUMINATED, getSingleParticleKitSelector(SingleParticleKitSelector.SingleParticleSelectors.EMBER), rarity, 100); + addGadget(Type.MYTHICAL, getSingleParticleKitSelector(SingleParticleKitSelector.SingleParticleSelectors.EMBER), rarity, 100); + + addGadget(Type.OMEGA, getSingleParticleKitSelector(SingleParticleKitSelector.SingleParticleSelectors.LOVE), rarity, 100); + addGadget(Type.ILLUMINATED, getSingleParticleKitSelector(SingleParticleKitSelector.SingleParticleSelectors.LOVE), rarity, 100); + addGadget(Type.MYTHICAL, getSingleParticleKitSelector(SingleParticleKitSelector.SingleParticleSelectors.LOVE), rarity, 100); } public UnknownPackageReward addMount(Type type, Mount mount, RewardRarity rarity, int weight) @@ -1045,6 +1085,11 @@ public class RewardManager return 0; } } + + private SingleParticleKitSelector getSingleParticleKitSelector(SingleParticleKitSelector.SingleParticleSelectors singleParticleSelectors) + { + return _gadgetManager.getSingleParticleKitSelector(singleParticleSelectors); + } public int getAmmoMin(RewardRarity rarity) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/stats/StatsManager.java b/Plugins/Mineplex.Core/src/mineplex/core/stats/StatsManager.java index 29804bc5b..c4290ff84 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/stats/StatsManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/stats/StatsManager.java @@ -21,6 +21,7 @@ import mineplex.core.account.CoreClient; import mineplex.core.account.CoreClientManager; import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilTasks; +import mineplex.core.leaderboard.LeaderboardManager; import mineplex.core.stats.command.GiveStatCommand; import mineplex.core.stats.command.MasterBuilderUnban; import mineplex.core.stats.command.SetLevelCommand; @@ -39,6 +40,7 @@ public class StatsManager extends MiniDbClientPlugin private final CoreClientManager _coreClientManager; private final StatsRepository _repository; + private final LeaderboardManager _leaderboard; private final Map _stats = new HashMap<>(); private final Map> _statUploadQueue = new HashMap<>(); @@ -50,11 +52,21 @@ public class StatsManager extends MiniDbClientPlugin _repository = new StatsRepository(); _coreClientManager = clientManager; + + _leaderboard = new LeaderboardManager(plugin); UtilScheduler.runAsyncEvery(UpdateType.SEC, () -> { - save(_statUploadQueue, _repository::saveStats, "increment"); - save(_statUploadQueueOverRidable, map -> _repository.saveStats(map, true), "override"); + save(_statUploadQueue, map -> + { + _repository.saveStats(map); + _leaderboard.handleStatIncrease(map); + }, "increment"); + save(_statUploadQueueOverRidable, map -> + { + _repository.saveStats(map, true); + _leaderboard.handleStatIncrease(map); + }, "override"); }); for (Stat stat : _repository.retrieveStats()) @@ -88,6 +100,16 @@ public class StatsManager extends MiniDbClientPlugin return stats; }); } + + public void loadStatId(String statName, Consumer idConsumer) + { + registerNewStat(statName, () -> + { + final int statId = _stats.get(statName); + + runSync(() -> idConsumer.accept(Integer.valueOf(statId))); + }); + } /** @@ -115,6 +137,7 @@ public class StatsManager extends MiniDbClientPlugin * * @param value The value, must be greater or equal to zero */ + @Deprecated public void setStat(Player player, String statName, long value) { if (value < 0) @@ -148,6 +171,7 @@ public class StatsManager extends MiniDbClientPlugin * * @param value The value, must be greater or equal to zero */ + @Deprecated public void setStat(final int accountId, final String statName, final long value) { if (value < 0) @@ -161,7 +185,8 @@ public class StatsManager extends MiniDbClientPlugin _repository.saveStats(uploadQueue, true); }); } - + + @Deprecated private void addToOverRidableQueue(String statName, CoreClient client, long value) { if (client.getAccountId() == -1) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java index 3421cb3d8..a4b0a0b88 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java @@ -184,7 +184,7 @@ public class Hub extends JavaPlugin implements IRelation String boosterGroup = serverConfiguration.getServerGroup().getBoosterGroup(); ThankManager thankManager = new ThankManager(this, clientManager, donationManager); BoosterManager boosterManager = new BoosterManager(this, boosterGroup, clientManager, donationManager, inventoryManager, thankManager); - HubManager hubManager = new HubManager(this, blockRestore, clientManager, incognito, donationManager, inventoryManager, conditionManager, disguiseManager, new TaskManager(this, clientManager), portal, partyManager, preferenceManager, petManager, pollManager, statsManager, achievementManager, new HologramManager(this, packetHandler), npcManager, personalServerManager, packetHandler, punish, serverStatusManager, customDataManager, thankManager, boosterManager, castleManager); + HubManager hubManager = new HubManager(this, blockRestore, clientManager, incognito, donationManager, inventoryManager, conditionManager, disguiseManager, new TaskManager(this, clientManager), portal, partyManager, preferenceManager, petManager, pollManager, statsManager, achievementManager, hologramManager, npcManager, personalServerManager, packetHandler, punish, serverStatusManager, customDataManager, thankManager, boosterManager, castleManager); QueueManager queueManager = new QueueManager(this, clientManager, donationManager, eloManager, partyManager); ServerManager serverManager = new ServerManager(this, clientManager, donationManager, portal, partyManager, serverStatusManager, hubManager, queueManager, boosterManager); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ServerManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ServerManager.java index a305c124b..f72c95a65 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ServerManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ServerManager.java @@ -787,6 +787,11 @@ public class ServerManager extends MiniPlugin implements BrawlShopProvider { return _statusManager; } + + public ShopBase getCastleAssaultShop() + { + return _serverNpcShopMap.get("Castle Assault"); + } public ShopBase getCastleSiegeShop() { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/ServerGameMenu.java b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/ServerGameMenu.java index 5bfebcbdd..00498e1d3 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/ServerGameMenu.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/ServerGameMenu.java @@ -21,6 +21,7 @@ import mineplex.hub.server.ui.button.SelectBHButton; import mineplex.hub.server.ui.button.SelectBLDButton; import mineplex.hub.server.ui.button.SelectBRButton; import mineplex.hub.server.ui.button.SelectBawkButton; +import mineplex.hub.server.ui.button.SelectCAButton; import mineplex.hub.server.ui.button.SelectCLANSButton; import mineplex.hub.server.ui.button.SelectCSButton; import mineplex.hub.server.ui.button.SelectCTFButton; @@ -63,14 +64,22 @@ public class ServerGameMenu extends ShopPageBase { add(1, Material.EGG, C.cYellowB + "Bawk Bawk Battles " + C.cGray + "Challenges", new String[] { - (_extraValue ? C.cAquaB : C.cWhiteB) + "NEW GAME", C.Reset + "", C.Reset + "Follow Bawk Bawk's instructions", C.Reset + "Complete different tasks", C.Reset + "If you lose, chickens will devour you!" }, "BBB", "Bawk_Bawk_Battles", new SelectBawkButton(this)); + + add(3, Material.DIAMOND_CHESTPLATE, C.cYellowB + "Castle Assault " + C.cGray + "Fast Paced PvP", new String[] + { + (_extraValue ? C.cAquaB : C.cWhiteB) + "NEW GAME", + C.Reset + "", + C.Reset + "Combatants must battle to", + C.Reset + "win the day for their king", + C.Reset + "at all costs!", + }, "CA", "Castle_Assault", new SelectCAButton(this)); - add(4, Material.QUARTZ_BLOCK, C.cYellowB + "Speed Builders " + C.cGray + "Competitive Building", new String[] + add(5, Material.QUARTZ_BLOCK, C.cYellowB + "Speed Builders " + C.cGray + "Competitive Building", new String[] { C.Reset + "", C.Reset + "Memorize Gwen the Guardian's builds", @@ -631,6 +640,11 @@ public class ServerGameMenu extends ShopPageBase { getPlugin().getCtfShop().attemptShopOpen(player); } + + public void openCA(Player player) + { + getPlugin().getCastleAssaultShop().attemptShopOpen(player); + } public void openCS(Player player) { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/button/SelectCAButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/button/SelectCAButton.java new file mode 100644 index 000000000..6ab3a36c8 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/button/SelectCAButton.java @@ -0,0 +1,23 @@ +package mineplex.hub.server.ui.button; + +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import mineplex.core.shop.item.IButton; +import mineplex.hub.server.ui.ServerGameMenu; + +public class SelectCAButton implements IButton +{ + private ServerGameMenu _menu; + + public SelectCAButton(ServerGameMenu menu) + { + _menu = menu; + } + + @Override + public void onClick(Player player, ClickType clickType) + { + _menu.openCA(player); + } +} diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java index 731d73616..7eb6eee04 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java @@ -1,10 +1,10 @@ package nautilus.game.arcade; +import static mineplex.core.Managers.require; + import java.io.File; import java.util.HashMap; -import net.minecraft.server.v1_8_R3.MinecraftServer; - import org.bukkit.Bukkit; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; @@ -52,7 +52,6 @@ import mineplex.core.ignore.IgnoreManager; import mineplex.core.incognito.IncognitoManager; import mineplex.core.inventory.InventoryManager; import mineplex.core.itemstack.ItemStackFactory; -import mineplex.core.leaderboard.LeaderboardManager; import mineplex.core.memory.MemoryFix; import mineplex.core.message.MessageManager; import mineplex.core.monitor.LagMeter; @@ -83,12 +82,10 @@ import mineplex.core.visibility.VisibilityManager; import mineplex.core.website.WebsiteLinkManager; import mineplex.minecraft.game.core.combat.CombatManager; import mineplex.minecraft.game.core.damage.DamageManager; - import nautilus.game.arcade.anticheatmetadata.GameInfoMetadata; import nautilus.game.arcade.game.Game; import nautilus.game.arcade.game.GameServerConfig; - -import static mineplex.core.Managers.require; +import net.minecraft.server.v1_8_R3.MinecraftServer; public class Arcade extends JavaPlugin { @@ -167,7 +164,6 @@ public class Arcade extends JavaPlugin incognito.setPreferencesManager(preferenceManager); Creature creature = new Creature(this); - LeaderboardManager leaderboardManager = new LeaderboardManager(this, _clientManager); Teleport teleport = new Teleport(this, _clientManager); Portal portal = new Portal(); new FileUpdater(this, portal, serverStatusManager.getCurrentServerName(), serverStatusManager.getRegion(), GenericServer.HUB); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java index 49effeb23..0f8926b18 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java @@ -4,8 +4,6 @@ import java.io.File; import java.util.ArrayList; import java.util.HashSet; -import net.minecraft.server.v1_8_R3.EntityLiving; - import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.GameMode; @@ -39,6 +37,8 @@ import mineplex.core.MiniPlugin; import mineplex.core.account.CoreClient; import mineplex.core.account.CoreClientManager; import mineplex.core.achievement.AchievementManager; +import mineplex.core.antihack.compedaccount.CompromisedAccountManager; +import mineplex.core.antihack.compedaccount.PriorityCause; import mineplex.core.blockrestore.BlockRestore; import mineplex.core.blood.Blood; import mineplex.core.bonuses.BonusManager; @@ -123,7 +123,6 @@ import mineplex.minecraft.game.core.condition.ConditionManager; import mineplex.minecraft.game.core.damage.DamageManager; import mineplex.minecraft.game.core.fire.Fire; import mineplex.serverdata.Region; - import nautilus.game.arcade.addons.SoupAddon; import nautilus.game.arcade.booster.GameBoosterManager; import nautilus.game.arcade.command.CancelNextGameCommand; @@ -168,6 +167,7 @@ import nautilus.game.arcade.managers.lobby.current.NewGameLobbyManager; import nautilus.game.arcade.managers.lobby.legacy.LegacyGameLobbyManager; import nautilus.game.arcade.player.ArcadePlayer; import nautilus.game.arcade.shop.ArcadeShop; +import net.minecraft.server.v1_8_R3.EntityLiving; public class ArcadeManager extends MiniPlugin implements IRelation { @@ -262,6 +262,7 @@ public class ArcadeManager extends MiniPlugin implements IRelation public final boolean IsHolidayEnabled; private final Titles _titles; + private final CompromisedAccountManager _compromisedAccountManager = require(CompromisedAccountManager.class); public ArcadeManager(Arcade plugin, ServerStatusManager serverStatusManager, GameServerConfig serverConfig, CoreClientManager clientManager, DonationManager donationManager, DamageManager damageManager, @@ -500,7 +501,6 @@ public class ArcadeManager extends MiniPlugin implements IRelation scoreboard.get(ArcadeScoreboardLine.PLAYERS_NAME).write(C.cYellow + C.Bold + "Players"); scoreboard.get(ArcadeScoreboardLine.KIT_NAME).write(C.cGray + C.Bold + "Kit"); - scoreboard.get(ArcadeScoreboardLine.GEM_NAME).write(C.cGreen + C.Bold + "Gems"); scoreboard.get(ArcadeScoreboardLine.SERVER_NAME).write(C.cAqua + C.Bold + "Server"); scoreboard.get(ArcadeScoreboardLine.SERVER_VALUE).write(_plugin.getConfig().getString("serverstatus.name")); } @@ -525,7 +525,16 @@ public class ArcadeManager extends MiniPlugin implements IRelation } scoreboard.get(ArcadeScoreboardLine.PLAYERS_VALUE).write(_gameManager.getValidPlayersForGameStart().size() + "/" + GetPlayerFull()); - scoreboard.get(ArcadeScoreboardLine.GEM_VALUE).write(donationManager.Get(scoreboard.getOwner()).getBalance(GlobalCurrency.GEM)); + if (GetGame() != null && GetGame().CrownsEnabled) + { + scoreboard.get(ArcadeScoreboardLine.GEM_NAME).write(C.cGold + C.Bold + "Crowns"); + scoreboard.get(ArcadeScoreboardLine.GEM_VALUE).write(donationManager.getCrowns(scoreboard.getOwner())); + } + else + { + scoreboard.get(ArcadeScoreboardLine.GEM_NAME).write(C.cGreen + C.Bold + "Gems"); + scoreboard.get(ArcadeScoreboardLine.GEM_VALUE).write(donationManager.Get(scoreboard.getOwner()).getBalance(GlobalCurrency.GEM)); + } if (GetGame() != null) { @@ -977,6 +986,8 @@ public class ArcadeManager extends MiniPlugin implements IRelation @EventHandler public void MessageJoin(PlayerJoinEvent event) { + _compromisedAccountManager.triggerPriorityBan(event.getPlayer(), PriorityCause.JOIN_GAME); + if (_incognitoManager.Get(event.getPlayer()).Status) { event.setJoinMessage(null); @@ -2069,4 +2080,9 @@ public class ArcadeManager extends MiniPlugin implements IRelation { return this._titles; } + + public CompromisedAccountManager getCompromisedAccountManager() + { + return _compromisedAccountManager; + } } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/GameType.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/GameType.java index f7bac3e5e..301541dba 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/GameType.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/GameType.java @@ -7,7 +7,6 @@ import mineplex.core.common.MinecraftVersion; import mineplex.core.common.Pair; import mineplex.core.game.GameCategory; import mineplex.core.game.GameDisplay; - import nautilus.game.arcade.game.Game; import nautilus.game.arcade.game.games.baconbrawl.BaconBrawl; import nautilus.game.arcade.game.games.barbarians.Barbarians; @@ -26,6 +25,8 @@ import nautilus.game.arcade.game.games.build.modes.DukesOfDecoration; import nautilus.game.arcade.game.games.build.modes.TeamBuild; import nautilus.game.arcade.game.games.buildmavericks.BuildMavericks; import nautilus.game.arcade.game.games.cards.Cards; +import nautilus.game.arcade.game.games.castleassault.CastleAssault; +import nautilus.game.arcade.game.games.castleassault.CastleAssaultTDM; import nautilus.game.arcade.game.games.castlesiege.CastleSiege; import nautilus.game.arcade.game.games.champions.ChampionsCTF; import nautilus.game.arcade.game.games.champions.ChampionsDominate; @@ -131,6 +132,8 @@ public enum GameType Basketball(Basketball.class, GameDisplay.Basketball), BossBattles(BossBattles.class, GameDisplay.BossBattles), Bridge(Bridge.class, GameDisplay.Bridge), + CastleAssault(CastleAssault.class, GameDisplay.CastleAssault), + CastleAssaultTDM(CastleAssaultTDM.class, GameDisplay.CastleAssaultTDM), CastleSiege(CastleSiege.class, GameDisplay.CastleSiege), ChampionsCTF(ChampionsCTF.class, GameDisplay.ChampionsCTF), ChampionsDominate(ChampionsDominate.class, GameDisplay.ChampionsDominate), diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/Game.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/Game.java index 26aacf6fe..70cc48c37 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/Game.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/Game.java @@ -253,6 +253,8 @@ public abstract class Game extends ListenerComponent implements Lifetimed public boolean WorldSoilTrample = false; public boolean WorldBoneMeal = false; public boolean WorldChunkUnload = false; + + public boolean AllowFlintAndSteel = false; public int HungerSet = -1; public int HealthSet = -1; @@ -319,6 +321,8 @@ public abstract class Game extends ListenerComponent implements Lifetimed public final ChatStatData BlankLine = new ChatStatData().blankLine(); // Gems + public boolean CrownsEnabled = false; + public double GemMultiplier = 1; public boolean GemHunterEnabled = true; public boolean GemBoosterEnabled = true; @@ -337,6 +341,7 @@ public abstract class Game extends ListenerComponent implements Lifetimed public Location SpectatorSpawn = null; public boolean FirstKill = true; + public int FirstKillReward = 10; public String Winner = "Nobody"; public GameTeam WinnerTeam = null; diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/CastleAssault.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/CastleAssault.java new file mode 100644 index 000000000..f4ed36446 --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/CastleAssault.java @@ -0,0 +1,1430 @@ +package nautilus.game.arcade.game.games.castleassault; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.WeakHashMap; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.FireworkEffect.Type; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.Chest; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.EnderCrystal; +import org.bukkit.entity.EnderPearl; +import org.bukkit.entity.Entity; +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.Painting; +import org.bukkit.entity.Player; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.entity.Zombie; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockDispenseEvent; +import org.bukkit.event.block.BlockFadeEvent; +import org.bukkit.event.block.BlockFormEvent; +import org.bukkit.event.block.BlockFromToEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.block.LeavesDecayEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.ExplosionPrimeEvent; +import org.bukkit.event.entity.ItemDespawnEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.entity.ProjectileHitEvent; +import org.bukkit.event.hanging.HangingBreakEvent; +import org.bukkit.event.inventory.InventoryAction; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.inventory.PrepareItemCraftEvent; +import org.bukkit.event.player.PlayerBucketEmptyEvent; +import org.bukkit.event.player.PlayerBucketFillEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.material.Dispenser; +import org.bukkit.material.MaterialData; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.metadata.MetadataValue; +import org.bukkit.util.Vector; + +import mineplex.core.Managers; +import mineplex.core.common.Pair; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilEvent; +import mineplex.core.common.util.UtilEvent.ActionType; +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextBottom; +import mineplex.core.common.util.UtilTime; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.leaderboard.Leaderboard; +import mineplex.core.leaderboard.LeaderboardManager; +import mineplex.core.leaderboard.LeaderboardRepository.LeaderboardSQLType; +import mineplex.core.loot.ChestLoot; +import mineplex.core.recharge.Recharge; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.minecraft.game.core.combat.DeathMessageType; +import mineplex.minecraft.game.core.combat.event.CombatDeathEvent; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.GameType; +import nautilus.game.arcade.events.FirstBloodEvent; +import nautilus.game.arcade.events.GameStateChangeEvent; +import nautilus.game.arcade.game.GameTeam; +import nautilus.game.arcade.game.GemData; +import nautilus.game.arcade.game.TeamGame; +import nautilus.game.arcade.game.games.castleassault.data.KillStreakData; +import nautilus.game.arcade.game.games.castleassault.data.ObjectiveTNTSpawner; +import nautilus.game.arcade.game.games.castleassault.data.TeamCrystal; +import nautilus.game.arcade.game.games.castleassault.data.TeamKing; +import nautilus.game.arcade.game.games.castleassault.kits.KitArcher; +import nautilus.game.arcade.game.games.castleassault.kits.KitDemolitionist; +import nautilus.game.arcade.game.games.castleassault.kits.KitFighter; +import nautilus.game.arcade.game.games.castleassault.kits.KitPlayer; +import nautilus.game.arcade.game.games.castleassault.kits.KitTank; +import nautilus.game.arcade.game.modules.compass.CompassModule; +import nautilus.game.arcade.kit.Kit; +import nautilus.game.arcade.managers.lobby.current.NewGameLobbyManager; + +public class CastleAssault extends TeamGame +{ + private static final int MAX_FLINT_AND_STEEL_USES = 4; + private static final int ITEMS_PER_CHEST = 5; + private static final long TIME_TILL_REFILL = 2 * 60 * 1000; + + private long _lastRefill; + + private ItemBuilder _flintAndSteel; + private ItemBuilder _wearableTnt; + + private Map _streakData = new WeakHashMap<>(); + private Map> _crystals = new HashMap<>(); + private Map _kings = new HashMap<>(); + private List _tntCarry = new ArrayList<>(); + + private List _chests = new ArrayList<>(); + + private ChestLoot _rangedGear = new ChestLoot(true); + private ChestLoot _rodsAndGaps = new ChestLoot(true); + private ChestLoot _potionGearCommon = new ChestLoot(true); + private ChestLoot _potionGearRare = new ChestLoot(true); + private ChestLoot _miscGear = new ChestLoot(); + + private ObjectiveTNTSpawner _tntSpawner; + + private boolean _writeScoreboard = true; + + @SuppressWarnings("deprecation") + public CastleAssault(ArcadeManager manager) + { + super(manager, GameType.CastleAssault, + new Kit[] + { + //new KitAlchemist(manager), + new KitArcher(manager), + new KitDemolitionist(manager), + //new KitEnchanter(manager), + new KitFighter(manager), + //new KitHardline(manager), + //new KitNinja(manager), + new KitTank(manager) + }, + new String[] + { + "Destroy enemy sentry crystals with running TNT", + "After the crystals are destroyed you must slay their king", + "First team to kill the enemy king wins", + "Chests refill every 2 minutes", + "TNT Respawns every 1 minute" + } + ); + + _help = new String[] + { + "Use the TNT spawning platforms to run TNT to the enemy crystals to destroy them!", + "The enemy king is invulnerable until you destroy the two sentry crystals on each sentry tower", + "Go on Kill Streaks to earn Kill Streak Rewards to obtain better armor & weapons!", + "Chests refill every 2 minutes with potions, golden applegates, fishing rods, and other useful PvP items!" + }; + + this.StrictAntiHack = true; + this.HungerSet = 20; + this.DeathOut = false; + this.DeathSpectateSecs = 5; + this.CreatureAllow = false; + this.DeathDropItems = false; + this.WorldWeatherEnabled = false; + this.AllowParticles = false; + this.SoupEnabled = false; + this.InventoryClick = true; + this.InventoryOpenChest = true; + this.InventoryOpenBlock = true; + this.ItemDrop = true; + this.ItemPickup = true; + this.AllowFlintAndSteel = true; + this.BlockPlaceAllow.add(Material.FIRE.getId()); + this.CrownsEnabled = true; + this.FirstKillReward = 20; + this.GemKillDeathRespawn = 1; + + new CompassModule() + .setGiveCompass(true) + .setGiveCompassToSpecs(true) + .setGiveCompassToAlive(false) + .register(this); + + _flintAndSteel = new ItemBuilder(Material.FLINT_AND_STEEL).setData((short) (Material.FLINT_AND_STEEL.getMaxDurability() - MAX_FLINT_AND_STEEL_USES)); + _wearableTnt = new ItemBuilder(Material.TNT).setTitle(C.cRed + "TNT").addLore(C.cRedB + "Right Click with Weapon to " + F.name("Detonate")); + generateLoot(); + + if (manager.IsRewardStats()) + { + if (manager.GetLobby() instanceof NewGameLobbyManager) + { + Map> lobbyCustomLocs = ((NewGameLobbyManager)manager.GetLobby()).getCustomLocs(); + if (lobbyCustomLocs.containsKey("TOP_DAILY_WINS")) + { + Location loc = lobbyCustomLocs.get("TOP_DAILY_WINS").get(0); + Managers.get(LeaderboardManager.class).registerLeaderboard("TOP_CASTLEASSAULT_DAILY_WINS", new Leaderboard("Top Daily Wins", Pair.create("Win", "Wins"), new String[] {"Castle Assault.Wins"}, LeaderboardSQLType.DAILY, loc, 10)); + } + if (lobbyCustomLocs.containsKey("TOP_DAILY_KILLS")) + { + Location loc = lobbyCustomLocs.get("TOP_DAILY_KILLS").get(0); + Managers.get(LeaderboardManager.class).registerLeaderboard("TOP_CASTLEASSAULT_DAILY_KILLS", new Leaderboard("Top Daily Kills", Pair.create("Kill", "Kills"), new String[] {"Castle Assault.Kills"}, LeaderboardSQLType.DAILY, loc, 10)); + } + if (lobbyCustomLocs.containsKey("TOP_WINS")) + { + Location loc = lobbyCustomLocs.get("TOP_WINS").get(0); + Managers.get(LeaderboardManager.class).registerLeaderboard("TOP_CASTLEASSAULT_WINS", new Leaderboard("Top Wins", Pair.create("Win", "Wins"), new String[] {"Castle Assault.Wins"}, LeaderboardSQLType.ALL_SEASON, loc, 10)); + } + if (lobbyCustomLocs.containsKey("TOP_KILLS")) + { + Location loc = lobbyCustomLocs.get("TOP_KILLS").get(0); + Managers.get(LeaderboardManager.class).registerLeaderboard("TOP_CASTLEASSAULT_KILLS", new Leaderboard("Top Kills", Pair.create("Kill", "Kills"), new String[] {"Castle Assault.Kills"}, LeaderboardSQLType.ALL_SEASON, loc, 10)); + } + } + } + } + + private void generateLoot() + { + { + _rangedGear.addLoot(new ItemStack(Material.BOW), 3); + _rangedGear.addLoot(Material.ARROW, 3, 8, 16); + } + { + _rodsAndGaps.addLoot(new ItemStack(Material.FISHING_ROD), 3); + _rodsAndGaps.addLoot(new ItemBuilder(Material.GOLDEN_APPLE).setTitle(C.cPurple + "Golden Applegate").build(), 3); + } + { + _potionGearCommon.addLoot(new ItemBuilder(Material.POTION).setData((short)16418).build(), 2); + _potionGearCommon.addLoot(new ItemBuilder(Material.POTION).setData((short)16417).build(), 2); + } + { + _potionGearRare.addLoot(new ItemBuilder(Material.POTION).setData((short)8193).build(), 2); + _potionGearRare.addLoot(new ItemBuilder(Material.POTION).setData((short)8195).build(), 2); + } + { + _miscGear.addLoot(new ItemStack(Material.ENDER_PEARL), 2); + _miscGear.addLoot(new ItemStack(Material.WATER_BUCKET), 2); + _miscGear.addLoot(_flintAndSteel.build(), 2); + _miscGear.addLoot(new ItemStack(Material.SNOW_BALL, 16), 3); + } + } + + private void fillChest(Block block) + { + if (block.getType() != Material.CHEST && block.getType() != Material.TRAPPED_CHEST) + { + return; + } + Chest chest = (Chest) block.getState(); + + chest.getBlockInventory().clear(); + int[] slots = UtilMath.random.ints(ITEMS_PER_CHEST, 0, chest.getBlockInventory().getSize()).toArray(); + + for (int slot : slots) + { + double chance = UtilMath.random.nextDouble(); + double subChance = UtilMath.random.nextDouble(); + + ChestLoot loot = _miscGear; + if (chance <= 0.6) + { + loot = _rodsAndGaps; + } + if (chance <= 0.5) + { + loot = _potionGearCommon; + if (subChance <= 0.45) + { + loot = _potionGearRare; + } + } + if (chance <= 0.3) + { + loot = _rangedGear; + } + chest.getBlockInventory().setItem(slot, loot.getLoot()); + } + } + + public ItemStack getNewFlintAndSteel(boolean kitItem) + { + if (kitItem) + { + return _flintAndSteel.clone().setLore(C.cGold + "Kit Item").build(); + } + return _flintAndSteel.build(); + } + + public void writeScoreboard() + { + if (!_writeScoreboard) + { + return; + } + Scoreboard.reset(); + Scoreboard.write(C.cDRedB + GetName()); + Scoreboard.writeNewLine(); + Scoreboard.write(C.cGreenB + "Chest Refill"); + long refillTime = _lastRefill + TIME_TILL_REFILL - System.currentTimeMillis(); + if (!IsLive()) + { + refillTime = TIME_TILL_REFILL; + } + Scoreboard.write(UtilTime.MakeStr(refillTime)); + Scoreboard.writeNewLine(); + Scoreboard.write(C.cGreenB + "TNT Spawn"); + long tntTime = _tntSpawner.getNextTNT(); + if (!IsLive()) + { + tntTime = 60000; + } + if (_tntSpawner.isSpawned()) + { + Scoreboard.write("Spawned"); + } + else + { + Scoreboard.write(UtilTime.MakeStr(tntTime)); + } + Scoreboard.writeNewLine(); + GameTeam red = GetTeam(ChatColor.RED); + long redCrystals = _crystals.get(red).stream().filter(TeamCrystal::isActive).count(); + GameTeam blue = GetTeam(ChatColor.AQUA); + long blueCrystals = _crystals.get(blue).stream().filter(TeamCrystal::isActive).count(); + if (redCrystals > 0) + { + Scoreboard.write(_kings.get(red).getName(true)); + Scoreboard.write(redCrystals + "/2 Crystals Active"); + } + else + { + Scoreboard.write(_kings.get(red).getName(true) + " Health"); + Scoreboard.write(_kings.get(red).getHealth() + ""); + } + Scoreboard.writeNewLine(); + if (blueCrystals > 0) + { + Scoreboard.write(_kings.get(blue).getName(true)); + Scoreboard.write(blueCrystals + "/2 Crystals Active"); + } + else + { + Scoreboard.write(_kings.get(blue).getName(true) + " Health"); + Scoreboard.write(_kings.get(blue).getHealth() + ""); + } + Scoreboard.draw(); + } + + public void writeFinalScoreboard(String deadKing, String winKing, String warrior) + { + _writeScoreboard = false; + Scoreboard.reset(); + Scoreboard.writeNewLine(); + Scoreboard.write(deadKing + "'s " + C.cWhite + "castle has been conquered"); + Scoreboard.write(C.cWhite + "by " + winKing + "'s " + C.cWhite + "army with the help of"); + Scoreboard.write(warrior + C.cWhite + "!"); + Scoreboard.writeNewLine(); + + Scoreboard.draw(); + } + + @Override + public void ParseData() + { + for (Location chestLoc : WorldData.GetDataLocs("BROWN")) + { + Block block = chestLoc.getBlock(); + block.setType(Material.CHEST); + fillChest(block); + _chests.add(block); + } + GameTeam red = GetTeam(ChatColor.RED); + GameTeam blue = GetTeam(ChatColor.AQUA); + Location redKing = WorldData.GetDataLocs("RED").get(0); + Location blueKing = WorldData.GetDataLocs("BLUE").get(0); + Vector redBlue = UtilAlg.getTrajectory(redKing, blueKing); + Vector blueRed = UtilAlg.getTrajectory(blueKing, redKing); + redKing.setPitch(UtilAlg.GetPitch(redBlue)); + redKing.setYaw(UtilAlg.GetYaw(redBlue)); + blueKing.setPitch(UtilAlg.GetPitch(blueRed)); + blueKing.setYaw(UtilAlg.GetYaw(blueRed)); + _crystals.put(red, Arrays.asList(new TeamCrystal(red, WorldData.GetDataLocs("PINK").get(0)), new TeamCrystal(red, WorldData.GetDataLocs("PINK").get(1)))); + _crystals.put(blue, Arrays.asList(new TeamCrystal(blue, WorldData.GetDataLocs("LIGHT_BLUE").get(0)), new TeamCrystal(blue, WorldData.GetDataLocs("LIGHT_BLUE").get(1)))); + this.CreatureAllowOverride = true; + _kings.put(red, new TeamKing(red, "King Jon", redKing)); + _kings.put(blue, new TeamKing(blue, "King Ryan", blueKing)); + for (Kit kit : GetKits()) + { + List spawns = WorldData.GetCustomLocs(kit.GetName().toUpperCase()); + for (Location spawn : spawns) + { + Entity ent = kit.SpawnEntity(spawn); + Manager.GetLobby().addKitLocation(ent, kit, spawn); + } + } + this.CreatureAllowOverride = false; + _tntSpawner = new ObjectiveTNTSpawner(WorldData.GetDataLocs("BLACK")); + } + + @Override + public void EndCheck() + { + if (!IsLive()) + { + return; + } + + List teamsAlive = new ArrayList<>(); + + for (GameTeam team : GetTeamList()) + { + if (team.GetPlayers(true).size() > 0) + { + teamsAlive.add(team); + } + } + + if (teamsAlive.size() <= 1) + { + //Announce + if (teamsAlive.size() > 0) + { + GameTeam winner = teamsAlive.get(0); + TeamKing king = _kings.get(winner); + TeamKing dead = _kings.values().stream().filter(k -> k.getOwner().GetColor() != king.getOwner().GetColor()).findFirst().get(); + AnnounceEnd(winner); + writeFinalScoreboard(dead.getName(false), king.getName(false), dead.getOwner().GetColor() + "Quitters"); + for (GameTeam team : GetTeamList()) + { + for (Player player : team.GetPlayers(true)) + { + if (team.GetColor() == winner.GetColor()) + { + AddGems(player, 100, "Winning Team", false, false); + } + else + { + AddGems(player, 50, "Losing Team", false, false); + } + if (player.isOnline()) + { + AddGems(player, 10, "Participation", false, false); + } + + int crowns = 0; + for (Entry data : GetGems(player).entrySet()) + { + if (data.getKey().equals("Kills")) + { + crowns += data.getValue().Gems; + } + } + + { + int streak = _streakData.getOrDefault(player, new KillStreakData()).getBestStreak(); + if (streak >= 2 && streak < 4) + { + AddGems(player, 0.5 * crowns, streak + " Player Kill Streak", false, false); + } + else if (streak >= 4 && streak < 6) + { + AddGems(player, 1 * crowns, streak + " Player Kill Streak", false, false); + } + else if (streak >= 6 && streak < 8) + { + AddGems(player, 1.5 * crowns, streak + " Player Kill Streak", false, false); + } + else if (streak >= 8) + { + AddGems(player, 2 * crowns, streak + " Player Kill Streak", false, false); + } + } + } + } + SetState(GameState.End); + return; + } + } + } + + @Override + @EventHandler + public void ScoreboardUpdate(UpdateEvent event) {}; + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + { + return; + } + if (IsLive()) + { + if (UtilTime.elapsed(_lastRefill, TIME_TILL_REFILL)) + { + _lastRefill = System.currentTimeMillis(); + _chests.forEach(this::fillChest); + Bukkit.broadcastMessage(C.cGreenB + "Chests have refilled!"); + } + + GameTeam red = GetTeam(ChatColor.RED); + GameTeam blue = GetTeam(ChatColor.AQUA); + TeamKing redKing = _kings.get(red); + TeamKing blueKing = _kings.get(blue); + redKing.update(_crystals.get(red).stream().filter(TeamCrystal::isActive).count() > 0); + if (redKing.isDead()) + { + AnnounceEnd(blue); + writeFinalScoreboard(redKing.getName(false), blueKing.getName(false), blue.GetColor() + redKing.getLastDamager()); + for (GameTeam team : GetTeamList()) + { + for (Player player : team.GetPlayers(true)) + { + if (player.getName().equals(redKing.getLastDamager())) + { + AddGems(player, 20, "King Slayer", false, false); + } + if (team.GetColor() == ChatColor.AQUA) + { + AddGems(player, 100, "Winning Team", false, false); + } + else + { + AddGems(player, 50, "Losing Team", false, false); + } + if (player.isOnline()) + { + AddGems(player, 10, "Participation", false, false); + } + + int crowns = 0; + for (Entry data : GetGems(player).entrySet()) + { + if (data.getKey().equals("Kills")) + { + crowns += data.getValue().Gems; + } + } + + { + int streak = _streakData.getOrDefault(player, new KillStreakData()).getBestStreak(); + if (streak >= 2 && streak < 4) + { + AddGems(player, 0.5 * crowns, streak + " Player Kill Streak", false, false); + } + else if (streak >= 4 && streak < 6) + { + AddGems(player, 1 * crowns, streak + " Player Kill Streak", false, false); + } + else if (streak >= 6 && streak < 8) + { + AddGems(player, 1.5 * crowns, streak + " Player Kill Streak", false, false); + } + else if (streak >= 8) + { + AddGems(player, 2 * crowns, streak + " Player Kill Streak", false, false); + } + } + } + } + SetState(GameState.End); + return; + } + blueKing.update(_crystals.get(blue).stream().filter(TeamCrystal::isActive).count() > 0); + if (blueKing.isDead()) + { + AnnounceEnd(red); + writeFinalScoreboard(blueKing.getName(false), redKing.getName(false), red.GetColor() + blueKing.getLastDamager()); + for (GameTeam team : GetTeamList()) + { + for (Player player : team.GetPlayers(true)) + { + if (player.getName().equals(blueKing.getLastDamager())) + { + AddGems(player, 20, "King Slayer", false, false); + } + if (team.GetColor() == ChatColor.RED) + { + AddGems(player, 100, "Winning Team", false, false); + } + else + { + AddGems(player, 50, "Losing Team", false, false); + } + if (player.isOnline()) + { + AddGems(player, 10, "Participation", false, false); + } + + int crowns = 0; + for (Entry data : GetGems(player).entrySet()) + { + if (data.getKey().equals("Kills")) + { + crowns += data.getValue().Gems; + } + } + + { + int streak = _streakData.getOrDefault(player, new KillStreakData()).getBestStreak(); + if (streak >= 2 && streak < 4) + { + AddGems(player, 0.5 * crowns, streak + " Player Kill Streak", false, false); + } + else if (streak >= 4 && streak < 6) + { + AddGems(player, 1 * crowns, streak + " Player Kill Streak", false, false); + } + else if (streak >= 6 && streak < 8) + { + AddGems(player, 1.5 * crowns, streak + " Player Kill Streak", false, false); + } + else if (streak >= 8) + { + AddGems(player, 2 * crowns, streak + " Player Kill Streak", false, false); + } + } + } + } + SetState(GameState.End); + return; + } + + _tntSpawner.update(); + } + if (InProgress()) + { + writeScoreboard(); + } + } + + @EventHandler + public void onEditSettings(GameStateChangeEvent event) + { + if (event.GetGame() != this) + { + return; + } + + if (event.GetState() == GameState.Live) + { + _lastRefill = System.currentTimeMillis(); + _tntSpawner.onStart(); + Manager.GetDamage().SetEnabled(false); + Manager.GetExplosion().setEnabled(false); + Manager.GetCreature().SetDisableCustomDrops(true); + } + + if (event.GetState() == GameState.End) + { + Manager.GetDamage().SetEnabled(true); + Manager.GetExplosion().setEnabled(true); + Manager.GetCreature().SetDisableCustomDrops(false); + } + + if (event.GetState() == GameState.Dead) + { + Managers.get(LeaderboardManager.class).unregisterLeaderboard("TOP_CASTLEASSAULT_DAILY_WINS"); + Managers.get(LeaderboardManager.class).unregisterLeaderboard("TOP_CASTLEASSAULT_DAILY_KILLS"); + Managers.get(LeaderboardManager.class).unregisterLeaderboard("TOP_CASTLEASSAULT_WINS"); + Managers.get(LeaderboardManager.class).unregisterLeaderboard("TOP_CASTLEASSAULT_KILLS"); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void handleDeath(CombatDeathEvent event) + { + if (!IsLive()) + { + return; + } + + event.SetBroadcastType(DeathMessageType.Detailed); + } + + @EventHandler + public void disableDamageLevel(CustomDamageEvent event) + { + event.SetDamageToLevel(false); + } + + @EventHandler + public void BlockFade(BlockFadeEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void BlockBurn(BlockBurnEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void BlockDecay(LeavesDecayEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void hangingBreak(HangingBreakEvent event) + { + if (event.getEntity() instanceof ItemFrame || event.getEntity() instanceof Painting) + { + event.setCancelled(true); + } + } + + @EventHandler + public void noFlow(BlockFromToEvent event) + { + if (!IsLive()) + { + return; + } + + Block block = event.getBlock(); + if (block.getType() == Material.WATER || block.getType() == Material.STATIONARY_WATER || block.getType() == Material.LAVA || block.getType() == Material.STATIONARY_LAVA) + { + event.setCancelled(true); + } + if (event.getToBlock().getType() == Material.ICE) + { + event.setCancelled(true); + } + } + + @EventHandler + public void onBlockChange(BlockFormEvent e) + { + if (!IsLive()) + { + return; + } + if (e.getNewState().getType() == Material.ICE) + { + e.setCancelled(true); + } + } + + @SuppressWarnings("deprecation") + @EventHandler(ignoreCancelled=true) + public void onPlayerEmptyBucket(PlayerBucketEmptyEvent event) + { + if (!IsLive()) + { + return; + } + + Player player = event.getPlayer(); + if (player.getItemInHand().getType() == Material.WATER_BUCKET) + { + player.getItemInHand().setType(Material.BUCKET); + Block block = event.getBlockClicked().getRelative(event.getBlockFace()); + if (block.getType().toString().contains("LAVA") || (block.getType().toString().contains("WATER") && block.getType() != Material.WATER_LILY)) + { + event.setCancelled(true); + player.sendBlockChange(block.getLocation(), block.getType(), block.getData()); + return; + } + for (BlockFace bf : BlockFace.values()) + { + Block relative = block.getRelative(bf); + if (relative.getType().toString().contains("LAVA") || (relative.getType().toString().contains("WATER") && relative.getType() != Material.WATER_LILY)) + { + event.setCancelled(true); + player.sendBlockChange(block.getLocation(), block.getType(), block.getData()); + } + } + } + else if (player.getItemInHand().getType() == Material.LAVA_BUCKET) + { + event.setCancelled(true); + Block block = event.getBlockClicked().getRelative(event.getBlockFace()); + player.sendBlockChange(block.getLocation(), block.getType(), block.getData()); + } + } + + @SuppressWarnings("deprecation") + @EventHandler(ignoreCancelled=true) + public void onPlayerFillBucket(PlayerBucketFillEvent event) + { + if (!IsLive()) + { + return; + } + + Player player = event.getPlayer(); + Block block = event.getBlockClicked().getRelative(event.getBlockFace()); + if (block.getType() == Material.LAVA || block.getType() == Material.STATIONARY_LAVA) + { + event.setCancelled(true); + player.sendBlockChange(block.getLocation(), block.getType(), block.getData()); + } + } + + @EventHandler(ignoreCancelled=true) + public void onBlockDispense(BlockDispenseEvent event) + { + if (!IsLive()) + { + return; + } + + if (event.getItem().getType() == Material.WATER_BUCKET) + { + Block dispenser = event.getBlock(); + + MaterialData mat = dispenser.getState().getData(); + Dispenser disp_mat = (Dispenser)mat; + BlockFace face = disp_mat.getFacing(); + Block block = dispenser.getRelative(face); + if (block.getType().toString().contains("LAVA") || (block.getType().toString().contains("WATER") && block.getType() != Material.WATER_LILY)) + { + event.setCancelled(true); + return; + } + for (BlockFace bf : BlockFace.values()) + { + if (block.getRelative(bf).getType().toString().contains("LAVA") || (block.getRelative(bf).getType().toString().contains("WATER") && block.getRelative(bf).getType() != Material.WATER_LILY)) + { + event.setCancelled(true); + } + } + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onCombatDeath(CombatDeathEvent event) + { + if (!IsLive()) + { + return; + } + + if (event.GetLog().GetKiller() == null) + { + return; + } + + if (!event.GetLog().GetKiller().IsPlayer()) + { + return; + } + + Player player = UtilPlayer.searchExact(event.GetLog().GetKiller().GetName()); + if (player == null) + { + return; + } + + AddStat(player, GetKit(player).GetName() + "KitKills", 1, false, false); + + if (UtilPlayer.isSpectator(player)) + { + return; + } + + player.setLevel(player.getLevel() + 1); + player.getInventory().addItem(new ItemBuilder(Material.GOLDEN_APPLE).setTitle(C.cPurple + "Golden Applegate").build()); + KillStreakData data = _streakData.computeIfAbsent(player, (key) -> new KillStreakData()); + boolean hardLine = GetKit(player).GetName().equals("Hardline"); + if (data.addKill(hardLine)) + { + AddStat(player, "KillStreak", 1, false, false); + ((KitPlayer)GetKit(player)).awardKillStreak(player, hardLine ? (data.getKills() + 1) : data.getKills()); + } + if (UtilMath.isEven(data.getKills())) + { + Bukkit.broadcastMessage(F.main("Game", C.cGreen + C.Bold + player.getName() + ChatColor.RESET + " is on a " + F.elem(C.cDPurple + data.getKills() + " player Kill Streak") + "!")); + } + } + + @EventHandler + public void TNTExplosion(ExplosionPrimeEvent event) + { + if (!event.getEntity().hasMetadata("THROWER")) + { + return; + } + float radius = event.getRadius(); + event.setRadius(0f); + + Player player = UtilPlayer.searchExact(((MetadataValue)UtilEnt.GetMetadata(event.getEntity(), "THROWER")).asString()); + if (player == null) + { + return; + } + if (GetTeam(player) == null) + { + return; + } + if (GetKit(player).GetName().equals("Demolitionist")) + { + radius += 3; + } + + Map nearby = UtilPlayer.getInRadius(event.getEntity().getLocation(), radius); + for (Player near : nearby.keySet()) + { + if (UtilPlayer.isSpectator(near)) + { + continue; + } + if (near.getEntityId() != player.getEntityId() && GetTeam(near).GetColor() == GetTeam(player).GetColor()) + { + continue; + } + if (near.getEntityId() == player.getEntityId() && event.getEntity().hasMetadata("OBJECTIVE_TNT")) + { + continue; + } + + double mult = nearby.get(near); + + int highestBlastProt = 0; + int blastProtEPF = 0; + for (ItemStack item : near.getInventory().getArmorContents()) + { + if (item != null && item.getEnchantments().containsKey(Enchantment.PROTECTION_EXPLOSIONS)) + { + blastProtEPF += (2 * item.getEnchantmentLevel(Enchantment.PROTECTION_EXPLOSIONS)); + if (item.getEnchantmentLevel(Enchantment.PROTECTION_EXPLOSIONS) > highestBlastProt) + { + highestBlastProt = item.getEnchantmentLevel(Enchantment.PROTECTION_EXPLOSIONS); + } + } + } + blastProtEPF = Math.min(blastProtEPF, 20); + + double damage = 8 * mult; + damage = damage * (1 - (blastProtEPF / 25)); + + double knockbackReduction = 1 - (highestBlastProt * 0.15); + + near.damage(damage, event.getEntity()); + UtilAction.velocity(near, UtilAlg.getTrajectory(event.getEntity().getLocation(), near.getLocation()), 1 * mult * knockbackReduction, false, 0, mult * knockbackReduction, 10, true); + } + + if (event.getEntity().hasMetadata("OBJECTIVE_TNT")) + { + List crystals = new ArrayList<>(); + + for (List c : _crystals.values()) + { + crystals.addAll(c); + } + for (TeamCrystal crystal : crystals) + { + if (crystal.isActive() && !crystal.getOwner().HasPlayer(player) && UtilMath.offset(event.getEntity().getLocation(), crystal.getLocation()) <= radius) + { + crystal.destroy(); + AddGems(player, 40, "Crystal Destruction", false, true); + long remaining = crystals.stream().filter(b -> b.getOwner().GetColor() == crystal.getOwner().GetColor()).filter(TeamCrystal::isActive).count(); + if (remaining > 0) + { + Bukkit.broadcastMessage(F.main("Game", "One of " + F.elem(crystal.getOwner().GetFormattedName() + "'s Crystals") + " has been destroyed!")); + } + else + { + Bukkit.broadcastMessage(F.main("Game", "All of " + F.elem(crystal.getOwner().GetFormattedName() + "'s Crystals") + " has been destroyed and " + F.elem(_kings.get(crystal.getOwner()).getName(false)) + " is now vulnerable!")); + } + } + } + for (TeamKing king : _kings.values()) + { + if (king.isDead() && !king.getOwner().HasPlayer(player) && UtilMath.offset(event.getEntity().getLocation(), king.getLocation()) <= radius) + { + king.handleDamage(player.getName(), 50); + } + } + } + } + + @EventHandler + public void TNTThrow(PlayerInteractEvent event) + { + if (!IsLive()) + { + return; + } + + if (!UtilEvent.isAction(event, ActionType.L)) + { + return; + } + + Player player = event.getPlayer(); + + if (!UtilInv.IsItem(player.getItemInHand(), Material.TNT, (byte) 0)) + { + return; + } + + if (!IsAlive(player)) + { + return; + } + + event.setCancelled(true); + + if (!Manager.GetGame().CanThrowTNT(player.getLocation())) + { + // Inform + UtilPlayer.message(event.getPlayer(), F.main(GetName(), "You cannot use " + F.item("Throwing TNT") + " here.")); + return; + } + + UtilInv.remove(player, Material.TNT, (byte) 0, 1); + UtilInv.Update(player); + + TNTPrimed tnt = player.getWorld().spawn(player.getEyeLocation().add(player.getLocation().getDirection()), TNTPrimed.class); + + tnt.setFuseTicks(60); + + double throwMult = 1; + + if (GetKit(player).GetName().equals("Demolitionist")) + { + throwMult = ((KitDemolitionist)GetKit(player)).getThrowMultiplier(player); + } + + UtilAction.velocity(tnt, player.getLocation().getDirection(), 0.5 * throwMult, false, 0, 0.1, 10, false); + + UtilEnt.SetMetadata(tnt, "THROWER", player.getName()); + } + + @EventHandler + public void onLaunch(ProjectileHitEvent event) + { + if (!IsLive()) + { + return; + } + + if (event.getEntity() instanceof EnderPearl && event.getEntity().getShooter() != null && event.getEntity().getShooter() instanceof Entity) + { + Entity shooter = (Entity) event.getEntity().getShooter(); + if (_tntCarry.contains(shooter)) + { + return; + } + Location teleport = event.getEntity().getLocation(); + teleport.setPitch(shooter.getLocation().getPitch()); + teleport.setYaw(shooter.getLocation().getYaw()); + shooter.teleport(teleport); + } + if (event.getEntity() instanceof Arrow) + { + Manager.runSyncLater(event.getEntity()::remove, 1L); + } + } + + @EventHandler + public void onOpenChest(PlayerInteractEvent event) + { + if (!IsLive()) + { + return; + } + + if (event.getClickedBlock() != null && event.getClickedBlock().getType() == Material.CHEST) + { + if (UtilPlayer.isSpectator(event.getPlayer())) + { + event.setCancelled(true); + } + } + } + + @EventHandler(ignoreCancelled = true) + public void onDamage(EntityDamageEvent event) + { + if (!IsLive()) + { + return; + } + if (Manager.GetLobby().getKits().containsKey(event.getEntity())) + { + event.setCancelled(true); + return; + } + if (event.getEntity() instanceof EnderCrystal) + { + event.setCancelled(true); + return; + } + if (event.getEntity() instanceof Zombie) + { + event.setCancelled(true); + if (event instanceof EntityDamageByEntityEvent) + { + if (!event.getEntity().getCustomName().contains("Ryan") && !event.getEntity().getCustomName().contains("Jon")) + { + return; + } + GameTeam owner = event.getEntity().getCustomName().contains("Ryan") ? GetTeam(ChatColor.AQUA) : GetTeam(ChatColor.RED); + EntityDamageByEntityEvent e = (EntityDamageByEntityEvent) event; + if (e.getDamager() instanceof Player) + { + Player p = (Player) e.getDamager(); + if (UtilPlayer.isSpectator(p)) + { + return; + } + if (owner.HasPlayer(p)) + { + return; + } + if (_crystals.get(owner).stream().filter(TeamCrystal::isActive).count() > 0) + { + UtilPlayer.message(p, F.main("Game", "You cannot attack the enemy king until your team has destroyed his protective crystals!")); + return; + } + TeamKing king = _kings.get(owner); + if (king.handleDamage(p.getName(), e.getDamage())) + { + for (Player alert : owner.GetPlayers(true)) + { + if (Recharge.Instance.use(alert, "KingDamageAlert", 5000, false, false)) + { + alert.sendMessage(king.getName(true) + " is under attack!"); + } + } + } + } + } + } + } + + @EventHandler + public void onDrop(PlayerDropItemEvent event) + { + if (!IsLive()) + { + return; + } + + ItemStack drop = event.getItemDrop().getItemStack(); + if (drop.hasItemMeta() && drop.getItemMeta().hasLore() && drop.getItemMeta().getLore().stream().map(ChatColor::stripColor).anyMatch(lore -> lore.equals("Kit Item"))) + { + event.setCancelled(true); + return; + } + + event.getItemDrop().remove(); + } + + @EventHandler + public void craftItem(PrepareItemCraftEvent event) + { + if (!IsLive()) + { + return; + } + + if (event.getInventory().getResult().getType() == Material.FLINT_AND_STEEL) + { + event.getInventory().setResult(_flintAndSteel.build()); + } + } + + @EventHandler + public void onInvClick(InventoryClickEvent event) + { + if (!IsLive()) + { + return; + } + ItemStack current = event.getCurrentItem(); + if (event.getAction() == InventoryAction.HOTBAR_SWAP || event.getAction() == InventoryAction.HOTBAR_MOVE_AND_READD) + { + current = event.getWhoClicked().getInventory().getItem(event.getHotbarButton()); + } + if (current == null || !current.hasItemMeta()) + { + return; + } + if (current.getItemMeta().hasDisplayName() && current.getItemMeta().getDisplayName().equals(C.cRed + "TNT")) + { + event.setCancelled(true); + return; + } + if (event.getView().getTopInventory() != null && event.getView().getTopInventory().getType() == InventoryType.CHEST) + { + if (current.getItemMeta().hasLore()) + { + for (String lore : current.getItemMeta().getLore()) + { + if (ChatColor.stripColor(lore).equalsIgnoreCase("Kit Item")) + { + event.setCancelled(true); + break; + } + } + } + + } + } + + @EventHandler + public void onFirstBlood(FirstBloodEvent event) + { + if (!IsLive()) + { + return; + } + + AddStat(event.getPlayer(), "FirstBlood", 1, true, false); + } + + @EventHandler + public void onPearl(PlayerInteractEvent event) + { + if (!IsLive()) + { + return; + } + + if (!UtilEvent.isAction(event, ActionType.R)) + { + return; + } + + if (event.getItem() != null && event.getItem().getType() == Material.ENDER_PEARL) + { + Player player = (Player) event.getPlayer(); + if (!Recharge.Instance.use(player, "Enderpearl", 4000, true, true)) + { + event.setCancelled(true); + player.updateInventory(); + } + } + } + + @EventHandler + public void onItemDespawn(ItemDespawnEvent event) + { + if (!IsLive()) + { + return; + } + + if (_tntSpawner.isSpawned()) + { + if (_tntSpawner.getItem().getEntityId() == event.getEntity().getEntityId()) + { + event.setCancelled(true); + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onPickup(PlayerPickupItemEvent event) + { + if (!IsLive()) + { + return; + } + if (UtilPlayer.isSpectator(event.getPlayer())) + { + return; + } + + if (_tntSpawner.isSpawned() && event.getItem().getEntityId() == _tntSpawner.getItem().getEntityId()) + { + event.setCancelled(true); + if (!_tntCarry.contains(event.getPlayer())) + { + _tntSpawner.pickup(); + _tntCarry.add(event.getPlayer()); + event.getPlayer().setMetadata("OLD_HELM", new FixedMetadataValue(UtilServer.getPlugin(), event.getPlayer().getInventory().getHelmet())); + event.getPlayer().setMetadata("TNT_START", new FixedMetadataValue(UtilServer.getPlugin(), System.currentTimeMillis())); + event.getPlayer().getInventory().setHelmet(_wearableTnt.build()); + UtilPlayer.message(event.getPlayer(), F.main("Game", "You picked up " + F.skill("TNT") + ".")); + UtilPlayer.message(event.getPlayer(), F.main("Game", F.elem("Right-Click") + " to detonate yourself.")); + UtilPlayer.message(event.getPlayer(), F.main("Game", "Run to the enemy Crystal and Detonate to destroy it.")); + } + } + } + + @EventHandler(ignoreCancelled = true) + public void TNTUse(PlayerInteractEvent event) + { + Player player = event.getPlayer(); + + if (!_tntCarry.contains(player)) + { + return; + } + + if (!UtilEvent.isAction(event, ActionType.R)) + { + return; + } + + event.setCancelled(true); + + player.getInventory().setHelmet((ItemStack) player.getMetadata("OLD_HELM").get(0).value()); + player.removeMetadata("OLD_HELM", UtilServer.getPlugin()); + player.removeMetadata("TNT_START", UtilServer.getPlugin()); + _tntCarry.remove(player); + + TNTPrimed tnt = player.getWorld().spawn(player.getEyeLocation(), TNTPrimed.class); + UtilEnt.SetMetadata(tnt, "THROWER", player.getName()); + UtilEnt.SetMetadata(tnt, "OBJECTIVE_TNT", true); + tnt.setFuseTicks(0); + UtilPlayer.message(player, F.main("Game", "You used " + F.skill("Detonate") + ".")); + } + + @EventHandler + public void TNTExpire(UpdateEvent event) + { + if (!IsLive()) + { + return; + } + + if (event.getType() != UpdateType.FASTER) + { + return; + } + + Bukkit.getOnlinePlayers().forEach(player -> + { + player.getInventory().remove(_wearableTnt.build()); + }); + + Iterator tntIterator = _tntCarry.iterator(); + + while (tntIterator.hasNext()) + { + Player player = tntIterator.next(); + + if (player.isDead() || UtilTime.elapsed(player.getMetadata("TNT_START").get(0).asLong(), 60000)) + { + TNTPrimed tnt = player.getWorld().spawn(player.getEyeLocation(), TNTPrimed.class); + UtilEnt.SetMetadata(tnt, "THROWER", player.getName()); + UtilEnt.SetMetadata(tnt, "OBJECTIVE_TNT", true); + tnt.setFuseTicks(0); + + if (!player.isDead()) + { + player.getInventory().setHelmet((ItemStack) player.getMetadata("OLD_HELM").get(0).value()); + } + player.removeMetadata("OLD_HELM", UtilServer.getPlugin()); + player.removeMetadata("TNT_START", UtilServer.getPlugin()); + + tntIterator.remove(); + continue; + } + + List crystals = new ArrayList<>(); + + for (List c : _crystals.values()) + { + crystals.addAll(c); + } + for (TeamCrystal crystal : crystals) + { + if (crystal.isActive() && !crystal.getOwner().HasPlayer(player) && UtilMath.offset(player.getLocation(), crystal.getLocation()) <= 3) + { + TNTPrimed tnt = player.getWorld().spawn(player.getEyeLocation(), TNTPrimed.class); + UtilEnt.SetMetadata(tnt, "THROWER", player.getName()); + UtilEnt.SetMetadata(tnt, "OBJECTIVE_TNT", true); + tnt.setFuseTicks(0); + + if (!player.isDead()) + { + player.getInventory().setHelmet((ItemStack) player.getMetadata("OLD_HELM").get(0).value()); + } + player.removeMetadata("OLD_HELM", UtilServer.getPlugin()); + player.removeMetadata("TNT_START", UtilServer.getPlugin()); + + tntIterator.remove(); + } + } + + UtilTextBottom.display(GetTeam(player).GetColor() + player.getName() + " has the TNT!", UtilServer.getPlayers()); + UtilFirework.playFirework(player.getEyeLocation(), Type.BURST, GetTeam(player).GetColorBase(), false, false); + if (player.getInventory().getHelmet() == null || player.getInventory().getHelmet().getType() == Material.AIR) + { + player.getInventory().setHelmet(_wearableTnt.build()); + } + } + } + + @EventHandler + public void onDeath(PlayerDeathEvent event) + { + Player player = event.getEntity(); + + _streakData.getOrDefault(player, new KillStreakData()).reset(); + + if (!_tntCarry.contains(player)) + { + return; + } + + player.removeMetadata("OLD_HELM", UtilServer.getPlugin()); + player.removeMetadata("TNT_START", UtilServer.getPlugin()); + _tntCarry.remove(player); + TNTPrimed tnt = player.getWorld().spawn(player.getEyeLocation(), TNTPrimed.class); + UtilEnt.SetMetadata(tnt, "THROWER", player.getName()); + UtilEnt.SetMetadata(tnt, "OBJECTIVE_TNT", true); + tnt.setFuseTicks(0); + UtilPlayer.message(player, F.main("Game", "You used " + F.skill("Detonate") + ".")); + } + + @EventHandler + public void onBlockPlace(BlockPlaceEvent event) + { + if (!_tntSpawner.canPlaceFireAt(event.getBlock())) + { + event.setCancelled(true); + } + } +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/CastleAssaultTDM.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/CastleAssaultTDM.java new file mode 100644 index 000000000..e83f12804 --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/CastleAssaultTDM.java @@ -0,0 +1,1084 @@ +package nautilus.game.arcade.game.games.castleassault; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.Chest; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.EnderPearl; +import org.bukkit.entity.Entity; +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.Painting; +import org.bukkit.entity.Player; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockDispenseEvent; +import org.bukkit.event.block.BlockFadeEvent; +import org.bukkit.event.block.BlockFormEvent; +import org.bukkit.event.block.BlockFromToEvent; +import org.bukkit.event.block.LeavesDecayEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.ExplosionPrimeEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.entity.ProjectileHitEvent; +import org.bukkit.event.hanging.HangingBreakEvent; +import org.bukkit.event.inventory.InventoryAction; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.inventory.PrepareItemCraftEvent; +import org.bukkit.event.player.PlayerBucketEmptyEvent; +import org.bukkit.event.player.PlayerBucketFillEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.material.Dispenser; +import org.bukkit.material.MaterialData; +import org.bukkit.metadata.MetadataValue; + +import mineplex.core.Managers; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilEvent; +import mineplex.core.common.util.UtilEvent.ActionType; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.leaderboard.LeaderboardManager; +import mineplex.core.loot.ChestLoot; +import mineplex.core.recharge.Recharge; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.minecraft.game.core.combat.DeathMessageType; +import mineplex.minecraft.game.core.combat.event.CombatDeathEvent; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.GameType; +import nautilus.game.arcade.events.FirstBloodEvent; +import nautilus.game.arcade.events.GameStateChangeEvent; +import nautilus.game.arcade.game.GameTeam; +import nautilus.game.arcade.game.GemData; +import nautilus.game.arcade.game.TeamGame; +import nautilus.game.arcade.game.games.castleassault.data.KillStreakData; +import nautilus.game.arcade.game.games.castleassault.kits.KitArcher; +import nautilus.game.arcade.game.games.castleassault.kits.KitDemolitionist; +import nautilus.game.arcade.game.games.castleassault.kits.KitFighter; +import nautilus.game.arcade.game.games.castleassault.kits.KitPlayer; +import nautilus.game.arcade.game.games.castleassault.kits.KitTank; +import nautilus.game.arcade.game.modules.compass.CompassModule; +import nautilus.game.arcade.kit.Kit; + +public class CastleAssaultTDM extends TeamGame +{ + private static final int MAX_FLINT_AND_STEEL_USES = 4; + private static final int ITEMS_PER_CHEST = 5; + private static final long TIME_TILL_REFILL = 2 * 60 * 1000; + + private long _lastRefill; + + private ItemBuilder _flintAndSteel; + + private Map _streakData = new WeakHashMap<>(); + private Map _teamKills = new HashMap<>(); + + private List _chests = new ArrayList<>(); + + private ChestLoot _rangedGear = new ChestLoot(true); + private ChestLoot _rodsAndGaps = new ChestLoot(true); + private ChestLoot _potionGearCommon = new ChestLoot(true); + private ChestLoot _potionGearRare = new ChestLoot(true); + private ChestLoot _miscGear = new ChestLoot(); + + private boolean _writeScoreboard = true; + + @SuppressWarnings("deprecation") + public CastleAssaultTDM(ArcadeManager manager) + { + super(manager, GameType.CastleAssaultTDM, + new Kit[] + { + //new KitAlchemist(manager), + new KitArcher(manager), + new KitDemolitionist(manager), + //new KitEnchanter(manager), + new KitFighter(manager), + //new KitHardline(manager), + //new KitNinja(manager), + new KitTank(manager) + }, + new String[] {"AlexTheCoder is awesome!"}); + + this.StrictAntiHack = true; + this.HungerSet = 20; + this.DeathOut = false; + this.DeathSpectateSecs = 5; + this.CreatureAllow = false; + this.DeathDropItems = false; + this.WorldWeatherEnabled = false; + this.AllowParticles = false; + this.SoupEnabled = false; + this.InventoryClick = true; + this.InventoryOpenChest = true; + this.InventoryOpenBlock = true; + this.ItemDrop = true; + this.ItemPickup = true; + this.AllowFlintAndSteel = true; + this.BlockPlaceAllow.add(Material.FIRE.getId()); + this.CrownsEnabled = true; + this.FirstKillReward = 20; + this.GemKillDeathRespawn = 1; + + new CompassModule() + .setGiveCompass(true) + .setGiveCompassToSpecs(true) + .setGiveCompassToAlive(false) + .register(this); + + _flintAndSteel = new ItemBuilder(Material.FLINT_AND_STEEL).setData((short) (Material.FLINT_AND_STEEL.getMaxDurability() - MAX_FLINT_AND_STEEL_USES)); + generateLoot(); + +// if (manager.IsRewardStats()) +// { +// if (manager.GetLobby() instanceof NewGameLobbyManager) +// { +// Map> lobbyCustomLocs = ((NewGameLobbyManager)manager.GetLobby()).getCustomLocs(); +// if (lobbyCustomLocs.containsKey("TOP_DAILY_WINS")) +// { +// Location loc = lobbyCustomLocs.get("TOP_DAILY_WINS").get(0); +// Managers.get(LeaderboardManager.class).registerLeaderboard("TOP_CASTLEASSAULT_DAILY_WINS", new Leaderboard("Top Daily Wins", Pair.create("Win", "Wins"), new String[] {"Castle Assault TDM.Wins"}, LeaderboardSQLType.DAILY_SEASON, loc, 10)); +// } +// if (lobbyCustomLocs.containsKey("TOP_DAILY_KILLS")) +// { +// Location loc = lobbyCustomLocs.get("TOP_DAILY_KILLS").get(0); +// Managers.get(LeaderboardManager.class).registerLeaderboard("TOP_CASTLEASSAULT_DAILY_KILLS", new Leaderboard("Top Daily Kills", Pair.create("Kill", "Kills"), new String[] {"Castle Assault TDM.Kills"}, LeaderboardSQLType.DAILY_SEASON, loc, 10)); +// } +// if (lobbyCustomLocs.containsKey("TOP_WINS")) +// { +// Location loc = lobbyCustomLocs.get("TOP_WINS").get(0); +// Managers.get(LeaderboardManager.class).registerLeaderboard("TOP_CASTLEASSAULT_WINS", new Leaderboard("Top Wins", Pair.create("Win", "Wins"), new String[] {"Castle Assault TDM.Wins"}, LeaderboardSQLType.ALL_SEASON, loc, 10)); +// } +// if (lobbyCustomLocs.containsKey("TOP_KILLS")) +// { +// Location loc = lobbyCustomLocs.get("TOP_KILLS").get(0); +// Managers.get(LeaderboardManager.class).registerLeaderboard("TOP_CASTLEASSAULT_KILLS", new Leaderboard("Top Kills", Pair.create("Kill", "Kills"), new String[] {"Castle Assault TDM.Kills"}, LeaderboardSQLType.ALL_SEASON, loc, 10)); +// } +// } +// } + } + + private void generateLoot() + { + { + _rangedGear.addLoot(new ItemStack(Material.BOW), 3); + _rangedGear.addLoot(Material.ARROW, 3, 8, 16); + } + { + _rodsAndGaps.addLoot(new ItemStack(Material.FISHING_ROD), 3); + _rodsAndGaps.addLoot(new ItemBuilder(Material.GOLDEN_APPLE).setTitle(C.cPurple + "Golden Applegate").build(), 3); + } + { + _potionGearCommon.addLoot(new ItemBuilder(Material.POTION).setData((short)16418).build(), 2); + _potionGearCommon.addLoot(new ItemBuilder(Material.POTION).setData((short)16417).build(), 2); + } + { + _potionGearRare.addLoot(new ItemBuilder(Material.POTION).setData((short)8193).build(), 2); + _potionGearRare.addLoot(new ItemBuilder(Material.POTION).setData((short)8195).build(), 2); + } + { + _miscGear.addLoot(new ItemStack(Material.ENDER_PEARL), 2); + _miscGear.addLoot(new ItemStack(Material.WATER_BUCKET), 2); + _miscGear.addLoot(_flintAndSteel.build(), 2); + _miscGear.addLoot(new ItemStack(Material.SNOW_BALL, 16), 3); + } + } + + private void fillChest(Block block) + { + if (block.getType() != Material.CHEST && block.getType() != Material.TRAPPED_CHEST) + { + return; + } + Chest chest = (Chest) block.getState(); + + chest.getBlockInventory().clear(); + int[] slots = UtilMath.random.ints(ITEMS_PER_CHEST, 0, chest.getBlockInventory().getSize()).toArray(); + + for (int slot : slots) + { + double chance = UtilMath.random.nextDouble(); + double subChance = UtilMath.random.nextDouble(); + + ChestLoot loot = _miscGear; + if (chance <= 0.6) + { + loot = _rodsAndGaps; + } + if (chance <= 0.5) + { + loot = _potionGearCommon; + if (subChance <= 0.45) + { + loot = _potionGearRare; + } + } + if (chance <= 0.3) + { + loot = _rangedGear; + } + chest.getBlockInventory().setItem(slot, loot.getLoot()); + } + } + + public ItemStack getNewFlintAndSteel(boolean kitItem) + { + if (kitItem) + { + return _flintAndSteel.clone().setLore(C.cGold + "Kit Item").build(); + } + return _flintAndSteel.build(); + } + + public void writeScoreboard() + { + if (!_writeScoreboard) + { + return; + } + Scoreboard.reset(); + Scoreboard.write(C.cDRedB + GetName()); + Scoreboard.writeNewLine(); + Scoreboard.write(C.cGreenB + "Chest Refill"); + long refillTime = _lastRefill + TIME_TILL_REFILL - System.currentTimeMillis(); + if (!IsLive()) + { + refillTime = TIME_TILL_REFILL; + } + Scoreboard.write(UtilTime.MakeStr(refillTime)); + Scoreboard.writeNewLine(); + GameTeam red = GetTeam(ChatColor.RED); + GameTeam blue = GetTeam(ChatColor.AQUA); + Scoreboard.write(red.GetFormattedName() + " Team Kills"); + Scoreboard.write(_teamKills.get(red) + "/50"); + Scoreboard.writeNewLine(); + Scoreboard.write(blue.GetFormattedName() + " Team Kills"); + Scoreboard.write(_teamKills.get(blue) + "/50"); + Scoreboard.draw(); + } + + public void writeFinalScoreboard(String winner, int kills) + { + _writeScoreboard = false; + Scoreboard.reset(); + Scoreboard.writeNewLine(); + Scoreboard.write(winner + C.cWhite + " has won"); + Scoreboard.write(C.cWhite + "with " + C.cGreen + kills + C.cWhite + " kills!"); + Scoreboard.writeNewLine(); + + Scoreboard.draw(); + } + + @Override + public void ParseData() + { + for (Location chestLoc : WorldData.GetDataLocs("BROWN")) + { + Block block = chestLoc.getBlock(); + block.setType(Material.CHEST); + fillChest(block); + _chests.add(block); + } + GameTeam red = GetTeam(ChatColor.RED); + _teamKills.put(red, 0); + GameTeam blue = GetTeam(ChatColor.AQUA); + _teamKills.put(blue, 0); + this.CreatureAllowOverride = true; + for (Kit kit : GetKits()) + { + List spawns = WorldData.GetCustomLocs(kit.GetName().toUpperCase()); + for (Location spawn : spawns) + { + Entity ent = kit.SpawnEntity(spawn); + Manager.GetLobby().addKitLocation(ent, kit, spawn); + } + } + this.CreatureAllowOverride = false; + } + + @Override + public void EndCheck() + { + if (!IsLive()) + { + return; + } + + List teamsAlive = new ArrayList<>(); + + for (GameTeam team : GetTeamList()) + { + if (team.GetPlayers(true).size() > 0) + { + teamsAlive.add(team); + } + } + + if (teamsAlive.size() <= 1) + { + //Announce + if (teamsAlive.size() > 0) + { + GameTeam winner = teamsAlive.get(0); + AnnounceEnd(winner); + writeFinalScoreboard(winner.GetColor() + winner.GetName(), _teamKills.get(winner)); + for (GameTeam team : GetTeamList()) + { + for (Player player : team.GetPlayers(true)) + { + if (team.GetColor() == winner.GetColor()) + { + AddGems(player, 100, "Winning Team", false, false); + } + else + { + AddGems(player, 50, "Losing Team", false, false); + } + if (player.isOnline()) + { + AddGems(player, 10, "Participation", false, false); + } + + { + int crowns = 0; + for (GemData data : GetGems(player).values()) + { + crowns += data.Gems; + } + int streak = _streakData.getOrDefault(player, new KillStreakData()).getBestStreak(); + if (streak >= 2 && streak < 4) + { + AddGems(player, 0.5 * crowns, streak + " Player Kill Streak", false, false); + } + else if (streak >= 4 && streak < 6) + { + AddGems(player, crowns, streak + " Player Kill Streak", false, false); + } + else if (streak >= 6 && streak < 8) + { + AddGems(player, 1.5 * crowns, streak + " Player Kill Streak", false, false); + } + else if (streak >= 8) + { + AddGems(player, 2 * crowns, streak + " Player Kill Streak", false, false); + } + } + + if (GetKit(player) != null) + { + KitPlayer kit = (KitPlayer) GetKit(player); + int kitLevel = kit.getUpgradeLevel(player.getUniqueId()); + if (kitLevel > 0) + { + int crowns = 0; + for (GemData data : GetGems(player).values()) + { + crowns += data.Gems; + } + + AddGems(player, (0.5 * kitLevel) * crowns, kit.GetName() + " Kit Level Bonus", false, false); + } + } + } + } + SetState(GameState.End); + return; + } + } + } + + @Override + @EventHandler + public void ScoreboardUpdate(UpdateEvent event) {}; + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + { + return; + } + if (IsLive()) + { + if (UtilTime.elapsed(_lastRefill, TIME_TILL_REFILL)) + { + _lastRefill = System.currentTimeMillis(); + _chests.forEach(this::fillChest); + Bukkit.broadcastMessage(C.cGreenB + "Chests have refilled!"); + } + + GameTeam red = GetTeam(ChatColor.RED); + GameTeam blue = GetTeam(ChatColor.AQUA); + if (_teamKills.get(blue).intValue() >= 50) + { + AnnounceEnd(blue); + writeFinalScoreboard(blue.GetColor() + blue.GetName(), _teamKills.get(blue)); + for (GameTeam team : GetTeamList()) + { + for (Player player : team.GetPlayers(true)) + { + if (team.GetColor() == ChatColor.AQUA) + { + AddGems(player, 100, "Winning Team", false, false); + } + else + { + AddGems(player, 50, "Losing Team", false, false); + } + if (player.isOnline()) + { + AddGems(player, 10, "Participation", false, false); + } + + { + int crowns = 0; + for (GemData data : GetGems(player).values()) + { + crowns += data.Gems; + } + int streak = _streakData.getOrDefault(player, new KillStreakData()).getBestStreak(); + if (streak >= 2 && streak < 4) + { + AddGems(player, 0.5 * crowns, streak + " Player Kill Streak", false, false); + } + else if (streak >= 4 && streak < 6) + { + AddGems(player, crowns, streak + " Player Kill Streak", false, false); + } + else if (streak >= 6 && streak < 8) + { + AddGems(player, 1.5 * crowns, streak + " Player Kill Streak", false, false); + } + else if (streak >= 8) + { + AddGems(player, 2 * crowns, streak + " Player Kill Streak", false, false); + } + } + + KitPlayer kit = (KitPlayer) GetKit(player); + int kitLevel = kit.getUpgradeLevel(player.getUniqueId()); + if (kitLevel > 0) + { + int crowns = 0; + for (GemData data : GetGems(player).values()) + { + crowns += data.Gems; + } + + AddGems(player, (0.5 * kitLevel) * crowns, kit.GetName() + " Kit Level Bonus", false, false); + } + } + } + SetState(GameState.End); + return; + } + if (_teamKills.get(red).intValue() >= 50) + { + AnnounceEnd(red); + writeFinalScoreboard(red.GetColor() + red.GetName(), _teamKills.get(red)); + for (GameTeam team : GetTeamList()) + { + for (Player player : team.GetPlayers(true)) + { + if (team.GetColor() == ChatColor.RED) + { + AddGems(player, 100, "Winning Team", false, false); + } + else + { + AddGems(player, 50, "Losing Team", false, false); + } + if (player.isOnline()) + { + AddGems(player, 10, "Participation", false, false); + } + + { + int crowns = 0; + for (GemData data : GetGems(player).values()) + { + crowns += data.Gems; + } + int streak = _streakData.getOrDefault(player, new KillStreakData()).getBestStreak(); + if (streak >= 2 && streak < 4) + { + AddGems(player, 0.5 * crowns, streak + " Player Kill Streak", false, false); + } + else if (streak >= 4 && streak < 6) + { + AddGems(player, crowns, streak + " Player Kill Streak", false, false); + } + else if (streak >= 6 && streak < 8) + { + AddGems(player, 1.5 * crowns, streak + " Player Kill Streak", false, false); + } + else if (streak >= 8) + { + AddGems(player, 2 * crowns, streak + " Player Kill Streak", false, false); + } + } + + KitPlayer kit = (KitPlayer) GetKit(player); + int kitLevel = kit.getUpgradeLevel(player.getUniqueId()); + if (kitLevel > 0) + { + int crowns = 0; + for (GemData data : GetGems(player).values()) + { + crowns += data.Gems; + } + + AddGems(player, (0.5 * kitLevel) * crowns, kit.GetName() + " Kit Level Bonus", false, false); + } + } + } + SetState(GameState.End); + return; + } + } + if (InProgress()) + { + writeScoreboard(); + } + } + + @EventHandler + public void onEditSettings(GameStateChangeEvent event) + { + if (event.GetGame() != this) + { + return; + } + + if (event.GetState() == GameState.Live) + { + _lastRefill = System.currentTimeMillis(); + Manager.GetDamage().SetEnabled(false); + Manager.GetExplosion().setEnabled(false); + Manager.GetCreature().SetDisableCustomDrops(true); + } + + if (event.GetState() == GameState.End) + { + Manager.GetDamage().SetEnabled(true); + Manager.GetExplosion().setEnabled(true); + Manager.GetCreature().SetDisableCustomDrops(false); + Managers.get(LeaderboardManager.class).unregisterLeaderboard("TOP_CASTLEASSAULT_DAILY_WINS"); + Managers.get(LeaderboardManager.class).unregisterLeaderboard("TOP_CASTLEASSAULT_DAILY_KILLS"); + Managers.get(LeaderboardManager.class).unregisterLeaderboard("TOP_CASTLEASSAULT_WINS"); + Managers.get(LeaderboardManager.class).unregisterLeaderboard("TOP_CASTLEASSAULT_KILLS"); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void handleDeath(CombatDeathEvent event) + { + if (!IsLive()) + { + return; + } + + event.SetBroadcastType(DeathMessageType.Detailed); + } + + @EventHandler + public void disableDamageLevel(CustomDamageEvent event) + { + event.SetDamageToLevel(false); + } + + @EventHandler + public void BlockFade(BlockFadeEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void BlockBurn(BlockBurnEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void BlockDecay(LeavesDecayEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void hangingBreak(HangingBreakEvent event) + { + if (event.getEntity() instanceof ItemFrame || event.getEntity() instanceof Painting) + { + event.setCancelled(true); + } + } + + @EventHandler + public void noFlow(BlockFromToEvent event) + { + if (!IsLive()) + { + return; + } + + Block block = event.getBlock(); + if (block.getType() == Material.WATER || block.getType() == Material.STATIONARY_WATER || block.getType() == Material.LAVA || block.getType() == Material.STATIONARY_LAVA) + { + event.setCancelled(true); + } + if (event.getToBlock().getType() == Material.ICE) + { + event.setCancelled(true); + } + } + + @EventHandler + public void onBlockChange(BlockFormEvent e) + { + if (!IsLive()) + { + return; + } + if (e.getNewState().getType() == Material.ICE) + { + e.setCancelled(true); + } + } + + @SuppressWarnings("deprecation") + @EventHandler(ignoreCancelled=true) + public void onPlayerEmptyBucket(PlayerBucketEmptyEvent event) + { + if (!IsLive()) + { + return; + } + + Player player = event.getPlayer(); + if (player.getItemInHand().getType() == Material.WATER_BUCKET) + { + player.getItemInHand().setType(Material.BUCKET); + Block block = event.getBlockClicked().getRelative(event.getBlockFace()); + if (block.getType().toString().contains("LAVA") || (block.getType().toString().contains("WATER") && block.getType() != Material.WATER_LILY)) + { + event.setCancelled(true); + player.sendBlockChange(block.getLocation(), block.getType(), block.getData()); + return; + } + for (BlockFace bf : BlockFace.values()) + { + Block relative = block.getRelative(bf); + if (relative.getType().toString().contains("LAVA") || (relative.getType().toString().contains("WATER") && relative.getType() != Material.WATER_LILY)) + { + event.setCancelled(true); + player.sendBlockChange(block.getLocation(), block.getType(), block.getData()); + } + } + } + else if (player.getItemInHand().getType() == Material.LAVA_BUCKET) + { + event.setCancelled(true); + Block block = event.getBlockClicked().getRelative(event.getBlockFace()); + player.sendBlockChange(block.getLocation(), block.getType(), block.getData()); + } + } + + @SuppressWarnings("deprecation") + @EventHandler(ignoreCancelled=true) + public void onPlayerFillBucket(PlayerBucketFillEvent event) + { + if (!IsLive()) + { + return; + } + + Player player = event.getPlayer(); + Block block = event.getBlockClicked().getRelative(event.getBlockFace()); + if (block.getType() == Material.LAVA || block.getType() == Material.STATIONARY_LAVA) + { + event.setCancelled(true); + player.sendBlockChange(block.getLocation(), block.getType(), block.getData()); + } + } + + @EventHandler(ignoreCancelled=true) + public void onBlockDispense(BlockDispenseEvent event) + { + if (!IsLive()) + { + return; + } + + if (event.getItem().getType() == Material.WATER_BUCKET) + { + Block dispenser = event.getBlock(); + + MaterialData mat = dispenser.getState().getData(); + Dispenser disp_mat = (Dispenser)mat; + BlockFace face = disp_mat.getFacing(); + Block block = dispenser.getRelative(face); + if (block.getType().toString().contains("LAVA") || (block.getType().toString().contains("WATER") && block.getType() != Material.WATER_LILY)) + { + event.setCancelled(true); + return; + } + for (BlockFace bf : BlockFace.values()) + { + if (block.getRelative(bf).getType().toString().contains("LAVA") || (block.getRelative(bf).getType().toString().contains("WATER") && block.getRelative(bf).getType() != Material.WATER_LILY)) + { + event.setCancelled(true); + } + } + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onCombatDeath(CombatDeathEvent event) + { + if (!IsLive()) + { + return; + } + + if (event.GetLog().GetKiller() == null) + { + return; + } + + if (!event.GetLog().GetKiller().IsPlayer()) + { + return; + } + + Player player = UtilPlayer.searchExact(event.GetLog().GetKiller().GetName()); + if (player == null) + { + return; + } + + AddStat(player, GetKit(player).GetName() + "KitKills", 1, false, false); + _teamKills.merge(GetTeam(player), 1, Integer::sum); + + if (UtilPlayer.isSpectator(player)) + { + return; + } + + player.setLevel(player.getLevel() + 1); + player.getInventory().addItem(new ItemBuilder(Material.GOLDEN_APPLE).setTitle(C.cPurple + "Golden Applegate").build()); + KillStreakData data = _streakData.computeIfAbsent(player, (key) -> new KillStreakData()); + boolean hardLine = GetKit(player).GetName().equals("Hardline"); + if (data.addKill(hardLine)) + { + AddStat(player, "KillStreak", 1, false, false); + ((KitPlayer)GetKit(player)).awardKillStreak(player, hardLine ? (data.getKills() + 1) : data.getKills()); + } + if (UtilMath.isEven(data.getKills())) + { + Bukkit.broadcastMessage(F.main("Game", C.cGreen + C.Bold + player.getName() + ChatColor.RESET + " is on a " + F.elem(C.cDPurple + data.getKills() + " player Kill Streak") + "!")); + } + } + + @EventHandler + public void TNTExplosion(ExplosionPrimeEvent event) + { + if (!event.getEntity().hasMetadata("THROWER")) + { + return; + } + + float radius = event.getRadius(); + event.setRadius(0f); + + Player player = UtilPlayer.searchExact(((MetadataValue)UtilEnt.GetMetadata(event.getEntity(), "THROWER")).asString()); + if (player == null) + { + return; + } + if (GetTeam(player) == null) + { + return; + } + + if (GetKit(player).GetName().equals("Demolitionist")) + { + radius += 3; + } + + Map nearby = UtilPlayer.getInRadius(event.getEntity().getLocation(), radius); + for (Player near : nearby.keySet()) + { + if (UtilPlayer.isSpectator(near)) + { + continue; + } + if (near.getEntityId() != player.getEntityId() && GetTeam(near).GetColor() == GetTeam(player).GetColor()) + { + continue; + } + + double mult = nearby.get(near); + + int highestBlastProt = 0; + int blastProtEPF = 0; + for (ItemStack item : near.getInventory().getArmorContents()) + { + if (item != null && item.getEnchantments().containsKey(Enchantment.PROTECTION_EXPLOSIONS)) + { + blastProtEPF += (2 * item.getEnchantmentLevel(Enchantment.PROTECTION_EXPLOSIONS)); + if (item.getEnchantmentLevel(Enchantment.PROTECTION_EXPLOSIONS) > highestBlastProt) + { + highestBlastProt = item.getEnchantmentLevel(Enchantment.PROTECTION_EXPLOSIONS); + } + } + } + blastProtEPF = Math.min(blastProtEPF, 20); + + double damage = 8 * mult; + damage = damage * (1 - (blastProtEPF / 25)); + + double knockbackReduction = 1 - (highestBlastProt * 0.15); + + near.damage(damage, event.getEntity()); + UtilAction.velocity(near, UtilAlg.getTrajectory(event.getEntity().getLocation(), near.getLocation()), 1 * mult * knockbackReduction, false, 0, mult * knockbackReduction, 10, true); + } + } + + @EventHandler + public void TNTThrow(PlayerInteractEvent event) + { + if (!IsLive()) + { + return; + } + + if (!UtilEvent.isAction(event, ActionType.L)) + { + return; + } + + Player player = event.getPlayer(); + + if (!UtilInv.IsItem(player.getItemInHand(), Material.TNT, (byte) 0)) + { + return; + } + + if (!IsAlive(player)) + { + return; + } + + event.setCancelled(true); + + if (!Manager.GetGame().CanThrowTNT(player.getLocation())) + { + // Inform + UtilPlayer.message(event.getPlayer(), F.main(GetName(), "You cannot use " + F.item("Throwing TNT") + " here.")); + return; + } + + UtilInv.remove(player, Material.TNT, (byte) 0, 1); + UtilInv.Update(player); + + TNTPrimed tnt = player.getWorld().spawn(player.getEyeLocation().add(player.getLocation().getDirection()), TNTPrimed.class); + + tnt.setFuseTicks(60); + + double throwMult = 1; + + if (GetKit(player).GetName().equals("Demolitionist")) + { + throwMult = ((KitDemolitionist)GetKit(player)).getThrowMultiplier(player); + } + + UtilAction.velocity(tnt, player.getLocation().getDirection(), 0.5 * throwMult, false, 0, 0.1, 10, false); + + UtilEnt.SetMetadata(tnt, "THROWER", player.getName()); + } + + @EventHandler + public void onLaunch(ProjectileHitEvent event) + { + if (!IsLive()) + { + return; + } + + if (event.getEntity() instanceof EnderPearl && event.getEntity().getShooter() != null && event.getEntity().getShooter() instanceof Entity) + { + Entity shooter = (Entity) event.getEntity().getShooter(); + Location teleport = event.getEntity().getLocation(); + teleport.setPitch(shooter.getLocation().getPitch()); + teleport.setYaw(shooter.getLocation().getYaw()); + shooter.teleport(teleport); + } + if (event.getEntity() instanceof Arrow) + { + Manager.runSyncLater(event.getEntity()::remove, 1L); + } + } + + @EventHandler + public void onOpenChest(PlayerInteractEvent event) + { + if (!IsLive()) + { + return; + } + + if (event.getClickedBlock() != null && event.getClickedBlock().getType() == Material.CHEST) + { + if (UtilPlayer.isSpectator(event.getPlayer())) + { + event.setCancelled(true); + } + } + } + + @EventHandler + public void onDrop(PlayerDropItemEvent event) + { + if (!IsLive()) + { + return; + } + + ItemStack drop = event.getItemDrop().getItemStack(); + if (drop.hasItemMeta() && drop.getItemMeta().hasLore() && drop.getItemMeta().getLore().stream().map(ChatColor::stripColor).anyMatch(lore -> lore.equals("Kit Item"))) + { + event.setCancelled(true); + return; + } + + event.getItemDrop().remove(); + } + + @EventHandler + public void craftItem(PrepareItemCraftEvent event) + { + if (!IsLive()) + { + return; + } + + if (event.getInventory().getResult().getType() == Material.FLINT_AND_STEEL) + { + event.getInventory().setResult(_flintAndSteel.build()); + } + } + + @EventHandler + public void onInvClick(InventoryClickEvent event) + { + if (!IsLive()) + { + return; + } + if (event.getView().getTopInventory() != null && event.getView().getTopInventory().getType() == InventoryType.CHEST) + { + ItemStack current = event.getCurrentItem(); + if (event.getAction() == InventoryAction.HOTBAR_SWAP || event.getAction() == InventoryAction.HOTBAR_MOVE_AND_READD) + { + current = event.getWhoClicked().getInventory().getItem(event.getHotbarButton()); + } + + if (current != null && current.hasItemMeta()) + { + if (current.getItemMeta().hasLore()) + { + for (String lore : current.getItemMeta().getLore()) + { + if (ChatColor.stripColor(lore).equalsIgnoreCase("Kit Item")) + { + event.setCancelled(true); + break; + } + } + } + } + } + } + + @EventHandler + public void onFirstBlood(FirstBloodEvent event) + { + if (!IsLive()) + { + return; + } + + AddStat(event.getPlayer(), "FirstBlood", 1, true, false); + } + + @EventHandler + public void onPearl(PlayerInteractEvent event) + { + if (!IsLive()) + { + return; + } + + if (!UtilEvent.isAction(event, ActionType.R)) + { + return; + } + + if (event.getItem() != null && event.getItem().getType() == Material.ENDER_PEARL) + { + Player player = (Player) event.getPlayer(); + if (!Recharge.Instance.use(player, "Enderpearl", 4000, true, true)) + { + event.setCancelled(true); + player.updateInventory(); + } + } + } + + @EventHandler + public void onDeath(PlayerDeathEvent event) + { + Player player = event.getEntity(); + + _streakData.getOrDefault(player, new KillStreakData()).reset(); + } + + @EventHandler(ignoreCancelled = true) + public void onDamage(EntityDamageEvent event) + { + if (!IsLive()) + { + return; + } + if (Manager.GetLobby().getKits().containsKey(event.getEntity())) + { + event.setCancelled(true); + return; + } + } +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/data/CapturePoint.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/data/CapturePoint.java new file mode 100644 index 000000000..43709f165 --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/data/CapturePoint.java @@ -0,0 +1,71 @@ +package nautilus.game.arcade.game.games.castleassault.data; + +import org.bukkit.Location; +import org.bukkit.entity.Player; + +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import nautilus.game.arcade.game.GameTeam; + +public class CapturePoint +{ + private static final int POINTS_TO_CAPTURE = 100; + private static final long TIME_PER_POINT = 1000; + private static final int POINTS_PER_TICK = 1; + + private Location _loc; + + private long _lastCap; + private int _points = 0; + private GameTeam _owner = null; + + public CapturePoint(GameTeam owner, Location loc) + { + _owner = owner; + + _loc = loc; + } + + public int getMaxPoints() + { + return POINTS_TO_CAPTURE; + } + + public int getPoints() + { + return _points; + } + + public boolean isCaptured() + { + return _points >= POINTS_TO_CAPTURE; + } + + public void update() + { + if (!UtilTime.elapsed(_lastCap, TIME_PER_POINT)) + { + return; + } + + int capping = 0; + for (Player player : UtilPlayer.getInRadius(_loc, 3.5).keySet()) + { + if (UtilPlayer.isSpectator(player)) + { + continue; + } + if (_owner.HasPlayer(player)) + { + continue; + } + capping++; + } + + if (capping > 0 && _points < POINTS_TO_CAPTURE) + { + _lastCap = System.currentTimeMillis(); + _points += POINTS_PER_TICK; + } + } +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/data/KillStreakData.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/data/KillStreakData.java new file mode 100644 index 000000000..1e86d8266 --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/data/KillStreakData.java @@ -0,0 +1,47 @@ +package nautilus.game.arcade.game.games.castleassault.data; + +public class KillStreakData +{ + private static final int[] REWARDED_STREAKS = {2, 4, 6, 8}; + private int _kills; + private int _bestStreak; + + public KillStreakData() + { + _kills = 0; + _bestStreak = 0; + } + + public int getKills() + { + return _kills; + } + + public int getBestStreak() + { + return Math.max(_bestStreak, _kills); + } + + public boolean addKill(boolean hardLine) + { + _kills++; + for (int streak : REWARDED_STREAKS) + { + if ((_kills + (hardLine ? 1 : 0)) == streak) + { + return true; + } + } + + return false; + } + + public void reset() + { + if (_kills > _bestStreak) + { + _bestStreak = _kills; + } + _kills = 0; + } +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/data/ObjectiveTNTSpawner.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/data/ObjectiveTNTSpawner.java new file mode 100644 index 000000000..076913cf1 --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/data/ObjectiveTNTSpawner.java @@ -0,0 +1,100 @@ +package nautilus.game.arcade.game.games.castleassault.data; + +import java.util.List; + +import org.bukkit.Color; +import org.bukkit.FireworkEffect.Type; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Item; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilTime; + +public class ObjectiveTNTSpawner +{ + private static final long TNT_SPAWN_DELAY = 60000; + private List _locs; + private Location _lastSpawnLoc; + private Item _entity; + private long _lastPickedUp; + + public ObjectiveTNTSpawner(List locs) + { + _locs = locs; + _lastSpawnLoc = null; + _entity = null; + _lastPickedUp = System.currentTimeMillis(); + } + + public Item getItem() + { + return _entity; + } + + public boolean isSpawned() + { + return _entity != null; + } + + public boolean canPlaceFireAt(Block block) + { + for (Location loc : _locs) + { + if (UtilMath.offsetSquared(loc, block.getLocation()) <= 9) + { + return false; + } + } + + return true; + } + + public long getNextTNT() + { + return (_lastPickedUp + TNT_SPAWN_DELAY) - System.currentTimeMillis(); + } + + public void spawn() + { + Location spawn = _locs.get(UtilMath.r(_locs.size())); + spawn.getBlock().getRelative(BlockFace.DOWN).setType(Material.REDSTONE_BLOCK); + _lastSpawnLoc = spawn.clone(); + _entity = spawn.getWorld().dropItem(spawn, new ItemStack(Material.TNT)); + UtilFirework.playFirework(spawn, Type.BURST, Color.RED, false, false); + } + + public void pickup() + { + _entity.getLocation().getBlock().getRelative(BlockFace.DOWN).setType(Material.IRON_BLOCK); + _entity.remove(); + _entity = null; + _lastSpawnLoc = null; + _lastPickedUp = System.currentTimeMillis(); + } + + public void update() + { + if (!isSpawned() && UtilTime.elapsed(_lastPickedUp, TNT_SPAWN_DELAY)) + { + spawn(); + } + else if (isSpawned()) + { + _entity.teleport(_lastSpawnLoc); + if (!_entity.isValid() || _entity.isDead()) + { + _entity = _lastSpawnLoc.getWorld().dropItem(_lastSpawnLoc, new ItemStack(Material.TNT)); + } + } + } + + public void onStart() + { + _lastPickedUp = System.currentTimeMillis(); + } +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/data/TeamCrystal.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/data/TeamCrystal.java new file mode 100644 index 000000000..e44bc9e9a --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/data/TeamCrystal.java @@ -0,0 +1,54 @@ +package nautilus.game.arcade.game.games.castleassault.data; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.EnderCrystal; + +import nautilus.game.arcade.game.GameTeam; + +public class TeamCrystal +{ + private Location _loc; + private GameTeam _owner; + private EnderCrystal _crystal; + private boolean _destroyed; + + public TeamCrystal(GameTeam owner, Location loc) + { + _owner = owner; + _loc = loc; + + spawn(); + } + + public GameTeam getOwner() + { + return _owner; + } + + public Location getLocation() + { + return _loc; + } + + public boolean isActive() + { + return !_destroyed; + } + + public void spawn() + { + _destroyed = false; + _crystal = _loc.getWorld().spawn(_loc, EnderCrystal.class); + _loc.getBlock().getRelative(0, -2, 0).setType(Material.BEACON); + } + + public void destroy() + { + _destroyed = true; + _crystal.remove(); + _crystal = null; + _loc.getBlock().getRelative(0, -2, 0).setType(Material.SMOOTH_BRICK); + } +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/data/TeamKing.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/data/TeamKing.java new file mode 100644 index 000000000..af9fad64a --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/data/TeamKing.java @@ -0,0 +1,122 @@ +package nautilus.game.arcade.game.games.castleassault.data; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Zombie; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilTime; +import mineplex.core.itemstack.ItemBuilder; +import nautilus.game.arcade.game.GameTeam; + +public class TeamKing +{ + private static final int MAX_HEALTH = 600; + private Location _loc; + private String _name; + private GameTeam _owner; + private Zombie _entity; + private int _health; + private String _lastDamager; + private long _lastDamage; + + public TeamKing(GameTeam owner, String name, Location loc) + { + _owner = owner; + _loc = loc; + _name = name; + _health = MAX_HEALTH; + _entity = (Zombie) loc.getWorld().spawnEntity(loc, EntityType.ZOMBIE); + UtilEnt.vegetate(_entity, true); + _entity.getEquipment().setHelmet(new ItemBuilder(Material.DIAMOND_HELMET).setUnbreakable(true).build()); + _entity.getEquipment().setChestplate(new ItemBuilder(Material.DIAMOND_CHESTPLATE).setUnbreakable(true).build()); + _entity.getEquipment().setLeggings(new ItemBuilder(Material.DIAMOND_LEGGINGS).setUnbreakable(true).build()); + _entity.getEquipment().setBoots(new ItemBuilder(Material.DIAMOND_BOOTS).setUnbreakable(true).build()); + _entity.setRemoveWhenFarAway(false); + _entity.setCustomName(owner.GetColor() + name); + } + + public GameTeam getOwner() + { + return _owner; + } + + public Location getLocation() + { + return _loc; + } + + public String getName(boolean bold) + { + return _owner.GetColor() + (bold ? C.Bold : "") + _name; + } + + public String getLastDamager() + { + return _lastDamager; + } + + public int getHealth() + { + return Math.max(_health, 0); + } + + public boolean isDead() + { + return getHealth() <= 0; + } + + public void update(boolean beaconsAlive) + { + _entity.teleport(_loc); + for (int y = 0; y <= 4; y++) + { + for (int x = -4; x <= 4; x++) + { + for (int z = -4; z <= 4; z++) + { + Block block = _loc.clone().add(x, y, z).getBlock(); + if ((block.getType() != Material.IRON_FENCE && block.getType() != Material.IRON_BLOCK) || !beaconsAlive) + { + block.setType(Material.AIR); + } + if (beaconsAlive) + { + if (x == -4 || x == 4 || z == -4 || z == 4) + { + if (y != 4) + { + block.setType(Material.IRON_FENCE); + } + } + if (y == 4) + { + block.setType(Material.IRON_BLOCK); + } + } + } + } + } + } + + public boolean handleDamage(String player, double damage) + { + if (!UtilTime.elapsed(_lastDamage, 400)) + { + return false; + } + _lastDamager = player; + _lastDamage = System.currentTimeMillis(); + + int dmg = (int)Math.ceil(damage); + + _health -= dmg; + + UtilEnt.PlayDamageSound(_entity); + + return true; + } +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/data/medals/MedalData.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/data/medals/MedalData.java new file mode 100644 index 000000000..a64e7f68c --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/data/medals/MedalData.java @@ -0,0 +1,55 @@ +package nautilus.game.arcade.game.games.castleassault.data.medals; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.ChatColor; + +import mineplex.core.common.util.C; + +public class MedalData +{ + private Map _medalScore; + + public MedalData() + { + _medalScore = new HashMap<>(); + } + + public Double getScore(MedalType type) + { + return _medalScore.computeIfAbsent(type, key -> 0D); + } + + public void addScore(MedalType kingDmg, Double score) + { + _medalScore.merge(kingDmg, score, Double::sum); + } + + public static enum MedalLevel + { + GOLD(C.cGold + "Gold", ChatColor.GOLD), + SILVER(C.cGray + "Silver", ChatColor.GRAY), + BRONZE(C.cWhite + "Bronze", ChatColor.WHITE) + ; + + private String _name; + private ChatColor _color; + + private MedalLevel(String name, ChatColor color) + { + _name = name; + _color = color; + } + + public String getName() + { + return _name; + } + + public ChatColor getColor() + { + return _color; + } + } +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/data/medals/MedalType.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/data/medals/MedalType.java new file mode 100644 index 000000000..47abb13c9 --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/data/medals/MedalType.java @@ -0,0 +1,21 @@ +package nautilus.game.arcade.game.games.castleassault.data.medals; + +public enum MedalType +{ + ELIM("Eliminations"), + KING_DMG("Damage on King"), + OBJECTIVE_KILL("Objective Kills") + ; + + private String _name; + + private MedalType(String name) + { + _name = name; + } + + public String getName() + { + return _name; + } +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitAlchemist.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitAlchemist.java new file mode 100644 index 000000000..d42c40ae0 --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitAlchemist.java @@ -0,0 +1,32 @@ +package nautilus.game.arcade.game.games.castleassault.kits; + +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import mineplex.core.itemstack.ItemBuilder; +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.kit.KitAvailability; +import nautilus.game.arcade.kit.Perk; + +public class KitAlchemist extends KitPlayer +{ + public KitAlchemist(ArcadeManager manager) + { + super(manager, "Alchemist", KitAvailability.Free, new String[] {}, new Perk[] {}, Material.POTION); + } + + @Override + public void GiveItems(Player player) + { + player.getInventory().setItem(0, new ItemBuilder(Material.IRON_SWORD).setUnbreakable(true).build()); + player.getInventory().setItem(1, new ItemBuilder(Material.POTION).setData((short)8194).build()); + player.getInventory().setItem(2, new ItemBuilder(Material.POTION).setData((short)8193).build()); + player.getInventory().setHelmet(new ItemBuilder(Material.IRON_HELMET).setUnbreakable(true).build()); + player.getInventory().setChestplate(new ItemBuilder(Material.IRON_CHESTPLATE).setUnbreakable(true).build()); + player.getInventory().setLeggings(new ItemBuilder(Material.IRON_LEGGINGS).setUnbreakable(true).build()); + player.getInventory().setBoots(new ItemBuilder(Material.IRON_BOOTS).setUnbreakable(true).build()); + } + + @Override + public void awardKillStreak(Player player, int streak) {} +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitArcher.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitArcher.java new file mode 100644 index 000000000..94efc77d0 --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitArcher.java @@ -0,0 +1,137 @@ +package nautilus.game.arcade.game.games.castleassault.kits; + +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.itemstack.EnchantedBookBuilder; +import mineplex.core.itemstack.ItemBuilder; +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.kit.KitAvailability; +import nautilus.game.arcade.kit.Perk; +import nautilus.game.arcade.kit.perks.PerkFletcher; + +public class KitArcher extends KitPlayer +{ + public KitArcher(ArcadeManager manager) + { + super(manager, "Archer", KitAvailability.Free, + new String[] + { + C.cGrayB + "Starting Kit:", + C.cGray + "Diamond Sword", + C.cGray + "Diamond Helmet, Iron Chestplate, Iron Leggings, Diamond Boots", + C.cGray + "10 Fletched Arrows", + C.cGreenB + "Starting Ability:", + C.cGreen + "Fletcher: Obtain 1 Fletched Arrow every 7 seconds (Max of 10)" + }, + new Perk[][] + { + new Perk[] {new PerkFletcher(7, 10, true, false)}, + new Perk[] {new PerkFletcher(7, 16, true, false)}, + new Perk[] {new PerkFletcher(7, 24, true, false)}, + new Perk[] {new PerkFletcher(7, 32, true, false)}, + new Perk[] {new PerkFletcher(7, 32, true, false)}, + new Perk[] {new PerkFletcher(7, 32, true, false)} + }, + new String[][] + { + { + C.cGray + "Increase maximum and starting amount of Fletched Arrows to 16" + }, + { + C.cGray + "Increase maximum and starting amount of Fletched Arrows to 24", + C.cGray + "Obtain a Power I Enchantment on your Bow" + }, + { + C.cGray + "Increase maximum and starting amount of Fletched Arrows to 32", + }, + { + C.cGray + "Obtain a Power II Enchantment on your Bow" + }, + { + C.cGray + "Receive a Feather Falling IV Enchantment on your Diamond Boots" + } + }, + Material.BOW); + } + + @Override + public void GiveItems(Player player) + { + giveRegeneration(player); + + player.getInventory().setItem(0, new ItemBuilder(Material.DIAMOND_SWORD).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + + int level = getUpgradeLevel(player.getUniqueId()); + if (level == 0) + { + player.getInventory().setItem(1, new ItemBuilder(Material.BOW).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setItem(2, new ItemBuilder(Material.ARROW).setAmount(10).setTitle(F.item("Fletched Arrow")).build()); + } + else if (level == 1) + { + player.getInventory().setItem(1, new ItemBuilder(Material.BOW).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setItem(2, new ItemBuilder(Material.ARROW).setAmount(16).setTitle(F.item("Fletched Arrow")).build()); + } + else if (level == 2) + { + player.getInventory().setItem(1, new ItemBuilder(Material.BOW).addEnchantment(Enchantment.ARROW_DAMAGE, 1).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setItem(2, new ItemBuilder(Material.ARROW).setAmount(24).setTitle(F.item("Fletched Arrow")).build()); + } + else if (level == 3) + { + player.getInventory().setItem(1, new ItemBuilder(Material.BOW).addEnchantment(Enchantment.ARROW_DAMAGE, 1).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setItem(2, new ItemBuilder(Material.ARROW).setAmount(32).setTitle(F.item("Fletched Arrow")).build()); + } + else if (level == 4) + { + player.getInventory().setItem(1, new ItemBuilder(Material.BOW).addEnchantment(Enchantment.ARROW_DAMAGE, 2).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setItem(2, new ItemBuilder(Material.ARROW).setAmount(32).setTitle(F.item("Fletched Arrow")).build()); + } + else if (level == 5) + { + player.getInventory().setItem(1, new ItemBuilder(Material.BOW).addEnchantment(Enchantment.ARROW_DAMAGE, 2).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setItem(2, new ItemBuilder(Material.ARROW).setAmount(32).setTitle(F.item("Fletched Arrow")).build()); + } + + player.getInventory().setHelmet(new ItemBuilder(Material.DIAMOND_HELMET).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setChestplate(new ItemBuilder(Material.IRON_CHESTPLATE).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setLeggings(new ItemBuilder(Material.IRON_LEGGINGS).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + if (level < 5) + { + player.getInventory().setBoots(new ItemBuilder(Material.DIAMOND_BOOTS).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + } + else + { + player.getInventory().setBoots(new ItemBuilder(Material.DIAMOND_BOOTS).addEnchantment(Enchantment.PROTECTION_FALL, 4).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + } + } + + @Override + public void awardKillStreak(Player player, int streak) + { + if (streak == 2) + { + player.sendMessage(C.cRedB + "You have received 8 Arrows as a Kill Streak Reward!"); + player.getInventory().addItem(new ItemBuilder(Material.ARROW).setAmount(8).setTitle(F.item("Fletched Arrow")).build()); + } + else if (streak == 4) + { + player.sendMessage(C.cRedB + "You have received 12 Arrows as a Kill Streak Reward!"); + player.getInventory().addItem(new ItemBuilder(Material.ARROW).setAmount(12).setTitle(F.item("Fletched Arrow")).build()); + } + else if (streak == 6) + { + player.sendMessage(C.cRedB + "You have received a Punch I book as a Kill Streak Reward!"); + player.getInventory().addItem(new EnchantedBookBuilder(1).setLevel(Enchantment.ARROW_KNOCKBACK, 1).build()); + } + else if (streak == 8) + { + player.sendMessage(C.cRedB + "You have received 32 Arrows as a Kill Streak Reward!"); + player.getInventory().addItem(new ItemBuilder(Material.ARROW).setAmount(32).setTitle(F.item("Fletched Arrow")).build()); + } + } +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitBuilder.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitBuilder.java new file mode 100644 index 000000000..9e3134e75 --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitBuilder.java @@ -0,0 +1,32 @@ +package nautilus.game.arcade.game.games.castleassault.kits; + +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import mineplex.core.itemstack.ItemBuilder; +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.kit.KitAvailability; +import nautilus.game.arcade.kit.Perk; + +public class KitBuilder extends KitPlayer +{ + public KitBuilder(ArcadeManager manager) + { + super(manager, "Builder", KitAvailability.Free, new String[] {}, new Perk[] {}, Material.STONE); + } + + @Override + public void GiveItems(Player player) + { + player.getInventory().setItem(0, new ItemBuilder(Material.IRON_SWORD).setUnbreakable(true).build()); + player.getInventory().setItem(1, new ItemBuilder(Material.STONE).setAmount(64).build()); + player.getInventory().setItem(2, new ItemBuilder(Material.WOOD).setAmount(64).build()); + player.getInventory().setHelmet(new ItemBuilder(Material.IRON_HELMET).setUnbreakable(true).build()); + player.getInventory().setChestplate(new ItemBuilder(Material.IRON_CHESTPLATE).setUnbreakable(true).build()); + player.getInventory().setLeggings(new ItemBuilder(Material.IRON_LEGGINGS).setUnbreakable(true).build()); + player.getInventory().setBoots(new ItemBuilder(Material.IRON_BOOTS).setUnbreakable(true).build()); + } + + @Override + public void awardKillStreak(Player player, int streak) {} +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitDemolitionist.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitDemolitionist.java new file mode 100644 index 000000000..5af012192 --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitDemolitionist.java @@ -0,0 +1,152 @@ +package nautilus.game.arcade.game.games.castleassault.kits; + +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.itemstack.ItemBuilder; +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.kit.KitAvailability; +import nautilus.game.arcade.kit.Perk; +import nautilus.game.arcade.kit.perks.PerkBomberHG; + +public class KitDemolitionist extends KitPlayer +{ + public KitDemolitionist(ArcadeManager manager) + { + super(manager, "Demolitionist", KitAvailability.Free, + new String[] + { + C.cGrayB + "Starting Kit:", + C.cGray + "Diamond Sword, Flint and Steel", + C.cGray + "Diamond Helmet, Iron Chestplate, Iron Leggings, Diamond Boots", + C.cGray + "Blast Protection IV on all Armor", + C.cGray + "2 Throwing TNT", + C.cGreenB + "Passive Ability:", + C.cGreen + "3 Block Range Increase on TNT Damage", + C.cGreenB + "Starting Ability:", + C.cGreen + "Bombmaker: Obtain 1 Throwing TNT every 10 seconds (Max of 2)" + }, + new Perk[][] + { + new Perk[] {new PerkBomberHG(10, 2, true)}, + new Perk[] {new PerkBomberHG(10, 4, true)}, + new Perk[] {new PerkBomberHG(10, 6, true)}, + new Perk[] {new PerkBomberHG(10, 4, true)}, + new Perk[] {new PerkBomberHG(10, 4, true)}, + new Perk[] {new PerkBomberHG(10, 6, true)} + }, + new String[][] + { + { + C.cGray + "Increase maximum and starting amount of Throwing TNT to 4" + }, + { + C.cGray + "Increase maximum and starting amount of Throwing TNT to 6" + }, + { + C.cGray + "Reduce maximum and starting amount of Throwing TNT to 4", + C.cGray + "Increase range of Throwing TNT by 1.5 times" + }, + { + C.cGray + "Increase range of Throwing TNT by 2.5 times" + }, + { + C.cGray + "Increase maximum and starting amount of Throwing TNT to 6", + C.cGray + "Increase range of Throwing TNT by 3 times" + } + }, + Material.TNT); + } + + public double getThrowMultiplier(Player player) + { + int level = getUpgradeLevel(player.getUniqueId()); + if (level == 3) + { + return 1.5; + } + else if (level == 4) + { + return 2.5; + } + else if (level == 5) + { + return 3; + } + + return 1; + } + + @Override + public void GiveItems(Player player) + { + giveRegeneration(player); + + player.getInventory().setItem(0, new ItemBuilder(Material.DIAMOND_SWORD).setUnbreakable(true).build()); + + int level = getUpgradeLevel(player.getUniqueId()); + if (level == 0) + { + player.getInventory().setItem(1, getGame().getNewFlintAndSteel(true)); + player.getInventory().setItem(2, new ItemBuilder(Material.TNT).setTitle(F.item("Throwing TNT")).setAmount(2).build()); + } + else if (level == 1) + { + player.getInventory().setItem(1, getGame().getNewFlintAndSteel(true)); + player.getInventory().setItem(2, new ItemBuilder(Material.TNT).setTitle(F.item("Throwing TNT")).setAmount(4).build()); + } + else if (level == 2) + { + player.getInventory().setItem(1, getGame().getNewFlintAndSteel(true)); + player.getInventory().setItem(2, new ItemBuilder(Material.TNT).setTitle(F.item("Throwing TNT")).setAmount(6).build()); + } + else if (level == 3) + { + player.getInventory().setItem(1, getGame().getNewFlintAndSteel(true)); + player.getInventory().setItem(2, new ItemBuilder(Material.TNT).setTitle(F.item("Throwing TNT")).setAmount(4).build()); + } + else if (level == 4) + { + player.getInventory().setItem(1, getGame().getNewFlintAndSteel(true)); + player.getInventory().setItem(2, new ItemBuilder(Material.TNT).setTitle(F.item("Throwing TNT")).setAmount(4).build()); + } + else if (level == 5) + { + player.getInventory().setItem(1, getGame().getNewFlintAndSteel(true)); + player.getInventory().setItem(2, new ItemBuilder(Material.TNT).setTitle(F.item("Throwing TNT")).setAmount(6).build()); + } + + player.getInventory().setHelmet(new ItemBuilder(Material.DIAMOND_HELMET).addEnchantment(Enchantment.PROTECTION_EXPLOSIONS, 4).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setChestplate(new ItemBuilder(Material.IRON_CHESTPLATE).addEnchantment(Enchantment.PROTECTION_EXPLOSIONS, 4).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setLeggings(new ItemBuilder(Material.IRON_LEGGINGS).addEnchantment(Enchantment.PROTECTION_EXPLOSIONS, 4).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setBoots(new ItemBuilder(Material.DIAMOND_BOOTS).addEnchantment(Enchantment.PROTECTION_EXPLOSIONS, 4).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + } + + @Override + public void awardKillStreak(Player player, int streak) + { + if (streak == 2) + { + player.sendMessage(C.cRedB + "You have received 2 Throwing TNT as a Kill Streak Reward!"); + player.getInventory().addItem(new ItemBuilder(Material.TNT).setTitle(F.item("Throwing TNT")).setAmount(2).build()); + } + else if (streak == 4) + { + player.sendMessage(C.cRedB + "You have received 3 Throwing TNT as a Kill Streak Reward!"); + player.getInventory().addItem(new ItemBuilder(Material.TNT).setTitle(F.item("Throwing TNT")).setAmount(3).build()); + } + else if (streak == 6) + { + player.sendMessage(C.cRedB + "You have received 4 Throwing TNT as a Kill Streak Reward!"); + player.getInventory().addItem(new ItemBuilder(Material.TNT).setTitle(F.item("Throwing TNT")).setAmount(4).build()); + } + else if (streak == 8) + { + player.sendMessage(C.cRedB + "You have received 5 Throwing TNT as a Kill Streak Reward!"); + player.getInventory().addItem(new ItemBuilder(Material.TNT).setTitle(F.item("Throwing TNT")).setAmount(5).build()); + } + } +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitEnchanter.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitEnchanter.java new file mode 100644 index 000000000..fc15f48ba --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitEnchanter.java @@ -0,0 +1,35 @@ +package nautilus.game.arcade.game.games.castleassault.kits; + +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; + +import mineplex.core.itemstack.EnchantedBookBuilder; +import mineplex.core.itemstack.ItemBuilder; +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.kit.KitAvailability; +import nautilus.game.arcade.kit.Perk; + +public class KitEnchanter extends KitPlayer +{ + public KitEnchanter(ArcadeManager manager) + { + super(manager, "Enchanter", KitAvailability.Free, new String[] {}, new Perk[] {}, Material.ENCHANTED_BOOK); + } + + @Override + public void GiveItems(Player player) + { + player.getInventory().setItem(0, new ItemBuilder(Material.IRON_SWORD).setUnbreakable(true).build()); + player.getInventory().setItem(1, new EnchantedBookBuilder(1).setLevel(Enchantment.DAMAGE_ALL, 1).build()); + player.getInventory().setItem(2, new EnchantedBookBuilder(1).setLevel(Enchantment.PROTECTION_ENVIRONMENTAL, 1).build()); + player.getInventory().setItem(3, new ItemBuilder(Material.EXP_BOTTLE).setAmount(32).build()); + player.getInventory().setHelmet(new ItemBuilder(Material.IRON_HELMET).setUnbreakable(true).build()); + player.getInventory().setChestplate(new ItemBuilder(Material.IRON_CHESTPLATE).setUnbreakable(true).build()); + player.getInventory().setLeggings(new ItemBuilder(Material.IRON_LEGGINGS).setUnbreakable(true).build()); + player.getInventory().setBoots(new ItemBuilder(Material.IRON_BOOTS).setUnbreakable(true).build()); + } + + @Override + public void awardKillStreak(Player player, int streak) {} +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitFighter.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitFighter.java new file mode 100644 index 000000000..d5b49974d --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitFighter.java @@ -0,0 +1,130 @@ +package nautilus.game.arcade.game.games.castleassault.kits; + +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.EnchantedBookBuilder; +import mineplex.core.itemstack.ItemBuilder; +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.kit.KitAvailability; +import nautilus.game.arcade.kit.Perk; + +public class KitFighter extends KitPlayer +{ + public KitFighter(ArcadeManager manager) + { + super(manager, "Fighter", KitAvailability.Free, + new String[] + { + C.cGrayB + "Starting Kit:", + C.cGray + "Diamond Sword", + C.cGray + "1 Golden Applegate", + C.cGray + "Diamond Helmet, Iron Chestplate, Iron Leggings, Diamond Boots", + C.cGreenB + "Passive Ability:", + C.cGreen + "Bloodlust: Deal half a heart more damage for 3 seconds after killing an enemy" + }, + new Perk[][] + { + new Perk[] {new PerkBloodlust(1, 3)}, + new Perk[] {new PerkBloodlust(1, 3)}, + new Perk[] {new PerkBloodlust(1, 3)}, + new Perk[] {new PerkBloodlust(1, 3)}, + new Perk[] {new PerkBloodlust(1, 3)}, + new Perk[] {new PerkBloodlust(1, 3)} + }, + new String[][] + { + { + C.cGray + "Increase starting amount of Golden Applegates to 2" + }, + { + C.cGray + "Obtain a Fishing Rod" + }, + { + C.cGray + "Obtain a Sharpness I Enchantment on your Diamond Sword" + }, + { + C.cGray + "Obtain a Knockback II Enchantment on your Fishing Rod", + C.cGray + "Increase starting amount of Golden Applegates to 3" + }, + { + C.cGray + "Obtain a Sharpness II Enchantment on your Diamond Sword" + } + }, + Material.DIAMOND_SWORD); + } + + @Override + public void GiveItems(Player player) + { + giveRegeneration(player); + + int level = getUpgradeLevel(player.getUniqueId()); + if (level == 0) + { + player.getInventory().setItem(0, new ItemBuilder(Material.DIAMOND_SWORD).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setItem(1, new ItemBuilder(Material.GOLDEN_APPLE).setAmount(1).setTitle(C.cPurple + "Golden Applegate").setLore(C.cGold + "Kit Item").build()); + } + else if (level == 1) + { + player.getInventory().setItem(0, new ItemBuilder(Material.DIAMOND_SWORD).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setItem(1, new ItemBuilder(Material.GOLDEN_APPLE).setAmount(2).setTitle(C.cPurple + "Golden Applegate").setLore(C.cGold + "Kit Item").build()); + } + else if (level == 2) + { + player.getInventory().setItem(0, new ItemBuilder(Material.DIAMOND_SWORD).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setItem(1, new ItemBuilder(Material.FISHING_ROD).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setItem(2, new ItemBuilder(Material.GOLDEN_APPLE).setAmount(2).setTitle(C.cPurple + "Golden Applegate").setLore(C.cGold + "Kit Item").build()); + } + else if (level == 3) + { + player.getInventory().setItem(0, new ItemBuilder(Material.DIAMOND_SWORD).addEnchantment(Enchantment.DAMAGE_ALL, 1).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setItem(1, new ItemBuilder(Material.FISHING_ROD).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setItem(2, new ItemBuilder(Material.GOLDEN_APPLE).setAmount(2).setTitle(C.cPurple + "Golden Applegate").setLore(C.cGold + "Kit Item").build()); + } + else if (level == 4) + { + player.getInventory().setItem(0, new ItemBuilder(Material.DIAMOND_SWORD).addEnchantment(Enchantment.DAMAGE_ALL, 1).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setItem(1, new ItemBuilder(Material.FISHING_ROD).addEnchantment(Enchantment.KNOCKBACK, 2).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setItem(2, new ItemBuilder(Material.GOLDEN_APPLE).setAmount(3).setTitle(C.cPurple + "Golden Applegate").setLore(C.cGold + "Kit Item").build()); + } + else if (level == 5) + { + player.getInventory().setItem(0, new ItemBuilder(Material.DIAMOND_SWORD).addEnchantment(Enchantment.DAMAGE_ALL, 2).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setItem(1, new ItemBuilder(Material.FISHING_ROD).addEnchantment(Enchantment.KNOCKBACK, 2).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setItem(2, new ItemBuilder(Material.GOLDEN_APPLE).setAmount(3).setTitle(C.cPurple + "Golden Applegate").setLore(C.cGold + "Kit Item").build()); + } + + player.getInventory().setHelmet(new ItemBuilder(Material.DIAMOND_HELMET).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setChestplate(new ItemBuilder(Material.IRON_CHESTPLATE).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setLeggings(new ItemBuilder(Material.IRON_LEGGINGS).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setBoots(new ItemBuilder(Material.DIAMOND_BOOTS).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + } + + @Override + public void awardKillStreak(Player player, int streak) + { + if (streak == 2) + { + player.sendMessage(C.cRedB + "You have received a Golden Applegate as a Kill Streak Reward!"); + player.getInventory().addItem(new ItemBuilder(Material.GOLDEN_APPLE).setAmount(1).setTitle(C.cPurple + "Golden Applegate").build()); + } + else if (streak == 4) + { + player.sendMessage(C.cRedB + "You have received a Splash Healing II Potion as a Kill Streak Reward!"); + player.getInventory().addItem(new ItemBuilder(Material.POTION).setData((short)16421).build()); + } + else if (streak == 6) + { + player.sendMessage(C.cRedB + "You have received a Speed II Potion as a Kill Streak Reward!"); + player.getInventory().addItem(new ItemBuilder(Material.POTION).setData((short)8290).build()); + } + else if (streak == 8) + { + player.sendMessage(C.cRedB + "You have received a Fire Aspect I book as a Kill Streak Reward!"); + player.getInventory().addItem(new EnchantedBookBuilder(1).setLevel(Enchantment.FIRE_ASPECT, 1).build()); + } + } +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitHardline.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitHardline.java new file mode 100644 index 000000000..7cb59e5f4 --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitHardline.java @@ -0,0 +1,30 @@ +package nautilus.game.arcade.game.games.castleassault.kits; + +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import mineplex.core.itemstack.ItemBuilder; +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.kit.KitAvailability; +import nautilus.game.arcade.kit.Perk; + +public class KitHardline extends KitPlayer +{ + public KitHardline(ArcadeManager manager) + { + super(manager, "Hardline", KitAvailability.Free, new String[] {}, new Perk[] {}, Material.GOLDEN_APPLE); + } + + @Override + public void GiveItems(Player player) + { + player.getInventory().setItem(0, new ItemBuilder(Material.IRON_SWORD).setUnbreakable(true).build()); + player.getInventory().setHelmet(new ItemBuilder(Material.IRON_HELMET).setUnbreakable(true).build()); + player.getInventory().setChestplate(new ItemBuilder(Material.IRON_CHESTPLATE).setUnbreakable(true).build()); + player.getInventory().setLeggings(new ItemBuilder(Material.IRON_LEGGINGS).setUnbreakable(true).build()); + player.getInventory().setBoots(new ItemBuilder(Material.IRON_BOOTS).setUnbreakable(true).build()); + } + + @Override + public void awardKillStreak(Player player, int streak) {} +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitNinja.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitNinja.java new file mode 100644 index 000000000..acb2f4590 --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitNinja.java @@ -0,0 +1,33 @@ +package nautilus.game.arcade.game.games.castleassault.kits; + +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import mineplex.core.itemstack.ItemBuilder; +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.kit.KitAvailability; +import nautilus.game.arcade.kit.Perk; +import nautilus.game.arcade.kit.perks.PerkFallModifier; + +public class KitNinja extends KitPlayer +{ + public KitNinja(ArcadeManager manager) + { + super(manager, "Ninja", KitAvailability.Free, new String[] {}, new Perk[] {new PerkFallModifier(0.5)}, Material.ENDER_PEARL); + } + + @Override + public void GiveItems(Player player) + { + player.getInventory().setItem(0, new ItemBuilder(Material.IRON_SWORD).setUnbreakable(true).build()); + player.getInventory().setItem(1, new ItemBuilder(Material.WATER_BUCKET).build()); + player.getInventory().setItem(2, new ItemBuilder(Material.ENDER_PEARL).setAmount(2).build()); + player.getInventory().setHelmet(new ItemBuilder(Material.IRON_HELMET).setUnbreakable(true).build()); + player.getInventory().setChestplate(new ItemBuilder(Material.IRON_CHESTPLATE).setUnbreakable(true).build()); + player.getInventory().setLeggings(new ItemBuilder(Material.IRON_LEGGINGS).setUnbreakable(true).build()); + player.getInventory().setBoots(new ItemBuilder(Material.IRON_BOOTS).setUnbreakable(true).build()); + } + + @Override + public void awardKillStreak(Player player, int streak) {} +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitPlayer.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitPlayer.java new file mode 100644 index 000000000..1b90a1793 --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitPlayer.java @@ -0,0 +1,65 @@ +package nautilus.game.arcade.game.games.castleassault.kits; + +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.game.games.castleassault.CastleAssault; +import nautilus.game.arcade.kit.KitAvailability; +import nautilus.game.arcade.kit.Perk; +import nautilus.game.arcade.kit.ProgressingKit; + +public abstract class KitPlayer extends ProgressingKit +{ + private boolean _progressionEnabled = false; + + public KitPlayer(ArcadeManager manager, String name, KitAvailability availability, String[] description, Perk[] perks, Material holding) + { + super(manager, name, "castleassault" + name.toLowerCase(), availability, description, perks, EntityType.ZOMBIE, new ItemStack(holding)); + } + + public KitPlayer(ArcadeManager manager, String name, KitAvailability availability, String[] description, Perk[][] perks, String[][] upgradeDetails, Material holding) + { + super(manager, name, "castleassault" + name.toLowerCase(), availability, description, perks, upgradeDetails, EntityType.ZOMBIE, new ItemStack(holding)); + + _progressionEnabled = true; + } + + public abstract void awardKillStreak(Player player, int streak); + + protected CastleAssault getGame() + { + return (CastleAssault) Manager.GetGame(); + } + + protected void giveRegeneration(Player player) + { + player.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, 20 * 3, 3)); + } + + @Override + public void SpawnCustom(LivingEntity ent) {} + + @Override + public boolean showUpgrades() + { + return _progressionEnabled; + } + + @Override + public boolean crownsEnabled() + { + return true; + } + + @Override + public boolean usesXp() + { + return false; + } +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitTank.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitTank.java new file mode 100644 index 000000000..c6b01406f --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitTank.java @@ -0,0 +1,143 @@ +package nautilus.game.arcade.game.games.castleassault.kits; + +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.EnchantedBookBuilder; +import mineplex.core.itemstack.ItemBuilder; +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.kit.KitAvailability; +import nautilus.game.arcade.kit.Perk; + +public class KitTank extends KitPlayer +{ + public KitTank(ArcadeManager manager) + { + super(manager, "Tank", KitAvailability.Free, + new String[] + { + C.cGrayB + "Starting Kit:", + C.cGray + "Diamond Sword", + C.cGray + "Diamond Helmet, Iron Chestplate, Iron Leggings, Diamond Boots", + C.cGray + "Protection I on Iron Armor" + }, + new Perk[][] + { + new Perk[] {}, + new Perk[] {}, + new Perk[] {}, + new Perk[] {}, + new Perk[] {}, + new Perk[] {} + }, + new String[][] + { + { + C.cGray + "Obtain a Protection II Enchantment on your Iron Armor" + }, + { + C.cGray + "Obtain a Protection I Enchantment on your Diamond Helmet" + }, + { + C.cGray + "Obtain a Protection I Enchantment on your Diamond Boots" + }, + { + C.cGray + "Obtain a Protection II Enchantment on your Diamond Helmet", + C.cGray + "Obtain a Protection II Enchantment on your Diamond Boots" + }, + { + C.cGray + "Obtain a Protection III Enchantment on your Iron Chestplate", + C.cGray + "Obtain a Protection III Enchantment on your Iron Leggings" + } + }, + Material.DIAMOND_CHESTPLATE); + } + + @Override + public void GiveItems(Player player) + { + giveRegeneration(player); + + player.getInventory().setItem(0, new ItemBuilder(Material.DIAMOND_SWORD).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + + int level = getUpgradeLevel(player.getUniqueId()); + if (level == 0) + { + player.getInventory().setHelmet(new ItemBuilder(Material.DIAMOND_HELMET).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setChestplate(new ItemBuilder(Material.IRON_CHESTPLATE).addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 1).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setLeggings(new ItemBuilder(Material.IRON_LEGGINGS).addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 1).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setBoots(new ItemBuilder(Material.DIAMOND_BOOTS).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + } + else if (level == 1) + { + player.getInventory().setHelmet(new ItemBuilder(Material.DIAMOND_HELMET).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setChestplate(new ItemBuilder(Material.IRON_CHESTPLATE).addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 2).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setLeggings(new ItemBuilder(Material.IRON_LEGGINGS).addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 2).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setBoots(new ItemBuilder(Material.DIAMOND_BOOTS).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + } + else if (level == 2) + { + player.getInventory().setHelmet(new ItemBuilder(Material.DIAMOND_HELMET).addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 1).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setChestplate(new ItemBuilder(Material.IRON_CHESTPLATE).addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 2).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setLeggings(new ItemBuilder(Material.IRON_LEGGINGS).addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 2).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setBoots(new ItemBuilder(Material.DIAMOND_BOOTS).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + } + else if (level == 3) + { + player.getInventory().setHelmet(new ItemBuilder(Material.DIAMOND_HELMET).addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 1).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setChestplate(new ItemBuilder(Material.IRON_CHESTPLATE).addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 2).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setLeggings(new ItemBuilder(Material.IRON_LEGGINGS).addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 2).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setBoots(new ItemBuilder(Material.DIAMOND_BOOTS).addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 1).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + } + else if (level == 4) + { + player.getInventory().setHelmet(new ItemBuilder(Material.DIAMOND_HELMET).addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 2).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setChestplate(new ItemBuilder(Material.IRON_CHESTPLATE).addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 2).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setLeggings(new ItemBuilder(Material.IRON_LEGGINGS).addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 2).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setBoots(new ItemBuilder(Material.DIAMOND_BOOTS).addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 2).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + } + else if (level == 5) + { + player.getInventory().setHelmet(new ItemBuilder(Material.DIAMOND_HELMET).addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 2).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setChestplate(new ItemBuilder(Material.IRON_CHESTPLATE).addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 3).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setLeggings(new ItemBuilder(Material.IRON_LEGGINGS).addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 3).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + player.getInventory().setBoots(new ItemBuilder(Material.DIAMOND_BOOTS).addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 2).setLore(C.cGold + "Kit Item").setUnbreakable(true).build()); + } + } + + @Override + public void awardKillStreak(Player player, int streak) + { + if (streak == 2) + { + player.sendMessage(C.cRedB + "You have received a Golden Applegate as a Kill Streak Reward!"); + player.getInventory().addItem(new ItemBuilder(Material.GOLDEN_APPLE).setAmount(1).setTitle(C.cPurple + "Golden Applegate").build()); + } + else if (streak == 4) + { + player.sendMessage(C.cRedB + "You have received a Regeneration II Potion as a Kill Streak Reward!"); + player.getInventory().addItem(new ItemBuilder(Material.POTION).setData((short)8289).build()); + } + else if (streak == 6) + { + player.sendMessage(C.cRedB + "You have received a Resistance I Potion as a Kill Streak Reward!"); + ItemStack item = new ItemBuilder(Material.POTION).setData((short)8205).build(); + PotionMeta pm = (PotionMeta) item.getItemMeta(); + pm.clearCustomEffects(); + pm.addCustomEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 20 * 60, 0), true); + item.setItemMeta(pm); + player.getInventory().addItem(item); + } + else if (streak == 8) + { + player.sendMessage(C.cRedB + "You have received a Thorns II book as a Kill Streak Reward!"); + player.getInventory().addItem(new EnchantedBookBuilder(1).setLevel(Enchantment.THORNS, 2).build()); + } + } +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitWorkman.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitWorkman.java new file mode 100644 index 000000000..0cb37d4e1 --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/KitWorkman.java @@ -0,0 +1,33 @@ +package nautilus.game.arcade.game.games.castleassault.kits; + +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; + +import mineplex.core.itemstack.ItemBuilder; +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.kit.KitAvailability; +import nautilus.game.arcade.kit.Perk; + +public class KitWorkman extends KitPlayer +{ + public KitWorkman(ArcadeManager manager) + { + super(manager, "Workman", KitAvailability.Free, new String[] {}, new Perk[] {}, Material.DIAMOND_PICKAXE); + } + + @Override + public void GiveItems(Player player) + { + player.getInventory().setItem(0, new ItemBuilder(Material.IRON_SWORD).setUnbreakable(true).build()); + player.getInventory().setItem(1, new ItemBuilder(Material.DIAMOND_PICKAXE).addEnchantment(Enchantment.DIG_SPEED, 2).setUnbreakable(true).build()); + player.getInventory().setItem(2, new ItemBuilder(Material.DIAMOND_SPADE).addEnchantment(Enchantment.DIG_SPEED, 2).setUnbreakable(true).build()); + player.getInventory().setHelmet(new ItemBuilder(Material.IRON_HELMET).setUnbreakable(true).build()); + player.getInventory().setChestplate(new ItemBuilder(Material.IRON_CHESTPLATE).setUnbreakable(true).build()); + player.getInventory().setLeggings(new ItemBuilder(Material.IRON_LEGGINGS).setUnbreakable(true).build()); + player.getInventory().setBoots(new ItemBuilder(Material.IRON_BOOTS).setUnbreakable(true).build()); + } + + @Override + public void awardKillStreak(Player player, int streak) {} +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/PerkBloodlust.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/PerkBloodlust.java new file mode 100644 index 000000000..9dc21c017 --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castleassault/kits/PerkBloodlust.java @@ -0,0 +1,135 @@ +package nautilus.game.arcade.game.games.castleassault.kits; + +import java.util.Map; +import java.util.WeakHashMap; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.PlayerDeathEvent; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.minecraft.game.core.combat.event.CombatDeathEvent; +import nautilus.game.arcade.kit.Perk; + +public class PerkBloodlust extends Perk +{ + private Map _lusting = new WeakHashMap<>(); + + private double _damageBoost; + private int _duration; + + public PerkBloodlust(double damageBoost, int duration) + { + super("Bloodlust", + new String[] + { + C.cGray + "Deal an extra " + (damageBoost / 2) + " hearts of damage for " + duration + " seconds after a kill.", + } + ); + + _damageBoost = damageBoost; + _duration = duration; + } + + @EventHandler + public void onDeath(PlayerDeathEvent event) + { + Integer id = _lusting.remove(event.getEntity()); + if (id != null) + { + Bukkit.getScheduler().cancelTask(id.intValue()); + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onCombatDeath(CombatDeathEvent event) + { + if (event.GetLog().GetKiller() == null) + { + return; + } + + if (!event.GetLog().GetKiller().IsPlayer()) + { + return; + } + + Player player = UtilPlayer.searchExact(event.GetLog().GetKiller().GetName()); + if (player == null) + { + return; + } + + if (!Kit.HasKit(player)) + { + return; + } + + if (!Manager.GetGame().IsAlive(player)) + { + return; + } + + if (UtilPlayer.isSpectator(player)) + { + return; + } + + if (!hasPerk(player)) + { + return; + } + + Integer id = _lusting.remove(player); + if (id != null) + { + Bukkit.getScheduler().cancelTask(id.intValue()); + } + + player.sendMessage(C.cRed + "You are now channeling bloodlust for 3 seconds!"); + _lusting.put(player, Bukkit.getScheduler().runTaskLater(UtilServer.getPlugin(), () -> _lusting.remove(player), _duration * 20).getTaskId()); + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void damageIncrease(EntityDamageByEntityEvent event) + { + if (event.getCause() == DamageCause.FIRE_TICK) + return; + + if (event.getDamage() <= 1) + return; + + if (!(event.getDamager() instanceof Player)) + return; + + Player damager = (Player) event.getDamager(); + + if (!Kit.HasKit(damager)) + { + return; + } + + if (!hasPerk(damager)) + { + return; + } + + if (!Manager.IsAlive(damager)) + { + return; + } + + if (!_lusting.containsKey(damager)) + { + return; + } + + event.setDamage(event.getDamage() + _damageBoost); + } +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/ProgressingKit.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/ProgressingKit.java index 75cf10209..ff7c6fdeb 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/ProgressingKit.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/ProgressingKit.java @@ -18,7 +18,6 @@ import org.bukkit.entity.EntityType; import org.bukkit.entity.Firework; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.meta.FireworkMeta; import org.bukkit.scheduler.BukkitRunnable; @@ -319,7 +318,23 @@ public abstract class ProgressingKit extends Kit implements ProgressiveKit { PlayerKit playerKit = _dataManager.get(player); Donor donor = Manager.GetDonation().Get(Bukkit.getPlayer(player)); - return Calculations.canUpgrade(Calculations.getNextUpgradeLevel(playerKit.getLevel(getInternalName())), donor.getBalance(GlobalCurrency.GEM)) && playerKit.getLevel(getInternalName()) >= Calculations.getLevelRequiredFor(upgradeLevel); + int balance = donor.getBalance(GlobalCurrency.GEM); + + if (crownsEnabled()) + { + if (getUpgradeLevel(player) != (upgradeLevel - 1)) + { + return false; + } + balance = Manager.GetDonation().getCrowns(player); + } + + if (!usesXp()) + { + return Calculations.canUpgradeXpLess(upgradeLevel, balance); + } + + return Calculations.canUpgrade(Calculations.getNextUpgradeLevel(playerKit.getLevel(getInternalName())), balance) && playerKit.getLevel(getInternalName()) >= Calculations.getLevelRequiredFor(upgradeLevel); } @Override @@ -427,7 +442,7 @@ public abstract class ProgressingKit extends Kit implements ProgressiveKit public static String receiveItem(String item, int amount) { - return "Receive " + (amount == 1 ? (UtilText.startsWithVowel(item) ? "an" :" a") : C.cGreen + amount) + " " + item; + return "Receive " + (amount == 1 ? (UtilText.startsWithVowel(item) ? "an" :"a") : C.cGreen + amount) + " " + item; } public static String click(boolean left, String comp) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkBomberHG.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkBomberHG.java index 947e7a3aa..7edda2765 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkBomberHG.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkBomberHG.java @@ -1,6 +1,16 @@ package nautilus.game.arcade.kit.perks; import java.util.HashSet; +import java.util.Set; + +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.inventory.ItemStack; import mineplex.core.common.util.C; import mineplex.core.common.util.F; @@ -13,20 +23,18 @@ import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import nautilus.game.arcade.kit.Perk; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.entity.PlayerDeathEvent; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.player.PlayerDropItemEvent; - public class PerkBomberHG extends Perk { private int _spawnRate; private int _max; - + private boolean _onlyRestrictNamed; + public PerkBomberHG(int spawnRate, int max) + { + this(spawnRate, max, false); + } + + public PerkBomberHG(int spawnRate, int max, boolean onlyRestrictNamed) { super("Explosives", new String[] { @@ -35,6 +43,7 @@ public class PerkBomberHG extends Perk _spawnRate = spawnRate; _max = max; + _onlyRestrictNamed = onlyRestrictNamed; } public void Apply(Player player) @@ -53,13 +62,19 @@ public class PerkBomberHG extends Perk if (!Kit.HasKit(cur)) continue; + if (!hasPerk(cur)) + continue; + if (!Manager.GetGame().IsAlive(cur)) continue; if (!Recharge.Instance.use(cur, GetName(), _spawnRate*1000, false, false)) continue; - if (UtilInv.contains(cur, Material.TNT, (byte)0, _max)) + if (_onlyRestrictNamed ? UtilInv.contains(cur, F.item("Throwing TNT"), Material.TNT, (byte)0, _max) : UtilInv.contains(cur, Material.TNT, (byte)0, _max)) + continue; + + if (UtilPlayer.isSpectator(cur)) continue; //Add @@ -75,7 +90,13 @@ public class PerkBomberHG extends Perk if (event.isCancelled()) return; - if (!UtilInv.IsItem(event.getItemDrop().getItemStack(), Material.TNT, (byte)0)) + if (_onlyRestrictNamed ? !UtilInv.IsItem(event.getItemDrop().getItemStack(), F.item("Throwing TNT"), Material.TNT, (byte)0) : !UtilInv.IsItem(event.getItemDrop().getItemStack(), Material.TNT, (byte)0)) + return; + + if (!Kit.HasKit(event.getPlayer())) + return; + + if (!hasPerk(event.getPlayer())) return; //Cancel @@ -91,23 +112,33 @@ public class PerkBomberHG extends Perk //boolean containerOpen = !(event.getView().getTopInventory().getHolder() instanceof Player); boolean clickInContainer = event.getClickedInventory() != null && !(event.getClickedInventory().getHolder() instanceof Player); - if(clickInContainer) + if (clickInContainer) { return; } + + if (!(event.getWhoClicked() instanceof Player)) + return; + + if (!Kit.HasKit((Player)event.getWhoClicked())) + return; + + if (!hasPerk((Player)event.getWhoClicked())) + return; + UtilInv.DisallowMovementOf(event, "Throwing TNT", Material.TNT, (byte) 0, true); } @EventHandler public void TNTDeathRemove(PlayerDeathEvent event) { - HashSet remove = new HashSet(); + Set remove = new HashSet<>(); - for (org.bukkit.inventory.ItemStack item : event.getDrops()) - if (UtilInv.IsItem(item, Material.TNT, (byte)0)) + for (ItemStack item : event.getDrops()) + if (_onlyRestrictNamed ? UtilInv.IsItem(item, "Throwing TNT", Material.TNT, (byte)0) : UtilInv.IsItem(item, Material.TNT, (byte)0)) remove.add(item); - for (org.bukkit.inventory.ItemStack item : remove) + for (ItemStack item : remove) event.getDrops().remove(item); } } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkFallModifier.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkFallModifier.java index bb8decc97..3068c6bc4 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkFallModifier.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkFallModifier.java @@ -1,13 +1,16 @@ package nautilus.game.arcade.kit.perks; -import mineplex.minecraft.game.core.damage.CustomDamageEvent; -import nautilus.game.arcade.kit.Perk; - import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import mineplex.core.Managers; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; +import mineplex.minecraft.game.core.damage.DamageManager; +import nautilus.game.arcade.kit.Perk; + public class PerkFallModifier extends Perk { private double _fall; @@ -41,4 +44,28 @@ public class PerkFallModifier extends Perk event.AddMod("Fall Modifier", "Reduce damage", _fall, false); } -} + + @EventHandler(priority = EventPriority.HIGH) + public void handle(EntityDamageEvent event) + { + if (Managers.get(DamageManager.class).IsEnabled()) + { + return; + } + if (event.getCause() != DamageCause.FALL) + return; + + if (!(event.getEntity() instanceof Player)) + return; + + Player player = (Player) event.getEntity(); + + if (!Kit.HasKit(player)) + return; + + if (!Manager.IsAlive(player)) + return; + + event.setDamage(event.getDamage() * _fall); + } +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkFletcher.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkFletcher.java index 3867996c0..1b2e54207 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkFletcher.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkFletcher.java @@ -183,6 +183,9 @@ public class PerkFletcher extends Perk if (!isFletchedArrow(event.getItemDrop().getItemStack())) return; + + if (!hasPerk(event.getPlayer())) + return; //Cancel event.setCancelled(true); @@ -207,6 +210,15 @@ public class PerkFletcher extends Perk @EventHandler public void FletchInvClick(InventoryClickEvent event) { + if (!(event.getWhoClicked() instanceof Player)) + { + return; + } + + if (!hasPerk((Player)event.getWhoClicked())) + { + return; + } UtilInv.DisallowMovementOf(event, _name, Material.ARROW, (byte)0, true); } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkIronSkin.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkIronSkin.java index ec662a740..9db6fb6d1 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkIronSkin.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkIronSkin.java @@ -3,23 +3,33 @@ package nautilus.game.arcade.kit.perks; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import mineplex.core.Managers; import mineplex.minecraft.game.core.damage.CustomDamageEvent; +import mineplex.minecraft.game.core.damage.DamageManager; import nautilus.game.arcade.kit.Perk; public class PerkIronSkin extends Perk { private double _reduction; + private boolean _percentage; - public PerkIronSkin(double d) + public PerkIronSkin(double d) + { + this(d, false); + } + + public PerkIronSkin(double d, boolean percentage) { super("Iron Skin", new String[] { - "You take " + d + " less damage from attacks", + "You take " + (d * (percentage ? 100 : 1)) + (percentage ? "%" : "") + " less damage from attacks", }); _reduction = d; + _percentage = percentage; } @EventHandler(priority = EventPriority.HIGH) @@ -40,6 +50,54 @@ public class PerkIronSkin extends Perk if (!Kit.HasKit(damagee)) return; - event.AddMod(damagee.getName(), GetName(), -_reduction, false); + if (!hasPerk(damagee)) + return; + + if (_percentage) + { + event.AddMult(damagee.getName(), GetName(), _reduction, false); + } + else + { + event.AddMod(damagee.getName(), GetName(), -_reduction, false); + } } -} + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void damageDecrease(EntityDamageEvent event) + { + if (Managers.get(DamageManager.class).IsEnabled()) + { + return; + } + + if (event.getCause() == DamageCause.FIRE_TICK) + return; + + if (event.getDamage() <= 1) + return; + + if (!(event.getEntity() instanceof Player)) + return; + + Player damagee = (Player) event.getEntity(); + + if (!Kit.HasKit(damagee)) + return; + + if (!hasPerk(damagee)) + return; + + if (!Manager.IsAlive(damagee)) + return; + + if (_percentage) + { + event.setDamage(event.getDamage() * _reduction); + } + else + { + event.setDamage(event.getDamage() - _reduction); + } + } +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameAchievementManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameAchievementManager.java index a14d161d7..50c0b8c80 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameAchievementManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameAchievementManager.java @@ -1,11 +1,18 @@ package nautilus.game.arcade.managers; +import org.bukkit.ChatColor; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; + import mineplex.core.achievement.Achievement; import mineplex.core.achievement.AchievementData; import mineplex.core.achievement.AchievementLog; import mineplex.core.common.currency.GlobalCurrency; import mineplex.core.common.util.C; -import mineplex.core.common.util.Callback; import mineplex.core.common.util.F; import mineplex.core.common.util.NautHashMap; import mineplex.core.common.util.UtilPlayer; @@ -16,14 +23,6 @@ import nautilus.game.arcade.events.GameStateChangeEvent; import nautilus.game.arcade.game.Game; import nautilus.game.arcade.game.Game.GameState; -import org.bukkit.ChatColor; -import org.bukkit.Sound; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; - public class GameAchievementManager implements Listener { ArcadeManager Manager; @@ -84,13 +83,21 @@ public class GameAchievementManager implements Listener //Display for (final Achievement type : log.keySet()) { - - AchievementData data = Manager.GetAchievement().get(player, type); String nameLevel = F.elem(C.cGold + C.Bold + type.getName()); - if (type.getMaxLevel() > 1) - nameLevel = F.elem(C.cGold + C.Bold + type.getName() + " " + ChatColor.RESET + C.cYellow + data.getLevel() + C.cGold + "/" + C.cYellow + type.getMaxLevel()); + if (type.getMaxLevel() > 1) + { + if (type.hasLevelNames()) + { + String tier = data.getLevel() == 0 ? type.getDefaultLevelName() : type.getLevelNames()[Math.min(data.getLevel(), type.getLevelNames().length) - 1]; + nameLevel = F.elem(C.cGold + C.Bold + type.getName() + " " + ChatColor.RESET + C.cYellow + " " + tier); + } + else + { + nameLevel = F.elem(C.cGold + C.Bold + type.getName() + " " + ChatColor.RESET + C.cYellow + data.getLevel() + C.cGold + "/" + C.cYellow + type.getMaxLevel()); + } + } String progress = F.elem(C.cGreen + "+" + log.get(type).Amount); @@ -102,17 +109,51 @@ public class GameAchievementManager implements Listener //Finishing for the first time if (!Manager.GetTaskManager().hasCompletedTask(player, type.getName())) { + int gems = type.getGemReward(); + int crowns = 0; + int xp = 0; + if (type.getLevelUpRewards().length > 0) + { + int[] rewards = type.getLevelUpRewards()[type.getLevelUpRewards().length - 1]; + gems += rewards[0]; + crowns += rewards[1]; + xp += rewards[2]; + } UtilPlayer.message(player, ""); - UtilPlayer.message(player, nameLevel + " " + F.elem(C.cAqua + C.Bold + "Completed!") + - " " + F.elem(C.cGreen + C.Bold + "+" + type.getGemReward() + " Gems")); + String inform = nameLevel + " " + F.elem(C.cAqua + C.Bold + "Completed!"); + if (gems > 0) + { + inform += " " + F.elem(C.cGreen + C.Bold + "+" + gems + " Gems"); + } + if (crowns > 0) + { + inform += " " + F.elem(C.cGold + C.Bold + "+" + crowns + " Crowns"); + } + if (xp > 0 && !Manager.GetTaskManager().hasCompletedTask(player, Achievement.GLOBAL_MINEPLEX_LEVEL.getName())) + { + inform += " " + F.elem(C.cYellow + C.Bold + "+" + xp + " XP"); + } + UtilPlayer.message(player, inform); player.playSound(player.getLocation(), Sound.LEVEL_UP, 1f, 1f); - Manager.GetTaskManager().completedTask(new Callback() + final int finalGems = gems; + final int finalCrowns = crowns; + final int finalXp = xp; + + Manager.GetTaskManager().completedTask(completed -> { - public void run(Boolean completed) + if (finalGems > 0) { - Manager.GetDonation().rewardCurrency(GlobalCurrency.GEM, player, type.getName(), type.getGemReward()); + Manager.GetDonation().rewardCurrency(GlobalCurrency.GEM, player, type.getName(), finalGems); + } + if (finalCrowns > 0) + { + Manager.GetDonation().rewardCrowns(finalCrowns, player); + } + if (finalXp > 0) + { + Manager.GetStatsManager().incrementStat(player, Achievement.GLOBAL_MINEPLEX_LEVEL.getStats()[0], finalXp); } }, player, type.getName()); } @@ -125,9 +166,31 @@ public class GameAchievementManager implements Listener //Multi-Level Achievements else if (log.get(type).LevelUp) { + int gems = 0; + int crowns = 0; + int xp = 0; + if (type.getLevelUpRewards().length > 0) + { + int[] rewards = type.getLevelUpRewards()[Math.min(data.getLevel(), type.getLevelUpRewards().length) - 1]; + gems += rewards[0]; + crowns += rewards[1]; + xp += rewards[2]; + } UtilPlayer.message(player, ""); - UtilPlayer.message(player, nameLevel + " " + progress + - " " + F.elem(C.cAqua + C.Bold + "LEVEL UP!")); + String inform = nameLevel + " " + progress + " " + F.elem(C.cAqua + C.Bold + "LEVEL UP!"); + if (gems > 0) + { + inform += " " + F.elem(C.cGreen + C.Bold + "+" + gems + " Gems"); + } + if (crowns > 0) + { + inform += " " + F.elem(C.cGold + C.Bold + "+" + crowns + " Crowns"); + } + if (xp > 0 && !Manager.GetTaskManager().hasCompletedTask(player, Achievement.GLOBAL_MINEPLEX_LEVEL.getName())) + { + inform += " " + F.elem(C.cYellow + C.Bold + "+" + xp + " XP"); + } + UtilPlayer.message(player, inform); player.playSound(player.getLocation(), Sound.LEVEL_UP, 1f, 1f); } @@ -179,4 +242,4 @@ public class GameAchievementManager implements Listener UtilPlayer.message(player, ""); UtilPlayer.message(player, ArcadeFormat.Line); } -} +} \ No newline at end of file diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameFlagManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameFlagManager.java index b7a2119d0..68791ddff 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameFlagManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameFlagManager.java @@ -54,6 +54,7 @@ import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockBurnEvent; import org.bukkit.event.block.BlockGrowEvent; import org.bukkit.event.block.BlockIgniteEvent; +import org.bukkit.event.block.BlockIgniteEvent.IgniteCause; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.LeavesDecayEvent; import org.bukkit.event.entity.CreatureSpawnEvent; @@ -1172,6 +1173,11 @@ public class GameFlagManager implements Listener if (game.WorldFireSpread) return; + if (event.getCause() == IgniteCause.FLINT_AND_STEEL && game.AllowFlintAndSteel) + { + return; + } + event.setCancelled(true); } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameRewardManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameRewardManager.java index f1834bdaf..2e5e4fbdf 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameRewardManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameRewardManager.java @@ -80,7 +80,7 @@ public class GameRewardManager implements Listener //First Kill if (game.FirstKill) { - game.AddGems(killer, 10, "First Blood", false, false); + game.AddGems(killer, game.FirstKillReward, "First Blood", false, false); Manager.getPluginManager().callEvent(new FirstBloodEvent(killer)); @@ -191,7 +191,7 @@ public class GameRewardManager implements Listener } // Gem Finder - if (game.GemHunterEnabled) + if (game.GemHunterEnabled && !game.CrownsEnabled) { int gemFinder = Manager.GetAchievement().get(player, Achievement.GLOBAL_GEM_HUNTER).getLevel(); if (gemFinder > 0) @@ -216,7 +216,7 @@ public class GameRewardManager implements Listener } } - if (DoubleGem && game.GemDoubleEnabled) + if (DoubleGem && game.GemDoubleEnabled && !game.CrownsEnabled) gemsToReward += baseGemsEarned; Rank rank = Manager.GetClients().Get(player).GetRank(); @@ -232,17 +232,35 @@ public class GameRewardManager implements Listener shardsToReward += baseShardsEarned * 2; else if (rank.has(Rank.ETERNAL)) shardsToReward += baseShardsEarned * 2.5; - - Manager.GetDonation().rewardCurrency(GlobalCurrency.GEM, player, "Earned " + game.GetName(), gemsToReward); + + if (!game.CrownsEnabled) + { + Manager.GetDonation().rewardCurrency(GlobalCurrency.GEM, player, "Earned " + game.GetName(), gemsToReward); + } + else + { + Manager.GetDonation().rewardCrowns(gemsToReward, player); + } if (accountId != -1) { Manager.GetDonation().rewardCurrencyUntilSuccess(GlobalCurrency.TREASURE_SHARD, player, "Earned", shardsToReward); } - Manager.getTrackManager().getTrack(GemCollectorTrack.class).earnedGems(player, gemsToReward); + if (!game.CrownsEnabled) + { + Manager.getTrackManager().getTrack(GemCollectorTrack.class).earnedGems(player, gemsToReward); + } //Stats - Manager.GetStatsManager().incrementStat(player, "Global.GemsEarned", gemsToReward); - Manager.GetStatsManager().incrementStat(player, game.GetName() + ".GemsEarned", gemsToReward); + if (!game.CrownsEnabled) + { + Manager.GetStatsManager().incrementStat(player, "Global.GemsEarned", gemsToReward); + Manager.GetStatsManager().incrementStat(player, game.GetName() + ".GemsEarned", gemsToReward); + } + else + { + Manager.GetStatsManager().incrementStat(player, "Global.CrownsEarned", gemsToReward); + Manager.GetStatsManager().incrementStat(player, game.GetName() + ".CrownsEarned", gemsToReward); + } } private void changeName(Player player, String newName) @@ -274,7 +292,7 @@ public class GameRewardManager implements Listener UtilPlayer.message(player, ""); UtilPlayer.message(player, ArcadeFormat.Line); - UtilPlayer.message(player, Manager.IsRewardGems() ? "§f§lGems Earned" : "§f§lGame Stats"); + UtilPlayer.message(player, Manager.IsRewardGems() ? (game.CrownsEnabled ? "§f§lCrowns Earned" : "§f§lGems Earned") : "§f§lGame Stats"); UtilPlayer.message(player, ""); int earnedGems = 0; @@ -294,7 +312,7 @@ public class GameRewardManager implements Listener String out = ""; if (Manager.IsRewardGems()) - out += F.elem(C.cGreen + "+" + (int) (gemCount * game.GemMultiplier) + " Gems") + " for "; + out += F.elem((game.CrownsEnabled ? C.cGold : C.cGreen) + "+" + (int) (gemCount * game.GemMultiplier) + (game.CrownsEnabled ? " Crowns" : " Gems")) + " for "; out += F.elem(amountStr + type); UtilPlayer.message(player, out); @@ -313,7 +331,7 @@ public class GameRewardManager implements Listener int totalGems = earnedGems; //Gem Finder - if (game.GemHunterEnabled) + if (game.GemHunterEnabled && !game.CrownsEnabled) { int gemFinder = Manager.GetAchievement().get(player, Achievement.GLOBAL_GEM_HUNTER).getLevel(); if (gemFinder > 0) @@ -341,7 +359,7 @@ public class GameRewardManager implements Listener if (extraGems > 0) { - UtilPlayer.message(player, F.elem(C.cGreen + "+" + extraGems + " Gems") + " for " + + UtilPlayer.message(player, F.elem((game.CrownsEnabled ? C.cGold : C.cGreen) + "+" + extraGems + (game.CrownsEnabled ? " Crowns" : " Gems")) + " for " + F.elem("Online for " + UtilTime.MakeStr(timeOnline) + C.cGreen + " +" + (int) (hoursOnline * 20) + "%")); totalGems += extraGems; @@ -350,7 +368,7 @@ public class GameRewardManager implements Listener } //Double Gem - if (DoubleGem && game.GemDoubleEnabled) + if (DoubleGem && game.GemDoubleEnabled && !game.CrownsEnabled) { UtilPlayer.message(player, F.elem(C.cGreen + "+" + (earnedGems) + " Gems") + " for " + F.elem(C.cDGreen + "Double Gem Weekend")); @@ -393,13 +411,13 @@ public class GameRewardManager implements Listener if (give) { UtilPlayer.message(player, F.elem(C.cWhite + "§lYou now have " + - C.cGreen + C.Bold + (Manager.GetDonation().Get(player.getUniqueId()).getBalance(GlobalCurrency.GEM) + totalGems) + " Gems") + C.cWhite + C.Bold + " and " + + (game.CrownsEnabled ? (C.cGoldB + (Manager.GetDonation().getCrowns(player) + totalGems) + " Crowns") : (C.cGreenB + (Manager.GetDonation().Get(player.getUniqueId()).getBalance(GlobalCurrency.GEM) + totalGems) + " Gems"))) + C.cWhite + C.Bold + " and " + F.elem(C.cAqua + C.Bold + (Manager.GetDonation().Get(player.getUniqueId()).getBalance(GlobalCurrency.TREASURE_SHARD) + shards) + " Treasure Shards")); } else { UtilPlayer.message(player, F.elem(C.cWhite + "§lGame is still in progress...")); - UtilPlayer.message(player, F.elem(C.cWhite + "§lYou may earn more " + C.cGreen + C.Bold + "Gems" + C.cWhite + C.Bold + " when its completed.")); + UtilPlayer.message(player, F.elem(C.cWhite + "§lYou may earn more " + (game.CrownsEnabled ? (C.cGoldB + "Crowns") : (C.cGreenB + "Gems")) + C.cWhite + C.Bold + " when it's completed.")); } UtilPlayer.message(player, ArcadeFormat.Line); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameStatManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameStatManager.java index 8e7128943..5916af5b1 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameStatManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameStatManager.java @@ -3,17 +3,6 @@ package nautilus.game.arcade.managers; import java.util.HashMap; import java.util.UUID; -import mineplex.core.common.Rank; -import mineplex.core.common.util.C; -import mineplex.core.common.util.UtilMath; -import mineplex.core.common.util.UtilPlayer; -import mineplex.core.leaderboard.LeaderboardManager; -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.GameType; -import nautilus.game.arcade.events.GameStateChangeEvent; -import nautilus.game.arcade.game.Game.GameState; -import nautilus.game.arcade.stats.StatTracker; - import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -23,6 +12,16 @@ import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; +import mineplex.core.common.Rank; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.GameType; +import nautilus.game.arcade.events.GameStateChangeEvent; +import nautilus.game.arcade.game.Game.GameState; +import nautilus.game.arcade.stats.StatTracker; + public class GameStatManager implements Listener { ArcadeManager Manager; @@ -73,11 +72,6 @@ public class GameStatManager implements Listener continue; Manager.GetStatsManager().incrementStat(player, stat, value); - - // Leaderboard hook for logging appropriate stat events - // Note: Rejects stat events that are not of the appropriate types. - int gameId = event.GetGame().GetType().getGameId(); - LeaderboardManager.getInstance().attemptStatEvent(player, stat.split("\\.")[1], gameId, value); } } } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/ProgressingKitManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/ProgressingKitManager.java index 6491ee32c..35442c7a3 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/ProgressingKitManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/ProgressingKitManager.java @@ -83,7 +83,7 @@ public class ProgressingKitManager implements Listener _tasks.remove(player); return; } - kit.displaySelectedEffect(kit.getLivingEntity(), Bukkit.getPlayer(player)); + kit.displaySelectedEffect(kit.getLivingEntity(), _manager.getCosmeticManager().getGadgetManager(), Bukkit.getPlayer(player)); } }.runTaskTimer(_manager.getPlugin(), 0L, 1L)); } @@ -263,6 +263,10 @@ public class ProgressingKitManager implements Listener { return; } + if (!data.getKit().usesXp()) + { + return; + } player.sendMessage(SPACE); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/chat/GameChatManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/chat/GameChatManager.java index 69e9958d2..a65ffd6cf 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/chat/GameChatManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/chat/GameChatManager.java @@ -15,6 +15,7 @@ import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.jooq.tools.json.JSONObject; +import mineplex.core.antihack.compedaccount.PriorityCause; import mineplex.core.common.Rank; import mineplex.core.common.jsonchat.JsonMessage; import mineplex.core.common.util.C; @@ -67,6 +68,8 @@ public class GameChatManager implements Listener if (event.getMessage().trim().length() == 0) return; + _manager.getCompromisedAccountManager().triggerPriorityBan(event.getPlayer(), PriorityCause.CHAT); + Player sender = event.getPlayer(); String senderName = sender.getName(); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/lobby/current/NewGameLobbyManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/lobby/current/NewGameLobbyManager.java index a0a07de20..11b970117 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/lobby/current/NewGameLobbyManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/lobby/current/NewGameLobbyManager.java @@ -1,24 +1,20 @@ package nautilus.game.arcade.managers.lobby.current; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import mineplex.core.common.util.MapUtil; -import mineplex.core.common.util.UtilAlg; -import mineplex.core.common.util.UtilEnt; -import mineplex.core.common.timing.TimingManager; -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.game.Game; -import nautilus.game.arcade.game.GameTeam; -import nautilus.game.arcade.game.games.deathtag.DeathTag; -import nautilus.game.arcade.game.games.hideseek.HideSeek; -import nautilus.game.arcade.game.games.smash.SuperSmash; -import nautilus.game.arcade.game.games.wither.WitherGame; -import nautilus.game.arcade.kit.Kit; -import nautilus.game.arcade.kit.KitAvailability; -import nautilus.game.arcade.kit.KitSorter; -import nautilus.game.arcade.kit.NullKit; -import nautilus.game.arcade.managers.LobbyEnt; -import nautilus.game.arcade.managers.lobby.LobbyManager; +import java.io.BufferedReader; +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.AbstractMap; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; + import org.bukkit.DyeColor; import org.bukkit.Location; import org.bukkit.Material; @@ -32,16 +28,26 @@ import org.bukkit.entity.Sheep; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerArmorStandManipulateEvent; -import java.io.BufferedReader; -import java.io.DataInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +import mineplex.core.common.timing.TimingManager; +import mineplex.core.common.util.MapUtil; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilEnt; +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.game.Game; +import nautilus.game.arcade.game.GameTeam; +import nautilus.game.arcade.game.games.deathtag.DeathTag; +import nautilus.game.arcade.game.games.hideseek.HideSeek; +import nautilus.game.arcade.game.games.smash.SuperSmash; +import nautilus.game.arcade.game.games.wither.WitherGame; +import nautilus.game.arcade.kit.Kit; +import nautilus.game.arcade.kit.KitAvailability; +import nautilus.game.arcade.kit.KitSorter; +import nautilus.game.arcade.kit.NullKit; +import nautilus.game.arcade.managers.LobbyEnt; +import nautilus.game.arcade.managers.lobby.LobbyManager; /** * @@ -574,5 +580,15 @@ public class NewGameLobbyManager extends LobbyManager return null; } - -} + + public Map> getCustomLocs() + { + Map> ret = new HashMap<>(); + ret.putAll(_multipleLocs); + for (Entry singleEntry : _singleLocs.entrySet()) + { + ret.put(singleEntry.getKey(), Arrays.asList(singleEntry.getValue())); + } + return ret; + } +} \ No newline at end of file diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootChestReward.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootChestReward.java index 5ef354ec1..323c184f9 100644 --- a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootChestReward.java +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootChestReward.java @@ -1,5 +1,6 @@ package mineplex.gemhunters.loot.rewards; +import mineplex.gemhunters.util.SlackRewardBot; import org.bukkit.inventory.ItemStack; import mineplex.core.Managers; @@ -10,14 +11,14 @@ public class LootChestReward extends LootItemReward { private final InventoryManager _inventory; - + private final String _chestName; private final int _amount; - + public LootChestReward(long cashOutDelay, ItemStack itemStack, String chestName, int amount) { super(chestName + " Chest", cashOutDelay, itemStack); - + _inventory = Managers.require(InventoryManager.class); _chestName = chestName; _amount = amount; @@ -26,27 +27,19 @@ public class LootChestReward extends LootItemReward @Override public void onCollectItem() { - + } @Override public void onSuccessful() { - _inventory.addItemToInventory(new Callback() - { - - @Override - public void run(Boolean success) - { - //DebugModule.getInstance().d("Success= " + success); - } - }, _player, _chestName + " Chest", _amount); + _inventory.addItemToInventory(success -> SlackRewardBot.logReward(_player, this, success ? "Success" : "Failure"), _player, _chestName + " Chest", _amount); } @Override public void onDeath() { - + } } diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootGadgetReward.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootGadgetReward.java index 59f9db30f..03ba74fe6 100644 --- a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootGadgetReward.java +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootGadgetReward.java @@ -1,5 +1,9 @@ package mineplex.gemhunters.loot.rewards; +import com.sun.org.apache.xpath.internal.operations.Bool; +import mineplex.core.common.util.Callback; +import mineplex.core.server.util.TransactionResponse; +import mineplex.gemhunters.util.SlackRewardBot; import org.bukkit.inventory.ItemStack; import mineplex.core.Managers; @@ -35,13 +39,11 @@ public class LootGadgetReward extends LootItemReward if (donor.ownsUnknownSalesPackage(_gadget)) { - //DebugModule.getInstance().d("Shard duplicate"); - _donation.rewardCurrencyUntilSuccess(GlobalCurrency.TREASURE_SHARD, _player, "Earned", (int) (500 + 1000 * Math.random())); + _donation.rewardCurrencyUntilSuccess(GlobalCurrency.TREASURE_SHARD, _player, "Earned", (int) (500 + 1000 * Math.random()), success -> SlackRewardBot.logReward(_player, this, (success ? "Success" : "Failure") + " (Shard Dupe)")); } else { - //DebugModule.getInstance().d("Adding gadget"); - _donation.purchaseUnknownSalesPackage(_player, _gadget, GlobalCurrency.TREASURE_SHARD, 0, true, null); + _donation.purchaseUnknownSalesPackage(_player, _gadget, GlobalCurrency.TREASURE_SHARD, 0, true, transaction -> SlackRewardBot.logReward(_player, this, transaction == TransactionResponse.Success ? "Success" : "Failure")); } } diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootRankReward.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootRankReward.java index 58ae67fb3..e0e592fd3 100644 --- a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootRankReward.java +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootRankReward.java @@ -2,6 +2,7 @@ package mineplex.gemhunters.loot.rewards; import java.util.concurrent.TimeUnit; +import mineplex.gemhunters.util.SlackRewardBot; import org.bukkit.inventory.ItemStack; import mineplex.core.Managers; @@ -70,11 +71,11 @@ public class LootRankReward extends LootItemReward if (newRank == null) { _player.sendMessage(F.main("Loot", "Since you already have eternal ( You are lucky :) ). So instead you can have " + CONSOLATION_PRICE + " shards.")); - _donation.rewardCurrencyUntilSuccess(GlobalCurrency.TREASURE_SHARD, _player, "Earned", CONSOLATION_PRICE); + _donation.rewardCurrencyUntilSuccess(GlobalCurrency.TREASURE_SHARD, _player, "Earned", CONSOLATION_PRICE, success -> SlackRewardBot.logReward(_player, this, (success ? "Success" : "Failure") + " (Shard Dupe)")); return; } - _clientManager.SaveRank(_player.getName(), _player.getUniqueId(), newRank, true); + _clientManager.SaveRank(callback -> SlackRewardBot.logReward(_player, this, callback.Name), _player.getName(), _player.getUniqueId(), newRank, true); } @Override diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootShardReward.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootShardReward.java index af1119a73..458e577e1 100644 --- a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootShardReward.java +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootShardReward.java @@ -1,5 +1,6 @@ package mineplex.gemhunters.loot.rewards; +import mineplex.gemhunters.util.SlackRewardBot; import org.bukkit.inventory.ItemStack; import mineplex.core.Managers; @@ -30,7 +31,7 @@ public class LootShardReward extends LootItemReward @Override public void onSuccessful() { - _donation.rewardCurrencyUntilSuccess(GlobalCurrency.TREASURE_SHARD, _player, "Earned", _amount); + _donation.rewardCurrencyUntilSuccess(GlobalCurrency.TREASURE_SHARD, _player, "Earned", _amount, success -> SlackRewardBot.logReward(_player, this, success ? "Success" : "Failure")); } @Override diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/persistence/PersistenceModule.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/persistence/PersistenceModule.java index 9337a7284..dcf2afde9 100644 --- a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/persistence/PersistenceModule.java +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/persistence/PersistenceModule.java @@ -135,7 +135,7 @@ public class PersistenceModule extends MiniPlugin } } - @EventHandler + @EventHandler(priority = EventPriority.LOWEST) public void serverTransfer(ServerTransferEvent event) { if (event.getServer().startsWith("GH-")) diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/util/SlackRewardBot.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/util/SlackRewardBot.java new file mode 100644 index 000000000..8544e411b --- /dev/null +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/util/SlackRewardBot.java @@ -0,0 +1,49 @@ +package mineplex.gemhunters.util; + +import mineplex.core.Managers; +import mineplex.core.common.util.UtilServer; +import mineplex.core.monitor.LagMeter; +import mineplex.core.slack.SlackAPI; +import mineplex.core.slack.SlackMessage; +import mineplex.core.slack.SlackTeam; +import mineplex.gemhunters.loot.rewards.LootItemReward; +import org.bukkit.entity.Player; + +import java.net.MalformedURLException; +import java.net.URL; +import java.text.DecimalFormat; + +public class SlackRewardBot +{ + + private static final DecimalFormat FORMAT = new DecimalFormat("0.0"); + private static final String SLACK_CHANNEL_NAME = "#gem-hunters-logging"; + private static final String SLACK_USERNAME = "Gem Hunters"; + private static final String SLACK_ICON = "http://moppletop.github.io/mineplex/chest-image.png"; + + private static LagMeter _lag; + + public static void logReward(Player player, LootItemReward reward, String status) + { + if (_lag == null) + { + _lag = Managers.get(LagMeter.class); + } + + try + { + SlackAPI.getInstance().sendMessage(SlackTeam.DEVELOPER, SLACK_CHANNEL_NAME, new SlackMessage(SLACK_USERNAME, new URL(SLACK_ICON), + "Rewarding a " + reward.getClass().getSimpleName() + + "\nName: " + reward.getItemStack().getItemMeta().getDisplayName() + + "\nPlayer: " + player.getName() + + "\nStatus: *" + status + "*" + + "\nServer: " + UtilServer.getServerName() + + "\nTPS: " + FORMAT.format(_lag.getTicksPerSecond())), + true); + } + catch (MalformedURLException e) + { + } + } + +} \ No newline at end of file