From f2fc70f4005d3ad59f0fbf33b2b80ebc967abfab Mon Sep 17 00:00:00 2001 From: samczsun Date: Sat, 22 Oct 2016 17:20:41 -0400 Subject: [PATCH] Titles --- Orebfuscator | 1 + .../mineplex/core/common/function/Result.java | 7 - .../mineplex/core/common/util/UtilText.java | 29 +- .../src/mineplex/core/CustomTagFix.java | 14 + .../src/mineplex/core/MiniPlugin.java | 141 ++++- .../src/mineplex/core/book/BookBuilder.java | 109 ++++ .../src/mineplex/core/book/PageBuilder.java | 37 ++ .../src/mineplex/core/creature/Creature.java | 2 +- .../core/disguise/DisguiseManager.java | 2 +- .../disguises/DisguiseInsentient.java | 2 +- .../core/gadget/event/ItemGadgetUseEvent.java | 12 - .../core/gadget/types/ItemGadget.java | 7 +- .../core/powerplayclub/PowerPlayData.java | 2 +- .../src/mineplex/core/titles/Titles.java | 551 ++++++++++++++++++ .../titles/commands/TitleBoostCommand.java | 21 + .../core/titles/commands/TrackCommand.java | 46 ++ .../core/titles/tracks/KitCollectorTrack.java | 50 ++ .../core/titles/tracks/LuckyTrack.java | 88 +++ .../titles/tracks/MineplexMasteryTrack.java | 56 ++ .../core/titles/tracks/PartyAnimalTrack.java | 70 +++ .../core/titles/tracks/PowerPlayTrack.java | 26 + .../core/titles/tracks/SweetToothTrack.java | 64 ++ .../mineplex/core/titles/tracks/Track.java | 99 ++++ .../core/titles/tracks/TrackManager.java | 51 ++ .../core/titles/tracks/TrackRequirements.java | 63 ++ .../core/titles/tracks/TrackTier.java | 65 +++ .../titles/tracks/TreasureHunterTrack.java | 84 +++ .../core/titles/tracks/UnluckyTrack.java | 77 +++ .../core/treasure/TreasureLocation.java | 8 +- .../treasure/event/TreasurePreStartEvent.java | 57 ++ .../treasure/event/TreasureStartEvent.java | 31 +- .../Mineplex.Hub/src/mineplex/hub/Hub.java | 5 + .../mineplex/hub/modules/ParkourManager.java | 4 +- .../mineplex/hub/modules/StackerManager.java | 6 +- .../redis/RedisServerRepository.java | 3 +- 35 files changed, 1809 insertions(+), 81 deletions(-) create mode 160000 Orebfuscator delete mode 100644 Plugins/Mineplex.Core.Common/src/mineplex/core/common/function/Result.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/book/BookBuilder.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/book/PageBuilder.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/titles/Titles.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/titles/commands/TitleBoostCommand.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/titles/commands/TrackCommand.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/KitCollectorTrack.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/LuckyTrack.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/MineplexMasteryTrack.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/PartyAnimalTrack.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/PowerPlayTrack.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/SweetToothTrack.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/Track.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/TrackManager.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/TrackRequirements.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/TrackTier.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/TreasureHunterTrack.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/UnluckyTrack.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/treasure/event/TreasurePreStartEvent.java diff --git a/Orebfuscator b/Orebfuscator new file mode 160000 index 000000000..e3db5bfa0 --- /dev/null +++ b/Orebfuscator @@ -0,0 +1 @@ +Subproject commit e3db5bfa00f95115616cb25cec08b5cbe480a363 diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/function/Result.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/function/Result.java deleted file mode 100644 index cb45540e3..000000000 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/function/Result.java +++ /dev/null @@ -1,7 +0,0 @@ -package mineplex.core.common.function; - -@FunctionalInterface -public interface Result -{ - public void Get(T result); -} diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilText.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilText.java index c151fcf84..66b9c562a 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilText.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilText.java @@ -778,7 +778,8 @@ public class UtilText * @param s The string * @return A buffered image containing the text */ - public static BufferedImage stringToBufferedImage(Font font, String s) { + public static BufferedImage stringToBufferedImage(Font font, String s) + { BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR); Graphics g = img.getGraphics(); g.setFont(font); @@ -801,4 +802,30 @@ public class UtilText return img; } + + static final int MIN_VALUE = 1; + static final int MAX_VALUE = 3999; + static final String[] RN_M = {"", "M", "MM", "MMM"}; + static final String[] RN_C = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"}; + static final String[] RN_X = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"}; + static final String[] RN_I = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"}; + + public static String toRomanNumeral(int number) + { + if (number < MIN_VALUE || number > MAX_VALUE) + { + throw new IllegalArgumentException( + String.format( + "The number must be in the range [%d, %d]", + MIN_VALUE, + MAX_VALUE + ) + ); + } + + return RN_M[number / 1000] + + RN_C[number % 1000 / 100] + + RN_X[number % 100 / 10] + + RN_I[number % 10]; + } } \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/CustomTagFix.java b/Plugins/Mineplex.Core/src/mineplex/core/CustomTagFix.java index 8372203e6..c4ea24040 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/CustomTagFix.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/CustomTagFix.java @@ -9,6 +9,17 @@ import java.util.Map.Entry; import java.util.Set; import java.util.UUID; +import mineplex.core.common.DummyEntity; +import mineplex.core.common.MinecraftVersion; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.event.CustomTagEvent; +import mineplex.core.packethandler.IPacketHandler; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.packethandler.PacketHandler; +import mineplex.core.packethandler.PacketVerifier; +import mineplex.core.packethandler.PacketInfo; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; import net.minecraft.server.v1_8_R3.DataWatcher; import net.minecraft.server.v1_8_R3.DataWatcher.WatchableObject; import net.minecraft.server.v1_8_R3.Entity; @@ -120,6 +131,9 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler // wat return; + if (UtilPlayer.getVersion(owner) != MinecraftVersion.Version1_8) + return; + if (!_entityMap.containsKey(owner.getUniqueId())) { _entityMap.put(owner.getUniqueId(), new HashMap<>()); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/MiniPlugin.java b/Plugins/Mineplex.Core/src/mineplex/core/MiniPlugin.java index 02e063daf..631c05202 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/MiniPlugin.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/MiniPlugin.java @@ -8,6 +8,7 @@ import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilTime; import mineplex.core.common.util.UtilTime.TimeUnit; import mineplex.core.thread.ThreadPool; + import org.bukkit.Bukkit; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; @@ -19,11 +20,11 @@ import org.bukkit.scheduler.BukkitTask; /** * In the future, all implementations of MiniPlugin should only have one constructor: - * + *

* private MiniPlugin() - * + *

* MiniPlugins should also not depend on load order. - * + *

* This way, we can reflectively create them during {@link #require} when they do not exist, leading to much cleaner code */ public abstract class MiniPlugin implements Listener @@ -41,10 +42,10 @@ public abstract class MiniPlugin implements Listener public MiniPlugin(String moduleName, JavaPlugin plugin) { - _moduleName = moduleName; - _plugin = plugin; - - _initializedTime = System.currentTimeMillis(); + _moduleName = moduleName; + _plugin = plugin; + + _initializedTime = System.currentTimeMillis(); _commands = new NautHashMap<>(); @@ -54,37 +55,37 @@ public abstract class MiniPlugin implements Listener Managers.put(this); } - + public PluginManager getPluginManager() { return _plugin.getServer().getPluginManager(); } - + public BukkitScheduler getScheduler() { return _plugin.getServer().getScheduler(); } - + public JavaPlugin getPlugin() { return _plugin; } - + public void registerEvents(Listener listener) { _plugin.getServer().getPluginManager().registerEvents(listener, _plugin); } - + public void registerSelf() { registerEvents(this); } - + public void deregisterSelf() { HandlerList.unregisterAll(this); } - + public final void onEnable() { long epoch = System.currentTimeMillis(); @@ -97,26 +98,32 @@ public abstract class MiniPlugin implements Listener public final void onDisable() { disable(); - + log("Disabled."); } - public void enable() { } - - public void disable() { } - - public void addCommands() { } - + public void enable() + { + } + + public void disable() + { + } + + public void addCommands() + { + } + public final String getName() { return _moduleName; } - + public final void addCommand(ICommand command) { CommandCenter.Instance.addCommand(command); } - + public final void removeCommand(ICommand command) { CommandCenter.Instance.removeCommand(command); @@ -126,30 +133,90 @@ public abstract class MiniPlugin implements Listener { Bukkit.getConsoleSender().sendMessage(F.main(_moduleName, message)); } - + public void runAsync(Runnable runnable) { - ThreadPool.ASYNC.execute(runnable); + Exception exception = new Exception(); + exception.fillInStackTrace(); + ThreadPool.ASYNC.execute(() -> + { + try + { + runnable.run(); + } + catch (Throwable t) + { + throw new RuntimeException(exception); + } + }); } - + public BukkitTask runAsync(Runnable runnable, long time) { - return _plugin.getServer().getScheduler().runTaskLaterAsynchronously(_plugin, runnable, time); + Exception exception = new Exception(); + exception.fillInStackTrace(); + return _plugin.getServer().getScheduler().runTaskLaterAsynchronously(_plugin, () -> + { + try + { + runnable.run(); + } + catch (Throwable t) + { + throw new RuntimeException(exception); + } + }, time); } public BukkitTask runAsyncTimer(Runnable runnable, long time, long period) { - return _plugin.getServer().getScheduler().runTaskTimerAsynchronously(_plugin, runnable, time, period); + Exception exception = new Exception(); + exception.fillInStackTrace(); + return _plugin.getServer().getScheduler().runTaskTimerAsynchronously(_plugin, () -> + { + try + { + runnable.run(); + } + catch (Throwable t) + { + throw new RuntimeException(exception); + } + }, time, period); } public BukkitTask runSync(Runnable runnable) { - return _plugin.getServer().getScheduler().runTask(_plugin, runnable); + Exception exception = new Exception(); + exception.fillInStackTrace(); + return _plugin.getServer().getScheduler().runTask(_plugin, () -> + { + try + { + runnable.run(); + } + catch (Throwable t) + { + throw new RuntimeException(exception); + } + }); } public BukkitTask runSyncLater(Runnable runnable, long delay) { - return _plugin.getServer().getScheduler().runTaskLater(_plugin, runnable, delay); + Exception exception = new Exception(); + exception.fillInStackTrace(); + return _plugin.getServer().getScheduler().runTaskLater(_plugin, () -> + { + try + { + runnable.run(); + } + catch (Throwable t) + { + throw new RuntimeException(exception); + } + }, delay); } public BukkitTask runSyncLater(BukkitRunnable runnable, long delay) @@ -159,7 +226,19 @@ public abstract class MiniPlugin implements Listener public BukkitTask runSyncTimer(Runnable runnable, long delay, long period) { - return _plugin.getServer().getScheduler().runTaskTimer(_plugin, runnable, delay, period); + Exception exception = new Exception(); + exception.fillInStackTrace(); + return _plugin.getServer().getScheduler().runTaskTimer(_plugin, () -> + { + try + { + runnable.run(); + } + catch (Throwable t) + { + throw new RuntimeException(exception); + } + }, delay, period); } public BukkitTask runSyncTimer(BukkitRunnable runnable, long delay, long period) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/book/BookBuilder.java b/Plugins/Mineplex.Core/src/mineplex/core/book/BookBuilder.java new file mode 100644 index 000000000..657df48f0 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/book/BookBuilder.java @@ -0,0 +1,109 @@ +package mineplex.core.book; + +import java.util.ArrayList; +import java.util.List; + +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.chat.ComponentSerializer; +import net.minecraft.server.v1_8_R3.Items; +import net.minecraft.server.v1_8_R3.NBTTagCompound; +import net.minecraft.server.v1_8_R3.NBTTagList; +import net.minecraft.server.v1_8_R3.NBTTagString; + +import org.apache.commons.lang3.Validate; +import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack; +import org.bukkit.inventory.ItemStack; + +public class BookBuilder +{ + public static BookBuilder newBuilder() + { + return new BookBuilder(); + } + + private final List _pageBuilders = new ArrayList<>(); + + private String _title; + private String _author = ""; + private int _generation = 0; + private boolean _resolved = true; + + private BookBuilder() + { + + } + + public PageBuilder newPage(int index) + { + PageBuilder pageBuilder = new PageBuilder(this); + _pageBuilders.add(index, pageBuilder); + return pageBuilder; + } + + public PageBuilder newPage() + { + PageBuilder pageBuilder = new PageBuilder(this); + _pageBuilders.add(pageBuilder); + return pageBuilder; + } + + public int getPageNumber(PageBuilder builder) + { + return _pageBuilders.indexOf(builder); + } + + public BookBuilder title(String title) + { + Validate.notNull(title, "Title cannot be null"); + Validate.isTrue(title.length() < 32, "Title cannot be longer than 32 characters"); + this._title = title; + return this; + } + + public BookBuilder author(String author) + { + Validate.notNull(author, "Author cannot be null"); + this._author = author; + return this; + } + + public BookBuilder resolved(boolean resolved) + { + this._resolved = resolved; + return this; + } + + public BookBuilder generation(int generation) + { + this._generation = generation; + return this; + } + + public ItemStack toItem() + { + net.minecraft.server.v1_8_R3.ItemStack itemStack = new net.minecraft.server.v1_8_R3.ItemStack(Items.WRITTEN_BOOK); + itemStack.setTag(toCompound()); + return CraftItemStack.asCraftMirror(itemStack); + } + + public NBTTagCompound toCompound() + { + NBTTagCompound compound = new NBTTagCompound(); + compound.setString("author", _author); + compound.setString("title", _title); + compound.setInt("generation", _generation); + compound.setBoolean("resolved", _resolved); + + NBTTagList pages = new NBTTagList(); + for (PageBuilder pageBuilder : _pageBuilders) + { + pages.add(new NBTTagString(pageBuilder.build())); + } + + compound.set("pages", pages); + + return compound; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/book/PageBuilder.java b/Plugins/Mineplex.Core/src/mineplex/core/book/PageBuilder.java new file mode 100644 index 000000000..876b8c1b4 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/book/PageBuilder.java @@ -0,0 +1,37 @@ +package mineplex.core.book; + +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.chat.ComponentSerializer; + +public class PageBuilder +{ + private final BookBuilder _parent; + + private BaseComponent[] _components = new BaseComponent[0]; + + protected PageBuilder(BookBuilder builder) + { + this._parent = builder; + } + + public int getPage() + { + return this._parent.getPageNumber(this); + } + + public PageBuilder component(BaseComponent... components) + { + _components = components; + return this; + } + + public BookBuilder bookBuilder() + { + return this._parent; + } + + protected String build() + { + return ComponentSerializer.toString(_components); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/creature/Creature.java b/Plugins/Mineplex.Core/src/mineplex/core/creature/Creature.java index a759cdcbc..3678cda49 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/creature/Creature.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/creature/Creature.java @@ -87,7 +87,7 @@ public class Creature extends MiniPlugin return; //Useless Laggy Squids - if (event.getEntityType() == EntityType.SQUID) + if (event.getEntityType() == EntityType.SQUID && event.getSpawnReason() != CreatureSpawnEvent.SpawnReason.CUSTOM) { event.setCancelled(true); return; diff --git a/Plugins/Mineplex.Core/src/mineplex/core/disguise/DisguiseManager.java b/Plugins/Mineplex.Core/src/mineplex/core/disguise/DisguiseManager.java index 6e1e32169..643652f1c 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/disguise/DisguiseManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/disguise/DisguiseManager.java @@ -586,7 +586,7 @@ public class DisguiseManager extends MiniPlugin implements IPacketHandler * * Basically, we need to delay by an arbitrary amount of ticks (in this case, 5) because of the client. * - * In the client, the renderer renders batches of 16x16x16, and entites are stored in ChunkSections. + * In the client, the renderer renders batches of 16x16x16, and entities are stored in ChunkSections. * However, the data structure used is a HashMultimap, and the hashCode() method for Entity simply returns its entity id * * Now, due to an unfortunate coincidence, sending a PacketPlayOutEntityDestroy does not immediately remove an entity from the client. diff --git a/Plugins/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseInsentient.java b/Plugins/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseInsentient.java index 843af0c09..94d880968 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseInsentient.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseInsentient.java @@ -43,7 +43,7 @@ public abstract class DisguiseInsentient extends DisguiseLiving public void setCustomNameVisible(boolean visible) { - DataWatcher.watch(3, Byte.valueOf((byte) (visible ? 1 : 0)), EntityInsentient.META_CUSTOMNAME_VISIBLE, visible); + DataWatcher.watch(3, (byte) (visible ? 1 : 0), EntityInsentient.META_CUSTOMNAME_VISIBLE, visible); } public boolean getCustomNameVisible() diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/event/ItemGadgetUseEvent.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/event/ItemGadgetUseEvent.java index 1a5122f51..a4d9b13c0 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/event/ItemGadgetUseEvent.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/event/ItemGadgetUseEvent.java @@ -14,8 +14,6 @@ public class ItemGadgetUseEvent extends Event private ItemGadget _gadget; private int _count; - private boolean _cancelled = false; - public ItemGadgetUseEvent(Player player, ItemGadget gadget, int count) { _player = player; @@ -47,14 +45,4 @@ public class ItemGadgetUseEvent extends Event { return _player; } - - public void setCancelled(boolean cancel) - { - _cancelled = cancel; - } - - public boolean isCancelled() - { - return _cancelled; - } } \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/ItemGadget.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/ItemGadget.java index 657ad67ac..382ad3560 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/ItemGadget.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/ItemGadget.java @@ -19,8 +19,10 @@ import mineplex.core.common.util.UtilBlock; import mineplex.core.common.util.UtilGear; import mineplex.core.common.util.UtilInv; import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; import mineplex.core.gadget.GadgetManager; import mineplex.core.gadget.event.ItemGadgetOutOfAmmoEvent; +import mineplex.core.gadget.event.ItemGadgetUseEvent; import mineplex.core.gadget.gadgets.Ammo; import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.recharge.Recharge; @@ -175,7 +177,10 @@ public abstract class ItemGadget extends Gadget Manager.getInventoryManager().addItemToInventory(player, getName(), -1); player.getInventory().setItem(Manager.getActiveItemSlot(), ItemStackFactory.Instance.CreateStack(getDisplayMaterial(), getDisplayData(), 1, F.item(Manager.getInventoryManager().Get(player).getItemCount(getName()) + " " + getName()))); - + + ItemGadgetUseEvent itemGadgetUseEvent = new ItemGadgetUseEvent(player, this, 1); + UtilServer.CallEvent(itemGadgetUseEvent); + ActivateCustom(event.getPlayer()); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/powerplayclub/PowerPlayData.java b/Plugins/Mineplex.Core/src/mineplex/core/powerplayclub/PowerPlayData.java index b1f0c93c0..f478de57c 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/powerplayclub/PowerPlayData.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/powerplayclub/PowerPlayData.java @@ -33,7 +33,7 @@ public class PowerPlayData { if (subscriptions.isEmpty()) { - return new PowerPlayData(Optional.empty(), Collections.emptySet(), Collections.emptySet()); + return new PowerPlayData(Optional.empty(), new HashSet<>(), new HashSet<>()); } final LocalDate today = LocalDate.now(); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/titles/Titles.java b/Plugins/Mineplex.Core/src/mineplex/core/titles/Titles.java new file mode 100644 index 000000000..ee75c45e9 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/titles/Titles.java @@ -0,0 +1,551 @@ +package mineplex.core.titles; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; + +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.HoverEvent; +import net.minecraft.server.v1_8_R3.DataWatcher; +import net.minecraft.server.v1_8_R3.EntityArmorStand; +import net.minecraft.server.v1_8_R3.EntityPlayer; +import net.minecraft.server.v1_8_R3.EntitySlime; +import net.minecraft.server.v1_8_R3.Items; +import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy; +import net.minecraft.server.v1_8_R3.PacketPlayOutEntityMetadata; +import net.minecraft.server.v1_8_R3.PacketPlayOutHeldItemSlot; +import net.minecraft.server.v1_8_R3.PacketPlayOutNamedEntitySpawn; +import net.minecraft.server.v1_8_R3.PacketPlayOutNewAttachEntity; +import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving; +import net.minecraft.server.v1_8_R3.PacketPlayOutWindowItems; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerToggleSneakEvent; + +import mineplex.core.MiniPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.book.BookBuilder; +import mineplex.core.book.PageBuilder; +import mineplex.core.command.CommandBase; +import mineplex.core.common.DummyEntity; +import mineplex.core.common.MinecraftVersion; +import mineplex.core.common.Rank; +import mineplex.core.common.util.LineFormat; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilEvent; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilText; +import mineplex.core.packethandler.IPacketHandler; +import mineplex.core.packethandler.PacketHandler; +import mineplex.core.packethandler.PacketInfo; +import mineplex.core.titles.commands.TrackCommand; +import mineplex.core.titles.tracks.Track; +import mineplex.core.titles.tracks.TrackManager; +import mineplex.core.titles.tracks.TrackTier; + +@ReflectivelyCreateMiniPlugin +public class Titles extends MiniPlugin implements IPacketHandler +{ + private static final int BOOK_SLOT = 2; + + private Map> _ids = new HashMap<>(); + private Map>> _remove = new HashMap<>(); + private Map _titles = new HashMap<>(); + + private final TrackManager _trackManager; + + private Titles() + { + super("Titles"); + require(PacketHandler.class).addPacketHandler(this, PacketHandler.ListenerPriority.LOW, PacketPlayOutNamedEntitySpawn.class, PacketPlayOutEntityDestroy.class); + + _trackManager = require(TrackManager.class); + } + + @Override + public void addCommands() + { + addCommand(new TrackCommand(this)); + + } + + public void setTrackForPlayer(Player player, Track track) + { + setTitle(player, track); + giveBook(player, true); + } + + @EventHandler + public void onJoin(PlayerJoinEvent event) + { + giveBook(event.getPlayer(), false); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onInteract(PlayerInteractEvent event) + { + if (event.getItem() != null && event.getItem().getType() == Material.WRITTEN_BOOK && UtilEvent.isAction(event, UtilEvent.ActionType.R)) + { + giveBook(event.getPlayer(), true); + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onSneak(PlayerToggleSneakEvent event) + { + if (event.isSneaking()) + { + Track type = _titles.remove(event.getPlayer().getEntityId()); + updateTitle(event.getPlayer()); + _titles.put(event.getPlayer().getEntityId(), type); + } + else + { + updateTitle(event.getPlayer()); + } + } + + public void giveBook(Player player, boolean open) + { + EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); + net.minecraft.server.v1_8_R3.ItemStack book; + if (player.getInventory().getItem(BOOK_SLOT) != null && player.getInventory().getItem(BOOK_SLOT).getType() == Material.WRITTEN_BOOK) + { + book = ((CraftItemStack) player.getInventory().getItem(BOOK_SLOT)).getHandle(); + } + else + { + book = new net.minecraft.server.v1_8_R3.ItemStack(Items.WRITTEN_BOOK); + ((CraftPlayer) player).getHandle().inventory.setItem(BOOK_SLOT, book); + } + BookBuilder bookBuilder = BookBuilder.newBuilder() + .title("Titles") + .author("Mineplex Games"); + + List pages = new ArrayList<>(); + List tracks = _trackManager.getAllTracks(); + + for (Track track : tracks) + { + ComponentBuilder trackHover = new ComponentBuilder("") + .append(track.getLongName()) + .color(track.getColor()) + .bold(true) + .append("\n\n", ComponentBuilder.FormatRetention.NONE) + .append( + Arrays.stream( + UtilText.splitLineToArray(track.getDescription(), LineFormat.LORE) + ).collect(Collectors.joining("\n")), + ComponentBuilder.FormatRetention.NONE + ) + .color(ChatColor.WHITE) + .append("\n\n", ComponentBuilder.FormatRetention.NONE); + if (track.getRequirements().getTier(player) != null) + { + if (_titles.get(player.getEntityId()) == track) + { + trackHover + .append("Click to disable: ", ComponentBuilder.FormatRetention.NONE) + .color(ChatColor.RED); + } + else + { + trackHover + .append("Click to enable: ", ComponentBuilder.FormatRetention.NONE) + .color(ChatColor.GREEN); + } + TrackTier tier = track.getRequirements().getTier(player); + trackHover.append(tier.getTitle()) + .color(tier.getColor()); + } + else + { + trackHover + .append("You have not unlocked any tiers in this track!", ComponentBuilder.FormatRetention.NONE) + .color(ChatColor.GRAY); + } + trackHover + .append("\n\n", ComponentBuilder.FormatRetention.NONE) + .append("ID: ") + .color(ChatColor.YELLOW) + .append(track.getId(), ComponentBuilder.FormatRetention.NONE) + .color(ChatColor.WHITE); + + PageBuilder page = bookBuilder.newPage(); + + ComponentBuilder pageContent = new ComponentBuilder(""); + pageContent + .append("☰") + .event(new ClickEvent(ClickEvent.Action.CHANGE_PAGE, "1")) + .append(" ", ComponentBuilder.FormatRetention.NONE) + .append(track.getShortName()) + .bold(true) + .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, trackHover.create())); + if (track.getRequirements().getTier(player) != null) + { + if (_titles.get(player.getEntityId()) == track) + { + pageContent + .color(ChatColor.DARK_GREEN) + .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/titles " + track.getId())); + } + else + { + pageContent + .color(ChatColor.BLACK) + .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/titles " + track.getId())); + } + } + else + { + pageContent + .color(ChatColor.BLACK); + } + pageContent + .append("\n\n", ComponentBuilder.FormatRetention.NONE) + .append("Next Tier ") + .color(ChatColor.DARK_AQUA) + .bold(true) + .append("\n", ComponentBuilder.FormatRetention.NONE); + + TrackTier nextTier = track.getRequirements().getNextTier(player); + if (nextTier != null) + { + int totalTicks = 20; + double progress = nextTier.getProgress(track, player); + String percent = ((int) (progress * 100.0)) + "%"; + int ticks = ((int) (progress * totalTicks * 1.0)); + pageContent.append("[", ComponentBuilder.FormatRetention.NONE); + StringBuilder pipes = new StringBuilder(); + for (int i = 0; i < ticks; i++) + { + pipes.append("|"); + } + pageContent + .append(pipes.toString(), ComponentBuilder.FormatRetention.NONE) + .color(ChatColor.DARK_GREEN); + pipes.setLength(0); + for (int i = ticks; i < totalTicks; i++) + { + pipes.append("|"); + } + pageContent + .append(pipes.toString(), ComponentBuilder.FormatRetention.NONE) + .color(ChatColor.GRAY) + .append("] (" + percent + ")", ComponentBuilder.FormatRetention.NONE) + .color(ChatColor.BLACK); + } + else + { + pageContent + .append("No more tiers!"); + } + + pageContent + .append("\n\n") + .append("Progress") + .color(ChatColor.DARK_AQUA) + .bold(true) + .append("\n", ComponentBuilder.FormatRetention.NONE); + + for (TrackTier tier : track.getRequirements().getTiers()) + { + int rank = track.getRequirements().getRank(tier); + + ComponentBuilder tierHover = new ComponentBuilder("") + .append(track.getLongName()) + .color(track.getColor()) + .bold(true) + .append(" Tier " + rank, ComponentBuilder.FormatRetention.NONE) + .color(tier.getColor()) + .append("\n\n", ComponentBuilder.FormatRetention.NONE) + .append( + Arrays.stream( + UtilText.splitLineToArray(tier.getDescription(), LineFormat.LORE) + ).collect(Collectors.joining("\n")), + ComponentBuilder.FormatRetention.NONE + ) + .append("\n\n", ComponentBuilder.FormatRetention.NONE) + .append("Title: ") + .color(ChatColor.YELLOW) + .append(tier.getTitle()) + .color(tier.getColor()) + .append("\n", ComponentBuilder.FormatRetention.NONE) + .append("Progress: ") + .color(ChatColor.YELLOW) + .append(Math.min(tier.get(track, player), tier.getGoal()) + "/" + tier.getGoal(), ComponentBuilder.FormatRetention.NONE) + .color(ChatColor.WHITE); + + if (tier.getProgress(track, player) >= 1.0) + { + tierHover + .append("\n\n", ComponentBuilder.FormatRetention.NONE) + .append("Complete!") + .color(ChatColor.AQUA); + } + + pageContent + .append(track.getShortName() + " " + UtilText.toRomanNumeral(rank), ComponentBuilder.FormatRetention.NONE) + .color(tier.getProgress(track, player) >= 1.0 ? ChatColor.DARK_GREEN : ChatColor.GRAY) + .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, tierHover.create())) + .append("\n", ComponentBuilder.FormatRetention.NONE); + } + + page.component(pageContent.create()); + + pages.add(page); + } + + { + ComponentBuilder componentBuilder1 = new ComponentBuilder("") + .append("Table of Contents") + .color(ChatColor.DARK_RED) + .bold(true) + .append("\n\n", ComponentBuilder.FormatRetention.NONE); + + int pageId = 2; + + for (Track track : tracks.subList(0, Math.min(tracks.size(), 12))) + { + if (track.getRequirements().getTier(player) != null) + { + if (_titles.get(player.getEntityId()) == track) + { + componentBuilder1 + .append("[✔]", ComponentBuilder.FormatRetention.NONE) + .color(ChatColor.DARK_GREEN) + .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/titles " + track.getId())); + } + else + { + componentBuilder1 + .append("[✘]", ComponentBuilder.FormatRetention.NONE) + .color(ChatColor.RED) + .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/titles " + track.getId())); + } + } + else + { + componentBuilder1 + .append("[✘]", ComponentBuilder.FormatRetention.NONE) + .color(ChatColor.GRAY); + } + componentBuilder1 + .append(" ", ComponentBuilder.FormatRetention.NONE) + .append(track.getShortName()) + .color(ChatColor.BLACK) + .event(new ClickEvent(ClickEvent.Action.CHANGE_PAGE, String.valueOf(pageId++))) + .append("\n", ComponentBuilder.FormatRetention.NONE); + } + // todo handle more than 13 titles + + PageBuilder tableOfContents = bookBuilder.newPage(0); + tableOfContents.component(componentBuilder1.create()); + } + + book.setTag(bookBuilder.toCompound()); + + entityPlayer.playerConnection.sendPacket(new PacketPlayOutWindowItems(entityPlayer.activeContainer.windowId, entityPlayer.activeContainer.a())); + + if (open) + { + int old = entityPlayer.inventory.itemInHandIndex; + if (old != BOOK_SLOT) + { + entityPlayer.playerConnection.sendPacket(new PacketPlayOutHeldItemSlot(BOOK_SLOT)); + } + ((CraftPlayer) player).getHandle().openBook(book); + if (old != BOOK_SLOT) + { + entityPlayer.playerConnection.sendPacket(new PacketPlayOutHeldItemSlot(old)); + } + } + } + + public void setTitle(Player player, Track type) + { + if (_titles.get(player.getEntityId()) != type) + { + _titles.put(player.getEntityId(), type); + } + else + { + _titles.remove(player.getEntityId()); + } + updateTitle(player); + } + + private void updateTitle(Player player) + { + Track type = _titles.get(player.getEntityId()); + _ids.getOrDefault(player.getEntityId(), Collections.emptyMap()).forEach((uuid, entityId) -> + { + DataWatcher armorStandWatcher = new DataWatcher(new DummyEntity(((CraftWorld) player.getWorld()).getHandle())); + armorStandWatcher.a(0, (byte) 0x20, net.minecraft.server.v1_8_R3.Entity.META_ENTITYDATA, (byte) 0x20); + armorStandWatcher.a(1, (short) 300, net.minecraft.server.v1_8_R3.Entity.META_AIR, 0); + if (type != null && type.getRequirements().getTier(player) != null) + { + TrackTier currentTier = type.getRequirements().getTier(player); + armorStandWatcher.a(2, currentTier.getColor().toString() + currentTier.getTitle(), net.minecraft.server.v1_8_R3.Entity.META_CUSTOMNAME, currentTier.getColor().toString() + currentTier.getTitle()); + armorStandWatcher.a(3, (byte) 1, net.minecraft.server.v1_8_R3.Entity.META_CUSTOMNAME_VISIBLE, true); + } + else + { + armorStandWatcher.a(2, "", net.minecraft.server.v1_8_R3.Entity.META_CUSTOMNAME, ""); + armorStandWatcher.a(3, (byte) 0, net.minecraft.server.v1_8_R3.Entity.META_CUSTOMNAME_VISIBLE, false); + } + armorStandWatcher.a(10, (byte) 0x10, EntityArmorStand.META_ARMOR_OPTION, (byte) 0x10); // Small + + PacketPlayOutEntityMetadata entityMetadata = new PacketPlayOutEntityMetadata(); + entityMetadata.a = entityId; + entityMetadata.b = armorStandWatcher.c(); + + ((CraftPlayer) Bukkit.getPlayer(uuid)).getHandle().playerConnection.networkManager.handle(entityMetadata); + }); + } + + @EventHandler + public void onQuit(PlayerQuitEvent event) + { + _ids.values().forEach(map -> map.keySet().removeIf(key -> key.equals(event.getPlayer().getUniqueId()))); + } + + @Override + public void handle(PacketInfo packetInfo) + { + if (packetInfo.isCancelled()) + return; + + if (packetInfo.getPacket() instanceof PacketPlayOutNamedEntitySpawn) + { + PacketPlayOutNamedEntitySpawn packet = (PacketPlayOutNamedEntitySpawn) packetInfo.getPacket(); + + if (UtilPlayer.getVersion(packetInfo.getPlayer()) != MinecraftVersion.Version1_8) + { + Track existingTitle = _titles.get(packet.a); + + DataWatcher squidWatcher = new DataWatcher(new DummyEntity(((CraftWorld) packetInfo.getPlayer().getWorld()).getHandle())); + squidWatcher.a(0, (byte) 0x20, net.minecraft.server.v1_8_R3.Entity.META_ENTITYDATA, (byte) 0x20); + + DataWatcher slimeWatcher = new DataWatcher(new DummyEntity(((CraftWorld) packetInfo.getPlayer().getWorld()).getHandle())); + slimeWatcher.a(0, (byte) 0x20, net.minecraft.server.v1_8_R3.Entity.META_ENTITYDATA, (byte) 0x20); + slimeWatcher.a(16, -1, EntitySlime.META_SIZE, -1); + + DataWatcher armorStandWatcher = new DataWatcher(new DummyEntity(((CraftWorld) packetInfo.getPlayer().getWorld()).getHandle())); + armorStandWatcher.a(0, (byte) 0x20, net.minecraft.server.v1_8_R3.Entity.META_ENTITYDATA, (byte) 0x20); + armorStandWatcher.a(1, (short) 300, net.minecraft.server.v1_8_R3.Entity.META_AIR, 0); + if (existingTitle != null) + { + TrackTier currentTier = existingTitle.getRequirements().getTier((Player) UtilEnt.getEntityById(packet.a)); + if (currentTier != null) + { + armorStandWatcher.a(2, currentTier.getColor().toString() + currentTier.getTitle(), net.minecraft.server.v1_8_R3.Entity.META_CUSTOMNAME, currentTier.getColor().toString() + currentTier.getTitle()); + armorStandWatcher.a(3, (byte) 1, net.minecraft.server.v1_8_R3.Entity.META_CUSTOMNAME_VISIBLE, true); + } + } + armorStandWatcher.a(10, (byte) 0x10, EntityArmorStand.META_ARMOR_OPTION, (byte) 0x10); // Small + + PacketPlayOutSpawnEntityLiving spawnSlime = new PacketPlayOutSpawnEntityLiving(); + spawnSlime.a = UtilEnt.getNewEntityId(); + spawnSlime.b = EntityType.SLIME.getTypeId(); + spawnSlime.c = packet.c; + spawnSlime.d = -150; + spawnSlime.e = packet.e; + spawnSlime.i = 0; + spawnSlime.j = 0; + spawnSlime.k = 0; + spawnSlime.f = 0; + spawnSlime.g = 0; + spawnSlime.h = 0; + spawnSlime.uuid = UUID.randomUUID(); + spawnSlime.l = slimeWatcher; + + PacketPlayOutSpawnEntityLiving spawnSquid = new PacketPlayOutSpawnEntityLiving(); + spawnSquid.a = UtilEnt.getNewEntityId(); + spawnSquid.b = EntityType.SQUID.getTypeId(); + spawnSquid.c = packet.c; + spawnSquid.d = -150; + spawnSquid.e = packet.e; + spawnSquid.i = 0; + spawnSquid.j = 0; + spawnSquid.k = 0; + spawnSquid.f = 0; + spawnSquid.g = 0; + spawnSquid.h = 0; + spawnSquid.uuid = UUID.randomUUID(); + spawnSquid.l = squidWatcher; + + PacketPlayOutSpawnEntityLiving spawnArmorStand = new PacketPlayOutSpawnEntityLiving(); + spawnArmorStand.a = UtilEnt.getNewEntityId(); + spawnArmorStand.b = EntityType.ARMOR_STAND.getTypeId(); + spawnArmorStand.c = packet.c; + spawnArmorStand.d = -150; + spawnArmorStand.e = packet.e; + spawnArmorStand.i = 0; + spawnArmorStand.j = 0; + spawnArmorStand.k = 0; + spawnArmorStand.f = 0; + spawnArmorStand.g = 0; + spawnArmorStand.h = 0; + spawnArmorStand.uuid = UUID.randomUUID(); + spawnArmorStand.l = armorStandWatcher; + + PacketPlayOutNewAttachEntity attachSlimeToPlayer = new PacketPlayOutNewAttachEntity(packet.a, new int[]{spawnSlime.a}); + PacketPlayOutNewAttachEntity attachSquidtoSlime = new PacketPlayOutNewAttachEntity(spawnSlime.a, new int[]{spawnSquid.a}); + PacketPlayOutNewAttachEntity attachArmorStandToSquid = new PacketPlayOutNewAttachEntity(spawnSquid.a, new int[]{spawnArmorStand.a}); + + _ids.computeIfAbsent(packet.a, key -> new HashMap<>()).put(packetInfo.getPlayer().getUniqueId(), spawnArmorStand.a); + _remove.computeIfAbsent(packet.a, key -> new HashMap<>()).put(packetInfo.getPlayer().getUniqueId(), Arrays.asList(spawnSlime.a, spawnSquid.a, spawnArmorStand.a)); + + runSync(() -> + { + packetInfo.getVerifier().bypassProcess(spawnSlime); + packetInfo.getVerifier().bypassProcess(spawnSquid); + packetInfo.getVerifier().bypassProcess(spawnArmorStand); + packetInfo.getVerifier().bypassProcess(attachSlimeToPlayer); + packetInfo.getVerifier().bypassProcess(attachSquidtoSlime); + packetInfo.getVerifier().bypassProcess(attachArmorStandToSquid); + }); + } + } + else if (packetInfo.getPacket() instanceof PacketPlayOutEntityDestroy) + { + PacketPlayOutEntityDestroy packet = (PacketPlayOutEntityDestroy) packetInfo.getPacket(); + for (int id : packet.a) + { + Map innerMap = _ids.getOrDefault(id, Collections.emptyMap()); + innerMap.remove(packetInfo.getPlayer().getUniqueId()); + int[] remove = _remove.getOrDefault(id, Collections.emptyMap()).getOrDefault(packetInfo.getPlayer().getUniqueId(), Collections.emptyList()).stream().mapToInt(Integer::intValue).toArray(); + + if (_remove.getOrDefault(id, Collections.emptyMap()).isEmpty()) + _remove.remove(id); + + PacketPlayOutEntityDestroy destroy = new PacketPlayOutEntityDestroy(remove); + packetInfo.getVerifier().bypassProcess(destroy); + + if (innerMap.isEmpty()) + { + _ids.remove(id); + } + } + } + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/titles/commands/TitleBoostCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/titles/commands/TitleBoostCommand.java new file mode 100644 index 000000000..927b3f7a0 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/titles/commands/TitleBoostCommand.java @@ -0,0 +1,21 @@ +package mineplex.core.titles.commands; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.Rank; +import mineplex.core.titles.Titles; + +public class TitleBoostCommand extends CommandBase +{ + public TitleBoostCommand(Titles plugin, Rank requiredRank, String... aliases) + { + super(plugin, requiredRank, aliases); + } + + @Override + public void Execute(Player caller, String[] args) + { + + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/titles/commands/TrackCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/titles/commands/TrackCommand.java new file mode 100644 index 000000000..69271a5ea --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/titles/commands/TrackCommand.java @@ -0,0 +1,46 @@ +package mineplex.core.titles.commands; + +import org.bukkit.entity.Player; + +import mineplex.core.Managers; +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.titles.Titles; +import mineplex.core.titles.tracks.Track; +import mineplex.core.titles.tracks.TrackManager; + +public class TrackCommand extends CommandBase +{ + private final TrackManager _trackManager; + + public TrackCommand(Titles plugin) + { + super(plugin, Rank.ALL, "track"); + + _trackManager = Managers.require(TrackManager.class); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (args.length == 0) + { + UtilPlayer.message(caller, F.main("Track", "You must specify the ID of a track")); + return; + } + Track track = _trackManager.getTrackById(args[0]); + if (track == null) + { + UtilPlayer.message(caller, F.main("Track", "That is not a valid track")); + return; + } + if (track.getRequirements().getTier(caller) == null) + { + UtilPlayer.message(caller, F.main("Track", "You have not unlocked any tiers on that track")); + return; + } + Plugin.setTrackForPlayer(caller, track); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/KitCollectorTrack.java b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/KitCollectorTrack.java new file mode 100644 index 000000000..090a58bc8 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/KitCollectorTrack.java @@ -0,0 +1,50 @@ +package mineplex.core.titles.tracks; + +import java.util.EnumMap; + +import net.md_5.bungee.api.ChatColor; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.reward.Reward; +import mineplex.core.reward.RewardRarity; +import mineplex.core.treasure.TreasureType; +import mineplex.core.treasure.event.TreasureStartEvent; + +public class KitCollectorTrack extends Track +{ + private static final int ACHIEVEMENT_KIT_BONUS = 5; + + public KitCollectorTrack() + { + super("kit-collector", "Kit Collector", "The Kit Collector tree is unlocked by having kits unlocked"); + getRequirements() + .addTier(new TrackTier( + "Kit Collector", + "Gain 25 Kit Collector Points", + ChatColor.GRAY, + (track, player) -> (int) track.getStat(player), + 20 + )) + .addTier(new TrackTier( + "Kit Hoarder", + "Gain 50 Kit Collector Points", + ChatColor.BLUE, + (track, player) -> (int) track.getStat(player), + 50 + )) + .addTier(new TrackTier( + "I Have Too Many Kits", + "Gain 100 Kit Collector Points", + ChatColor.RED, + (track, player) -> (int) track.getStat(player), + 100 + )); + } + + private int getUnlockedKits(Player player) + { + + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/LuckyTrack.java b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/LuckyTrack.java new file mode 100644 index 000000000..a666988d1 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/LuckyTrack.java @@ -0,0 +1,88 @@ +package mineplex.core.titles.tracks; + +import java.util.EnumMap; + +import net.md_5.bungee.api.ChatColor; + +import org.bukkit.event.EventHandler; + +import mineplex.core.reward.Reward; +import mineplex.core.reward.RewardRarity; +import mineplex.core.treasure.TreasureType; +import mineplex.core.treasure.event.TreasureStartEvent; + +public class LuckyTrack extends Track +{ + private static final EnumMap MULTIPLIER = new EnumMap<>(TreasureType.class); + private static final EnumMap POINTS = new EnumMap<>(RewardRarity.class); + + static + { + POINTS.put(RewardRarity.RARE, 1); + POINTS.put(RewardRarity.LEGENDARY, 5); + POINTS.put(RewardRarity.MYTHICAL, 50); + + MULTIPLIER.put(TreasureType.FREEDOM, 2); + MULTIPLIER.put(TreasureType.HAUNTED, 2); + MULTIPLIER.put(TreasureType.CHRISTMAS, 2); + MULTIPLIER.put(TreasureType.TRICK_OR_TREAT, 2); + MULTIPLIER.put(TreasureType.OMEGA, 3); + } + + public LuckyTrack() + { + super("lucky", "Lucky", "This tree is unlocked by getting fortunate chest drops"); + getRequirements() + .addTier(new TrackTier( + "Lucky", + "Gain 1,000 Lucky Points", + ChatColor.GRAY, + (track, player) -> (int) track.getStat(player), + 1000 + )) + .addTier(new TrackTier( + "Charmed", + "Gain 2,000 Lucky Points", + ChatColor.WHITE, + (track, player) -> (int) track.getStat(player), + 2000 + )) + .addTier(new TrackTier( + "Fortune Favored", + "Gain 3,000 Lucky Points", + ChatColor.BLUE, + (track, player) -> (int) track.getStat(player), + 3000 + )).addTier(new TrackTier( + "Golden", + "Gain 5,000 Lucky Points", + ChatColor.GREEN, + (track, player) -> (int) track.getStat(player), + 5000 + )).addTier(new TrackTier( + "Hashtag Blessed", + "Gain 10,000 Lucky Points", + ChatColor.RED, + (track, player) -> (int) track.getStat(player), + 10000 + )); + } + + // todo: handle chest loot in games + @EventHandler + public void onUseCosmetic(TreasureStartEvent event) + { + for (Reward reward : event.getRewards()) + { + if (!POINTS.containsKey(reward.getRarity())) + continue; + + int basePoints = POINTS.get(reward.getRarity()); + + if (MULTIPLIER.get(event.getTreasureType()) != null) + basePoints *= MULTIPLIER.get(event.getTreasureType()); + + incrementFor(event.getPlayer(), basePoints); + } + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/MineplexMasteryTrack.java b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/MineplexMasteryTrack.java new file mode 100644 index 000000000..88ca32fbc --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/MineplexMasteryTrack.java @@ -0,0 +1,56 @@ +package mineplex.core.titles.tracks; + +import net.md_5.bungee.api.ChatColor; + +import org.bukkit.entity.Player; + +import mineplex.core.Managers; +import mineplex.core.game.GameDisplay; +import mineplex.core.stats.StatsManager; + +public class MineplexMasteryTrack extends Track +{ + private final StatsManager _statsManager; + + protected MineplexMasteryTrack() + { + super("mineplex-mastery", "Mineplex Mastery", "This tree is unlocked by winning different games on Mineplex"); + getRequirements() + .addTier(new TrackTier( + "Mineplex Initiate", + "Win at least one game in 10 different Mineplex Games", + ChatColor.GRAY, + (track, player) -> getGames(player), + 10 + )) + .addTier(new TrackTier( + "Mineplex Veteran", + "Win at least one game in 20 different Mineplex Games", + ChatColor.BLUE, + (track, player) -> getGames(player), + 20 + )) + .addTier(new TrackTier( + "Mineplex Master", + "Win at least one game in 30 different Mineplex Games", + ChatColor.RED, + (track, player) -> getGames(player), + 30 + )); + _statsManager = Managers.require(StatsManager.class); + } + + private int getGames(Player player) + { + int count = 0; + for (GameDisplay display : GameDisplay.values()) + { + if (_statsManager.Get(player).getStat(display.getName() + ".Wins") > 0) + { + count++; + } + } + + return count; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/PartyAnimalTrack.java b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/PartyAnimalTrack.java new file mode 100644 index 000000000..d7bd750b2 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/PartyAnimalTrack.java @@ -0,0 +1,70 @@ +package mineplex.core.titles.tracks; + +import net.md_5.bungee.api.ChatColor; + +import org.bukkit.event.EventHandler; + +import mineplex.core.gadget.event.ItemGadgetUseEvent; +import mineplex.core.gadget.gadgets.item.ItemCoinBomb; +import mineplex.core.gadget.gadgets.item.ItemFirework; +import mineplex.core.gadget.gadgets.item.ItemPartyPopper; +import mineplex.core.gadget.set.SetParty; + +public class PartyAnimalTrack extends Track +{ + public PartyAnimalTrack() + { + super("party-animal", "Party Animal", "This tree is unlocked by partying with your friends and celebrating!"); + getRequirements() + .addTier(new TrackTier( + "Party Animal", + "Gain 10,000 Party Points", + ChatColor.GRAY, + (track, player) -> (int) track.getStat(player), + 10000 + )) + .addTier(new TrackTier( + "Can't Stop Won't Stop", + "Gain 25,000 Party Points", + ChatColor.BLUE, + (track, player) -> (int) track.getStat(player), + 25000 + )) + .addTier(new TrackTier( + "Life is a Party", + "Gain 50,000 Party Points", + ChatColor.RED, + (track, player) -> (int) track.getStat(player), + 50000 + )); + } + + @EventHandler + public void onUseCosmetic(ItemGadgetUseEvent event) + { + int basePoints = 0; + + if (event.getGadget() instanceof ItemPartyPopper) + { + basePoints = 20; + } + else if (event.getGadget() instanceof ItemFirework) + { + basePoints = 1; + } + else if (event.getGadget() instanceof ItemCoinBomb) + { + basePoints = 50; + } + + if (isSetActive(event.getPlayer(), SetParty.class)) + { + basePoints = basePoints * 2; + } + + if (basePoints != 0) + { + incrementFor(event.getPlayer(), basePoints); + } + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/PowerPlayTrack.java b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/PowerPlayTrack.java new file mode 100644 index 000000000..485c11277 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/PowerPlayTrack.java @@ -0,0 +1,26 @@ +package mineplex.core.titles.tracks; + +import net.md_5.bungee.api.ChatColor; + +import mineplex.core.Managers; +import mineplex.core.bonuses.BonusManager; +import mineplex.core.powerplayclub.PowerPlayClubRepository; + +public class PowerPlayTrack extends Track +{ + protected PowerPlayTrack() + { + super("power-play", ChatColor.AQUA, "Power Play", "Power Play VIP", "This is Binary; you either have it 100% or you do not"); + + PowerPlayClubRepository ppc = Managers.require(BonusManager.class).getPowerPlayClubRepository(); + + getRequirements() + .addTier(new TrackTier( + "Power Play Club", + "Currently subscribed to Power Play Club", + ChatColor.AQUA, + (track, player) -> ppc.getCachedData(player).getUnclaimedMonths().isEmpty() ? 0 : 1, + 1 + )); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/SweetToothTrack.java b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/SweetToothTrack.java new file mode 100644 index 000000000..aa9e8d0c9 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/SweetToothTrack.java @@ -0,0 +1,64 @@ +package mineplex.core.titles.tracks; + +import net.md_5.bungee.api.ChatColor; + +import org.bukkit.event.EventHandler; + +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.event.ItemGadgetUseEvent; +import mineplex.core.gadget.gadgets.item.ItemLovePotion; +import mineplex.core.gadget.gadgets.item.ItemMelonLauncher; + +import static mineplex.core.Managers.require; + +public class SweetToothTrack extends Track +{ + private final GadgetManager _gadgetManager = require(GadgetManager.class); + + public SweetToothTrack() + { + super("sweet-tooth", "Sweet Tooth", "This tree is unlocked by consuming Watermelon and other Sweets!"); + getRequirements() + .addTier(new TrackTier( + "Sweet Tooth", + "Consume 10,000 Sweet Points", + ChatColor.GRAY, + (track, player) -> (int) track.getStat(player), + 10000 + )) + .addTier(new TrackTier( + "Cavity Prone", + "Consume 25,000 Sweet Points", + ChatColor.BLUE, + (track, player) -> (int) track.getStat(player), + 25000 + )) + .addTier(new TrackTier( + "Candy Addict", + "Consume 50,000 Sweet Points", + ChatColor.RED, + (track, player) -> (int) track.getStat(player), + 50000 + )); + } + + @EventHandler + public void onUseCosmetic(ItemGadgetUseEvent event) + { + int basePoints = 0; + + if (event.getGadget() instanceof ItemMelonLauncher) + { + basePoints = 1; + } + else if (event.getGadget() instanceof ItemLovePotion) + { + basePoints = 10; + } + + if (basePoints != 0) + { + incrementFor(event.getPlayer(), basePoints); + } + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/Track.java b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/Track.java new file mode 100644 index 000000000..0fee4bdf0 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/Track.java @@ -0,0 +1,99 @@ +package mineplex.core.titles.tracks; + +import net.md_5.bungee.api.ChatColor; + +import org.apache.commons.lang3.Validate; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; + +import mineplex.core.Managers; +import mineplex.core.common.util.UtilServer; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.types.GadgetSet; +import mineplex.core.stats.StatsManager; + +import static mineplex.core.Managers.require; + +public class Track implements Listener +{ + private final String _id; + private final String _shortName; + private final String _longName; + private final String _desc; + private final ChatColor _color; + + private final TrackRequirements _trackRequirements; + + private final GadgetManager _gadgetManager = require(GadgetManager.class); + + protected Track(String trackId, String shortName, String description) + { + this(trackId, ChatColor.DARK_AQUA, shortName, shortName, description); + } + + protected Track(String trackId, ChatColor color, String shortName, String longName, String description) + { + // Book limits + Validate.isTrue(shortName.length() <= 16, "Short name cannot be longer than 16 characters"); + + this._id = trackId; + this._shortName = shortName; + this._longName = longName; + this._desc = description; + this._color = color; + this._trackRequirements = new TrackRequirements(this); + + UtilServer.RegisterEvents(this); + } + + + public final TrackRequirements getRequirements() + { + return this._trackRequirements; + } + + public final String getStatName() + { + return "track." + _id; + } + + public final void incrementFor(Player player, int amount) + { + Managers.require(StatsManager.class).incrementStat(player, getStatName(), amount); + } + + public final long getStat(Player player) + { + return Managers.require(StatsManager.class).Get(player).getStat(getStatName()); + } + + public final boolean isSetActive(Player player, Class setClass) + { + return _gadgetManager.getGadgetSet(setClass).isActive(player); + } + + public String getId() + { + return _id; + } + + public String getShortName() + { + return _shortName; + } + + public String getLongName() + { + return _longName; + } + + public String getDescription() + { + return _desc; + } + + public ChatColor getColor() + { + return this._color; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/TrackManager.java b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/TrackManager.java new file mode 100644 index 000000000..50611e7c7 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/TrackManager.java @@ -0,0 +1,51 @@ +package mineplex.core.titles.tracks; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import mineplex.core.MiniPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; + +@ReflectivelyCreateMiniPlugin +public class TrackManager extends MiniPlugin +{ + private final Map, Track> _registeredTracks = new LinkedHashMap<>(); + private final Map _trackById = new HashMap<>(); + + private TrackManager() + { + super("Track Manager"); + + registerTrack(new PowerPlayTrack()); + registerTrack(new MineplexMasteryTrack()); + registerTrack(new SweetToothTrack()); + registerTrack(new PartyAnimalTrack()); + registerTrack(new TreasureHunterTrack()); + registerTrack(new LuckyTrack()); + registerTrack(new UnluckyTrack()); + } + + private void registerTrack(Track track) + { + _registeredTracks.put(track.getClass(), track); + _trackById.put(track.getId(), track); + } + + public final Track getTrack(Class clazz) + { + return _registeredTracks.get(clazz); + } + + public final Track getTrackById(String id) + { + return _trackById.get(id); + } + + public final List getAllTracks() + { + return new ArrayList<>(_registeredTracks.values()); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/TrackRequirements.java b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/TrackRequirements.java new file mode 100644 index 000000000..84a2b816a --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/TrackRequirements.java @@ -0,0 +1,63 @@ +package mineplex.core.titles.tracks; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.bukkit.entity.Player; + +public class TrackRequirements +{ + private final Track _track; + private final List _tierRequirements = new ArrayList<>(); + + public TrackRequirements(Track track) + { + this._track = track; + } + + public TrackRequirements addTier(TrackTier tier) + { + this._tierRequirements.add(tier); + return this; + } + + public TrackTier getTier(int tier) + { + return this._tierRequirements.get(tier); + } + + public TrackTier getTier(Player player) + { + for (int i = _tierRequirements.size() - 1; i >= 0; i--) { + if (_tierRequirements.get(i).test(_track, player)) { + return _tierRequirements.get(i); + } + } + return null; + } + + public TrackTier getNextTier(Player player) + { + for (int i = _tierRequirements.size() - 1; i >= 0; i--) { + if (_tierRequirements.get(i).test(_track, player)) { + if (i == _tierRequirements.size() - 1) { + return null; + } else { + return _tierRequirements.get(i + 1); + } + } + } + return _tierRequirements.get(0); + } + + public List getTiers() + { + return Collections.unmodifiableList(this._tierRequirements); + } + + public int getRank(TrackTier tier) + { + return _tierRequirements.indexOf(tier) + 1; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/TrackTier.java b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/TrackTier.java new file mode 100644 index 000000000..a70ca2365 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/TrackTier.java @@ -0,0 +1,65 @@ +package mineplex.core.titles.tracks; + +import java.util.Arrays; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Consumer; + +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.TextComponent; + +import org.bukkit.entity.Player; + +public class TrackTier +{ + private final String _title; + private final String _description; + private final ChatColor _color; + private final BiFunction _current; + private final int _goal; + + public TrackTier(String title, String description, ChatColor color, BiFunction current, int goal) + { + this._title = title; + this._current = current; + this._goal = goal; + this._description = description; + this._color = color; + } + + public boolean test(Track track, Player player) + { + return getProgress(track, player) >= 1.0; + } + + public double getProgress(Track track, Player player) + { + return ((double) get(track, player)) / _goal; + } + + public int get(Track track, Player player) + { + return _current.apply(track, player); + } + + public String getTitle() + { + return this._title; + } + + public String getDescription() + { + return this._description; + } + + public ChatColor getColor() + { + return this._color; + } + + public int getGoal() + { + return _goal; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/TreasureHunterTrack.java b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/TreasureHunterTrack.java new file mode 100644 index 000000000..414f67b8f --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/TreasureHunterTrack.java @@ -0,0 +1,84 @@ +package mineplex.core.titles.tracks; + +import java.util.EnumMap; + +import net.md_5.bungee.api.ChatColor; + +import org.bukkit.event.EventHandler; + +import mineplex.core.gadget.set.SetWisdom; +import mineplex.core.treasure.TreasureType; +import mineplex.core.treasure.event.TreasureStartEvent; + +public class TreasureHunterTrack extends Track +{ + private static final EnumMap POINTS = new EnumMap<>(TreasureType.class); + + static + { + POINTS.put(TreasureType.OLD, 1); + POINTS.put(TreasureType.ANCIENT, 3); + POINTS.put(TreasureType.MYTHICAL, 5); + POINTS.put(TreasureType.ILLUMINATED, 10); + POINTS.put(TreasureType.FREEDOM, 25); + POINTS.put(TreasureType.HAUNTED, 25); + POINTS.put(TreasureType.CHRISTMAS, 25); + POINTS.put(TreasureType.TRICK_OR_TREAT, 25); + POINTS.put(TreasureType.OMEGA, 50); + } + + public TreasureHunterTrack() + { + super("treasure-hunter", "Treasure Hunter", "This tree is unlocked by opening chests in the lobby"); + getRequirements() + .addTier(new TrackTier( + "Rookie Treasure Hunter", + "Gain 100 Treasure Points", + ChatColor.GRAY, + (track, player) -> (int) track.getStat(player), + 100 + )) + .addTier(new TrackTier( + "Advanced Treasure Hunter", + "Gain 250 Treasure Points", + ChatColor.WHITE, + (track, player) -> (int) track.getStat(player), + 250 + )) + .addTier(new TrackTier( + "Veteran Treasure Hunter", + "Gain 500 Treasure Points", + ChatColor.BLUE, + (track, player) -> (int) track.getStat(player), + 500 + )).addTier(new TrackTier( + "Legendary Treasure Hunter", + "Gain 1,000 Treasure Points", + ChatColor.GREEN, + (track, player) -> (int) track.getStat(player), + 1000 + )).addTier(new TrackTier( + "Master Treasure Hunter", + "Gain 2,000 Treasure Points", + ChatColor.RED, + (track, player) -> (int) track.getStat(player), + 2000 + )); + } + + @EventHandler + public void onUseCosmetic(TreasureStartEvent event) + { + if (POINTS.containsKey(event.getTreasureType())) + { + int basePoints = POINTS.get(event.getTreasureType()); + + if (isSetActive(event.getPlayer(), SetWisdom.class)) + { + basePoints *= 2; + } + + incrementFor(event.getPlayer(), basePoints); + } + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/UnluckyTrack.java b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/UnluckyTrack.java new file mode 100644 index 000000000..2e5c0cf98 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/titles/tracks/UnluckyTrack.java @@ -0,0 +1,77 @@ +package mineplex.core.titles.tracks; + +import java.util.EnumMap; + +import net.md_5.bungee.api.ChatColor; + +import org.bukkit.event.EventHandler; + +import mineplex.core.reward.Reward; +import mineplex.core.reward.RewardRarity; +import mineplex.core.treasure.TreasureType; +import mineplex.core.treasure.event.TreasureStartEvent; + +public class UnluckyTrack extends Track +{ + private static final EnumMap POINTS = new EnumMap<>(RewardRarity.class); + + static + { + POINTS.put(RewardRarity.COMMON, 1); + POINTS.put(RewardRarity.UNCOMMON, 5); + } + + public UnluckyTrack() + { + super("unlucky", "Unlucky", "This tree is unlocked by getting bad chest drops"); + getRequirements() + .addTier(new TrackTier( + "Unlucky", + "Gain 1,000 Unlucky Points", + ChatColor.GRAY, + (track, player) -> (int) track.getStat(player), + 1000 + )) + .addTier(new TrackTier( + "Cursed", + "Gain 2,000 Unlucky Points", + ChatColor.WHITE, + (track, player) -> (int) track.getStat(player), + 2000 + )) + .addTier(new TrackTier( + "Accident Prone", + "Gain 3,000 Unlucky Points", + ChatColor.BLUE, + (track, player) -> (int) track.getStat(player), + 3000 + )).addTier(new TrackTier( + "Corroded", + "Gain 5,000 Unlucky Points", + ChatColor.GREEN, + (track, player) -> (int) track.getStat(player), + 5000 + )).addTier(new TrackTier( + "Things Don't Go My Way", + "Gain 10,000 Unlucky Points", + ChatColor.RED, + (track, player) -> (int) track.getStat(player), + 10000 + )); + } + + // todo: handle chest loot in games + @EventHandler + public void onUseCosmetic(TreasureStartEvent event) + { + for (Reward reward : event.getRewards()) + { + if (!POINTS.containsKey(reward.getRarity())) + continue; + + int basePoints = POINTS.get(reward.getRarity()); + + incrementFor(event.getPlayer(), basePoints); + } + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureLocation.java b/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureLocation.java index de8a2aa1b..40a8775d6 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureLocation.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureLocation.java @@ -1,5 +1,6 @@ package mineplex.core.treasure; +import java.util.Arrays; import java.util.List; import org.bukkit.Bukkit; @@ -27,6 +28,7 @@ import mineplex.core.common.util.F; import mineplex.core.common.util.UtilAction; import mineplex.core.common.util.UtilAlg; import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilText; import mineplex.core.common.util.UtilTextMiddle; import mineplex.core.donation.DonationManager; @@ -39,6 +41,7 @@ import mineplex.core.inventory.InventoryManager; import mineplex.core.reward.Reward; import mineplex.core.status.ServerStatusManager; import mineplex.core.treasure.event.TreasureFinishEvent; +import mineplex.core.treasure.event.TreasurePreStartEvent; import mineplex.core.treasure.event.TreasureStartEvent; import mineplex.core.treasure.gui.TreasureShop; import mineplex.core.updater.UpdateType; @@ -104,7 +107,7 @@ public class TreasureLocation implements Listener return; } - TreasureStartEvent event = new TreasureStartEvent(player, treasureType); + TreasurePreStartEvent event = new TreasurePreStartEvent(player, treasureType); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) @@ -169,6 +172,9 @@ public class TreasureLocation implements Listener Bukkit.broadcastMessage(F.main("Treasure", F.name(player.getName()) + " is opening " + pron + name)); } + TreasureStartEvent startEvent = new TreasureStartEvent(player, treasureType, Arrays.asList(rewards)); + UtilServer.CallEvent(startEvent); + Treasure treasure = new Treasure(player, rewards, treasureType.getRewardType(), _chestBlock, _chestSpawns, treasureType, _treasureManager.getBlockRestore(), _hologramManager, _statusManager); _currentTreasure = treasure; diff --git a/Plugins/Mineplex.Core/src/mineplex/core/treasure/event/TreasurePreStartEvent.java b/Plugins/Mineplex.Core/src/mineplex/core/treasure/event/TreasurePreStartEvent.java new file mode 100644 index 000000000..d384c61db --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/treasure/event/TreasurePreStartEvent.java @@ -0,0 +1,57 @@ +package mineplex.core.treasure.event; + +import mineplex.core.treasure.TreasureType; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Created by shaun on 14-09-12. + */ +public class TreasurePreStartEvent extends Event implements Cancellable +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _player; + private TreasureType _treasureType; + private boolean _cancelled = false; + + public TreasurePreStartEvent(Player player, TreasureType treasureType) + { + _player = player; + _treasureType = treasureType; + } + + public Player getPlayer() + { + return _player; + } + + public TreasureType getTreasureType() + { + return _treasureType; + } + + @Override + public boolean isCancelled() + { + return _cancelled; + } + + @Override + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/treasure/event/TreasureStartEvent.java b/Plugins/Mineplex.Core/src/mineplex/core/treasure/event/TreasureStartEvent.java index 0c541f079..771de876a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/treasure/event/TreasureStartEvent.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/treasure/event/TreasureStartEvent.java @@ -1,26 +1,28 @@ package mineplex.core.treasure.event; -import mineplex.core.treasure.TreasureType; +import java.util.Collections; +import java.util.List; + import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; -/** - * Created by shaun on 14-09-12. - */ -public class TreasureStartEvent extends Event implements Cancellable +import mineplex.core.reward.Reward; +import mineplex.core.treasure.TreasureType; + +public class TreasureStartEvent extends Event { private static final HandlerList handlers = new HandlerList(); private Player _player; private TreasureType _treasureType; - private boolean _cancelled = false; + private List _rewards; - public TreasureStartEvent(Player player, TreasureType treasureType) + public TreasureStartEvent(Player player, TreasureType treasureType, List rewards) { _player = player; _treasureType = treasureType; + _rewards = rewards; } public Player getPlayer() @@ -33,16 +35,9 @@ public class TreasureStartEvent extends Event implements Cancellable return _treasureType; } - @Override - public boolean isCancelled() + public List getRewards() { - return _cancelled; - } - - @Override - public void setCancelled(boolean cancelled) - { - _cancelled = cancelled; + return Collections.unmodifiableList(_rewards); } public HandlerList getHandlers() @@ -54,4 +49,4 @@ public class TreasureStartEvent extends Event implements Cancellable { return handlers; } -} \ No newline at end of file +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java index e838912dd..314fdacbb 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java @@ -71,6 +71,8 @@ import mineplex.hub.modules.BillboardManager; import mineplex.hub.modules.StackerManager; import mineplex.hub.queue.QueueManager; import mineplex.hub.server.ServerManager; +import mineplex.core.titles.Titles; +import mineplex.core.titles.tracks.TrackManager; import mineplex.minecraft.game.classcombat.Class.ClassManager; import mineplex.minecraft.game.classcombat.Condition.SkillConditionManager; import mineplex.minecraft.game.classcombat.Skill.SkillFactory; @@ -226,6 +228,9 @@ public class Hub extends JavaPlugin implements IRelation BrandingManager brandingManager = new BrandingManager(this); new BillboardManager(this, brandingManager); + + require(TrackManager.class); + require(Titles.class); } @Override diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/ParkourManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/ParkourManager.java index c887fc433..13c96bf19 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/ParkourManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/ParkourManager.java @@ -21,7 +21,7 @@ import mineplex.core.gadget.types.MusicGadget; import mineplex.core.mount.event.MountActivateEvent; import mineplex.core.recharge.Recharge; import mineplex.core.task.TaskManager; -import mineplex.core.treasure.event.TreasureStartEvent; +import mineplex.core.treasure.event.TreasurePreStartEvent; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.hub.HubManager; @@ -546,7 +546,7 @@ public class ParkourManager extends MiniPlugin } @EventHandler - public void preventTreasureNearParkour(TreasureStartEvent event) + public void preventTreasureNearParkour(TreasurePreStartEvent event) { if (InsideParkour(event.getPlayer().getLocation())) { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/StackerManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/StackerManager.java index c6b639b22..fa8080f8d 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/StackerManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/StackerManager.java @@ -63,7 +63,7 @@ public class StackerManager extends MiniPlugin implements IThrown _projectileManager = Managers.get(ProjectileManager.class); } - @EventHandler +// @EventHandler public void GrabEntity(PlayerInteractAtEntityEvent event) { if (event.isCancelled()) @@ -245,7 +245,7 @@ public class StackerManager extends MiniPlugin implements IThrown event.setCancelled(true); } - @EventHandler +// @EventHandler public void ThrowEntity(PlayerInteractEvent event) { if (!UtilEvent.isAction(event, ActionType.L)) @@ -312,7 +312,7 @@ public class StackerManager extends MiniPlugin implements IThrown Manager.SetPortalDelay(throwee); } - @Override +// @Override public void Collide(LivingEntity target, Block block, ProjectileUser data) { if (target == null) diff --git a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/redis/RedisServerRepository.java b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/redis/RedisServerRepository.java index 15120076e..2f5537437 100644 --- a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/redis/RedisServerRepository.java +++ b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/redis/RedisServerRepository.java @@ -222,7 +222,8 @@ public class RedisServerRepository extends RedisRepository implements ServerRepo if (data.entrySet().size() == 0) { - System.out.println("Encountered empty map! Skipping..."); + // please no +// System.out.println("Encountered empty map! Skipping..."); continue; }