From b5e8c0886ebb2eabd064feaf781dba2eeae43ca1 Mon Sep 17 00:00:00 2001 From: Aaron Brock Date: Tue, 28 Jul 2015 17:38:26 -0400 Subject: [PATCH 01/72] Stuff and things Signed-off-by: Aaron Brock --- .../src/mineplex/core/gui/ClickExecutor.java | 7 + .../src/mineplex/core/gui/Container.java | 5 + .../src/mineplex/core/gui/GuiInventory.java | 9 + .../src/mineplex/core/gui/GuiItem.java | 8 + .../src/mineplex/core/gui/ItemRefreasher.java | 5 + .../src/mineplex/core/gui/SimpleGui.java | 202 +++++++++++++++ .../src/mineplex/core/gui/SimpleGuiItem.java | 50 ++++ .../mineplex/core/gui/botton/BackBotton.java | 36 +++ .../core/gui/pages/LoadingWindow.java | 238 ++++++++++++++++++ .../core/gui/pages/MessageWindow.java | 87 +++++++ .../core/gui/pages/TimedMessageWindow.java | 65 +++++ 11 files changed, 712 insertions(+) create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/gui/ClickExecutor.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/gui/Container.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/gui/GuiInventory.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/gui/GuiItem.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/gui/ItemRefreasher.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/gui/SimpleGui.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/gui/SimpleGuiItem.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/gui/botton/BackBotton.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/gui/pages/LoadingWindow.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/gui/pages/MessageWindow.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/gui/pages/TimedMessageWindow.java diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gui/ClickExecutor.java b/Plugins/Mineplex.Core/src/mineplex/core/gui/ClickExecutor.java new file mode 100644 index 000000000..cd6fc9774 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gui/ClickExecutor.java @@ -0,0 +1,7 @@ +package mineplex.core.gui; + +import org.bukkit.event.inventory.ClickType; + +public interface ClickExecutor { + public void click(ClickType clickType); +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gui/Container.java b/Plugins/Mineplex.Core/src/mineplex/core/gui/Container.java new file mode 100644 index 000000000..9ad939f28 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gui/Container.java @@ -0,0 +1,5 @@ +package mineplex.core.gui; + +public interface Container { + public T getObject(); +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gui/GuiInventory.java b/Plugins/Mineplex.Core/src/mineplex/core/gui/GuiInventory.java new file mode 100644 index 000000000..68d347477 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gui/GuiInventory.java @@ -0,0 +1,9 @@ +package mineplex.core.gui; + +import org.bukkit.inventory.Inventory; + + +public interface GuiInventory { + public void openInventory(); + public Inventory getInventory(); +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gui/GuiItem.java b/Plugins/Mineplex.Core/src/mineplex/core/gui/GuiItem.java new file mode 100644 index 000000000..ec2442b27 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gui/GuiItem.java @@ -0,0 +1,8 @@ +package mineplex.core.gui; + +import org.bukkit.inventory.ItemStack; + +public interface GuiItem extends ClickExecutor, Container { + public void setup(); + public void close(); +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gui/ItemRefreasher.java b/Plugins/Mineplex.Core/src/mineplex/core/gui/ItemRefreasher.java new file mode 100644 index 000000000..fb723962d --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gui/ItemRefreasher.java @@ -0,0 +1,5 @@ +package mineplex.core.gui; + +public interface ItemRefreasher extends GuiInventory { + public void refreashItem(GuiItem item); +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gui/SimpleGui.java b/Plugins/Mineplex.Core/src/mineplex/core/gui/SimpleGui.java new file mode 100644 index 000000000..c434b06a6 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gui/SimpleGui.java @@ -0,0 +1,202 @@ +package mineplex.core.gui; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; + +import mineplex.core.common.util.UtilPlayer; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.plugin.Plugin; + +public class SimpleGui implements ItemRefreasher, Listener { + + private Map _bottonMap = new HashMap(); + + private Player _player; + private Plugin _plugin; + private int _size; + private String _title; + private Inventory _inv; + + public SimpleGui(Plugin plugin, Player player) + { + this(plugin, player, null, 0, null); + } + + public SimpleGui(Plugin plugin, Player player, int size) + { + this(plugin, player, null, size, null); + } + + public SimpleGui(Plugin plugin, Player player, String title) + { + this(plugin, player, title, 0, null); + } + + public SimpleGui(Plugin plugin, Player player, String title, int size) + { + this(plugin, player, title, size, null); + } + + public SimpleGui(Plugin plugin, Player player, String title, int size, Map bottonMap) + { + + Validate.notNull(plugin, "The plugin cannot be null!"); + Validate.notNull(player, "The player cannot be null!"); + + this._plugin = plugin; + this._player = player; + + if (size == 0) + setSize(9); + else + setSize(size); + + if (title == null) + setTitle(" "); + else + setTitle(title); + + if (bottonMap == null) + this._bottonMap = new HashMap(); + else + this._bottonMap = bottonMap; + } + + @Override + public void openInventory() + { + _inv = createInventory(); + + UtilPlayer.swapToInventory(_player, _inv); + Bukkit.getPluginManager().registerEvents(this, _plugin); + } + + + public Inventory createInventory() { + for (GuiItem item : new HashSet(getBottonMap().values())) { + item.setup(); + } + + Inventory inv = Bukkit.createInventory(_player, getSize(), getTitle()); + + for (Entry entry : _bottonMap.entrySet()) { + inv.setItem(entry.getKey(), entry.getValue().getObject()); + } + return inv; + } + + + @EventHandler + public void inventoryClick(InventoryClickEvent event) + { + + if (!event.getWhoClicked().equals(_player) || !event.getInventory().equals(_inv)) + return; + + GuiItem item = _bottonMap.get(event.getSlot()); + System.out.println(item); + if (item == null) + return; + + event.setCancelled(true); + + item.click(event.getClick()); + } + + @EventHandler + public void inventoryClose(InventoryCloseEvent event) + { + + if (!event.getPlayer().equals(_player)) + return; + + _inv = null; + HandlerList.unregisterAll(this); + + for (GuiItem item : new HashSet(getBottonMap().values())) { + item.close(); + } + } + + + + @Override + public void refreashItem(GuiItem item) + { + if (_inv == null) + return; + for (Entry entry : getBottonMap().entrySet()) { + if (entry.getValue().equals(item)) + _inv.setItem(entry.getKey(), entry.getValue().getObject()); + } + } + + public void refreashItem(int slot) + { + + GuiItem gi = getBottonMap().get(slot); + if (_inv == null || gi == null) + return; + + _inv.setItem(slot, gi.getObject()); + } + + public int getSize() + { + return _size; + } + + public String getTitle() + { + return _title; + } + + public Player getPlayer() + { + return _player; + } + + public Plugin getPlugin() + { + return _plugin; + } + + public void setTitle(String title) + { + this._title = title; + } + + @Override + public Inventory getInventory() + { + return _inv; + } + + public void setSize(int size) + { + Validate.isTrue(size % 9 == 0, "The size " + size + " is not divisable by 9"); + this._size = size; + } + + public Map getBottonMap() + { + return _bottonMap; + } + + public void setBottonMap(Map bottonMap) + { + this._bottonMap = bottonMap; + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gui/SimpleGuiItem.java b/Plugins/Mineplex.Core/src/mineplex/core/gui/SimpleGuiItem.java new file mode 100644 index 000000000..187aa259f --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gui/SimpleGuiItem.java @@ -0,0 +1,50 @@ +package mineplex.core.gui; + +import org.bukkit.Material; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +public class SimpleGuiItem extends ItemStack implements GuiItem { + + public SimpleGuiItem(Material type, int amount, short damage) + { + super(type, amount, damage); + } + + public SimpleGuiItem(Material type, int amount) + { + super(type, amount); + } + + public SimpleGuiItem(Material type) + { + super(type); + } + + public SimpleGuiItem(ItemStack itemStack) + { + super(itemStack); + } + + @Override + public void click(ClickType clickType) + { + } + + @Override + public ItemStack getObject() + { + return this; + } + + @Override + public void setup() + { + } + + @Override + public void close() + { + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gui/botton/BackBotton.java b/Plugins/Mineplex.Core/src/mineplex/core/gui/botton/BackBotton.java new file mode 100644 index 000000000..4335408eb --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gui/botton/BackBotton.java @@ -0,0 +1,36 @@ +package mineplex.core.gui.botton; + +import mineplex.core.gui.GuiInventory; +import mineplex.core.gui.SimpleGuiItem; +import mineplex.core.itemstack.ItemStackFactory; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +public class BackBotton extends SimpleGuiItem { + + private GuiInventory _gui; + + public BackBotton(GuiInventory gui) { + this(ItemStackFactory.Instance.CreateStack(Material.BED, (byte) 0, 1, ChatColor.DARK_GRAY + "<-- Go Back"), gui); + } + + public BackBotton(ItemStack itemStack, GuiInventory gui) + { + super(itemStack); + this._gui = gui; + } + + @Override + public void click(ClickType clickType) + { + getGui().openInventory(); + } + + public GuiInventory getGui() + { + return _gui; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gui/pages/LoadingWindow.java b/Plugins/Mineplex.Core/src/mineplex/core/gui/pages/LoadingWindow.java new file mode 100644 index 000000000..6398b4e6b --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gui/pages/LoadingWindow.java @@ -0,0 +1,238 @@ +package mineplex.core.gui.pages; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.itemstack.ItemStackFactory; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.plugin.Plugin; + +public class LoadingWindow implements Runnable, Listener { + + public static String[] messages = new String[]{"Sending Carrier Pigeons...", "#BlameChiss", "Converting to Morse Code...", "Training monkeys..."}; + public static long defaultWait = 30; + + public ItemStack _background; + public ItemStack _barLoading; + public ItemStack _barBack; + + private Inventory _inv; + private final InventoryView _currentInventory; + + private final int _id; + + private final Plugin _plugin; + private final UUID _playersUUID; + + private String _message; + private String _title; + + private final int _size; + + private final int[] _activeRows; + + private long _ticker = 0; + + public LoadingWindow(Plugin plugin, Player player, int size) { + this(plugin, player, null, size, null, null); + } + + public LoadingWindow(Plugin plugin, Player player, long startTime, int size) { + this(plugin, player, startTime, size, null, null); + } + + public LoadingWindow(Plugin plugin, Player player, long startTime, int size, String message) + { + this(plugin, player, startTime, size, message, message); + } + + @SuppressWarnings("deprecation") + public LoadingWindow(Plugin plugin, Player player, Long startTime, int size, String title, String message) + { + Validate.notNull(plugin, "The plugin can not be null!"); + Validate.notNull(player, "The player can not be null!"); + + _currentInventory = player.getOpenInventory(); + + _size = size; + _activeRows = getActiveRows(size / 9); + + _plugin = plugin; + _playersUUID = player.getUniqueId(); + + + _background = ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, DyeColor.BLACK.getData(), 1, _message); + _barLoading = ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, DyeColor.LIME.getData(), 1, _message); + _barBack = ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, DyeColor.WHITE.getData(), 1, _message); + + + if (title == null && message == null) + { + String randomName = UtilMath.randomElement(messages); + title = randomName; + message = randomName; + } + else if (title == null) + { + title = " "; + } + else if (message == null) + { + message = UtilMath.randomElement(messages); + } + if (startTime == null) + startTime = defaultWait; + + + _title = title; + setMessage(message); + _id = Bukkit.getScheduler().runTaskTimer(plugin, this, startTime, 5).getTaskId(); + } + + public void setMessage(String message) { + _message = message; + ItemMeta im =_background.getItemMeta(); + im.setDisplayName(_message); + _background.setItemMeta(im); + _barBack.setItemMeta(im); + _barLoading.setItemMeta(im); + + setBackGround(); + setLoadingBarItems(); + } + + public void setTitle(String title) { + _title = title; + + Player player = Bukkit.getPlayer(_playersUUID); + if (_inv == null || player == null) + return; + + ItemStack[] con = _inv.getContents(); + + _inv = Bukkit.createInventory(null, _size, _title); + _inv.setContents(con); + UtilPlayer.swapToInventory(player, _inv); + } + + @EventHandler + public void onClick(InventoryClickEvent event) { + if (event.getWhoClicked().getUniqueId().equals(_playersUUID) && event.getInventory().equals(_inv)) { + event.setCancelled(true); + } + } + + @EventHandler + public void inventoryClose(InventoryCloseEvent event) { + if (event.getPlayer().getUniqueId().equals(_playersUUID) && event.getInventory().equals(_inv)) { + end(); + } + } + + @Override + public void run() + { + Player player = Bukkit.getPlayer(_playersUUID); + + if (player == null || _inv == null ? !player.getOpenInventory().equals(_currentInventory) : (_inv != null && !player.getOpenInventory().getTopInventory().equals(_inv))) { + end(); + return; + } + if (_inv == null) { + _inv = Bukkit.createInventory(null, _size, _title); + + setBackGround(); + setLoadingBarItems(); + UtilPlayer.swapToInventory(player, _inv); + Bukkit.getPluginManager().registerEvents(this, _plugin); + } else + setLoadingBarItems(); + + _ticker++; + } + + public void end() { + HandlerList.unregisterAll(this); + Bukkit.getScheduler().cancelTask(_id); + _inv = null; + } + + private void setBackGround() { + if (_inv == null) + return; + + List ignore = new ArrayList(); + + for (int row : _activeRows) { + + int rowStart = row * 9; + int rowEnd = rowStart + 9; + + for (int i = rowStart; i < rowEnd; i++) { + ignore.add(i); + } + } + + for (int i = 0; i < _size; i++) { + if (!ignore.contains(i)) + _inv.setItem(i, _background); + } + } + + private void setLoadingBarItems() { + if (_inv == null) + return; + ItemStack[] loadingBar = getLoadingBar(); + + for (int row : _activeRows) { + int rowStart = row * 9; + for (int i = 0; i < 9; i++) { + _inv.setItem(i + rowStart, loadingBar[i]); + } + } + } + + public ItemStack[] getLoadingBar() + { + ItemStack[] loadingBar = new ItemStack[9]; + + int barStart = (int) (_ticker % 9); + int barEnd = (barStart + 3) % 9; + + boolean endAfter = barEnd > barStart; + + for (int i = 0; i < loadingBar.length; i++) { + if (endAfter ? (i >= barStart && i < barEnd) : (i >= barStart || i < barEnd)) + loadingBar[i] = _barLoading; + else + loadingBar[i] = _barBack; + } + return loadingBar; + } + + private static int[] getActiveRows(int rows) + { + float mid = rows / 2.0f; + if (mid == (int) mid) + return new int[] { (int) mid , (int) mid -1}; + else + return new int[] { (int) Math.floor(mid)}; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gui/pages/MessageWindow.java b/Plugins/Mineplex.Core/src/mineplex/core/gui/pages/MessageWindow.java new file mode 100644 index 000000000..d51bbcf79 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gui/pages/MessageWindow.java @@ -0,0 +1,87 @@ +package mineplex.core.gui.pages; + +import java.util.UUID; + +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.gui.GuiInventory; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; + +public class MessageWindow implements Listener, GuiInventory { + + private UUID _playersUUID; + private Plugin _plugin; + private Inventory _inv; + + public MessageWindow(Plugin plugin, Player player, ItemStack is, String title, int size) + { + _plugin = plugin; + + this._playersUUID = player.getUniqueId(); + + _inv = Bukkit.createInventory(null, size, title); + + for (int i = 0; i < size; i++) { + _inv.setItem(i, is); + } + } + + @EventHandler(ignoreCancelled = true) + public void onClick(InventoryClickEvent e) + { + if (!e.getWhoClicked().getUniqueId().equals(_playersUUID)) + return; + e.setCancelled(true); + } + + @EventHandler + public void onClose(InventoryCloseEvent e) + { + if (!e.getPlayer().getUniqueId().equals(_playersUUID)) + return; + HandlerList.unregisterAll(this); + close(); + } + + @Override + public void openInventory() + { + Player player = Bukkit.getPlayer(_playersUUID); + + if (player == null || player.getOpenInventory().getTopInventory().equals(_inv)) + return; + + UtilPlayer.swapToInventory(player, _inv); + Bukkit.getPluginManager().registerEvents(this, _plugin); + open(); + } + + @Override + public Inventory getInventory() + { + return _inv; + } + public UUID getPlayersUUID() + { + return _playersUUID; + } + public Plugin getPlugin() + { + return _plugin; + } + public void open() { + + } + public void close() { + + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gui/pages/TimedMessageWindow.java b/Plugins/Mineplex.Core/src/mineplex/core/gui/pages/TimedMessageWindow.java new file mode 100644 index 000000000..d84b3bdfa --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gui/pages/TimedMessageWindow.java @@ -0,0 +1,65 @@ +package mineplex.core.gui.pages; + +import mineplex.core.gui.GuiInventory; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; + +public class TimedMessageWindow extends MessageWindow implements Runnable { + private GuiInventory _gui; + private int _id; + private long _time; + + public TimedMessageWindow(Plugin plugin, Player player, ItemStack is, String title, int size, long time) + { + this(plugin, player, is, title, size, time, null); + } + + public TimedMessageWindow(Plugin plugin, Player player, ItemStack is, String title, int size, long time, GuiInventory gui) + { + super(plugin, player, is, title, size); + + this._gui = gui; + this._time = time; + } + + @Override + @EventHandler + public void onClick(InventoryClickEvent e) + { + super.onClick(e); + if (e.isCancelled() && _gui != null && (e.getWhoClicked() instanceof Player)) { + _gui.openInventory(); + } + } + + @Override + public void open() + { + this._id = Bukkit.getScheduler().runTaskLater(getPlugin(), this, _time).getTaskId(); + } + + @Override + public void close() + { + Bukkit.getScheduler().cancelTask(_id); + } + + @Override + public void run() + { + Player player = Bukkit.getPlayer(getPlayersUUID()); + if (player == null) + return; + + if (_gui != null) { + _gui.openInventory(); + } else + player.closeInventory(); + } + +} From 832fb4638a65301345f87aad76ae6f5dbc865443 Mon Sep 17 00:00:00 2001 From: Aaron Brock Date: Tue, 28 Jul 2015 17:42:00 -0400 Subject: [PATCH 02/72] More things Signed-off-by: Aaron Brock --- .../mineplex/core/common/util/UtilText.java | 11 + .../mineplex/hub/bonuses/BonusClientData.java | 41 +++ .../mineplex/hub/bonuses/BonusManager.java | 254 ++++++++++++++ .../mineplex/hub/bonuses/BonusRepository.java | 332 ++++++++++++++++++ .../hub/bonuses/commands/GuiCommand.java | 23 ++ .../mineplex/hub/bonuses/gui/BonusGui.java | 35 ++ .../bonuses/gui/buttons/DailyBonusBotton.java | 156 ++++++++ .../hub/bonuses/gui/buttons/PollButton.java | 165 +++++++++ .../bonuses/gui/buttons/RankBonusBotton.java | 172 +++++++++ .../hub/bonuses/gui/buttons/VoteButton.java | 237 +++++++++++++ 10 files changed, 1426 insertions(+) create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusClientData.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/GuiCommand.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusBotton.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusBotton.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java 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 4ae8f94dc..4372b6fba 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 @@ -2,6 +2,8 @@ package mineplex.core.common.util; import java.util.Collection; +import org.apache.commons.lang.WordUtils; + public class UtilText { public static String listToString(Collection inputList, boolean comma) { String out = ""; @@ -84,4 +86,13 @@ public class UtilText { return false; } + + public static String[] wrap(String text, int lineLength) + { + return wrap(text, lineLength, true); + } + + public static String[] wrap(String text, int lineLength, boolean wrapLongerWords) { + return WordUtils.wrap(text, lineLength, "\00D0", wrapLongerWords).split("\00D0"); + } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusClientData.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusClientData.java new file mode 100644 index 000000000..20b35e2c9 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusClientData.java @@ -0,0 +1,41 @@ +package mineplex.hub.bonuses; + +import java.sql.Date; +import java.sql.Timestamp; + +public class BonusClientData { + + private Timestamp _dailyTime; + private Date _rankTime; + private Date _voteTime; + + public Timestamp getDailyTime() + { + return _dailyTime; + } + + public void setDailyTime(Timestamp dailyTime) + { + this._dailyTime = dailyTime; + } + + public Date getRankTime() + { + return _rankTime; + } + + public void setRankTime(Date rankTime) + { + this._rankTime = rankTime; + } + + public Date getVoteTime() + { + return _voteTime; + } + + public void setVoteTime(Date _voteTime) + { + this._voteTime = _voteTime; + } +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java new file mode 100644 index 000000000..a4802e323 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -0,0 +1,254 @@ +package mineplex.hub.bonuses; + +import java.sql.Date; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.TimeZone; +import java.util.function.Consumer; + +import mineplex.core.MiniDbClientPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.Rank; +import mineplex.core.common.util.Callback; +import mineplex.core.donation.DonationManager; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.hub.bonuses.commands.GuiCommand; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.plugin.java.JavaPlugin; + +public class BonusManager extends MiniDbClientPlugin { + + public static final TimeZone TIMEZONE = TimeZone.getTimeZone("UTC"); + + private static long timeOffSet = 0; + + public static long getSqlTime() + { + return getSqlTime(System.currentTimeMillis()); + } + + public static long getSqlTime(long currentTime) + { + return currentTime + timeOffSet; + } + + public static long getLocalTime() + { + return System.currentTimeMillis(); + } + + public static long getLocalTime(long sqlTime) + { + return sqlTime - timeOffSet; + } + + public void updateOffSet() + { + _repository.getTimeOffset(new Callback() { + + @Override + public void run(Long data) + { + System.out.println("Sql time offset is: " + data); + timeOffSet = data; + } + }); + } + + private BonusRepository _repository; + + public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager) + { + super("Bonus", plugin, clientManager); + _repository = new BonusRepository(plugin, this, donationManager); + updateOffSet(); + registerSelf(); + } + + @Override + public void addCommands() + { + addCommand(new GuiCommand(this)); + } + + // Just keeping things up-to-date + @EventHandler + public void onSlow(UpdateEvent event) + { + if (event.getType() != UpdateType.MIN_16) + return; + System.err.println("Updating off set"); + updateOffSet(); + } + + // DAILY BONUS + + private static final long TIME_BETWEEN_BONUSES = 1000 * 60 * 60 * 8; + + public void atteptDailyBonus(final Player player, final Consumer result) + { + if (timeTillDailyBonus(player) > 0) + result.accept(false); + getRepository().atteptDailyBonus(player, result); + } + + public long timeTillDailyBonus(Player player) + { + return nextDailyBonus(player) - getLocalTime(); + } + + + // This calculates the the next daily bonus, IT HAS TO MATCH THE MYSQL STORED FUNCTION. + public long nextDailyBonus(Player player) + { + Timestamp timestamp = Get(player).getDailyTime(); + + if (timestamp == null) + return 0; + + long lastBonus = timestamp.getTime(); + + return getLocalTime(lastBonus + TIME_BETWEEN_BONUSES); + + } + + // RANK BONUS + public void atteptRankBonus(final Player player, final Consumer result) + { + if (timeTillRankBonus(player) > 0) + result.accept(false); + getRepository().atteptRankBonus(player, result); + } + + public long timeTillRankBonus(Player player) + { + return nextRankBonus(player) - getLocalTime(); + } + + + // This calculates the the next rank bonus, IT HAS TO MATCH THE MYSQL STORED FUNCTION. + public long nextRankBonus(Player player) + { + Date date = Get(player).getRankTime(); + + if (date == null) + return 0; + + long lastBonus = date.getTime(); + + + return getNextRankBonusTime(getLocalTime(lastBonus)); + + } + + public static long getNextRankBonusTime(long time) { + + Calendar calendar = Calendar.getInstance(); + calendar.setTimeZone(TIMEZONE); + calendar.setTimeInMillis(time); + + calendar.add(Calendar.MONTH, 1); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + + calendar.set(Calendar.DATE, calendar.getActualMinimum(Calendar.DAY_OF_MONTH)); + + return calendar.getTimeInMillis(); + } + + public int getRankBonusAmount(Player player) + { + Rank rank = getClientManager().Get(player).GetRank(); + + if (rank.Has(Rank.LEGEND)) { + return 30000; + } + + switch (rank) { + case ULTRA: + return 7500; + case HERO: + return 15000; + default: + return 0; + } + } + + + + //VOTE + + public void atteptVoteBonus(final Player player, final Consumer result) + { + if (timeTillRankBonus(player) > 0) + result.accept(false); + getRepository().atteptRankBonus(player, result); + } + + public long timeTillVoteBonus(Player player) + { + return nextVoteTime(player) - getLocalTime(); + } + + // This calculates the the next vote bonus, IT HAS TO MATCH THE MYSQL STORED FUNCTION. + public long nextVoteTime(Player player) + { + Date date = Get(player).getVoteTime(); + if (date == null) + return 0; + long lastBonus = date.getTime(); + + return getNextVoteTime(getLocalTime(lastBonus)); + + } + + public static long getNextVoteTime(long time) { + + Calendar calendar = Calendar.getInstance(); + calendar.setTimeZone(TIMEZONE); + calendar.setTimeInMillis(time); + + calendar.add(Calendar.DAY_OF_YEAR, 1); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + + return calendar.getTimeInMillis(); + } + + + // OTHER + @Override + protected BonusClientData AddPlayer(String player) + { + return new BonusClientData(); + } + + @Override + public void processLoginResultSet(String playerName, ResultSet resultSet) throws SQLException + { + Set(playerName, _repository.loadClientInformation(resultSet)); + } + + @Override + public String getQuery(int accountId, String uuid, String name) + { + return "SELECT * FROM bonus WHERE accountId = '" + accountId + "';"; + } + + public BonusRepository getRepository() + { + return _repository; + } + +} \ No newline at end of file diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java new file mode 100644 index 000000000..fd8fd81ad --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java @@ -0,0 +1,332 @@ +package mineplex.hub.bonuses; + +import java.sql.CallableStatement; +import java.sql.Connection; +import java.sql.Date; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.function.Consumer; + +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.database.DBPool; +import mineplex.core.database.RepositoryBase; +import mineplex.core.database.ResultSetCallable; +import mineplex.core.donation.DonationManager; +import mineplex.core.recharge.Recharge; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.JavaPlugin; + +public class BonusRepository extends RepositoryBase { + + // private static String INSERT_ACCOUNT = + // "INSERT INTO accountPreferences (uuid) VALUES (?) ON DUPLICATE KEY UPDATE uuid=uuid;"; + + private static String CREATE_BONUS_TABLE = "CREATE TABLE IF NOT EXISTS bonus (accountId INT NOT NULL AUTO_INCREMENT, dailytime TIMESTAMP NULL DEFAULT NULL, ranktime DATE NULL DEFAULT NULL, PRIMARY KEY (accountId), FOREIGN KEY (accountId) REFERENCES accounts(id));"; + private BonusManager _manager; + private DonationManager _donationManager; + + public BonusRepository(JavaPlugin plugin, BonusManager bonusManager, DonationManager donationManager) + { + super(plugin, DBPool.ACCOUNT); + _manager = bonusManager; + _donationManager = donationManager; + } + + public BonusClientData loadClientInformation(ResultSet resultSet) throws SQLException + { + BonusClientData clientData = new BonusClientData(); + + Date rankTime = null; + Timestamp dailyTime = null; + + while (resultSet.next()) { + rankTime = resultSet.getDate("ranktime"); + dailyTime = resultSet.getTimestamp("dailytime"); + System.err.println("COUNT---COUNT"); + } + + clientData.setRankTime(rankTime); + clientData.setDailyTime(dailyTime); + + return clientData; + } + + public void atteptDailyBonus(final Player player, final Consumer result) + { + if (!Recharge.Instance.usable(player, "AtteptDailyBonus")) { + result.accept(false); + return; + } + final int accountId = _manager.getClientManager().Get(player).getAccountId(); + final int coins = 500; + final int gems = 500; + /* + * if (coins == 0 && gems == 0) { result.accept(false); return; } + */ + final JavaPlugin plug = _manager.getPlugin(); + + Bukkit.getScheduler().runTaskAsynchronously(plug, new Runnable() { + @Override + public void run() + { + try (Connection connection = getConnection(); + CallableStatement callableStatement = connection.prepareCall("{call check_daily(?, ?, ?, ?, ?)}")) { + callableStatement.setInt(1, accountId); + callableStatement.setInt(2, coins); + callableStatement.setInt(3, gems); + callableStatement.registerOutParameter(4, java.sql.Types.BOOLEAN); + callableStatement.registerOutParameter(5, java.sql.Types.TIMESTAMP); + + callableStatement.executeUpdate(); + + final boolean pass = callableStatement.getBoolean(4); + + final Timestamp timeStamp = callableStatement.getTimestamp(5); + + Bukkit.getScheduler().runTask(plug, new Runnable() { + + @Override + public void run() + { + + if (pass) { + _manager.Get(player).setDailyTime(new Timestamp(BonusManager.getSqlTime())); + + _donationManager.RewardCoins(new Callback() { + + @Override + public void run(Boolean data) + { + if (data == false) + UtilPlayer.message(player, F.main("Fail", "Coins failed...")); + } + }, "Daily bonus", player.getName(), accountId, coins); + + _donationManager.RewardGems(new Callback() { + + @Override + public void run(Boolean data) + { + if (data == false) + UtilPlayer.message(player, F.main("Fail", "Gems failed...")); + } + }, "Daily bonus", player.getName(), player.getUniqueId(), gems); + + result.accept(true); + } else { + Recharge.Instance.use(player, "AtteptDailyBonus", 1000 * 10, false, false); + _manager.Get(player).setDailyTime(timeStamp); + result.accept(false); + } + } + }); + } catch (Exception e) { + Recharge.Instance.use(player, "AtteptDailyBonus", 1000 * 30, false, false); + e.printStackTrace(); + result.accept(false); + } + } + }); + } + + public void atteptRankBonus(final Player player, final Consumer result) + { + if (!Recharge.Instance.usable(player, "AtteptRankBonus")) { + result.accept(false); + return; + } + final int accountId = _manager.getClientManager().Get(player).getAccountId(); + final int coins = _manager.getRankBonusAmount(player); + + final int gems = 0; + + if (coins == 0/* && gems == 0 */) { + result.accept(false); + return; + } + + final JavaPlugin plug = _manager.getPlugin(); + + Bukkit.getScheduler().runTaskAsynchronously(plug, new Runnable() { + + @Override + public void run() + { + + try (Connection connection = getConnection(); + CallableStatement callableStatement = connection.prepareCall("{call check_rank(?, ?, ?, ?, ?)}")) { + callableStatement.setInt(1, accountId); + callableStatement.setInt(2, coins); + callableStatement.setInt(3, gems); + callableStatement.registerOutParameter(4, java.sql.Types.BOOLEAN); + callableStatement.registerOutParameter(5, java.sql.Types.DATE); + + callableStatement.executeUpdate(); + + final boolean pass = callableStatement.getBoolean(4); + + final Date date = callableStatement.getDate(5); + + Bukkit.getScheduler().runTask(plug, new Runnable() { + + @Override + public void run() + { + _manager.Get(player).setRankTime(date); + + if (pass) { + + _donationManager.RewardCoins(new Callback() { + + @Override + public void run(Boolean data) + { + if (data == false) + UtilPlayer.message(player, F.main("Fail", "Coins failed...")); + } + + }, "Rank bonus", player.getName(), accountId, coins); + + _donationManager.RewardGems(new Callback() { + + @Override + public void run(Boolean data) + { + if (data == false) + UtilPlayer.message(player, F.main("Fail", "Gems failed...")); + } + + }, "Rank bonus", player.getName(), player.getUniqueId(), gems); + + result.accept(true); + } else { + Recharge.Instance.use(player, "AtteptRankBonus", 1000 * 10, false, false); + result.accept(false); + } + } + }); + } catch (Exception e) { + Recharge.Instance.use(player, "AtteptRankBonus", 1000 * 30, false, false); + e.printStackTrace(); + result.accept(false); + } + } + }); + } + + public void voteBonus(final Player player, final Consumer result) + { + if (!Recharge.Instance.usable(player, "AtteptVoteBonus")) + { + result.accept(false); + return; + } + final int accountId = _manager.getClientManager().Get(player).getAccountId(); + final int coins = _manager.getRankBonusAmount(player); + + final int gems = 0; + + if (coins == 0/* && gems == 0 */) { + result.accept(false); + return; + } + + final JavaPlugin plug = _manager.getPlugin(); + + Bukkit.getScheduler().runTaskAsynchronously(plug, new Runnable() { + + @Override + public void run() + { + + try (Connection connection = getConnection(); + CallableStatement callableStatement = connection.prepareCall("{call check_vote(?, ?, ?, ?, ?)}")) { + callableStatement.setInt(1, accountId); + callableStatement.setInt(2, coins); + callableStatement.setInt(3, gems); + callableStatement.registerOutParameter(4, java.sql.Types.DATE); + + callableStatement.executeUpdate(); + + //final boolean pass = callableStatement.getBoolean(4); + + final Date date = callableStatement.getDate(4); + + Bukkit.getScheduler().runTask(plug, new Runnable() { + + @Override + public void run() + { + _manager.Get(player).setVoteTime(date); + + _donationManager.RewardCoins(null, "Vote bonus", player.getName(), accountId, coins); + _donationManager.RewardGems(null, "Vote bonus", player.getName(), player.getUniqueId(), gems); + + result.accept(true); + + } + }); + } catch (Exception e) { + e.printStackTrace(); + result.accept(false); + } + } + }); + } + + public void getTimeOffset(final Callback callback) + { + final long startTime = System.currentTimeMillis(); + final Plugin plugin = _manager.getPlugin(); + + Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() { + @Override + public void run() + { + executeQuery("SELECT CURRENT_TIMESTAMP", new ResultSetCallable() { + @Override + public void processResultSet(ResultSet resultSet) throws SQLException + { + resultSet.next(); + + long theirTimeUnadjusted = resultSet.getTimestamp(1).getTime(); + + long ourCurrentTime = System.currentTimeMillis(); + + long latencyOffset = (ourCurrentTime - startTime) / 2; + + long theirTime = theirTimeUnadjusted - latencyOffset; + + final long offSet = theirTime - ourCurrentTime; + + Bukkit.getScheduler().runTask(plugin, new Runnable() { + @Override + public void run() + { + callback.run(offSet); + } + }); + } + }); + } + }); + } + + @Override + protected void initialize() + { + executeUpdate(CREATE_BONUS_TABLE); + } + + @Override + protected void update() + { + } + +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/GuiCommand.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/GuiCommand.java new file mode 100644 index 000000000..79247514a --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/GuiCommand.java @@ -0,0 +1,23 @@ +package mineplex.hub.bonuses.commands; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.Rank; +import mineplex.hub.bonuses.BonusManager; +import mineplex.hub.bonuses.gui.BonusGui; + +public class GuiCommand extends CommandBase{ + + public GuiCommand(BonusManager plugin) + { + super(plugin, Rank.ALL, "bonus"); + } + + @Override + public void Execute(Player caller, String[] args) + { + new BonusGui(Plugin.getPlugin(), caller, Plugin).openInventory(); + } + +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java new file mode 100644 index 000000000..c8a1b4263 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java @@ -0,0 +1,35 @@ +package mineplex.hub.bonuses.gui; + +import mineplex.core.gui.SimpleGui; +import mineplex.hub.bonuses.BonusManager; +import mineplex.hub.bonuses.gui.buttons.DailyBonusBotton; +import mineplex.hub.bonuses.gui.buttons.RankBonusBotton; +import mineplex.hub.bonuses.gui.buttons.VoteButton; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +public class BonusGui extends SimpleGui { + + private BonusManager manager; + + public BonusGui(Plugin plugin, Player player, BonusManager manager) + { + super(plugin, player, player.getName() + "'s Bonuses", 6 * 9); + + this.manager = manager; + + getBottonMap().put(12, new VoteButton(plugin, player, this, manager)); + + getBottonMap().put(14, new RankBonusBotton(getPlugin(), player, this, manager)); + + getBottonMap().put(16, new DailyBonusBotton(getPlugin(), player, this, manager)); + } + + @Override + protected void finalize() throws Throwable + { + System.err.println("Deleting the MailboxGui!"); + super.finalize(); + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusBotton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusBotton.java new file mode 100644 index 000000000..01e705ec6 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusBotton.java @@ -0,0 +1,156 @@ +package mineplex.hub.bonuses.gui.buttons; + +import java.util.function.Consumer; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilTime.TimeUnit; +import mineplex.core.gui.GuiItem; +import mineplex.core.gui.ItemRefreasher; +import mineplex.core.gui.pages.LoadingWindow; +import mineplex.core.gui.pages.TimedMessageWindow; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.hub.bonuses.BonusManager; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; + +public class DailyBonusBotton implements GuiItem, Listener { + + + private ItemStack _item; + + private long bonusTime; + + private Player _player; + private Plugin _plugin; + private ItemRefreasher _gui; + + private BonusManager _bonusManager; + + public DailyBonusBotton(Plugin plugin, Player player, ItemRefreasher gui, BonusManager bonusManager) + { + this._bonusManager = bonusManager; + this._player = player; + this._plugin = plugin; + this._gui = gui; + } + + @Override + public void setup() + { + this.bonusTime = _bonusManager.nextDailyBonus(getPlayer()); + Bukkit.getPluginManager().registerEvents(this, getPlugin()); + setItem(); + } + + @Override + public void close() + { + HandlerList.unregisterAll(this); + } + + + @Override + public void click(ClickType clickType) + { + if (isAvailable()) { + _item = ItemStackFactory.Instance.CreateStack(Material.LAPIS_BLOCK, (byte)0, 1, ChatColor.BLUE + "Processing..."); + refreashItem(); + new LoadingWindow(getPlugin(), getPlayer(), 6*9); + _bonusManager.atteptDailyBonus(getPlayer(), new Consumer() { + @SuppressWarnings("deprecation") + @Override + public void accept(Boolean t) + { + if (t) { + if (getPlayer().getOpenInventory() != null) { + new TimedMessageWindow(getPlugin(), getPlayer(), ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, DyeColor.LIME.getData(), 1, ChatColor.GREEN + "Bonus collected!"), "Bonus collected!", 6*9, 20*3, getGui()).openInventory(); + } else { + UtilPlayer.message(getPlayer(), F.main("Bonus", "Bonus collected!")); + } + getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); + } else { + if (getPlayer().getOpenInventory() != null) { + new TimedMessageWindow(getPlugin(), getPlayer(), ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, DyeColor.RED.getData(), 1, ChatColor.RED + "Failed to collect bonus!"), "Failed to collect bonus!", 6*9, 20*3, getGui()).openInventory(); + } else { + UtilPlayer.message(getPlayer(), F.main("Bonus", "Failed to collect bonus!")); + } + getPlayer().playSound(getPlayer().getLocation(), Sound.ENDERDRAGON_GROWL, 1, 10); + } + } + }); + } else + getPlayer().playSound(getPlayer().getLocation(), Sound.ITEM_BREAK, 1, 10); + return; + + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (!event.getType().equals(UpdateType.SEC)) + return; + setItem(); + } + + @Override + public ItemStack getObject() + { + return _item; + } + + public void refreashItem() { + getGui().refreashItem(this); + } + + public void setItem() + { + if (isAvailable()) { + _item = ItemStackFactory.Instance.CreateStack(Material.CHEST, (byte) 0, 1, ChatColor.GREEN + "Click to collect daily bonus!"); + } else { + _item = ItemStackFactory.Instance.CreateStack(Material.REDSTONE_BLOCK, (byte) 0, 1, ChatColor.RED + "Next daily bonus in:", new String[] {ChatColor.WHITE + UtilTime.convertString(timeLeft(), 0, TimeUnit.FIT) }); + } + refreashItem(); + } + + public long timeLeft() + { + long timeLeft = this.bonusTime - System.currentTimeMillis(); + System.err.println(timeLeft); + return timeLeft; + } + + public boolean isAvailable() + { + return (timeLeft() <= 0); + } + + public Plugin getPlugin() + { + return _plugin; + } + + public Player getPlayer() + { + return _player; + } + + public ItemRefreasher getGui() + { + return _gui; + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java new file mode 100644 index 000000000..3a31a2e19 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java @@ -0,0 +1,165 @@ +package mineplex.hub.bonuses.gui.buttons; + +import java.util.HashMap; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.UtilText; +import mineplex.core.gui.GuiInventory; +import mineplex.core.gui.GuiItem; +import mineplex.core.gui.SimpleGui; +import mineplex.core.gui.SimpleGuiItem; +import mineplex.core.gui.botton.BackBotton; +import mineplex.core.gui.pages.TimedMessageWindow; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.hub.poll.Poll; +import mineplex.hub.poll.PollManager; + +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.plugin.Plugin; + +public class PollButton extends SimpleGui implements GuiItem { + + protected boolean _create; + + private PollManager _pollManager; + private CoreClientManager _clientManager; + private GuiInventory _master; + + private HashMap hard = new HashMap(); + + private Poll _poll; + + public PollButton(Plugin plugin, Player player, PollManager pollManager, CoreClientManager clientManager, GuiInventory master) + { + super(plugin, player, "Poll:", 6 * 9); + this._create = true; + this._master = master; + this._clientManager = clientManager; + this._pollManager = pollManager; + hard.put(0, new BackBotton(master)); + } + + @Override + public void setup() + { + if (_create) { + this._poll = _pollManager.getNextPoll(_pollManager.Get(getPlayer()), _clientManager.Get(getPlayer()).GetRank()); + + setBottonMap(new HashMap()); + + if (_poll != null) { + + getBottonMap().putAll(hard); + + getBottonMap().put(4, getQuestionItem(_poll.getQuestion())); + + int[] slots = even(9, _poll.getAnswers().length); + + for (int i = 0; i < slots.length; i++) { + + getBottonMap().put(9 * 2 + slots[i], new AnswerItem(_poll, i)); + + } + } + } + } + + + @Override + public ItemStack getObject() + { + if (_poll == null) + return ItemStackFactory.Instance.CreateStack(Material.REDSTONE_BLOCK, (byte) 0, 1, "No polls!"); + else + return ItemStackFactory.Instance.CreateStack(Material.BOOK_AND_QUILL, (byte) 0, 1, ChatColor.GREEN + _poll.getQuestion()); + } + + @Override + public void click(ClickType clickType) + { + if (_poll == null) { + getPlayer().playSound(getPlayer().getLocation(), Sound.ITEM_BREAK, 1, 1.6f); + } else { + getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); + openInventory(); + } + } + + public GuiItem getQuestionItem(String question) + { + return new SimpleGuiItem(ItemStackFactory.Instance.CreateStack(Material.BOOK_AND_QUILL, (byte) 0, 1, ChatColor.GREEN + "Question:", + wrap(question))); + } + + public static String[] wrap(String text) + { + return UtilText.wrap(text, 40); + } + + public static int[] even(int size, int amount) + { + int[] list = new int[amount]; + + float interval = (size / amount); + float offset = -(interval / 2); + + for (int i = 1; i <= amount; i++) { + list[i - 1] = (int) (Math.ceil(i * interval) + offset); + } + return list; + } + + public Poll getPoll() + { + return _poll; + } + + public GuiInventory getMaster() + { + return _master; + } + + private class AnswerItem implements GuiItem { + + private int num; + + private AnswerItem(Poll poll, int num) + { + this.num = num; + } + + @Override + public ItemStack getObject() + { + return ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, ChatColor.GREEN + "" + (num + 1) + ":", wrap(getPoll() + .getAnswers()[num])); + } + + @Override + public void click(ClickType clickType) + { + _create = true; + + _pollManager.answerPoll(getPlayer(), _poll, num); + + getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); + new TimedMessageWindow(getPlugin(), getPlayer(), ItemStackFactory.Instance.CreateStack(Material.EMERALD_BLOCK, (byte) 0, 1, ChatColor.GREEN + "Your anwser:", wrap(getPoll().getAnswers()[num])), ChatColor.GREEN + "Moo", 6 * 9, 50, getMaster()).openInventory(); + + } + + @Override + public void setup() {} + + @Override + public void close() {} + + } + + @Override + public void close() {} +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusBotton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusBotton.java new file mode 100644 index 000000000..03db7ef7c --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusBotton.java @@ -0,0 +1,172 @@ +package mineplex.hub.bonuses.gui.buttons; + +import java.util.function.Consumer; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilTime.TimeUnit; +import mineplex.core.gui.GuiItem; +import mineplex.core.gui.ItemRefreasher; +import mineplex.core.gui.pages.LoadingWindow; +import mineplex.core.gui.pages.TimedMessageWindow; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.hub.bonuses.BonusManager; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; + +public class RankBonusBotton implements GuiItem, Listener { + + private boolean hasRank; + + private ItemStack _item; + + private long bonusTime; + + private Player _player; + private Plugin _plugin; + private ItemRefreasher _gui; + + private BonusManager _bonusManager; + + public RankBonusBotton(Plugin plugin, Player player, ItemRefreasher gui, BonusManager bonusManager) + { + this._bonusManager = bonusManager; + this._player = player; + this._plugin = plugin; + this._gui = gui; + } + + @Override + public void setup() + { + if (_bonusManager.getRankBonusAmount(getPlayer()) > 0) + { + this.hasRank = true; + this.bonusTime = _bonusManager.nextRankBonus(getPlayer()); + Bukkit.getPluginManager().registerEvents(this, getPlugin()); + } + else + { + this.hasRank = false; + } + setItem(); + } + + @Override + public void close() + { + HandlerList.unregisterAll(this); + } + + + @Override + public void click(ClickType clickType) + { + if (isAvailable()) { + _item = ItemStackFactory.Instance.CreateStack(Material.LAPIS_BLOCK, (byte)0, 1, ChatColor.BLUE + "Processing..."); + refreashItem(); + new LoadingWindow(getPlugin(), getPlayer(), 6*9); + _bonusManager.atteptRankBonus(getPlayer(), new Consumer() { + @SuppressWarnings("deprecation") + @Override + public void accept(Boolean t) + { + if (t) { + if (getPlayer().getOpenInventory() != null) { + new TimedMessageWindow(getPlugin(), getPlayer(), ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, DyeColor.LIME.getData(), 1, ChatColor.GREEN + "Bonus collected!"), "Bonus collected!", 6*9, 20*3, getGui()).openInventory(); + } else { + UtilPlayer.message(getPlayer(), F.main("Bonus", "Bonus collected!")); + } + getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); + } else { + if (getPlayer().getOpenInventory() != null) { + new TimedMessageWindow(getPlugin(), getPlayer(), ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, DyeColor.RED.getData(), 1, ChatColor.RED + "Failed to collect bonus!"), "Failed to collect bonus!", 6*9, 20*3, getGui()).openInventory(); + } else { + UtilPlayer.message(getPlayer(), F.main("Bonus", "Failed to collect bonus!")); + } + getPlayer().playSound(getPlayer().getLocation(), Sound.ENDERDRAGON_GROWL, 1, 10); + } + } + }); + } else + getPlayer().playSound(getPlayer().getLocation(), Sound.ITEM_BREAK, 1, 10); + return; + + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (!event.getType().equals(UpdateType.SEC)) + return; + setItem(); + } + + @Override + public ItemStack getObject() + { + return _item; + } + + public void refreashItem() { + getGui().refreashItem(this); + } + + public void setItem() + { + if (!hasRank) + { + _item = ItemStackFactory.Instance.CreateStack(Material.COAL_BLOCK, (byte) 0, 1, ChatColor.YELLOW + "Buy rank plz!"); + } + else if (isAvailable()) + { + _item = ItemStackFactory.Instance.CreateStack(Material.ENDER_CHEST, (byte) 0, 1, ChatColor.GREEN + "Click to collect rank bonus!"); + } + else + { + _item = ItemStackFactory.Instance.CreateStack(Material.REDSTONE_BLOCK, (byte) 0, 1, ChatColor.RED + "Next Rank bonus in:", new String[] {ChatColor.WHITE + UtilTime.convertString(timeLeft(), 0, TimeUnit.FIT) }); + } + refreashItem(); + } + + public long timeLeft() + { + return this.bonusTime - System.currentTimeMillis(); + } + + public boolean isAvailable() + { + if (!hasRank) + return false; + return (timeLeft() <= 0); + } + + public Plugin getPlugin() + { + return _plugin; + } + + public Player getPlayer() + { + return _player; + } + + public ItemRefreasher getGui() + { + return _gui; + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java new file mode 100644 index 000000000..7c89af49e --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java @@ -0,0 +1,237 @@ +package mineplex.hub.bonuses.gui.buttons; + +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilTime.TimeUnit; +import mineplex.core.gui.GuiItem; +import mineplex.core.gui.ItemRefreasher; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.hub.bonuses.BonusManager; +import net.minecraft.server.v1_7_R4.ChatSerializer; +import net.minecraft.server.v1_7_R4.IChatBaseComponent; +import net.minecraft.server.v1_7_R4.PacketPlayOutChat; + +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.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; + +public class VoteButton implements GuiItem, Listener { + + private ItemStack _item; + + private long bonusTime; + + private String _url; + + private Player _player; + private Plugin _plugin; + private ItemRefreasher _gui; + + private BonusManager _bonusManager; + + public VoteButton(Plugin plugin, Player player, ItemRefreasher gui, BonusManager bonusManager) + { + this._bonusManager = bonusManager; + this._player = player; + this._plugin = plugin; + this._gui = gui; + } + + @Override + public void setup() + { + //TODO get url from db + _url = "http://minecraftservers.org/server/121070"; + + this.bonusTime = _bonusManager.nextVoteTime(getPlayer()); + + //if (_url != null) + Bukkit.getPluginManager().registerEvents(this, getPlugin()); + + setItem(); + } + + @Override + public void close() + { + HandlerList.unregisterAll(this); + } + + + @Override + public void click(ClickType clickType) + { + if (isAvailable()) { + getPlayer().closeInventory(); + + getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); + + // TODO This probably needs to be redone, I just looked stuff up and + // pasted it together + + UtilPlayer.message(getPlayer(), "============================================="); + UtilPlayer.message(getPlayer(), ""); + IChatBaseComponent comp = ChatSerializer.a("{\"text\":\"" + " " + "\",\"extra\":[{\"text\":\"" + ChatColor.GREEN + + + "---==Click to vote==---\",\"hoverEvent\":{\"action\":\"show_text\",\"value\":\"" + ChatColor.GREEN + + + _url.replace("http://", "").replace("https://", "") + "\"},\"clickEvent\":{\"action\":\"open_url\",\"value\":\"" + _url + + + "\"}}]}"); + + UtilPlayer.sendPacket(_player, new PacketPlayOutChat(comp, true)); + UtilPlayer.message(getPlayer(), ""); + UtilPlayer.message(getPlayer(), "============================================="); + + + + getPlayer().closeInventory(); + + } else + getPlayer().playSound(getPlayer().getLocation(), Sound.ITEM_BREAK, 1, 10); + return; + + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (!event.getType().equals(UpdateType.SEC)) + return; + setItem(); + } + + @Override + public ItemStack getObject() + { + return _item; + } + + public void refreashItem() { + getGui().refreashItem(this); + } + + public void setItem() + { + if (isAvailable()) { + _item = ItemStackFactory.Instance.CreateStack(Material.JUKEBOX, (byte) 0, 1, ChatColor.GREEN + "Click to vote!"); + } else { + _item = ItemStackFactory.Instance.CreateStack(Material.REDSTONE_BLOCK, (byte) 0, 1, ChatColor.RED + "Next link in:", new String[] {ChatColor.WHITE + UtilTime.convertString(timeLeft(), 0, TimeUnit.FIT) }); + } + refreashItem(); + } + + public long timeLeft() + { + return this.bonusTime - System.currentTimeMillis(); + } + + public boolean isAvailable() + { + if (_url == null) + return false; + return (timeLeft() <= 0); + } + + public Plugin getPlugin() + { + return _plugin; + } + + public Player getPlayer() + { + return _player; + } + + public ItemRefreasher getGui() + { + return _gui; + } +} + + + + + + + + + +/*implements GuiItem { + + private ItemStack _item; + private String _url; + private Player _player; + + public VoteButton(Player player) + { + this._player = player; + + //TODO get url from somewhere + _url = "http://minecraftservers.org/server/121070"; + + //TODO check if claimed + boolean claimed = false; + + if (_url == null) + _item = ItemStackFactory.Instance.CreateStack(Material.REDSTONE_BLOCK, (byte) 0, 1, ChatColor.RED + "Nothing to vote for!"); + else if (claimed) { + _item = ItemStackFactory.Instance.CreateStack(Material.REDSTONE_BLOCK, (byte) 0, 1, ChatColor.RED + "You have already voted!"); + _url = null; + } else + _item = ItemStackFactory.Instance.CreateStack(Material.JUKEBOX, (byte) 0, 1, ChatColor.GREEN + "Click to vote!"); + } + + @Override + public void setup() + { + + } + + @Override + public void close() + { + + } + + @Override + public void click(ClickType clickType) + { + if (_url == null) { + getPlayer().playSound(getPlayer().getLocation(), Sound.ITEM_BREAK, 1, 10); + return; + } + getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); + // TODO This probably needs to be redone, I just looked stuff up and + // pasted it together + IChatBaseComponent comp = ChatSerializer.a("{\"text\":\"" + ChatColor.BLUE + "Vote> \",\"extra\":[{\"text\":\"" + ChatColor.GREEN + + "Click to vote!\",\"hoverEvent\":{\"action\":\"show_text\",\"value\":\"" + ChatColor.GREEN + + _url.replace("http://", "").replace("https://", "") + "\"},\"clickEvent\":{\"action\":\"open_url\",\"value\":\"" + _url + + "\"}}]}"); + + UtilPlayer.sendPacket(_player, new PacketPlayOutChat(comp, true)); + getPlayer().closeInventory(); + } + + @Override + public ItemStack getObject() + { + return _item; + } + + public Player getPlayer() + { + return _player; + } +} +*/ From 971908d38b2c845201c82f8397c936de36da7769 Mon Sep 17 00:00:00 2001 From: Aaron Brock Date: Tue, 28 Jul 2015 17:52:43 -0400 Subject: [PATCH 03/72] Stuff Signed-off-by: Aaron Brock --- Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java | 7 ++++++- .../src/mineplex/hub/bonuses/BonusManager.java | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index 2e1dbc813..ab4feea5b 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -86,6 +86,7 @@ import mineplex.core.task.TaskManager; import mineplex.core.treasure.TreasureManager; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; +import mineplex.hub.bonuses.BonusManager; import mineplex.hub.commands.ForcefieldRadius; import mineplex.hub.commands.GadgetToggle; import mineplex.hub.commands.GameModeCommand; @@ -198,7 +199,11 @@ public class HubManager extends MiniClientPlugin new NotificationManager(getPlugin(), clientManager); ((CraftWorld)Bukkit.getWorlds().get(0)).getHandle().pvpMode = true; - + + + new BonusManager(plugin, clientManager, donationManager); + + // NotificationManager notificationManager = new NotificationManager(plugin, clientManager, donationManager); // new MailManager(_plugin, notificationManager); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index a4802e323..1f2b34058 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -235,7 +235,7 @@ public class BonusManager extends MiniDbClientPlugin { } @Override - public void processLoginResultSet(String playerName, ResultSet resultSet) throws SQLException + public void processLoginResultSet(String playerName, int accountId, ResultSet resultSet) throws SQLException { Set(playerName, _repository.loadClientInformation(resultSet)); } @@ -250,5 +250,7 @@ public class BonusManager extends MiniDbClientPlugin { { return _repository; } + + } \ No newline at end of file From da94c30c021677e8b6ea8820d03cdc557b97ff50 Mon Sep 17 00:00:00 2001 From: Aaron Brock Date: Tue, 28 Jul 2015 18:06:00 -0400 Subject: [PATCH 04/72] Stuff Signed-off-by: Aaron Brock --- .../mineplex/core/common/util/UtilMath.java | 6 +++++ .../mineplex/core/common/util/UtilPlayer.java | 25 +++++++++++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilMath.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilMath.java index c3513308c..72ce23304 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilMath.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilMath.java @@ -85,5 +85,11 @@ public class UtilMath return Math.random() * d; } + + public static T randomElement(T[] array) { + if (array.length == 0) + return null; + return array[random.nextInt(array.length)]; + } } 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 322a55134..321f16789 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 @@ -6,20 +6,23 @@ import java.util.LinkedList; import java.util.List; import java.util.UUID; +import net.minecraft.server.v1_7_R4.EntityPlayer; +import net.minecraft.server.v1_7_R4.Packet; +import net.minecraft.server.v1_7_R4.PlayerConnection; + import org.bukkit.ChatColor; -import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_7_R4.event.CraftEventFactory; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; import org.bukkit.util.Vector; -import net.minecraft.server.v1_7_R4.Packet; -import net.minecraft.server.v1_7_R4.PlayerConnection; - public class UtilPlayer { private static boolean hasIntersection(Vector3D p1, Vector3D p2, Vector3D min, Vector3D max) @@ -608,7 +611,19 @@ public class UtilPlayer return ((CraftPlayer) player).getHandle().spectating; return false; } - + + public static InventoryView swapToInventory(Player player, Inventory inv) { + + EntityPlayer nmsPlayer = ((CraftPlayer) player).getHandle(); + if (nmsPlayer.activeContainer != nmsPlayer.defaultContainer) + { + // Do this so that other inventories know their time is over. + CraftEventFactory.handleInventoryCloseEvent(nmsPlayer); + nmsPlayer.m(); + } + return player.openInventory(inv); + } + /* public void setListName(Player player, CoreClient client) { From fd65f27f0fafe580c057ba10073cf096a5cd8326 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Fri, 31 Jul 2015 10:01:19 -0500 Subject: [PATCH 05/72] Fix some typos/formatting issues --- Plugins/.idea/codeStyleSettings.xml | 2 +- Plugins/.idea/compiler.xml | 2 + Plugins/.idea/misc.xml | 2 +- .../src/mineplex/core/gui/ClickExecutor.java | 3 +- .../src/mineplex/core/gui/GuiItem.java | 3 +- .../src/mineplex/core/gui/ItemRefreasher.java | 5 -- .../src/mineplex/core/gui/ItemRefresher.java | 6 +++ .../src/mineplex/core/gui/SimpleGui.java | 50 ++++++++++--------- .../mineplex/hub/bonuses/BonusClientData.java | 44 ++++++++++++++++ .../mineplex/hub/bonuses/BonusManager.java | 10 ++-- .../mineplex/hub/bonuses/BonusRepository.java | 18 +++---- .../mineplex/hub/bonuses/gui/BonusGui.java | 13 ++--- ...BonusBotton.java => DailyBonusButton.java} | 12 ++--- .../hub/bonuses/gui/buttons/PollButton.java | 30 +++++++---- ...kBonusBotton.java => RankBonusButton.java} | 40 +++++++++------ .../hub/bonuses/gui/buttons/VoteButton.java | 24 +++++---- 16 files changed, 168 insertions(+), 96 deletions(-) delete mode 100644 Plugins/Mineplex.Core/src/mineplex/core/gui/ItemRefreasher.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/gui/ItemRefresher.java rename Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/{DailyBonusBotton.java => DailyBonusButton.java} (93%) rename Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/{RankBonusBotton.java => RankBonusButton.java} (84%) diff --git a/Plugins/.idea/codeStyleSettings.xml b/Plugins/.idea/codeStyleSettings.xml index 8e890f86b..f428c40c9 100644 --- a/Plugins/.idea/codeStyleSettings.xml +++ b/Plugins/.idea/codeStyleSettings.xml @@ -37,6 +37,6 @@ - - + \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/votifier/RedisVotifierCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/votifier/RedisVotifierCommand.java index b5e12e2e3..7b92598b3 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/votifier/RedisVotifierCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/votifier/RedisVotifierCommand.java @@ -1,9 +1,14 @@ package mineplex.core.votifier; +import java.util.UUID; + import mineplex.serverdata.commands.ServerCommand; public class RedisVotifierCommand extends ServerCommand { + private UUID _voterUUID; + + public RedisVotifierCommand() { diff --git a/Plugins/Mineplex.Votifier/plugin.yml b/Plugins/Mineplex.Votifier/plugin.yml index dca987662..75a40f893 100644 --- a/Plugins/Mineplex.Votifier/plugin.yml +++ b/Plugins/Mineplex.Votifier/plugin.yml @@ -1,3 +1,3 @@ -name: Hub +name: MineplexVotifier main: mineplex.votifier.Votifier version: 0.1 \ No newline at end of file diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/Votifier.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/Votifier.java index 8ffdc12d8..5ebb77b02 100644 --- a/Plugins/Mineplex.Votifier/src/mineplex/votifier/Votifier.java +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/Votifier.java @@ -3,6 +3,7 @@ package mineplex.votifier; import org.bukkit.plugin.java.JavaPlugin; import mineplex.core.account.CoreClientManager; +import mineplex.core.command.CommandCenter; import mineplex.core.donation.DonationManager; /** @@ -21,6 +22,7 @@ public class Votifier extends JavaPlugin String webServerAddress = getConfig().getString(WEB_CONFIG); + CommandCenter.Initialize(this); CoreClientManager clientManager = new CoreClientManager(this, webServerAddress); DonationManager donationManager = new DonationManager(this, clientManager, webServerAddress); diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java index 977eab053..30646a1f5 100644 --- a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java @@ -8,6 +8,7 @@ import com.vexsoftware.votifier.model.VotifierEvent; import mineplex.core.MiniPlugin; import mineplex.core.account.CoreClientManager; import mineplex.core.donation.DonationManager; +import mineplex.core.votifier.RedisVotifierCommand; /** * Created by shaun on 15-08-05. @@ -26,6 +27,8 @@ public class VotifierManager extends MiniPlugin { Vote vote = event.getVote(); + RedisVotifierCommand command = new RedisVotifierCommand(); + System.out.println("New Vote: " + vote.getUsername()); } } \ No newline at end of file From 44e30a0903a4edcf17f1c5f86a2064db33a04156 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Thu, 6 Aug 2015 15:34:56 -0500 Subject: [PATCH 16/72] SimpleGui Improvements, Change daily timer to 20 hours, Add Carl Spin button, Starter code for Spin Gui --- .../src/mineplex/core/gui/SimpleGui.java | 155 +++++++++++------- .../src/mineplex/core/reward/Reward.java | 2 + .../core/reward/rewards/CoinReward.java | 13 +- .../core/reward/rewards/InventoryReward.java | 17 ++ .../core/reward/rewards/RankReward.java | 14 ++ .../reward/rewards/UnknownPackageReward.java | 6 + .../mineplex/hub/bonuses/BonusManager.java | 4 +- .../mineplex/hub/bonuses/gui/BonusGui.java | 9 +- .../src/mineplex/hub/bonuses/gui/SpinGui.java | 14 ++ .../bonuses/gui/buttons/CarlSpinButton.java | 44 +++++ .../bonuses/gui/buttons/DailyBonusButton.java | 45 +++-- .../hub/bonuses/gui/buttons/PollButton.java | 11 +- .../bonuses/gui/buttons/RankBonusButton.java | 23 ++- .../hub/bonuses/gui/buttons/RewardButton.java | 47 ++++++ 14 files changed, 294 insertions(+), 110 deletions(-) create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RewardButton.java diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gui/SimpleGui.java b/Plugins/Mineplex.Core/src/mineplex/core/gui/SimpleGui.java index f6fef3357..0029d1864 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gui/SimpleGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gui/SimpleGui.java @@ -1,5 +1,6 @@ package mineplex.core.gui; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -15,12 +16,16 @@ import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; public class SimpleGui implements ItemRefresher, Listener { - private Map _buttonMap = new HashMap(); +// private Map _buttonMap = new HashMap(); + private GuiItem[] _items; private Player _player; private Plugin _plugin; @@ -30,25 +35,20 @@ public class SimpleGui implements ItemRefresher, Listener public SimpleGui(Plugin plugin, Player player) { - this(plugin, player, null, 0, null); + this(plugin, player, null, 0); } public SimpleGui(Plugin plugin, Player player, int size) { - this(plugin, player, null, size, null); + this(plugin, player, null, size); } public SimpleGui(Plugin plugin, Player player, String title) { - this(plugin, player, title, 0, null); + this(plugin, player, title, 0); } public SimpleGui(Plugin plugin, Player player, String title, int size) - { - this(plugin, player, title, size, null); - } - - public SimpleGui(Plugin plugin, Player player, String title, int size, Map buttonMap) { Validate.notNull(plugin, "The plugin cannot be null!"); @@ -67,93 +67,139 @@ public class SimpleGui implements ItemRefresher, Listener else setTitle(title); - if (buttonMap == null) - this._buttonMap = new HashMap(); - else - this._buttonMap = buttonMap; + updateArray(); + + _inv = createInventory(); + refreshInventory(); + } + + private void updateArray() + { + _items = new GuiItem[_size]; + } + + public void setItem(int i, GuiItem item) + { + Validate.isTrue(i >= 0 && i < _size, "Tried to add a gui item outside of inventory range"); + + GuiItem oldItem = getItem(i); + if (oldItem != null) oldItem.close(); + + if (item != null) + { + _items[i] = item; + item.setup(); + } + + refreshItem(i); + } + + public GuiItem getItem(int i) + { + return _items[i]; } @Override public void openInventory() { - _inv = createInventory(); - + refreshInventory(); UtilPlayer.swapToInventory(_player, _inv); Bukkit.getPluginManager().registerEvents(this, _plugin); } public Inventory createInventory() { - for (GuiItem item : new HashSet(getButtonMap().values())) - { - item.setup(); - } - Inventory inv = Bukkit.createInventory(_player, getSize(), getTitle()); - - for (Entry entry : _buttonMap.entrySet()) - { - inv.setItem(entry.getKey(), entry.getValue().getObject()); - } return inv; } - - + + public void refreshInventory() + { + for (int i = 0; i < _size; i++) + { + refreshItem(i); + } + } + @EventHandler public void inventoryClick(InventoryClickEvent event) { - if (!event.getWhoClicked().equals(_player) || !event.getInventory().equals(_inv)) return; - - GuiItem item = _buttonMap.get(event.getSlot()); - System.out.println(item); - if (item == null) - return; - - event.setCancelled(true); - item.click(event.getClick()); + if (event.getSlot() >= 0 && event.getSlot() < _size) + { + GuiItem item = getItem(event.getSlot()); + if (item == null) + return; + + event.setCancelled(true); + + item.click(event.getClick()); + } + } + + @EventHandler + public void teleport(PlayerTeleportEvent event) + { + if (!event.getPlayer().equals(_player)) + return; + + close(); } @EventHandler public void inventoryClose(InventoryCloseEvent event) { - if (!event.getPlayer().equals(_player)) return; - _inv = null; + close(); + } + + @EventHandler + public void quit(PlayerQuitEvent event) + { + if (!event.getPlayer().equals(_player)) + return; + + close(); + } + + private void close() + { +// _inv = null; // TODO - do we really need to null the inventory? HandlerList.unregisterAll(this); - for (GuiItem item : new HashSet(getButtonMap().values())) + for (int i = 0; i < _size; i++) { - item.close(); + GuiItem item = getItem(i); + if (item != null) item.close(); } } - - @Override + @Deprecated public void refreshItem(GuiItem item) { if (_inv == null) return; - for (Entry entry : getButtonMap().entrySet()) + + for (int i = 0; i < _size; i++) { - if (entry.getValue().equals(item)) - _inv.setItem(entry.getKey(), entry.getValue().getObject()); + if (item.equals(getItem(i))) + refreshItem(i); } } public void refreshItem(int slot) { + GuiItem gi = getItem(slot); - GuiItem gi = getButtonMap().get(slot); - if (_inv == null || gi == null) - return; + ItemStack itemStack = null; + if (gi != null) itemStack = gi.getObject(); - _inv.setItem(slot, gi.getObject()); + _inv.setItem(slot, itemStack); } public int getSize() @@ -192,15 +238,4 @@ public class SimpleGui implements ItemRefresher, Listener Validate.isTrue(size % 9 == 0, "The size " + size + " is not divisible by 9"); this._size = size; } - - public Map getButtonMap() - { - return _buttonMap; - } - - public void setButtonMap(Map bottonMap) - { - this._buttonMap = bottonMap; - } - } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/Reward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/Reward.java index 67659dc64..3bd5e8202 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/Reward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/Reward.java @@ -27,6 +27,8 @@ public abstract class Reward protected abstract RewardData giveRewardCustom(Player player); + public abstract RewardData getFakeRewardData(Player player); + public abstract boolean canGiveReward(Player player); public RewardRarity getRarity() diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/CoinReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/CoinReward.java index a0023e137..f6fbd063f 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/CoinReward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/CoinReward.java @@ -37,7 +37,7 @@ public class CoinReward extends Reward @Override public RewardData giveRewardCustom(Player player) { - int gemsToReward = _random.nextInt(_maxCoinCount - _minCoinCount) + _minCoinCount; + int coinsToReward = _random.nextInt(_maxCoinCount - _minCoinCount) + _minCoinCount; _donationManager.RewardCoins(new Callback() { @@ -46,9 +46,16 @@ public class CoinReward extends Reward { } - }, "Treasure Chest", player.getName(), _donationManager.getClientManager().Get(player).getAccountId(), gemsToReward); + }, "Treasure Chest", player.getName(), _donationManager.getClientManager().Get(player).getAccountId(), coinsToReward); - return new RewardData(getRarity().getColor() + gemsToReward + " Coins", new ItemStack(175)); + return new RewardData(getRarity().getColor() + coinsToReward + " Coins", new ItemStack(175)); + } + + @Override + public RewardData getFakeRewardData(Player player) + { + int coinsToReward = _random.nextInt(_maxCoinCount - _minCoinCount) + _minCoinCount; + return new RewardData(getRarity().getColor() + coinsToReward + " Coins", new ItemStack(175)); } @Override diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/InventoryReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/InventoryReward.java index 83c219e1c..68e01acf1 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/InventoryReward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/InventoryReward.java @@ -62,6 +62,23 @@ public class InventoryReward extends Reward return new RewardData(getRarity().getColor() + amountToGive + " " + _name, _itemStack); } + @Override + public RewardData getFakeRewardData(Player player) + { + int amountToGive; + + if (_minAmount != _maxAmount) + { + amountToGive = _random.nextInt(_maxAmount - _minAmount) + _minAmount; + } + else + { + amountToGive = _minAmount; + } + + return new RewardData(getRarity().getColor() + amountToGive + " " + _name, _itemStack); + } + @Override public boolean canGiveReward(Player player) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/RankReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/RankReward.java index 815edb705..bbf22db1f 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/RankReward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/RankReward.java @@ -41,6 +41,20 @@ public class RankReward extends Reward return new RewardData(getRarity().getColor() + rank.Name + " Rank", new ItemStack(Material.NETHER_STAR)); } + @Override + public RewardData getFakeRewardData(Player player) + { + Rank rank = null; + if (_clientManager.Get(player).GetRank() == Rank.ALL) rank = Rank.ULTRA; + else if (_clientManager.Get(player).GetRank() == Rank.ULTRA) rank = Rank.HERO; + else if (_clientManager.Get(player).GetRank() == Rank.HERO) rank = Rank.LEGEND; + + if (rank == null) + return new RewardData(getRarity().getColor() + "Rank Upgrade Error", new ItemStack(Material.PAPER)); + + return new RewardData(getRarity().getColor() + rank.Name + " Rank", new ItemStack(Material.NETHER_STAR)); + } + @Override public boolean canGiveReward(Player player) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/UnknownPackageReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/UnknownPackageReward.java index 6e041ee9b..364820d56 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/UnknownPackageReward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/UnknownPackageReward.java @@ -48,6 +48,12 @@ public class UnknownPackageReward extends Reward return !_donationManager.Get(player.getName()).OwnsUnknownPackage(_packageName); } + @Override + public RewardData getFakeRewardData(Player player) + { + return new RewardData(getRarity().getColor() + _name, _itemStack); + } + protected String getPackageName() { return _packageName; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index 8750d3bfb..5f2c1b0e9 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -121,8 +121,8 @@ public class BonusManager extends MiniClientPlugin implements I // DAILY BONUS - public static final long TIME_BETWEEN_BONUSES = 1000 * 60 * 60 * 16; - public static final long STREAK_RESET_TIME = 1000 * 60 * 60 * 8; + public static final long TIME_BETWEEN_BONUSES = 1000 * 60 * 60 * 20; + public static final long STREAK_RESET_TIME = 1000 * 60 * 60 * 12; public void attemptDailyBonus(final Player player, final BonusAmount amount, final Consumer result) { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java index 74dbe05c0..013873587 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java @@ -2,6 +2,7 @@ package mineplex.hub.bonuses.gui; import mineplex.core.gui.SimpleGui; import mineplex.hub.bonuses.BonusManager; +import mineplex.hub.bonuses.gui.buttons.CarlSpinButton; import mineplex.hub.bonuses.gui.buttons.DailyBonusButton; import mineplex.hub.bonuses.gui.buttons.RankBonusButton; import mineplex.hub.bonuses.gui.buttons.VoteButton; @@ -20,11 +21,13 @@ public class BonusGui extends SimpleGui this.manager = manager; - getButtonMap().put(11, new VoteButton(plugin, player, this, manager)); + setItem(11, new VoteButton(plugin, player, this, manager)); - getButtonMap().put(13, new RankBonusButton(getPlugin(), player, this, manager)); + setItem(13, new RankBonusButton(getPlugin(), player, this, manager)); - getButtonMap().put(15, new DailyBonusButton(getPlugin(), player, this, manager)); + setItem(15, new DailyBonusButton(getPlugin(), player, this, manager)); + + setItem(31, new CarlSpinButton()); } @Override diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java new file mode 100644 index 000000000..c88bde558 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java @@ -0,0 +1,14 @@ +package mineplex.hub.bonuses.gui; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import mineplex.core.gui.SimpleGui; + +public class SpinGui extends SimpleGui +{ + public SpinGui(Plugin plugin, Player player) + { + super(plugin, player); + } +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java new file mode 100644 index 000000000..5262d6c3f --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java @@ -0,0 +1,44 @@ +package mineplex.hub.bonuses.gui.buttons; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.gui.GuiItem; +import mineplex.core.shop.item.ShopItem; + +public class CarlSpinButton implements GuiItem +{ + + public CarlSpinButton() + { + + } + + @Override + public void setup() + { + } + + @Override + public void close() + { + + } + + @Override + public void click(ClickType clickType) + { + + } + + @Override + public ItemStack getObject() + { + ShopItem item = new ShopItem(Material.SKULL_ITEM, (byte) 4, "Carl's Spinner", new String[] {ChatColor.RESET + "Try your Luck!" }, 1, false, false); + + + return item; + } +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java index 4ca85f532..2ba7a359a 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java @@ -33,13 +33,11 @@ import org.bukkit.event.inventory.ClickType; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; -public class DailyBonusButton implements GuiItem, Listener { - +public class DailyBonusButton implements GuiItem, Listener +{ private ItemStack _item; - private long bonusTime; - private Player _player; private Plugin _plugin; private ItemRefresher _gui; @@ -57,7 +55,6 @@ public class DailyBonusButton implements GuiItem, Listener { @Override public void setup() { - this.bonusTime = _bonusManager.nextDailyBonus(getPlayer()); Bukkit.getPluginManager().registerEvents(this, getPlugin()); setItem(); } @@ -68,7 +65,6 @@ public class DailyBonusButton implements GuiItem, Listener { HandlerList.unregisterAll(this); } - @Override public void click(ClickType clickType) { @@ -82,6 +78,9 @@ public class DailyBonusButton implements GuiItem, Listener { public void accept(Boolean t) { if (t) { + + setItem(); + if (getPlayer().getOpenInventory() != null) { new TimedMessageWindow(getPlugin(), getPlayer(), ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, DyeColor.LIME.getData(), 1, ChatColor.GREEN + "Bonus collected!"), "Bonus collected!", 6*9, 20*3, getGui()).openInventory(); } else { @@ -101,7 +100,6 @@ public class DailyBonusButton implements GuiItem, Listener { } else getPlayer().playSound(getPlayer().getLocation(), Sound.ITEM_BREAK, 1, 10); return; - } @EventHandler @@ -109,20 +107,10 @@ public class DailyBonusButton implements GuiItem, Listener { { if (!event.getType().equals(UpdateType.SEC)) return; - setItem(); +// refreshItem(); // Todo Unnecessary? } - - @Override - public ItemStack getObject() - { - return _item; - } - - public void refreshItem() { - getGui().refreshItem(this); - } - - public void setItem() + + private void setItem() { ArrayList lore = new ArrayList(); Material material; @@ -172,14 +160,23 @@ public class DailyBonusButton implements GuiItem, Listener { lore.add(C.cYellow + "Streak: " + C.cWhite + "420"); - _item = new ShopItem(material, itemName, lore.toArray(new String[0]), 1, false, false); - - refreshItem(); + _item = new ShopItem(material, itemName, lore.toArray(new String[0]), 1, false, false); + } + + @Override + public ItemStack getObject() + { + return _item; + } + + public void refreshItem() + { + getGui().refreshItem(this); } public long timeLeft() { - long timeLeft = this.bonusTime - System.currentTimeMillis(); + long timeLeft = _bonusManager.nextDailyBonus(getPlayer()) - System.currentTimeMillis(); return timeLeft; } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java index ce0f3bbb8..9ae72899b 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java @@ -51,21 +51,20 @@ public class PollButton extends SimpleGui implements GuiItem { { this._poll = _pollManager.getNextPoll(_pollManager.Get(getPlayer()), _clientManager.Get(getPlayer()).GetRank()); - setButtonMap(new HashMap()); - if (_poll != null) { - - getButtonMap().putAll(hard); + + // Todo - Fix this! +// getButtonMap().putAll(hard); - getButtonMap().put(4, getQuestionItem(_poll.getQuestion())); + setItem(4, getQuestionItem(_poll.getQuestion())); int[] slots = even(9, _poll.getAnswers().length); for (int i = 0; i < slots.length; i++) { - getButtonMap().put(9 * 2 + slots[i], new AnswerItem(_poll, i)); + setItem(9 * 2 + slots[i], new AnswerItem(_poll, i)); } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java index ee2a9d9ba..e5007bd53 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java @@ -39,8 +39,6 @@ public class RankBonusButton implements GuiItem, Listener { private ItemStack _item; - private long bonusTime; - private Player _player; private Plugin _plugin; private ItemRefresher _gui; @@ -61,13 +59,13 @@ public class RankBonusButton implements GuiItem, Listener { if (_bonusManager.getRankBonusAmount(getPlayer()).isGreaterThanZero()) { this.hasRank = true; - this.bonusTime = _bonusManager.nextRankBonus(getPlayer()); Bukkit.getPluginManager().registerEvents(this, getPlugin()); } else { this.hasRank = false; } + setItem(); } @@ -91,6 +89,8 @@ public class RankBonusButton implements GuiItem, Listener { @Override public void accept(Boolean t) { + setItem(); + if (t) { if (getPlayer().getOpenInventory() != null) @@ -128,7 +128,7 @@ public class RankBonusButton implements GuiItem, Listener { { if (!event.getType().equals(UpdateType.SEC)) return; - setItem(); +// refreshItem(); // Todo Unnecessary? } @Override @@ -136,12 +136,8 @@ public class RankBonusButton implements GuiItem, Listener { { return _item; } - - public void refreshItem() { - getGui().refreshItem(this); - } - - public void setItem() + + private void setItem() { ArrayList lore = new ArrayList(); Material material; @@ -182,13 +178,16 @@ public class RankBonusButton implements GuiItem, Listener { } _item = new ShopItem(material, itemName, lore.toArray(new String[0]), 1, false, false); + } - refreshItem(); + public void refreshItem() + { + _gui.refreshItem(this); } public long timeLeft() { - return this.bonusTime - System.currentTimeMillis(); + return _bonusManager.nextRankBonus(getPlayer()) - System.currentTimeMillis(); } public boolean isAvailable() diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RewardButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RewardButton.java new file mode 100644 index 000000000..5f7b0050b --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RewardButton.java @@ -0,0 +1,47 @@ +package mineplex.hub.bonuses.gui.buttons; + +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import mineplex.core.gui.GuiItem; +import mineplex.core.reward.Reward; +import mineplex.core.reward.RewardData; + +public class RewardButton implements GuiItem +{ + private RewardData _data; + + public RewardButton(RewardData data) + { + _data = data; + } + + @Override + public void setup() + { + + } + + @Override + public void close() + { + + } + + @Override + public void click(ClickType clickType) + { + // Do nothing + } + + @Override + public ItemStack getObject() + { + ItemStack stack = _data.getDisplayItem(); + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName(_data.getFriendlyName()); + stack.setItemMeta(meta); + return stack; + } +} From 6311ceaa0f81a07be1f53494a5347a48f946b8ce Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Thu, 6 Aug 2015 21:15:17 -0500 Subject: [PATCH 17/72] Reward work for new Game reward rarity and setup for carl, work on carl spinner --- .../src/mineplex/core/gui/DisplayItem.java | 40 +++++++ .../src/mineplex/core/reward/RewardData.java | 9 +- .../mineplex/core/reward/RewardManager.java | 12 ++ .../mineplex/core/reward/RewardRarity.java | 44 ++++++-- .../src/mineplex/core/reward/RewardType.java | 16 ++- .../core/reward/rewards/CoinReward.java | 5 +- .../core/reward/rewards/GemReward.java | 75 +++++++++++++ .../core/reward/rewards/InventoryReward.java | 15 +-- .../core/reward/rewards/RankReward.java | 8 +- .../reward/rewards/UnknownPackageReward.java | 4 +- .../core/treasure/TreasureManager.java | 9 +- .../src/mineplex/hub/HubManager.java | 13 ++- .../mineplex/hub/bonuses/BonusManager.java | 12 +- .../hub/bonuses/commands/GuiCommand.java | 3 +- .../mineplex/hub/bonuses/gui/BonusGui.java | 5 +- .../src/mineplex/hub/bonuses/gui/SpinGui.java | 104 +++++++++++++++++- .../bonuses/gui/buttons/CarlSpinButton.java | 17 ++- 17 files changed, 335 insertions(+), 56 deletions(-) create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/gui/DisplayItem.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/GemReward.java diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gui/DisplayItem.java b/Plugins/Mineplex.Core/src/mineplex/core/gui/DisplayItem.java new file mode 100644 index 000000000..87e844b1c --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gui/DisplayItem.java @@ -0,0 +1,40 @@ +package mineplex.core.gui; + +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.gui.GuiItem; + +public class DisplayItem implements GuiItem +{ + private ItemStack _item; + + public DisplayItem(ItemStack item) + { + _item = item; + } + + @Override + public void setup() + { + + } + + @Override + public void close() + { + + } + + @Override + public void click(ClickType clickType) + { + + } + + @Override + public ItemStack getObject() + { + return _item; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardData.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardData.java index 77f8b91e3..0a20e5ccf 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardData.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardData.java @@ -9,11 +9,13 @@ public class RewardData { private final String _friendlyName; private final ItemStack _displayItem; + private final RewardRarity _rarity; - public RewardData(String friendlyName, ItemStack displayItem) + public RewardData(String friendlyName, ItemStack displayItem, RewardRarity rarity) { _friendlyName = friendlyName; _displayItem = displayItem; + _rarity = rarity; } public String getFriendlyName() @@ -26,4 +28,9 @@ public class RewardData return _displayItem; } + public RewardRarity getRarity() + { + return _rarity; + } + } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java index 775ab3cd5..b3d467ddc 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java @@ -18,6 +18,7 @@ import mineplex.core.donation.DonationManager; import mineplex.core.inventory.InventoryManager; import mineplex.core.pet.PetManager; import mineplex.core.reward.rewards.CoinReward; +import mineplex.core.reward.rewards.GemReward; import mineplex.core.reward.rewards.InventoryReward; import mineplex.core.reward.rewards.PetReward; import mineplex.core.reward.rewards.RankReward; @@ -53,12 +54,18 @@ public class RewardManager _doubleGadgetValue = doubleGadgetValue; + addGame(donationManager, inventoryManager, petManager); addCommon(donationManager, inventoryManager, petManager, commonValueMin, commonValueMax); addUncommon(donationManager, inventoryManager, petManager, uncommonValueMin, uncommonValueMax); addRare(donationManager, inventoryManager, petManager, rareValueMin, rareValueMax); addLegendary(donationManager, inventoryManager, petManager, legendValueMin, legendValueMax); } + public void addGame(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager) + { + addReward(new GemReward(donationManager, 100, 500, 1, RewardRarity.GAME)); + } + public void addCommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) { RewardRarity rarity = RewardRarity.COMMON; @@ -393,6 +400,11 @@ public class RewardManager } } + System.out.println("null"); + System.out.println("type: " + type.toString()); + System.out.println("rarity: " + rarity); + System.out.println("total weight: " + totalWeight); + return null; } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java index fc186ed03..1f56de46a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java @@ -1,5 +1,9 @@ package mineplex.core.reward; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + import mineplex.core.common.util.C; import static mineplex.core.common.util.C.*; @@ -14,20 +18,31 @@ public enum RewardRarity * (Fireworks, sounds, etc) */ - OTHER("Other", cWhite), - COMMON("Common", cWhite), - UNCOMMON("Uncommon", cAqua), - RARE("Rare", cPurple), - LEGENDARY("Legendary", cGreen), - MYTHICAL("Mythical", cRed); + OTHER("Other", cWhite, Material.STAINED_GLASS_PANE, (byte) 0), + COMMON("Common", cWhite, Material.STAINED_GLASS_PANE, (byte) 0), + GAME("Game", cYellow, Material.STAINED_GLASS_PANE, (byte) 4), + UNCOMMON("Uncommon", cAqua, Material.STAINED_GLASS_PANE, (byte) 3), + RARE("Rare", cPurple, Material.STAINED_GLASS_PANE, (byte) 10), + LEGENDARY("Legendary", cGreen, Material.STAINED_GLASS_PANE, (byte) 5), + MYTHICAL("Mythical", cRed, Material.STAINED_GLASS_PANE, (byte) 14); private String _name; private String _color; + private Material _material; + private byte _data; + private ItemStack _stack; - RewardRarity(String name, String color) + RewardRarity(String name, String color, Material material, byte data) { _name = name; _color = color; + _material = material; + _data = data; + + _stack = new ItemStack(getMaterial(), 1, (short) 0, getData()); + ItemMeta meta = _stack.getItemMeta(); + meta.setDisplayName(_color + _name); + _stack.setItemMeta(meta); } public String getColor() @@ -40,4 +55,19 @@ public enum RewardRarity return _name; } + public Material getMaterial() + { + return _material; + } + + public byte getData() + { + return _data; + } + + public ItemStack getItemStack() + { + return _stack; + } + } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java index 556c7f5e0..febaec152 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java @@ -3,22 +3,25 @@ package mineplex.core.reward; public enum RewardType { //% Chances Mythic Legend Rare Uncommon - GameLoot( 0.000001, 0.00001, 0.0001, 3), - OldChest( 0, 0.05, 0.4, 5), - AncientChest( 0, 1, 4, 25), - MythicalChest( 0.5, 3, 12, 75); + GameLoot( 0.000001, 0.00001, 0.0001, 3, 10), + Spinner( 0.000001, 0.2, 0.8, 10, 10), + OldChest( 0, 0.05, 0.4, 5, 0), + AncientChest( 0, 1, 4, 25, 0), + MythicalChest( 0.5, 3, 12, 75, 0); private double _mythicalChance; private double _legendaryChance; private double _rareChance; private double _uncommonChance; - - RewardType(double mythical, double legend, double rare, double uncommon) + private double _gameChance; + + RewardType(double mythical, double legend, double rare, double uncommon, double game) { _mythicalChance = (mythical / 100d); _legendaryChance = _mythicalChance + (legend / 100d); //Add previous chance to prep for generateRarity random values. _rareChance = _legendaryChance + (rare / 100d); _uncommonChance = _rareChance + (uncommon / 100d); + _gameChance = _uncommonChance + (game / 100d); } public RewardRarity generateRarity(boolean requiresUncommon) @@ -31,6 +34,7 @@ public enum RewardType else if (rand <= _legendaryChance) rarity = RewardRarity.LEGENDARY; else if (rand <= _rareChance) rarity = RewardRarity.RARE; else if (rand <= _uncommonChance || requiresUncommon) rarity = RewardRarity.UNCOMMON; + else if (rand <= _gameChance) rarity = RewardRarity.GAME; return rarity; } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/CoinReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/CoinReward.java index f6fbd063f..1bf59afb9 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/CoinReward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/CoinReward.java @@ -48,14 +48,13 @@ public class CoinReward extends Reward } }, "Treasure Chest", player.getName(), _donationManager.getClientManager().Get(player).getAccountId(), coinsToReward); - return new RewardData(getRarity().getColor() + coinsToReward + " Coins", new ItemStack(175)); + return new RewardData(getRarity().getColor() + coinsToReward + " Coins", new ItemStack(175), getRarity()); } @Override public RewardData getFakeRewardData(Player player) { - int coinsToReward = _random.nextInt(_maxCoinCount - _minCoinCount) + _minCoinCount; - return new RewardData(getRarity().getColor() + coinsToReward + " Coins", new ItemStack(175)); + return new RewardData(getRarity().getColor() + "Coins", new ItemStack(175), getRarity()); } @Override diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/GemReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/GemReward.java new file mode 100644 index 000000000..26e695abb --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/GemReward.java @@ -0,0 +1,75 @@ +package mineplex.core.reward.rewards; + +import java.util.Random; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.Callback; +import mineplex.core.donation.DonationManager; +import mineplex.core.reward.Reward; +import mineplex.core.reward.RewardData; +import mineplex.core.reward.RewardManager; +import mineplex.core.reward.RewardRarity; + +public class GemReward extends Reward +{ + private DonationManager _donationManager; + private Random _random; + private int _minGemCount; + private int _maxGemCount; + + public GemReward(DonationManager donationManager, int minGemCount, int maxGemCount, int weight, RewardRarity rarity) + { + this(donationManager, minGemCount, maxGemCount, weight, rarity, RANDOM); + } + + public GemReward(DonationManager donationManager, int minGemCount, int maxGemCount, int weight, RewardRarity rarity, Random random) + { + super(rarity, weight); + _donationManager = donationManager; + _minGemCount = minGemCount; + _maxGemCount = maxGemCount; + + _random = random; + } + + @Override + public RewardData giveRewardCustom(Player player) + { + int GemsToReward = _random.nextInt(_maxGemCount - _minGemCount) + _minGemCount; + + _donationManager.RewardGems(new Callback() + { + @Override + public void run(Boolean data) + { + + } + }, "Treasure Chest", player.getName(), player.getUniqueId(), GemsToReward); + + return new RewardData(getRarity().getColor() + GemsToReward + " Gems", new ItemStack(Material.EMERALD), getRarity()); + } + + @Override + public RewardData getFakeRewardData(Player player) + { + return new RewardData(getRarity().getColor() + "Gems", new ItemStack(Material.EMERALD), getRarity()); + } + + @Override + public boolean canGiveReward(Player player) + { + return true; + } + + @Override + public boolean equals(Object obj) + { + if (obj instanceof GemReward) + return true; + + return false; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/InventoryReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/InventoryReward.java index 68e01acf1..0eb1504e0 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/InventoryReward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/InventoryReward.java @@ -59,24 +59,13 @@ public class InventoryReward extends Reward _inventoryManager.addItemToInventory(player, "Item", _packageName, amountToGive); - return new RewardData(getRarity().getColor() + amountToGive + " " + _name, _itemStack); + return new RewardData(getRarity().getColor() + amountToGive + " " + _name, _itemStack, getRarity()); } @Override public RewardData getFakeRewardData(Player player) { - int amountToGive; - - if (_minAmount != _maxAmount) - { - amountToGive = _random.nextInt(_maxAmount - _minAmount) + _minAmount; - } - else - { - amountToGive = _minAmount; - } - - return new RewardData(getRarity().getColor() + amountToGive + " " + _name, _itemStack); + return new RewardData(getRarity().getColor() + _name, _itemStack, getRarity()); } @Override diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/RankReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/RankReward.java index bbf22db1f..6c3ce1a6a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/RankReward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/RankReward.java @@ -33,12 +33,12 @@ public class RankReward extends Reward else if (_clientManager.Get(player).GetRank() == Rank.HERO) rank = Rank.LEGEND; if (rank == null) - return new RewardData(getRarity().getColor() + "Rank Upgrade Error", new ItemStack(Material.PAPER)); + return new RewardData(getRarity().getColor() + "Rank Upgrade Error", new ItemStack(Material.PAPER), getRarity()); _clientManager.Get(player).SetRank(rank); _clientManager.getRepository().saveRank(null, player.getName(), player.getUniqueId(), rank, true); - return new RewardData(getRarity().getColor() + rank.Name + " Rank", new ItemStack(Material.NETHER_STAR)); + return new RewardData(getRarity().getColor() + rank.Name + " Rank", new ItemStack(Material.NETHER_STAR), getRarity()); } @Override @@ -50,9 +50,9 @@ public class RankReward extends Reward else if (_clientManager.Get(player).GetRank() == Rank.HERO) rank = Rank.LEGEND; if (rank == null) - return new RewardData(getRarity().getColor() + "Rank Upgrade Error", new ItemStack(Material.PAPER)); + return new RewardData(getRarity().getColor() + "Rank Upgrade Error", new ItemStack(Material.PAPER), getRarity()); - return new RewardData(getRarity().getColor() + rank.Name + " Rank", new ItemStack(Material.NETHER_STAR)); + return new RewardData(getRarity().getColor() + rank.Name + " Rank", new ItemStack(Material.NETHER_STAR), getRarity()); } @Override diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/UnknownPackageReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/UnknownPackageReward.java index 364820d56..af27a817e 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/UnknownPackageReward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/UnknownPackageReward.java @@ -33,7 +33,7 @@ public class UnknownPackageReward extends Reward { _donationManager.PurchaseUnknownSalesPackage(null, player.getName(), _donationManager.getClientManager().Get(player).getAccountId(), _packageName, true, 0, true); - return new RewardData(getRarity().getColor() + _name, _itemStack); + return new RewardData(getRarity().getColor() + _name, _itemStack, getRarity()); } @Override @@ -51,7 +51,7 @@ public class UnknownPackageReward extends Reward @Override public RewardData getFakeRewardData(Player player) { - return new RewardData(getRarity().getColor() + _name, _itemStack); + return new RewardData(getRarity().getColor() + _name, _itemStack, getRarity()); } protected String getPackageName() diff --git a/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java b/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java index 39de66bf0..5746bc978 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java @@ -32,19 +32,14 @@ public class TreasureManager extends MiniPlugin private HologramManager _hologramManager; private List _treasureLocations; - public TreasureManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, BlockRestore blockRestore, HologramManager hologramManager) + public TreasureManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, BlockRestore blockRestore, HologramManager hologramManager, RewardManager rewardManager) { super("Treasure", plugin); _inventoryManager = inventoryManager; _blockRestore = blockRestore; _hologramManager = hologramManager; - _rewardManager = new RewardManager(clientManager, donationManager, inventoryManager, petManager, - 100, 250, - 500, 1000, - 4000, 6000, - 12000, 32000, - true); + _rewardManager = rewardManager; World world = Bukkit.getWorlds().get(0); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index b87554309..2b5188a30 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -78,6 +78,7 @@ import mineplex.core.pet.PetManager; import mineplex.core.portal.Portal; import mineplex.core.preferences.PreferencesManager; import mineplex.core.projectile.ProjectileManager; +import mineplex.core.reward.RewardManager; import mineplex.core.stats.StatsManager; import mineplex.core.task.TaskManager; import mineplex.core.treasure.TreasureManager; @@ -177,7 +178,15 @@ public class HubManager extends MiniClientPlugin _inventoryManager = new InventoryManager(plugin, clientManager); new BenefitManager(plugin, clientManager, _inventoryManager); _gadgetManager = new GadgetManager(_plugin, clientManager, donationManager, _inventoryManager, _mountManager, petManager, preferences, disguiseManager, blockRestore, new ProjectileManager(plugin)); - _treasureManager = new TreasureManager(_plugin, clientManager, donationManager, _inventoryManager, petManager, _blockRestore, hologramManager); + + RewardManager rewardManager = new RewardManager(clientManager, donationManager, _inventoryManager, petManager, + 100, 250, + 500, 1000, + 4000, 6000, + 12000, 32000, + true); + + _treasureManager = new TreasureManager(_plugin, clientManager, donationManager, _inventoryManager, petManager, _blockRestore, hologramManager, rewardManager); new CosmeticManager(_plugin, clientManager, donationManager, _inventoryManager, _gadgetManager, _mountManager, petManager, _treasureManager); _petManager = petManager; @@ -198,7 +207,7 @@ public class HubManager extends MiniClientPlugin ((CraftWorld)Bukkit.getWorlds().get(0)).getHandle().pvpMode = true; - new BonusManager(plugin, clientManager, donationManager, npcManager, hologramManager); + new BonusManager(plugin, clientManager, donationManager, npcManager, hologramManager, rewardManager); // NotificationManager notificationManager = new NotificationManager(plugin, clientManager, donationManager); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index 5f2c1b0e9..f5b67a4a5 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -21,6 +21,7 @@ import mineplex.core.hologram.Hologram; import mineplex.core.hologram.HologramManager; import mineplex.core.npc.Npc; import mineplex.core.npc.NpcManager; +import mineplex.core.reward.RewardManager; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.hub.bonuses.commands.GuiCommand; @@ -84,9 +85,10 @@ public class BonusManager extends MiniClientPlugin implements I private DonationManager _donationManager; private NpcManager _npcManager; private HologramManager _hologramManager; + private RewardManager _rewardManager; private Npc _carlNpc; - public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, NpcManager npcManager, HologramManager hologramManager) + public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, NpcManager npcManager, HologramManager hologramManager, RewardManager rewardManager) { super("Bonus", plugin); _repository = new BonusRepository(plugin, this, donationManager); @@ -94,6 +96,7 @@ public class BonusManager extends MiniClientPlugin implements I _donationManager = donationManager; _npcManager = npcManager; _hologramManager = hologramManager; + _rewardManager = rewardManager; // Hope to god this works! _carlNpc = _npcManager.getNpcByName("Carl the Creeper"); @@ -402,7 +405,7 @@ public class BonusManager extends MiniClientPlugin implements I if (entity instanceof LivingEntity && entity.getType().equals(EntityType.CREEPER) && ((LivingEntity) entity).getCustomName().contains("Carl the Creeper")) { updateDailyStreak(event.getPlayer()); - new BonusGui(_plugin, event.getPlayer(), this).openInventory(); + new BonusGui(_plugin, event.getPlayer(), this, _rewardManager).openInventory(); } } @@ -535,6 +538,11 @@ public class BonusManager extends MiniClientPlugin implements I return _clientManager; } + public RewardManager getRewardManager() + { + return _rewardManager; + } + @Override @EventHandler public void UnloadPlayer(final ClientUnloadEvent event) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/GuiCommand.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/GuiCommand.java index 79247514a..655a94199 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/GuiCommand.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/GuiCommand.java @@ -4,6 +4,7 @@ import org.bukkit.entity.Player; import mineplex.core.command.CommandBase; import mineplex.core.common.Rank; +import mineplex.core.reward.RewardManager; import mineplex.hub.bonuses.BonusManager; import mineplex.hub.bonuses.gui.BonusGui; @@ -17,7 +18,7 @@ public class GuiCommand extends CommandBase{ @Override public void Execute(Player caller, String[] args) { - new BonusGui(Plugin.getPlugin(), caller, Plugin).openInventory(); + new BonusGui(Plugin.getPlugin(), caller, Plugin, Plugin.getRewardManager()).openInventory(); } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java index 013873587..083288461 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java @@ -1,6 +1,7 @@ package mineplex.hub.bonuses.gui; import mineplex.core.gui.SimpleGui; +import mineplex.core.reward.RewardManager; import mineplex.hub.bonuses.BonusManager; import mineplex.hub.bonuses.gui.buttons.CarlSpinButton; import mineplex.hub.bonuses.gui.buttons.DailyBonusButton; @@ -15,7 +16,7 @@ public class BonusGui extends SimpleGui private BonusManager manager; - public BonusGui(Plugin plugin, Player player, BonusManager manager) + public BonusGui(Plugin plugin, Player player, BonusManager manager, RewardManager rewardManager) { super(plugin, player, player.getName() + "'s Bonuses", 5 * 9); @@ -27,7 +28,7 @@ public class BonusGui extends SimpleGui setItem(15, new DailyBonusButton(getPlugin(), player, this, manager)); - setItem(31, new CarlSpinButton()); + setItem(31, new CarlSpinButton(getPlugin(), player, rewardManager)); } @Override diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java index c88bde558..8701b3618 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java @@ -1,14 +1,114 @@ package mineplex.hub.bonuses.gui; +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.EventHandler; +import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; +import mineplex.core.gui.DisplayItem; import mineplex.core.gui.SimpleGui; +import mineplex.core.reward.Reward; +import mineplex.core.reward.RewardData; +import mineplex.core.reward.RewardManager; +import mineplex.core.reward.RewardType; +import mineplex.core.shop.item.ShopItem; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.hub.bonuses.gui.buttons.RewardButton; public class SpinGui extends SimpleGui { - public SpinGui(Plugin plugin, Player player) + private static final int SELECT_OFFSET = 4; + private static final int REWARDS_TO_GENERATE = 1000; + private static final int HOPPER_SLOT = 22; + private static final int CARL_SLOT = 40; + private static final int[] LINE_NUMS = { -27, -18, -9, 9, 18 }; + + private int _tickCount; + private int _currentRewardIndex; + private int _ticksThisSwap; + private int _ticksPerSwap; + private int _swapCount; + private Reward[] _rewards; + + public SpinGui(Plugin plugin, Player player, RewardManager rewardManager) { - super(plugin, player); + super(plugin, player, "Carl's Spinner", 54); + + ShopItem carlItem = new ShopItem(Material.SKULL_ITEM, (byte) 4, "Carl's Spinner", new String[] {ChatColor.RESET + "Good Luck!" }, 1, false, false); + + setItem(HOPPER_SLOT, new DisplayItem(new ItemStack(Material.HOPPER))); + setItem(CARL_SLOT, new DisplayItem(carlItem)); + + _rewards = new Reward[REWARDS_TO_GENERATE]; + + for (int i = 0; i < REWARDS_TO_GENERATE; i++) + { + _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.Spinner, true); + } + + _ticksPerSwap = 3; } + + private void tick() + { + _ticksThisSwap++; + + // Swap + if (_ticksThisSwap >= _ticksPerSwap) + { + _ticksThisSwap = 0; + _swapCount++; + + updateGui(); + float pitch = Math.max(-2, 2 - (_swapCount / 50f)); +// Bukkit.broadcastMessage(pitch + ""); + getPlayer().playSound(getPlayer().getEyeLocation(), Sound.NOTE_PLING, 1, pitch); + + _currentRewardIndex++; + + // Slow + if (_swapCount % 10 == 0) + _ticksPerSwap++; + } + + _tickCount++; + } + + public void updateGui() + { + for (int i = 0; i < 9; i++) + { + int index = _currentRewardIndex + i; + index = index % REWARDS_TO_GENERATE; + + int slot = 27 + i; + RewardData data = _rewards[index].getFakeRewardData(getPlayer()); + setItem(slot, new RewardButton(data)); + + // Glass Panes + for (int j = 0; j < LINE_NUMS.length; j++) + { + int paneSlot = slot + LINE_NUMS[j]; + if (paneSlot == HOPPER_SLOT || paneSlot == CARL_SLOT) + continue; + + setItem(paneSlot, new DisplayItem(data.getRarity().getItemStack())); + } + } + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + return; + + tick(); + } + } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java index 5262d6c3f..e91626a23 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java @@ -2,18 +2,28 @@ package mineplex.hub.bonuses.gui.buttons; import org.bukkit.ChatColor; import org.bukkit.Material; +import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; import mineplex.core.gui.GuiItem; +import mineplex.core.reward.RewardManager; import mineplex.core.shop.item.ShopItem; +import mineplex.hub.bonuses.gui.SpinGui; public class CarlSpinButton implements GuiItem { - public CarlSpinButton() - { + private Plugin _plugin; + private Player _player; + private RewardManager _rewardManager; + public CarlSpinButton(Plugin plugin, Player player, RewardManager rewardManager) + { + _plugin = plugin; + _player = player; + _rewardManager = rewardManager; } @Override @@ -30,7 +40,7 @@ public class CarlSpinButton implements GuiItem @Override public void click(ClickType clickType) { - + new SpinGui(_plugin, _player, _rewardManager).openInventory(); } @Override @@ -38,7 +48,6 @@ public class CarlSpinButton implements GuiItem { ShopItem item = new ShopItem(Material.SKULL_ITEM, (byte) 4, "Carl's Spinner", new String[] {ChatColor.RESET + "Try your Luck!" }, 1, false, false); - return item; } } From be18dc1bf58971e363fc708d60af7e64dc0c8114 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Thu, 6 Aug 2015 21:41:56 -0500 Subject: [PATCH 18/72] Add experience rewards to reward manager --- .../mineplex/core/reward/RewardManager.java | 15 +++--- .../core/reward/rewards/ExperienceReward.java | 52 +++++++++++++++++++ .../src/mineplex/hub/HubManager.java | 2 +- .../game/arcade/managers/GameLootManager.java | 2 +- 4 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java index b3d467ddc..53bc45205 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java @@ -18,11 +18,13 @@ import mineplex.core.donation.DonationManager; import mineplex.core.inventory.InventoryManager; import mineplex.core.pet.PetManager; import mineplex.core.reward.rewards.CoinReward; +import mineplex.core.reward.rewards.ExperienceReward; import mineplex.core.reward.rewards.GemReward; import mineplex.core.reward.rewards.InventoryReward; import mineplex.core.reward.rewards.PetReward; import mineplex.core.reward.rewards.RankReward; import mineplex.core.reward.rewards.UnknownPackageReward; +import mineplex.core.stats.StatsManager; public class RewardManager { @@ -31,10 +33,10 @@ public class RewardManager private Random _random; private CoreClientManager _clientManager; - + private boolean _doubleGadgetValue; - public RewardManager(CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, + public RewardManager(CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, int commonValueMin, int commonValueMax, int uncommonValueMin, int uncommonValueMax, int rareValueMin, int rareValueMax, @@ -51,19 +53,20 @@ public class RewardManager } _clientManager = clientManager; - + _doubleGadgetValue = doubleGadgetValue; - addGame(donationManager, inventoryManager, petManager); + addGame(donationManager, inventoryManager, petManager, statsManager); addCommon(donationManager, inventoryManager, petManager, commonValueMin, commonValueMax); addUncommon(donationManager, inventoryManager, petManager, uncommonValueMin, uncommonValueMax); addRare(donationManager, inventoryManager, petManager, rareValueMin, rareValueMax); addLegendary(donationManager, inventoryManager, petManager, legendValueMin, legendValueMax); } - public void addGame(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager) + public void addGame(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager) { - addReward(new GemReward(donationManager, 100, 500, 1, RewardRarity.GAME)); + addReward(new GemReward(donationManager, 100, 500, 100, RewardRarity.GAME)); + addReward(new ExperienceReward(statsManager, 100, 5000, 100, RewardRarity.GAME)); } public void addCommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java new file mode 100644 index 000000000..a96245c6f --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java @@ -0,0 +1,52 @@ +package mineplex.core.reward.rewards; + +import java.util.Random; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.reward.Reward; +import mineplex.core.reward.RewardData; +import mineplex.core.reward.RewardRarity; +import mineplex.core.stats.StatsManager; + +public class ExperienceReward extends Reward +{ + private StatsManager _statsManager; + private Random _random; + private int _minExperience; + private int _maxExperience; + + public ExperienceReward(StatsManager statsManager, int minExperience, int maxExperience, int weight, RewardRarity rarity) + { + super(rarity, weight); + + _statsManager = statsManager; + _random = new Random(); + _minExperience = minExperience; + _maxExperience = maxExperience; + } + + @Override + protected RewardData giveRewardCustom(Player player) + { + int experience = _random.nextInt(_maxExperience - _minExperience) + _minExperience; + + _statsManager.incrementStat(player, "Global.ExpEarned", experience); + + return new RewardData(getRarity().getColor() + experience + " Experience", new ItemStack(Material.EXP_BOTTLE), RewardRarity.GAME); + } + + @Override + public RewardData getFakeRewardData(Player player) + { + return new RewardData(getRarity().getColor() + "Experience", new ItemStack(Material.EXP_BOTTLE), RewardRarity.GAME); + } + + @Override + public boolean canGiveReward(Player player) + { + return true; + } +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index 2b5188a30..4a4fbdd2b 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -179,7 +179,7 @@ public class HubManager extends MiniClientPlugin new BenefitManager(plugin, clientManager, _inventoryManager); _gadgetManager = new GadgetManager(_plugin, clientManager, donationManager, _inventoryManager, _mountManager, petManager, preferences, disguiseManager, blockRestore, new ProjectileManager(plugin)); - RewardManager rewardManager = new RewardManager(clientManager, donationManager, _inventoryManager, petManager, + RewardManager rewardManager = new RewardManager(clientManager, donationManager, _inventoryManager, petManager, statsManager, 100, 250, 500, 1000, 4000, 6000, diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java index 08fc48275..91e3ae9ec 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java @@ -50,7 +50,7 @@ public class GameLootManager implements Listener Manager.getPluginManager().registerEvents(this, Manager.getPlugin()); - _rewardManager = new RewardManager(Manager.GetClients(), Manager.GetDonation(), Manager.getInventoryManager(), petManager, + _rewardManager = new RewardManager(Manager.GetClients(), Manager.GetDonation(), Manager.getInventoryManager(), petManager, Manager.GetStatsManager(), 100, 250, 500, 1000, 1500, 2500, From 5f435a079ee8213ff99493cef8e2665b467c794e Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Thu, 6 Aug 2015 21:59:21 -0500 Subject: [PATCH 19/72] Update vote button --- .../mineplex/hub/bonuses/BonusManager.java | 9 + .../hub/bonuses/gui/buttons/VoteButton.java | 182 ++++++------------ 2 files changed, 73 insertions(+), 118 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index f5b67a4a5..5acba755a 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -268,6 +268,15 @@ public class BonusManager extends MiniClientPlugin implements I return amount; } + public BonusAmount getVoteBonusAmount(Player player) + { + BonusAmount amount = new BonusAmount(); + amount.setTickets(1); + amount.setBonusCoins(100); + amount.setBonusExperience(100); + return amount; + } + public BonusAmount getRankBonusAmount(Player player) { Rank rank = _clientManager.Get(player).GetRank(); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java index 963e8506e..164c55936 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java @@ -1,13 +1,21 @@ package mineplex.hub.bonuses.gui.buttons; +import java.util.ArrayList; + +import mineplex.core.common.jsonchat.ClickEvent; +import mineplex.core.common.jsonchat.JsonMessage; +import mineplex.core.common.util.C; import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilTime; import mineplex.core.common.util.UtilTime.TimeUnit; import mineplex.core.gui.GuiItem; import mineplex.core.gui.ItemRefresher; import mineplex.core.itemstack.ItemStackFactory; +import mineplex.core.shop.item.ShopItem; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; +import mineplex.hub.bonuses.BonusAmount; +import mineplex.hub.bonuses.BonusClientData; import mineplex.hub.bonuses.BonusManager; import net.minecraft.server.v1_7_R4.ChatSerializer; import net.minecraft.server.v1_7_R4.IChatBaseComponent; @@ -29,8 +37,6 @@ public class VoteButton implements GuiItem, Listener { private ItemStack _item; - private long bonusTime; - private String _url; private Player _player; @@ -51,14 +57,9 @@ public class VoteButton implements GuiItem, Listener { public void setup() { //TODO get url from db - _url = "http://minecraftservers.org/server/121070"; + _url = "http://minecraftservers.org/vote/121070"; - this.bonusTime = _bonusManager.nextVoteTime(getPlayer()); - - //if (_url != null) Bukkit.getPluginManager().registerEvents(this, getPlugin()); - - setItem(); } @Override @@ -77,22 +78,14 @@ public class VoteButton implements GuiItem, Listener { getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); - // TODO This probably needs to be redone, I just looked stuff up and - // pasted it together - - UtilPlayer.message(getPlayer(), "============================================="); + UtilPlayer.message(getPlayer(), C.cRed + "------------------------------------------------"); UtilPlayer.message(getPlayer(), ""); - IChatBaseComponent comp = ChatSerializer.a("{\"text\":\"" + " " + "\",\"extra\":[{\"text\":\"" + ChatColor.GREEN - - + "---==Click to vote==---\",\"hoverEvent\":{\"action\":\"show_text\",\"value\":\"" + ChatColor.GREEN - - + _url.replace("http://", "").replace("https://", "") + "\"},\"clickEvent\":{\"action\":\"open_url\",\"value\":\"" + _url - - + "\"}}]}"); - - UtilPlayer.sendPacket(_player, new PacketPlayOutChat(comp, true)); + + new JsonMessage("Click to Open in Web Browser").click(ClickEvent.OPEN_URL, _url).sendToPlayer(getPlayer()); + new JsonMessage(C.cGreen + _url).click(ClickEvent.OPEN_URL, _url).sendToPlayer(getPlayer()); + UtilPlayer.message(getPlayer(), ""); - UtilPlayer.message(getPlayer(), "============================================="); + UtilPlayer.message(getPlayer(), C.cRed + "------------------------------------------------"); @@ -105,37 +98,67 @@ public class VoteButton implements GuiItem, Listener { } } - @EventHandler - public void onUpdate(UpdateEvent event) - { - if (!event.getType().equals(UpdateType.SEC)) - return; - setItem(); - } - @Override public ItemStack getObject() { return _item; } - public void refreshItem() { - getGui().refreshItem(this); - } - - public void setItem() + private void setItem() { - if (isAvailable()) { - _item = ItemStackFactory.Instance.CreateStack(Material.JUKEBOX, (byte) 0, 1, ChatColor.GREEN + "Click to vote!"); - } else { - _item = ItemStackFactory.Instance.CreateStack(Material.REDSTONE_BLOCK, (byte) 0, 1, ChatColor.RED + "Next link in:", new String[] {ChatColor.WHITE + UtilTime.convertString(timeLeft(), 0, TimeUnit.FIT) }); + ArrayList lore = new ArrayList(); + Material material; + String itemName; + byte data = 0; + + if (isAvailable()) + { + material = Material.CHEST; + itemName = C.cGreen + C.Bold + "Vote Bonus"; + + lore.add(" "); + lore.add(ChatColor.RESET + "Click to Vote!"); } - refreshItem(); + else + { + material = Material.REDSTONE_BLOCK; + itemName = C.cRed + C.Bold + "Vote Bonus"; + + lore.add(" "); + lore.add(ChatColor.RESET + "Next vote in " + UtilTime.convertString(timeLeft(), 0, TimeUnit.FIT) + "!"); + } + + lore.add(" "); + + BonusClientData client = _bonusManager.Get(_player); + + BonusAmount bonusAmount = _bonusManager.getVoteBonusAmount(_player); + bonusAmount.addLore(lore); + + lore.add(C.cYellow + "Current Streak: " + C.cWhite + client.getVoteStreak()); + lore.add(C.cYellow + "Highest Streak: " + C.cWhite + client.getMaxVoteStreak()); + + if (client.getVoteTime() != null) + { + long lastBonus = _bonusManager.getLocalTime(client.getVoteTime().getTime()); + long timeLeft = _bonusManager.getStreakTimeRemaining(lastBonus, BonusManager.STREAK_RESET_TIME); + + if (timeLeft > 0) + { + lore.add(C.cYellow + "Streak Reset: " + C.cWhite + UtilTime.convertString(timeLeft, 1, TimeUnit.FIT)); + } + } + + lore.add(" "); + lore.add(C.cYellow + "Record Holder: " + C.cWhite + "Phinary"); + lore.add(C.cYellow + "Streak: " + C.cWhite + "420"); + + _item = new ShopItem(material, itemName, lore.toArray(new String[0]), 1, false, false); } public long timeLeft() { - return this.bonusTime - System.currentTimeMillis(); + return _bonusManager.nextVoteTime(getPlayer()) - System.currentTimeMillis(); } public boolean isAvailable() @@ -160,80 +183,3 @@ public class VoteButton implements GuiItem, Listener { return _gui; } } - - - - - - - - - -/*implements GuiItem { - - private ItemStack _item; - private String _url; - private Player _player; - - public VoteButton(Player player) - { - this._player = player; - - //TODO get url from somewhere - _url = "http://minecraftservers.org/server/121070"; - - //TODO check if claimed - boolean claimed = false; - - if (_url == null) - _item = ItemStackFactory.Instance.CreateStack(Material.REDSTONE_BLOCK, (byte) 0, 1, ChatColor.RED + "Nothing to vote for!"); - else if (claimed) { - _item = ItemStackFactory.Instance.CreateStack(Material.REDSTONE_BLOCK, (byte) 0, 1, ChatColor.RED + "You have already voted!"); - _url = null; - } else - _item = ItemStackFactory.Instance.CreateStack(Material.JUKEBOX, (byte) 0, 1, ChatColor.GREEN + "Click to vote!"); - } - - @Override - public void setup() - { - - } - - @Override - public void close() - { - - } - - @Override - public void click(ClickType clickType) - { - if (_url == null) { - getPlayer().playSound(getPlayer().getLocation(), Sound.ITEM_BREAK, 1, 10); - return; - } - getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); - // TODO This probably needs to be redone, I just looked stuff up and - // pasted it together - IChatBaseComponent comp = ChatSerializer.a("{\"text\":\"" + ChatColor.BLUE + "Vote> \",\"extra\":[{\"text\":\"" + ChatColor.GREEN - + "Click to vote!\",\"hoverEvent\":{\"action\":\"show_text\",\"value\":\"" + ChatColor.GREEN - + _url.replace("http://", "").replace("https://", "") + "\"},\"clickEvent\":{\"action\":\"open_url\",\"value\":\"" + _url - + "\"}}]}"); - - UtilPlayer.sendPacket(_player, new PacketPlayOutChat(comp, true)); - getPlayer().closeInventory(); - } - - @Override - public ItemStack getObject() - { - return _item; - } - - public Player getPlayer() - { - return _player; - } -} -*/ From 5f8e80a55f30980fd8bd08159ce8b1b916bf032b Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Fri, 7 Aug 2015 11:10:50 +0200 Subject: [PATCH 20/72] art --- Art/Carl.png | Bin 0 -> 352908 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Art/Carl.png diff --git a/Art/Carl.png b/Art/Carl.png new file mode 100644 index 0000000000000000000000000000000000000000..5d4fe6d3651d5897860b212e72fde071c521c501 GIT binary patch literal 352908 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%0DYK9e4 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%0D>nmim~Z3j0zA74T`9d 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 z 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 Date: Fri, 7 Aug 2015 04:13:09 -0500 Subject: [PATCH 21/72] Push fixes --- .../src/mineplex/hub/bonuses/BonusManager.java | 4 ++++ .../src/mineplex/hub/bonuses/gui/buttons/VoteButton.java | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index 5acba755a..d02890ff0 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -141,6 +141,7 @@ public class BonusManager extends MiniClientPlugin implements I { incrementDailyStreak(player); awardBonus(player, amount); + updateCreeperVisual(player); } result.accept(r); @@ -177,7 +178,10 @@ public class BonusManager extends MiniClientPlugin implements I public void accept(Boolean aBoolean) { if (aBoolean) + { awardBonus(player, getRankBonusAmount(player)); + updateCreeperVisual(player); + } result.accept(aBoolean); } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java index 164c55936..0552203d7 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java @@ -58,7 +58,8 @@ public class VoteButton implements GuiItem, Listener { { //TODO get url from db _url = "http://minecraftservers.org/vote/121070"; - + + setItem(); Bukkit.getPluginManager().registerEvents(this, getPlugin()); } @@ -68,7 +69,6 @@ public class VoteButton implements GuiItem, Listener { HandlerList.unregisterAll(this); } - @Override public void click(ClickType clickType) { @@ -113,7 +113,7 @@ public class VoteButton implements GuiItem, Listener { if (isAvailable()) { - material = Material.CHEST; + material = Material.JUKEBOX; itemName = C.cGreen + C.Bold + "Vote Bonus"; lore.add(" "); @@ -165,6 +165,8 @@ public class VoteButton implements GuiItem, Listener { { if (_url == null) return false; + System.out.println(timeLeft()); + return (timeLeft() <= 0); } From f76d9b0d37f021374ed3880fa117cb47597888c2 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Fri, 7 Aug 2015 04:20:54 -0500 Subject: [PATCH 22/72] Replace Consumers with Callbacks --- .../mineplex/hub/bonuses/BonusManager.java | 25 +++++++------ .../mineplex/hub/bonuses/BonusRepository.java | 35 +++++++++---------- .../bonuses/gui/buttons/DailyBonusButton.java | 7 ++-- .../bonuses/gui/buttons/RankBonusButton.java | 8 ++--- 4 files changed, 34 insertions(+), 41 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index d02890ff0..bfd1bca5a 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -4,7 +4,6 @@ import java.sql.Date; import java.sql.Timestamp; import java.util.Calendar; import java.util.TimeZone; -import java.util.function.Consumer; import mineplex.core.MiniClientPlugin; import mineplex.core.account.CoreClient; @@ -127,15 +126,15 @@ public class BonusManager extends MiniClientPlugin implements I public static final long TIME_BETWEEN_BONUSES = 1000 * 60 * 60 * 20; public static final long STREAK_RESET_TIME = 1000 * 60 * 60 * 12; - public void attemptDailyBonus(final Player player, final BonusAmount amount, final Consumer result) + public void attemptDailyBonus(final Player player, final BonusAmount amount, final Callback result) { if (timeTillDailyBonus(player) > 0) - result.accept(false); + result.run(false); - getRepository().attemptDailyBonus(player, new Consumer() + getRepository().attemptDailyBonus(player, new Callback() { @Override - public void accept(Boolean r) + public void run(Boolean r) { if (r) { @@ -144,7 +143,7 @@ public class BonusManager extends MiniClientPlugin implements I updateCreeperVisual(player); } - result.accept(r); + result.run(r); } }); } @@ -168,14 +167,14 @@ public class BonusManager extends MiniClientPlugin implements I } // RANK BONUS - public void attemptRankBonus(final Player player, final Consumer result) + public void attemptRankBonus(final Player player, final Callback result) { if (timeTillRankBonus(player) > 0) - result.accept(false); - getRepository().attemptRankBonus(player, new Consumer() + result.run(false); + getRepository().attemptRankBonus(player, new Callback() { @Override - public void accept(Boolean aBoolean) + public void run(Boolean aBoolean) { if (aBoolean) { @@ -183,7 +182,7 @@ public class BonusManager extends MiniClientPlugin implements I updateCreeperVisual(player); } - result.accept(aBoolean); + result.run(aBoolean); } }); } @@ -305,10 +304,10 @@ public class BonusManager extends MiniClientPlugin implements I //VOTE - public void atteptVoteBonus(final Player player, final Consumer result) + public void atteptVoteBonus(final Player player, final Callback result) { if (timeTillRankBonus(player) > 0) - result.accept(false); + result.run(false); getRepository().attemptRankBonus(player, result); } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java index 0ee538f8b..070e4aec0 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java @@ -6,11 +6,8 @@ import java.sql.Date; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; -import java.util.function.Consumer; import mineplex.core.common.util.Callback; -import mineplex.core.common.util.F; -import mineplex.core.common.util.UtilPlayer; import mineplex.core.database.DBPool; import mineplex.core.database.RepositoryBase; import mineplex.core.database.ResultSetCallable; @@ -60,10 +57,10 @@ public class BonusRepository extends RepositoryBase return record; } - public void attemptDailyBonus(final Player player, final Consumer result) + public void attemptDailyBonus(final Player player, final Callback result) { if (!Recharge.Instance.usable(player, "AttemptDailyBonus")) { - result.accept(false); + result.run(false); return; } final int accountId = _manager.getClientManager().Get(player).getAccountId(); @@ -105,13 +102,13 @@ public class BonusRepository extends RepositoryBase if (pass) { _manager.Get(player).setDailyTime(new Timestamp(BonusManager.getSqlTime())); - result.accept(true); + result.run(true); } else { Recharge.Instance.use(player, "AttemptDailyBonus", 1000 * 10, false, false); _manager.Get(player).setDailyTime(timeStamp); - result.accept(false); + result.run(false); } } }); @@ -120,23 +117,23 @@ public class BonusRepository extends RepositoryBase { Recharge.Instance.use(player, "AttemptDailyBonus", 1000 * 30, false, false); e.printStackTrace(); - result.accept(false); + result.run(false); } } }); } - public void attemptRankBonus(final Player player, final Consumer result) + public void attemptRankBonus(final Player player, final Callback result) { if (!Recharge.Instance.usable(player, "AttemptRankBonus")) { - result.accept(false); + result.run(false); return; } final int accountId = _manager.getClientManager().Get(player).getAccountId(); final int coins = _manager.getRankBonusAmount(player).getCoins(); if (coins == 0/* && gems == 0 */) { - result.accept(false); + result.run(false); return; } @@ -171,29 +168,29 @@ public class BonusRepository extends RepositoryBase if (pass) { - result.accept(true); + result.run(true); } else { Recharge.Instance.use(player, "AttemptRankBonus", 1000 * 10, false, false); - result.accept(false); + result.run(false); } } }); } catch (Exception e) { Recharge.Instance.use(player, "AttemptRankBonus", 1000 * 30, false, false); e.printStackTrace(); - result.accept(false); + result.run(false); } } }); } - public void voteBonus(final Player player, final Consumer result) + public void voteBonus(final Player player, final Callback result) { if (!Recharge.Instance.usable(player, "AttemptVoteBonus")) { - result.accept(false); + result.run(false); return; } final int accountId = _manager.getClientManager().Get(player).getAccountId(); @@ -202,7 +199,7 @@ public class BonusRepository extends RepositoryBase final int gems = 0; if (coins == 0/* && gems == 0 */) { - result.accept(false); + result.run(false); return; } @@ -237,13 +234,13 @@ public class BonusRepository extends RepositoryBase _donationManager.RewardCoins(null, "Vote bonus", player.getName(), accountId, coins); _donationManager.RewardGems(null, "Vote bonus", player.getName(), player.getUniqueId(), gems); - result.accept(true); + result.run(true); } }); } catch (Exception e) { e.printStackTrace(); - result.accept(false); + result.run(false); } } }); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java index 2ba7a359a..4554c8a58 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java @@ -1,9 +1,9 @@ package mineplex.hub.bonuses.gui.buttons; import java.util.ArrayList; -import java.util.function.Consumer; import mineplex.core.common.util.C; +import mineplex.core.common.util.Callback; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilTime; @@ -72,10 +72,9 @@ public class DailyBonusButton implements GuiItem, Listener _item = ItemStackFactory.Instance.CreateStack(Material.LAPIS_BLOCK, (byte)0, 1, ChatColor.BLUE + "Processing..."); refreshItem(); new LoadingWindow(getPlugin(), getPlayer(), 6*9); - _bonusManager.attemptDailyBonus(getPlayer(), _bonusManager.getDailyBonusAmount(_player), new Consumer() { - @SuppressWarnings("deprecation") + _bonusManager.attemptDailyBonus(getPlayer(), _bonusManager.getDailyBonusAmount(_player), new Callback() { @Override - public void accept(Boolean t) + public void run(Boolean t) { if (t) { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java index e5007bd53..3189ec5d5 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java @@ -1,9 +1,9 @@ package mineplex.hub.bonuses.gui.buttons; import java.util.ArrayList; -import java.util.function.Consumer; import mineplex.core.common.util.C; +import mineplex.core.common.util.Callback; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilTime; @@ -17,7 +17,6 @@ import mineplex.core.shop.item.ShopItem; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.hub.bonuses.BonusAmount; -import mineplex.hub.bonuses.BonusClientData; import mineplex.hub.bonuses.BonusManager; import org.bukkit.Bukkit; @@ -83,11 +82,10 @@ public class RankBonusButton implements GuiItem, Listener { _item = ItemStackFactory.Instance.CreateStack(Material.LAPIS_BLOCK, (byte)0, 1, ChatColor.BLUE + "Processing..."); refreshItem(); new LoadingWindow(getPlugin(), getPlayer(), 6*9); - _bonusManager.attemptRankBonus(getPlayer(), new Consumer() + _bonusManager.attemptRankBonus(getPlayer(), new Callback() { - @SuppressWarnings("deprecation") @Override - public void accept(Boolean t) + public void run(Boolean t) { setItem(); From 4f6dfdb856d9ab918e1aacd25532236fcbb3bc7d Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Sat, 8 Aug 2015 06:35:25 -0500 Subject: [PATCH 23/72] Update carl spin button to consume tickets, Updates to Votifier Plugin, Redis Vote Command, Various bug fixes --- .../core/votifier/RedisVotifierCommand.java | 17 --- .../core/votifier/VotifierCommand.java | 23 ++++ .../src/mineplex/hub/bonuses/BonusAmount.java | 1 - .../mineplex/hub/bonuses/BonusManager.java | 105 +++++++++++++++++- .../mineplex/hub/bonuses/BonusRepository.java | 65 +++++++++++ .../mineplex/hub/bonuses/StreakRecord.java | 23 ++++ .../src/mineplex/hub/bonuses/VoteHandler.java | 31 ++++++ .../mineplex/hub/bonuses/gui/BonusGui.java | 2 +- .../bonuses/gui/buttons/CarlSpinButton.java | 43 ++++++- .../bonuses/gui/buttons/DailyBonusButton.java | 12 +- .../hub/bonuses/gui/buttons/VoteButton.java | 13 ++- .../Mineplex.Votifier/Mineplex.Votifier.iml | 1 + .../mineplex/votifier/VotifierManager.java | 46 +++++++- 13 files changed, 342 insertions(+), 40 deletions(-) delete mode 100644 Plugins/Mineplex.Core/src/mineplex/core/votifier/RedisVotifierCommand.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/votifier/VotifierCommand.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/StreakRecord.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/VoteHandler.java diff --git a/Plugins/Mineplex.Core/src/mineplex/core/votifier/RedisVotifierCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/votifier/RedisVotifierCommand.java deleted file mode 100644 index 7b92598b3..000000000 --- a/Plugins/Mineplex.Core/src/mineplex/core/votifier/RedisVotifierCommand.java +++ /dev/null @@ -1,17 +0,0 @@ -package mineplex.core.votifier; - -import java.util.UUID; - -import mineplex.serverdata.commands.ServerCommand; - -public class RedisVotifierCommand extends ServerCommand -{ - private UUID _voterUUID; - - - public RedisVotifierCommand() - { - - } - -} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/votifier/VotifierCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/votifier/VotifierCommand.java new file mode 100644 index 000000000..a84087fb0 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/votifier/VotifierCommand.java @@ -0,0 +1,23 @@ +package mineplex.core.votifier; + +import java.util.UUID; + +import mineplex.serverdata.commands.ServerCommand; + +public class VotifierCommand extends ServerCommand +{ + private String _playerName; + + public VotifierCommand(String playerName, String targetServer) + { + super(targetServer); + + _playerName = playerName; + } + + public String getPlayerName() + { + return _playerName; + } + +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java index 9c5343077..d596a846b 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java @@ -143,7 +143,6 @@ public class BonusAmount addLore(lore, getGems(), getBonusGems(), "Gems"); addLore(lore, getGold(), getBonusGold(), "Gold"); addLore(lore, getExperience(), getBonusExperience(), "Experience"); - lore.add(" "); } private void addLore(List lore, int amount, int bonus, String suffix) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index bfd1bca5a..b4bd57948 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -23,10 +23,14 @@ import mineplex.core.npc.NpcManager; import mineplex.core.reward.RewardManager; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; +import mineplex.core.votifier.VotifierCommand; import mineplex.hub.bonuses.commands.GuiCommand; import mineplex.hub.bonuses.gui.BonusGui; import mineplex.database.tables.records.BonusRecord; +import mineplex.hub.bonuses.gui.SpinGui; +import mineplex.serverdata.commands.ServerCommandManager; +import org.bukkit.Bukkit; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; @@ -87,6 +91,10 @@ public class BonusManager extends MiniClientPlugin implements I private RewardManager _rewardManager; private Npc _carlNpc; + // Streak + private StreakRecord _dailyStreak; + private StreakRecord _voteStreak; + public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, NpcManager npcManager, HologramManager hologramManager, RewardManager rewardManager) { super("Bonus", plugin); @@ -102,7 +110,11 @@ public class BonusManager extends MiniClientPlugin implements I clientManager.addStoredProcedureLoginProcessor(this); + ServerCommandManager.getInstance().registerCommandType("VotifierCommand", VotifierCommand.class, + new VoteHandler(this)); + updateOffSet(); + updateStreakRecord(); } @Override @@ -121,6 +133,51 @@ public class BonusManager extends MiniClientPlugin implements I updateOffSet(); } + @EventHandler + public void updateStreak(UpdateEvent event) + { + if (event.getType() != UpdateType.MIN_16) + return; + + updateStreakRecord(); + } + + private void updateStreakRecord() + { + _repository.getDailyStreakRecord(new Callback() + { + @Override + public void run(StreakRecord data) + { + _dailyStreak = data; + } + }); + + _repository.getVoteStreakRecord(new Callback() + { + @Override + public void run(StreakRecord data) + { + _voteStreak = data; + } + }); + } + + public StreakRecord getDailyStreak() + { + return _dailyStreak; + } + + public StreakRecord getVoteStreak() + { + return _voteStreak; + } + + public void handleVote(Player player) + { + Bukkit.broadcastMessage("Recieved Vote: " + player.getName()); + } + // DAILY BONUS public static final long TIME_BETWEEN_BONUSES = 1000 * 60 * 60 * 20; @@ -186,6 +243,41 @@ public class BonusManager extends MiniClientPlugin implements I } }); } + + public void attemptCarlSpin(final Player player) + { + final BonusClientData clientData = Get(player); + + if (clientData.getTickets() > 0) + { + clientData.setTickets(clientData.getTickets() - 1); + + runAsync(new Runnable() + { + @Override + public void run() + { + int modified = clientData.getRecord().store(); + + if (modified == 1) + { + runSync(new Runnable() + { + @Override + public void run() + { + new SpinGui(getPlugin(), player, _rewardManager).openInventory(); + } + }); + } + else + { + UtilPlayer.message(player, F.main("Carl", "There was an error processing your request")); + } + } + }); + } + } public long timeTillRankBonus(Player player) { @@ -275,8 +367,6 @@ public class BonusManager extends MiniClientPlugin implements I { BonusAmount amount = new BonusAmount(); amount.setTickets(1); - amount.setBonusCoins(100); - amount.setBonusExperience(100); return amount; } @@ -330,7 +420,7 @@ public class BonusManager extends MiniClientPlugin implements I public void awardBonus(final Player player, BonusAmount amount) { - BonusClientData bonusClient = Get(player); + final BonusClientData bonusClient = Get(player); CoreClient coreClient = _clientManager.Get(player); final int gems = amount.getTotalGems(); @@ -399,7 +489,14 @@ public class BonusManager extends MiniClientPlugin implements I if (tickets > 0) { bonusClient.setTickets(tickets + bonusClient.getTickets()); - // TODO database save + runAsync(new Runnable() + { + @Override + public void run() + { + bonusClient.getRecord().store(); + } + }); UtilPlayer.message(player, F.main("Bonus", "Rewarded " + F.elem(tickets + " Carl Spin Ticket"))); } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java index 070e4aec0..8fcc95d6d 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java @@ -16,6 +16,8 @@ import mineplex.core.recharge.Recharge; import mineplex.database.Tables; import mineplex.database.tables.records.BonusRecord; import org.jooq.DSLContext; +import org.jooq.Record2; +import org.jooq.TableField; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -57,6 +59,42 @@ public class BonusRepository extends RepositoryBase return record; } + public void getDailyStreakRecord(Callback callback) + { + getStreakRecord(Tables.bonus.maxDailyStreak, callback); + } + + public void getVoteStreakRecord(Callback callback) + { + getStreakRecord(Tables.bonus.maxVoteStreak, callback); + } + + private void getStreakRecord(final TableField field, final Callback callback) + { + Bukkit.getScheduler().runTaskAsynchronously(_manager.getPlugin(), new Runnable() + { + @Override + public void run() + { + final Record2 record = jooq().select(Tables.accounts.name, field) + .from(Tables.bonus.join(Tables.accounts).on(Tables.bonus.accountId.eq(Tables.accounts.id))) + .orderBy(field.desc()).limit(1).fetchOne(); + + Bukkit.getScheduler().runTask(_manager.getPlugin(), new Runnable() + { + @Override + public void run() + { + if (record.value1() != null && record.value2() != null) + { + callback.run(new StreakRecord(record.value1(), record.value2())); + } + } + }); + } + }); + } + public void attemptDailyBonus(final Player player, final Callback result) { if (!Recharge.Instance.usable(player, "AttemptDailyBonus")) { @@ -123,6 +161,33 @@ public class BonusRepository extends RepositoryBase }); } + @Deprecated + public void attemptPurchaseSpin(final Player player, final Callback result) + { + final int accountId = _manager.getClientManager().Get(player).getAccountId(); + + Bukkit.getScheduler().runTaskAsynchronously(_manager.getPlugin(), new Runnable() + { + @Override + public void run() + { + final int newTickets = jooq().update(Tables.bonus).set(Tables.bonus.tickets, Tables.bonus.tickets.sub(-1)). + where(Tables.bonus.accountId.eq(accountId)).returning(Tables.bonus.tickets).fetchOne().getTickets(); + + Bukkit.getScheduler().runTask(_manager.getPlugin(), new Runnable() + { + @Override + public void run() + { + + + } + }); + + } + }); + } + public void attemptRankBonus(final Player player, final Callback result) { if (!Recharge.Instance.usable(player, "AttemptRankBonus")) { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/StreakRecord.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/StreakRecord.java new file mode 100644 index 000000000..901ef4ad6 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/StreakRecord.java @@ -0,0 +1,23 @@ +package mineplex.hub.bonuses; + +public class StreakRecord +{ + private String _playerName; + private int _streak; + + public StreakRecord(String playerName, int streak) + { + _playerName = playerName; + _streak = streak; + } + + public String getPlayerName() + { + return _playerName; + } + + public int getStreak() + { + return _streak; + } +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/VoteHandler.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/VoteHandler.java new file mode 100644 index 000000000..73e11305b --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/VoteHandler.java @@ -0,0 +1,31 @@ +package mineplex.hub.bonuses; + +import org.bukkit.entity.Player; + +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.votifier.VotifierCommand; +import mineplex.serverdata.commands.CommandCallback; +import mineplex.serverdata.commands.ServerCommand; + +public class VoteHandler implements CommandCallback +{ + private BonusManager _bonusManager; + + public VoteHandler(BonusManager bonusManager) + { + _bonusManager = bonusManager; + } + + @Override + public void run(ServerCommand command) + { + VotifierCommand v = ((VotifierCommand) command); + + Player player = UtilPlayer.searchExact(v.getPlayerName()); + + if (player != null) + { + _bonusManager.handleVote(player); + } + } +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java index 083288461..65aa961cf 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java @@ -28,7 +28,7 @@ public class BonusGui extends SimpleGui setItem(15, new DailyBonusButton(getPlugin(), player, this, manager)); - setItem(31, new CarlSpinButton(getPlugin(), player, rewardManager)); + setItem(31, new CarlSpinButton(getPlugin(), player, manager, rewardManager)); } @Override diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java index e91626a23..c68f95814 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java @@ -1,5 +1,7 @@ package mineplex.hub.bonuses.gui.buttons; +import java.util.ArrayList; + import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -7,22 +9,25 @@ import org.bukkit.event.inventory.ClickType; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; +import mineplex.core.common.util.C; import mineplex.core.gui.GuiItem; import mineplex.core.reward.RewardManager; import mineplex.core.shop.item.ShopItem; -import mineplex.hub.bonuses.gui.SpinGui; +import mineplex.hub.bonuses.BonusClientData; +import mineplex.hub.bonuses.BonusManager; public class CarlSpinButton implements GuiItem { - private Plugin _plugin; private Player _player; + private BonusManager _bonusManager; private RewardManager _rewardManager; - public CarlSpinButton(Plugin plugin, Player player, RewardManager rewardManager) + public CarlSpinButton(Plugin plugin, Player player, BonusManager bonusManager, RewardManager rewardManager) { _plugin = plugin; _player = player; + _bonusManager = bonusManager; _rewardManager = rewardManager; } @@ -40,14 +45,40 @@ public class CarlSpinButton implements GuiItem @Override public void click(ClickType clickType) { - new SpinGui(_plugin, _player, _rewardManager).openInventory(); + BonusClientData client = _bonusManager.Get(_player); + int tickets = client.getTickets(); + + if (tickets > 0) + { + _bonusManager.attemptCarlSpin(_player); + } +// new SpinGui(_plugin, _player, _rewardManager).openInventory(); } @Override public ItemStack getObject() { - ShopItem item = new ShopItem(Material.SKULL_ITEM, (byte) 4, "Carl's Spinner", new String[] {ChatColor.RESET + "Try your Luck!" }, 1, false, false); + BonusClientData client = _bonusManager.Get(_player); + int tickets = client.getTickets(); - return item; + String name = (tickets > 0 ? C.cGreen : C.cRed) + C.Bold + "Carl's Spinner"; + ArrayList lore = new ArrayList(); + Material material = Material.SKULL_ITEM; + byte data = (byte) 4; + + lore.add(" "); + if (tickets > 0) + { + lore.add(ChatColor.RESET + "Click to Spin"); + } + else + { + lore.add(ChatColor.RESET + "You need a Carl Spin Ticket to Spin"); + } + + lore.add(" "); + lore.add(ChatColor.YELLOW + "Your Tickets: " + C.cWhite + tickets); + + return new ShopItem(material, data, name, lore.toArray(new String[0]), 1, false, false); } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java index 4554c8a58..f6534589d 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java @@ -19,6 +19,7 @@ import mineplex.core.updater.event.UpdateEvent; import mineplex.hub.bonuses.BonusAmount; import mineplex.hub.bonuses.BonusClientData; import mineplex.hub.bonuses.BonusManager; +import mineplex.hub.bonuses.StreakRecord; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -139,6 +140,7 @@ public class DailyBonusButton implements GuiItem, Listener BonusAmount bonusAmount = _bonusManager.getDailyBonusAmount(_player); bonusAmount.addLore(lore); + lore.add(" "); lore.add(C.cYellow + "Current Streak: " + C.cWhite + client.getDailyStreak()); lore.add(C.cYellow + "Highest Streak: " + C.cWhite + client.getMaxDailyStreak()); @@ -154,9 +156,13 @@ public class DailyBonusButton implements GuiItem, Listener } } - lore.add(" "); - lore.add(C.cYellow + "Record Holder: " + C.cWhite + "Phinary"); - lore.add(C.cYellow + "Streak: " + C.cWhite + "420"); + StreakRecord streakRecord = _bonusManager.getDailyStreak(); + if (streakRecord != null) + { + lore.add(" "); + lore.add(C.cYellow + "Record: " + C.cWhite + streakRecord.getPlayerName()); + lore.add(C.cYellow + "Streak: " + C.cWhite + streakRecord.getStreak()); + } _item = new ShopItem(material, itemName, lore.toArray(new String[0]), 1, false, false); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java index 0552203d7..54021b6f2 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java @@ -17,6 +17,8 @@ import mineplex.core.updater.event.UpdateEvent; import mineplex.hub.bonuses.BonusAmount; import mineplex.hub.bonuses.BonusClientData; import mineplex.hub.bonuses.BonusManager; +import mineplex.hub.bonuses.StreakRecord; + import net.minecraft.server.v1_7_R4.ChatSerializer; import net.minecraft.server.v1_7_R4.IChatBaseComponent; import net.minecraft.server.v1_7_R4.PacketPlayOutChat; @@ -134,6 +136,7 @@ public class VoteButton implements GuiItem, Listener { BonusAmount bonusAmount = _bonusManager.getVoteBonusAmount(_player); bonusAmount.addLore(lore); + lore.add(" "); lore.add(C.cYellow + "Current Streak: " + C.cWhite + client.getVoteStreak()); lore.add(C.cYellow + "Highest Streak: " + C.cWhite + client.getMaxVoteStreak()); @@ -149,9 +152,13 @@ public class VoteButton implements GuiItem, Listener { } } - lore.add(" "); - lore.add(C.cYellow + "Record Holder: " + C.cWhite + "Phinary"); - lore.add(C.cYellow + "Streak: " + C.cWhite + "420"); + StreakRecord streakRecord = _bonusManager.getVoteStreak(); + if (streakRecord != null) + { + lore.add(" "); + lore.add(C.cYellow + "Record: " + C.cWhite + streakRecord.getPlayerName()); + lore.add(C.cYellow + "Streak: " + C.cWhite + streakRecord.getStreak()); + } _item = new ShopItem(material, itemName, lore.toArray(new String[0]), 1, false, false); } diff --git a/Plugins/Mineplex.Votifier/Mineplex.Votifier.iml b/Plugins/Mineplex.Votifier/Mineplex.Votifier.iml index 8d37a4051..b7d71d202 100644 --- a/Plugins/Mineplex.Votifier/Mineplex.Votifier.iml +++ b/Plugins/Mineplex.Votifier/Mineplex.Votifier.iml @@ -16,6 +16,7 @@ + diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java index 30646a1f5..ecef96339 100644 --- a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java @@ -8,27 +8,63 @@ import com.vexsoftware.votifier.model.VotifierEvent; import mineplex.core.MiniPlugin; import mineplex.core.account.CoreClientManager; import mineplex.core.donation.DonationManager; -import mineplex.core.votifier.RedisVotifierCommand; +import mineplex.core.votifier.VotifierCommand; +import mineplex.serverdata.Region; +import mineplex.serverdata.commands.ServerCommandManager; +import mineplex.serverdata.data.PlayerStatus; +import mineplex.serverdata.redis.RedisDataRepository; +import mineplex.serverdata.servers.ServerManager; /** * Created by shaun on 15-08-05. */ public class VotifierManager extends MiniPlugin { + private RedisDataRepository _usPlayerRepo; + private RedisDataRepository _euPlayerRepo; + public VotifierManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager) { super("Votifier", plugin); + + _usPlayerRepo = new RedisDataRepository(ServerManager.getMasterConnection(), ServerManager.getSlaveConnection(), + Region.US, PlayerStatus.class, "playerStatus"); + _euPlayerRepo = new RedisDataRepository(ServerManager.getMasterConnection(), ServerManager.getSlaveConnection(), + Region.EU, PlayerStatus.class, "playerStatus"); + + ServerCommandManager.getInstance().registerCommandType("VotifierCommand", VotifierCommand.class); } - - @EventHandler public void handleVote(VotifierEvent event) { Vote vote = event.getVote(); - RedisVotifierCommand command = new RedisVotifierCommand(); - System.out.println("New Vote: " + vote.getUsername()); + + PlayerStatus usStatus = _usPlayerRepo.getElement(vote.getUsername()); +// VotifierCommand command = new VotifierCommand(vote.getUsername(), "PhiTest-1"); +// command.publish(); + + if (usStatus != null) + { + System.out.println("Found on US Server: " + usStatus.getServer()); + VotifierCommand command = new VotifierCommand(vote.getUsername(), usStatus.getServer()); + command.publish(); + } + else + { + System.out.println("Not found on US Server!"); + } + + PlayerStatus euStatus = _euPlayerRepo.getElement(vote.getUsername()); + if (euStatus != null) + { + System.out.println("Found on EU Server: " + euStatus.getServer()); + } + else + { + System.out.println("Not found on EU Server!"); + } } } \ No newline at end of file From e6519206af6623cd0f16188a3b2c5cac3a39ef61 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Sat, 8 Aug 2015 16:29:03 -0500 Subject: [PATCH 24/72] Add event to be called when a player tries to buy a carl spin --- .../mineplex/hub/bonuses/BonusManager.java | 45 +++++++++------- .../hub/bonuses/event/CarlSpinnerEvent.java | 54 +++++++++++++++++++ 2 files changed, 80 insertions(+), 19 deletions(-) create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/event/CarlSpinnerEvent.java diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index b4bd57948..817db72db 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -25,6 +25,7 @@ import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.core.votifier.VotifierCommand; import mineplex.hub.bonuses.commands.GuiCommand; +import mineplex.hub.bonuses.event.CarlSpinnerEvent; import mineplex.hub.bonuses.gui.BonusGui; import mineplex.database.tables.records.BonusRecord; import mineplex.hub.bonuses.gui.SpinGui; @@ -250,32 +251,38 @@ public class BonusManager extends MiniClientPlugin implements I if (clientData.getTickets() > 0) { - clientData.setTickets(clientData.getTickets() - 1); + CarlSpinnerEvent event = new CarlSpinnerEvent(player); + Bukkit.getServer().getPluginManager().callEvent(event); - runAsync(new Runnable() + if (!event.isCancelled()) { - @Override - public void run() - { - int modified = clientData.getRecord().store(); + clientData.setTickets(clientData.getTickets() - 1); - if (modified == 1) + runAsync(new Runnable() + { + @Override + public void run() { - runSync(new Runnable() + int modified = clientData.getRecord().store(); + + if (modified == 1) { - @Override - public void run() + runSync(new Runnable() { - new SpinGui(getPlugin(), player, _rewardManager).openInventory(); - } - }); + @Override + public void run() + { + new SpinGui(getPlugin(), player, _rewardManager).openInventory(); + } + }); + } + else + { + UtilPlayer.message(player, F.main("Carl", "There was an error processing your request")); + } } - else - { - UtilPlayer.message(player, F.main("Carl", "There was an error processing your request")); - } - } - }); + }); + } } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/event/CarlSpinnerEvent.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/event/CarlSpinnerEvent.java new file mode 100644 index 000000000..fed71229b --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/event/CarlSpinnerEvent.java @@ -0,0 +1,54 @@ +package mineplex.hub.bonuses.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Called when a player attempts to purchase a spin through carl + */ +public class CarlSpinnerEvent extends Event implements Cancellable +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _player; + private boolean _cancelled; + + public CarlSpinnerEvent(Player player) + { + _player = player; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + + public Player getPlayer() + { + return _player; + } + + public void setPlayer(Player player) + { + _player = player; + } + + @Override + public boolean isCancelled() + { + return _cancelled; + } + + @Override + public void setCancelled(boolean b) + { + _cancelled = b; + } +} From 85c8e42f53f3b6f2a75a3383a74683b3d9dabc6a Mon Sep 17 00:00:00 2001 From: Sarah Date: Sun, 9 Aug 2015 15:00:54 +0200 Subject: [PATCH 25/72] Finalizing and improving the Carl spinner and adding creeper explosion animations. --- .../core/treasure/animation/Animation.java | 12 ++ .../mineplex/hub/bonuses/BonusManager.java | 137 +++++++++++++- .../hub/bonuses/animations/AnimationCarl.java | 102 +++++++++++ .../bonuses/commands/AnimationCommand.java | 28 +++ .../src/mineplex/hub/bonuses/gui/SpinGui.java | 170 +++++++++++++++--- .../bonuses/gui/buttons/CarlSpinButton.java | 1 + .../bonuses/gui/buttons/RankBonusButton.java | 18 +- 7 files changed, 435 insertions(+), 33 deletions(-) create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/animations/AnimationCarl.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/AnimationCommand.java diff --git a/Plugins/Mineplex.Core/src/mineplex/core/treasure/animation/Animation.java b/Plugins/Mineplex.Core/src/mineplex/core/treasure/animation/Animation.java index c3fbe6e62..a6b986660 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/treasure/animation/Animation.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/treasure/animation/Animation.java @@ -16,6 +16,8 @@ public abstract class Animation _treasure = treasure; _running = true; } + + public Animation() {} public void run() { @@ -50,5 +52,15 @@ public abstract class Animation { return _treasure; } + + public void setRunning(boolean b) + { + _running = b; + } + + public void setTicks(int ticks) + { + _ticks = ticks; + } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index 817db72db..dbd6db81a 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -2,7 +2,9 @@ package mineplex.hub.bonuses; import java.sql.Date; import java.sql.Timestamp; +import java.util.ArrayList; import java.util.Calendar; +import java.util.Iterator; import java.util.TimeZone; import mineplex.core.MiniClientPlugin; @@ -14,7 +16,16 @@ import mineplex.core.common.Rank; 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.UtilAction; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.disguise.disguises.DisguiseCreeper; import mineplex.core.donation.DonationManager; import mineplex.core.hologram.Hologram; import mineplex.core.hologram.HologramManager; @@ -24,6 +35,8 @@ import mineplex.core.reward.RewardManager; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.core.votifier.VotifierCommand; +import mineplex.hub.bonuses.animations.AnimationCarl; +import mineplex.hub.bonuses.commands.AnimationCommand; import mineplex.hub.bonuses.commands.GuiCommand; import mineplex.hub.bonuses.event.CarlSpinnerEvent; import mineplex.hub.bonuses.gui.BonusGui; @@ -32,15 +45,21 @@ import mineplex.hub.bonuses.gui.SpinGui; import mineplex.serverdata.commands.ServerCommandManager; import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.util.Vector; + import net.minecraft.server.v1_7_R4.DataWatcher; import net.minecraft.server.v1_7_R4.PacketPlayOutEntityMetadata; @@ -50,6 +69,11 @@ public class BonusManager extends MiniClientPlugin implements I public static final TimeZone TIMEZONE = TimeZone.getTimeZone("UTC"); private static long timeOffSet = 0; + + private ArrayList _pendingExplosions = new ArrayList<>(); + private ArrayList _pendingExplosionsPlayers = new ArrayList<>(); + private long _explode; + private boolean _canVote; public static long getSqlTime() { @@ -91,6 +115,7 @@ public class BonusManager extends MiniClientPlugin implements I private HologramManager _hologramManager; private RewardManager _rewardManager; private Npc _carlNpc; + private AnimationCarl _animation; // Streak private StreakRecord _dailyStreak; @@ -107,7 +132,10 @@ public class BonusManager extends MiniClientPlugin implements I _rewardManager = rewardManager; // Hope to god this works! + _canVote = true; _carlNpc = _npcManager.getNpcByName("Carl the Creeper"); + _animation = new AnimationCarl(_carlNpc.getEntity()); + _animation.setRunning(false); clientManager.addStoredProcedureLoginProcessor(this); @@ -122,6 +150,7 @@ public class BonusManager extends MiniClientPlugin implements I public void addCommands() { addCommand(new GuiCommand(this)); + addCommand(new AnimationCommand(this)); } // Just keeping things up-to-date @@ -176,7 +205,95 @@ public class BonusManager extends MiniClientPlugin implements I public void handleVote(Player player) { - Bukkit.broadcastMessage("Recieved Vote: " + player.getName()); + addPendingExplosion(player, player.getName()); + } + + @EventHandler + public void fireCreeper(UpdateEvent event) + { + if(event.getType() != UpdateType.SLOW) + return; + + if(_pendingExplosions.isEmpty()) + return; + + if(!_canVote) + return; + + if(_pendingExplosions.get(0) instanceof String) + { + String name = (String)_pendingExplosions.get(0); + Bukkit.broadcastMessage("Recieved Vote: " + name); + } + _explode = System.currentTimeMillis(); + _animation.setTicks(0); + _canVote = false; + } + + @EventHandler + public void creeperAnimation(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + return; + + if(_canVote) + return; + + Entity creeper = _carlNpc.getEntity(); + + double elapsed = (System.currentTimeMillis() - _explode)/1000d; + + //Not Detonated + if (elapsed < 1) + { + //Sound + creeper.getWorld().playSound(creeper.getLocation(), Sound.CREEPER_HISS, (float)(0.5 + elapsed), (float)(0.5 + elapsed)); + + IncreaseSize(creeper); + return; + } + + if(!_animation.isRunning()) + { + //Effect + UtilParticle.PlayParticle(ParticleType.HUGE_EXPLOSION, creeper.getLocation(), 0, 0, 0, 0, 1, ViewDist.MAX, UtilServer.getPlayers()); + creeper.getWorld().playSound(creeper.getLocation(), Sound.EXPLODE, 2f, 1f); + _animation.setType(_pendingExplosions.get(0)); + _animation.setPlayer(_pendingExplosionsPlayers.get(0)); + _animation.setTime(System.currentTimeMillis()); + _animation.setRunning(true); + } + + if(!_animation.isDone()) + return; + + DecreaseSize(creeper); + _pendingExplosions.remove(0); + _pendingExplosionsPlayers.remove(0); + _canVote = true; + } + + @EventHandler + public void updateAnimation(UpdateEvent event) + { + if(event.getType() != UpdateType.TICK) + return; + + if(!_animation.isRunning()) + return; + + _animation.run(); + } + + public void DecreaseSize(Entity player) + { + ((CraftEntity)_carlNpc.getEntity()).getHandle().getDataWatcher().watch(16, -1); + ((CraftEntity)_carlNpc.getEntity()).getHandle().getDataWatcher().watch(17, 1); + } + + public void IncreaseSize(Entity player) + { + ((CraftEntity)_carlNpc.getEntity()).getHandle().getDataWatcher().watch(16, 1); } // DAILY BONUS @@ -253,6 +370,7 @@ public class BonusManager extends MiniClientPlugin implements I { CarlSpinnerEvent event = new CarlSpinnerEvent(player); Bukkit.getServer().getPluginManager().callEvent(event); + final BonusManager manager = this; if (!event.isCancelled()) { @@ -272,7 +390,7 @@ public class BonusManager extends MiniClientPlugin implements I @Override public void run() { - new SpinGui(getPlugin(), player, _rewardManager).openInventory(); + new SpinGui(getPlugin(), player, _rewardManager, manager).openInventory(); } }); } @@ -374,6 +492,7 @@ public class BonusManager extends MiniClientPlugin implements I { BonusAmount amount = new BonusAmount(); amount.setTickets(1); + amount.setGems(500); return amount; } @@ -383,15 +502,19 @@ public class BonusManager extends MiniClientPlugin implements I BonusAmount data = new BonusAmount(); + if (rank.Has(Rank.MODERATOR)) + { + data.setCoins(35000); + } if (rank.Has(Rank.LEGEND)) { data.setCoins(30000); } - else if (rank.Has(Rank.ULTRA)) + else if (rank.Has(Rank.HERO)) { data.setCoins(15000); } - else if (rank.Has(Rank.HERO)) + else if (rank.Has(Rank.ULTRA)) { data.setCoins(7500); } @@ -685,4 +808,10 @@ public class BonusManager extends MiniClientPlugin implements I BonusClientData clientData = new BonusClientData(record); Set(playerName, clientData); } + + public void addPendingExplosion(Player player, Object obj) + { + _pendingExplosions.add(obj); + _pendingExplosionsPlayers.add(player); + } } \ No newline at end of file diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/animations/AnimationCarl.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/animations/AnimationCarl.java new file mode 100644 index 000000000..02783c89a --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/animations/AnimationCarl.java @@ -0,0 +1,102 @@ +package mineplex.hub.bonuses.animations; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilMath; +import mineplex.core.reward.Reward; +import mineplex.core.reward.RewardData; +import mineplex.core.treasure.animation.Animation; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + +public class AnimationCarl extends Animation +{ + + private boolean _isDone; + private Block _creeper; + private long _startTime; + private Object _type; + private Player _player; + + public AnimationCarl(Entity creeper) + { + _creeper = creeper.getLocation().getBlock(); + } + + @Override + protected void tick() + { + if(_type instanceof String) + { + if (getTicks() < 40) + { + Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), new ItemStack(Material.EMERALD)); + + //Velocity + long passed = System.currentTimeMillis() - _startTime; + Vector vel = new Vector(Math.sin(passed/5d), 0, Math.cos(passed/5d)); + + UtilAction.velocity(gem, vel, Math.abs(Math.sin(passed/3000d)), false, 0, 0.2 + Math.abs(Math.cos(passed/3000d))*0.6, 1, false); + + gem.setTicksLived(1170); + } + else + { + finish(); + } + } + if(_type instanceof Reward) + { + RewardData rewardData = ((Reward)_type).getFakeRewardData(null); + ItemStack itemStack = rewardData.getDisplayItem(); + if(itemStack.getType() == Material.PAPER) + { + itemStack = new ItemStack(Material.NETHER_STAR); + } + Item item = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), itemStack); + + Vector vel = new Vector(_player.getLocation().getX() - _creeper.getLocation().getX(), 0, _player.getLocation().getZ() - _creeper.getLocation().getZ()); + + UtilAction.velocity(item, vel, 0.1, false, 0, 0.2 + 1*0.4, 1, false); + + item.setTicksLived(1170); + finish(); + } + } + + @Override + protected void onFinish() { + _isDone = true; + setTicks(0); + } + + public boolean isDone() + { + return _isDone; + } + + public void setDone(boolean b) + { + _isDone = b; + } + + public void setTime(long time) + { + _startTime = time; + } + + public void setType(Object type) + { + _type = type; + } + + public void setPlayer(Player player) + { + _player = player; + } +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/AnimationCommand.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/AnimationCommand.java new file mode 100644 index 000000000..28e2f493a --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/AnimationCommand.java @@ -0,0 +1,28 @@ +package mineplex.hub.bonuses.commands; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.Rank; +import mineplex.hub.bonuses.BonusManager; + +public class AnimationCommand extends CommandBase{ + + BonusManager _plugin; + + public AnimationCommand(BonusManager plugin) + { + super(plugin, Rank.DEVELOPER, "animation"); + _plugin = plugin; + } + + @Override + public void Execute(Player caller, String[] args) + { + _plugin.addPendingExplosion(caller, "Test"); + _plugin.addPendingExplosion(caller, "Chiss"); + _plugin.addPendingExplosion(caller, "Phinary"); + _plugin.addPendingExplosion(caller, "xXVevzZXx"); + } + +} \ No newline at end of file diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java index 8701b3618..fb3355211 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java @@ -1,16 +1,13 @@ package mineplex.hub.bonuses.gui; -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.EventHandler; -import org.bukkit.inventory.ItemStack; -import org.bukkit.plugin.Plugin; +import java.util.ArrayList; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; import mineplex.core.gui.DisplayItem; import mineplex.core.gui.SimpleGui; +import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.reward.Reward; import mineplex.core.reward.RewardData; import mineplex.core.reward.RewardManager; @@ -18,44 +15,97 @@ import mineplex.core.reward.RewardType; import mineplex.core.shop.item.ShopItem; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; +import mineplex.hub.bonuses.BonusManager; import mineplex.hub.bonuses.gui.buttons.RewardButton; +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.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; + public class SpinGui extends SimpleGui { - private static final int SELECT_OFFSET = 4; private static final int REWARDS_TO_GENERATE = 1000; - private static final int HOPPER_SLOT = 22; - private static final int CARL_SLOT = 40; - private static final int[] LINE_NUMS = { -27, -18, -9, 9, 18 }; + private static final int HOPPER_SLOT = 4; + private static final int CARL_SLOT = 22; + private static final int[] LINE_NUMS = { /*-27, -18,*/ -9, 9/*, 18*/ }; + private static final int STOP_SPINNER_AT = 75; private int _tickCount; + private RewardData _rewardData; + private Reward _reward; + private BonusManager _manager; private int _currentRewardIndex; private int _ticksThisSwap; private int _ticksPerSwap; private int _swapCount; private Reward[] _rewards; + private boolean _stopped; + private boolean _rewarded; + private ArrayList _ticks; + private int _frame; + private float _pitch; + private int _stopSpinnerAt; - public SpinGui(Plugin plugin, Player player, RewardManager rewardManager) + public SpinGui(Plugin plugin, Player player, RewardManager rewardManager, BonusManager manager) { - super(plugin, player, "Carl's Spinner", 54); + super(plugin, player, "Carl's Spinner", 27); + + _manager = manager; ShopItem carlItem = new ShopItem(Material.SKULL_ITEM, (byte) 4, "Carl's Spinner", new String[] {ChatColor.RESET + "Good Luck!" }, 1, false, false); setItem(HOPPER_SLOT, new DisplayItem(new ItemStack(Material.HOPPER))); - setItem(CARL_SLOT, new DisplayItem(carlItem)); + //setItem(CARL_SLOT, new DisplayItem(carlItem)); _rewards = new Reward[REWARDS_TO_GENERATE]; + _ticks = new ArrayList<>(); + _frame = 0; + _pitch = 1; for (int i = 0; i < REWARDS_TO_GENERATE; i++) { _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.Spinner, true); } + + _ticksPerSwap = 1; + + _stopSpinnerAt = STOP_SPINNER_AT; + + for (int i=0 ; i<40 ; i++) + _ticks.add(1); + + for (int i=0 ; i<20 ; i++) + _ticks.add(2); - _ticksPerSwap = 3; + for (int i=0 ; i<10 ; i++) + _ticks.add(4); + + for (int i=0 ; i<5 ; i++) + _ticks.add(8); + + if (Math.random() > 0.5) + { + _ticks.add(12); + _stopSpinnerAt++; + } + + _reward = _rewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3]; + _rewardData = _reward.giveReward("Carls Spinner", getPlayer()); } private void tick() { + + if(_stopped) + return; + _ticksThisSwap++; // Swap @@ -65,15 +115,23 @@ public class SpinGui extends SimpleGui _swapCount++; updateGui(); - float pitch = Math.max(-2, 2 - (_swapCount / 50f)); -// Bukkit.broadcastMessage(pitch + ""); - getPlayer().playSound(getPlayer().getEyeLocation(), Sound.NOTE_PLING, 1, pitch); + if(_pitch == 1) + _pitch = (float) 1.5; + else if(_pitch == 1.5) + _pitch = 2; + else if(_pitch == 2) + _pitch = 1; + + getPlayer().playSound(getPlayer().getEyeLocation(), Sound.NOTE_PLING, 1, _pitch); _currentRewardIndex++; // Slow - if (_swapCount % 10 == 0) - _ticksPerSwap++; + _ticksPerSwap = _ticks.get(_currentRewardIndex - 1); + + if(_currentRewardIndex == _stopSpinnerAt) + _stopped = true; + } _tickCount++; @@ -86,7 +144,7 @@ public class SpinGui extends SimpleGui int index = _currentRewardIndex + i; index = index % REWARDS_TO_GENERATE; - int slot = 27 + i; + int slot = 9 + i; RewardData data = _rewards[index].getFakeRewardData(getPlayer()); setItem(slot, new RewardButton(data)); @@ -94,7 +152,7 @@ public class SpinGui extends SimpleGui for (int j = 0; j < LINE_NUMS.length; j++) { int paneSlot = slot + LINE_NUMS[j]; - if (paneSlot == HOPPER_SLOT || paneSlot == CARL_SLOT) + if (paneSlot == HOPPER_SLOT) continue; setItem(paneSlot, new DisplayItem(data.getRarity().getItemStack())); @@ -109,6 +167,72 @@ public class SpinGui extends SimpleGui return; tick(); + checkIfDone(); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void close(InventoryCloseEvent event) + { + if(_rewarded) + return; + + if(event.getPlayer() != getPlayer()) + return; + + _manager.addPendingExplosion(getPlayer(), _reward); + UtilPlayer.message(getPlayer(), F.main("Carl's Spinner", "You got " + _rewardData.getRarity().getColor() + _rewardData.getFriendlyName() + C.cGray + " From Carl's Spinner.")); + } + + @EventHandler + public void Glass(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + return; + + if(!_stopped) + return; + + if(!_rewarded) + return; + + if(_frame == 0) + { + setItem(CARL_SLOT, new DisplayItem(_rewardData.getRarity().getItemStack())); + setItem(HOPPER_SLOT, new DisplayItem(_rewardData.getRarity().getItemStack())); + _frame++; + } + else if(_frame < 5) + { + setItem(HOPPER_SLOT + _frame, new DisplayItem(_rewardData.getRarity().getItemStack())); + setItem(HOPPER_SLOT - _frame, new DisplayItem(_rewardData.getRarity().getItemStack())); + + setItem(CARL_SLOT + _frame, new DisplayItem(_rewardData.getRarity().getItemStack())); + setItem(CARL_SLOT - _frame, new DisplayItem(_rewardData.getRarity().getItemStack())); + + setItem(13 + _frame, new DisplayItem(_rewardData.getRarity().getItemStack())); + setItem(13 - _frame, new DisplayItem(_rewardData.getRarity().getItemStack())); + _frame++; + } + if(_frame == 6) + { + + } + } + + public void checkIfDone() + { + if(!_stopped) + return; + + if(_rewarded) + return; + + _manager.addPendingExplosion(getPlayer(), _reward); + ItemStack item = getInventory().getItem(13); + getInventory().setItem(13, ItemStackFactory.Instance.CreateStack(item.getType(), (byte) 0, 1, _rewardData.getFriendlyName())); + UtilPlayer.message(getPlayer(), F.main("Carl's Spinner", "You got " + _rewardData.getRarity().getColor() + _rewardData.getFriendlyName() + C.cGray + " From Carl's Spinner.")); + _rewarded = true; + } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java index c68f95814..4c295f5dd 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java @@ -52,6 +52,7 @@ public class CarlSpinButton implements GuiItem { _bonusManager.attemptCarlSpin(_player); } + // new SpinGui(_plugin, _player, _rewardManager).openInventory(); } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java index 3189ec5d5..5cfb45207 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java @@ -145,17 +145,23 @@ public class RankBonusButton implements GuiItem, Listener { if (!hasRank) { material = Material.COAL_BLOCK; - itemName = C.cRed + ChatColor.BOLD + "Rank Bonus"; + itemName = C.cRed + ChatColor.BOLD + "Rank Monthly Bonus"; lore.add(" "); - lore.add(ChatColor.WHITE + "Players with a rank get monthly rewards!"); - lore.add(ChatColor.WHITE + "Purchase at mineplex.com/shop"); + lore.add(ChatColor.WHITE + "Players with a Rank get a Monthly Bonus!"); + lore.add(ChatColor.WHITE + ""); + lore.add(ChatColor.AQUA + "Ultra: 7500 Coins"); + lore.add(ChatColor.LIGHT_PURPLE + "Hero: 15000 Coins"); + lore.add(ChatColor.GREEN + "Legend: 30000 Coins"); + lore.add(ChatColor.WHITE + ""); + lore.add(ChatColor.WHITE + "Purchase a Rank at;"); + lore.add(ChatColor.WHITE + "www.mineplex.com/shop"); } else { if (isAvailable()) { material = Material.ENDER_CHEST; - itemName = C.cGreen + C.Bold + "Rank Bonus"; + itemName = C.cGreen + C.Bold + "Rank Monthly Bonus"; lore.add(" "); lore.add(ChatColor.RESET + "Click to Claim!"); @@ -163,7 +169,7 @@ public class RankBonusButton implements GuiItem, Listener { else { material = Material.REDSTONE_BLOCK; - itemName = C.cRed + C.Bold + "Rank Bonus"; + itemName = C.cRed + C.Bold + "Rank Monthly Bonus"; lore.add(" "); lore.add(ChatColor.RESET + "Next reward in " + UtilTime.convertString(timeLeft(), 0, TimeUnit.FIT) + "!"); @@ -185,7 +191,7 @@ public class RankBonusButton implements GuiItem, Listener { public long timeLeft() { - return _bonusManager.nextRankBonus(getPlayer()) - System.currentTimeMillis(); + return _bonusManager.nextRankBonus(getPlayer()) - System.currentTimeMillis(); } public boolean isAvailable() From 941e746ca981a404b28c939b83a531a20b98fbd3 Mon Sep 17 00:00:00 2001 From: Sarah Date: Sun, 9 Aug 2015 16:47:03 +0200 Subject: [PATCH 26/72] Finalizing Poll GUI in Carl's GUI. --- .../src/mineplex/hub/HubManager.java | 4 ++- .../mineplex/hub/bonuses/BonusManager.java | 10 +++++- .../mineplex/hub/bonuses/gui/BonusGui.java | 10 ++++-- .../hub/bonuses/gui/buttons/PollButton.java | 36 +++++++++++++------ .../src/mineplex/hub/poll/PollManager.java | 4 +-- 5 files changed, 47 insertions(+), 17 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index 4a4fbdd2b..944e7d9b5 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -115,6 +115,7 @@ public class HubManager extends MiniClientPlugin private DisguiseManager _disguiseManager; private PartyManager _partyManager; private ForcefieldManager _forcefieldManager; + private PollManager _pollManager; private Portal _portal; private StatsManager _statsManager; private GadgetManager _gadgetManager; @@ -158,6 +159,7 @@ public class HubManager extends MiniClientPlugin _conditionManager = conditionManager; _donationManager = donationManager; _disguiseManager = disguiseManager; + _pollManager = pollManager; _portal = portal; @@ -207,7 +209,7 @@ public class HubManager extends MiniClientPlugin ((CraftWorld)Bukkit.getWorlds().get(0)).getHandle().pvpMode = true; - new BonusManager(plugin, clientManager, donationManager, npcManager, hologramManager, rewardManager); + new BonusManager(plugin, clientManager, donationManager, pollManager , npcManager, hologramManager, rewardManager); // NotificationManager notificationManager = new NotificationManager(plugin, clientManager, donationManager); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index dbd6db81a..6bd421b75 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -42,6 +42,7 @@ import mineplex.hub.bonuses.event.CarlSpinnerEvent; import mineplex.hub.bonuses.gui.BonusGui; import mineplex.database.tables.records.BonusRecord; import mineplex.hub.bonuses.gui.SpinGui; +import mineplex.hub.poll.PollManager; import mineplex.serverdata.commands.ServerCommandManager; import org.bukkit.Bukkit; @@ -111,6 +112,7 @@ public class BonusManager extends MiniClientPlugin implements I private BonusRepository _repository; private CoreClientManager _clientManager; private DonationManager _donationManager; + private PollManager _pollManager; private NpcManager _npcManager; private HologramManager _hologramManager; private RewardManager _rewardManager; @@ -121,7 +123,7 @@ public class BonusManager extends MiniClientPlugin implements I private StreakRecord _dailyStreak; private StreakRecord _voteStreak; - public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, NpcManager npcManager, HologramManager hologramManager, RewardManager rewardManager) + public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, PollManager pollManager, NpcManager npcManager, HologramManager hologramManager, RewardManager rewardManager) { super("Bonus", plugin); _repository = new BonusRepository(plugin, this, donationManager); @@ -130,6 +132,7 @@ public class BonusManager extends MiniClientPlugin implements I _npcManager = npcManager; _hologramManager = hologramManager; _rewardManager = rewardManager; + _pollManager = pollManager; // Hope to god this works! _canVote = true; @@ -814,4 +817,9 @@ public class BonusManager extends MiniClientPlugin implements I _pendingExplosions.add(obj); _pendingExplosionsPlayers.add(player); } + + public PollManager getPollManager() + { + return _pollManager; + } } \ No newline at end of file diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java index 65aa961cf..ea7978621 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java @@ -5,11 +5,13 @@ import mineplex.core.reward.RewardManager; import mineplex.hub.bonuses.BonusManager; import mineplex.hub.bonuses.gui.buttons.CarlSpinButton; import mineplex.hub.bonuses.gui.buttons.DailyBonusButton; +import mineplex.hub.bonuses.gui.buttons.PollButton; import mineplex.hub.bonuses.gui.buttons.RankBonusButton; import mineplex.hub.bonuses.gui.buttons.VoteButton; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; +import org.omg.CORBA._PolicyStub; public class BonusGui extends SimpleGui { @@ -22,12 +24,14 @@ public class BonusGui extends SimpleGui this.manager = manager; - setItem(11, new VoteButton(plugin, player, this, manager)); + setItem(10, new VoteButton(plugin, player, this, manager)); - setItem(13, new RankBonusButton(getPlugin(), player, this, manager)); + setItem(12, new RankBonusButton(getPlugin(), player, this, manager)); - setItem(15, new DailyBonusButton(getPlugin(), player, this, manager)); + setItem(14, new DailyBonusButton(getPlugin(), player, this, manager)); + setItem(16, new PollButton(getPlugin(), player, manager.getPollManager(), manager.getClientManager(), this)); + setItem(31, new CarlSpinButton(getPlugin(), player, manager, rewardManager)); } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java index 9ae72899b..5584e5b65 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java @@ -1,8 +1,10 @@ package mineplex.hub.bonuses.gui.buttons; +import java.util.ArrayList; import java.util.HashMap; import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.C; import mineplex.core.common.util.UtilText; import mineplex.core.gui.GuiInventory; import mineplex.core.gui.GuiItem; @@ -53,9 +55,6 @@ public class PollButton extends SimpleGui implements GuiItem { if (_poll != null) { - - // Todo - Fix this! -// getButtonMap().putAll(hard); setItem(4, getQuestionItem(_poll.getQuestion())); @@ -63,22 +62,38 @@ public class PollButton extends SimpleGui implements GuiItem { for (int i = 0; i < slots.length; i++) { - - setItem(9 * 2 + slots[i], new AnswerItem(_poll, i)); - + AnswerItem item = new AnswerItem(_poll, i); + setItem(9 * 2 + slots[i], item); } } } } - @Override public ItemStack getObject() { + ArrayList lore = new ArrayList<>(); if (_poll == null) - return ItemStackFactory.Instance.CreateStack(Material.REDSTONE_BLOCK, (byte) 0, 1, "No polls!"); + { + lore.add(C.cRed + "You've already voted on all of the polls!"); + return ItemStackFactory.Instance.CreateStack(Material.REDSTONE_BLOCK, (byte) 0, 1, ChatColor.RED + C.Bold + "Vote on Poll", lore); + } else - return ItemStackFactory.Instance.CreateStack(Material.BOOK_AND_QUILL, (byte) 0, 1, ChatColor.GREEN + _poll.getQuestion()); + { + lore.add(C.cWhite + _poll.getQuestion()); + lore.add(""); + int i = 1; + for(String str : _poll.getAnswers()) + { + lore.add(C.cAqua + "" + i + ".) " + str); + i++; + } + lore.add(""); + lore.add(C.cYellow + C.Bold + "Reward: 500 Gems"); + lore.add(""); + lore.add(C.cGreen + "Click to go to the vote page!"); + return ItemStackFactory.Instance.CreateStack(Material.BOOK_AND_QUILL, (byte) 0, 1, C.cGreen + C.Bold + "Vote on Poll", lore); + } } @Override @@ -155,8 +170,9 @@ public class PollButton extends SimpleGui implements GuiItem { _pollManager.answerPoll(getPlayer(), _poll, num); getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); + new TimedMessageWindow(getPlugin(), getPlayer(), ItemStackFactory.Instance.CreateStack(Material.EMERALD_BLOCK, (byte) 0, 1, ChatColor.GREEN + "Your anwser:", wrap(getPoll().getAnswers()[num])), ChatColor.GREEN + "Moo", 6 * 9, 50, getMaster()).openInventory(); - + getPlayer().closeInventory(); } @Override diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollManager.java index 8820efd46..7fb0e00fd 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollManager.java @@ -64,7 +64,7 @@ public class PollManager extends MiniDbClientPlugin pollData.setPollCooldown(5000); } - @EventHandler + /*@EventHandler public void update(UpdateEvent event) { if (event.getType() != UpdateType.SLOW) @@ -88,7 +88,7 @@ public class PollManager extends MiniDbClientPlugin pollData.updatePollCooldown(); } } - } + }*/ public Poll getNextPoll(PlayerPollData pollData, Rank playerRank) { From 8c66ef7f15883ec3c629a665af694572939fdb28 Mon Sep 17 00:00:00 2001 From: Sarah Date: Sun, 9 Aug 2015 18:33:44 +0200 Subject: [PATCH 27/72] changing Hub items and adding Profile GUI. --- .../core/achievement/AchievementManager.java | 28 +--------- .../personalServer/HostServerCommand.java | 2 +- .../personalServer/PersonalServerManager.java | 1 - .../core/preferences/PreferencesManager.java | 55 ++++++++++++------- .../Mineplex.Hub/src/mineplex/hub/Hub.java | 6 +- .../src/mineplex/hub/HubManager.java | 16 +++++- .../hub/bonuses/gui/buttons/PollButton.java | 35 +++++++++--- .../bonuses/gui/buttons/RankBonusButton.java | 14 ++++- .../hub/profile/buttons/ButtonMPS.java | 51 +++++++++++++++++ .../hub/profile/buttons/ButtonPrefs.java | 51 +++++++++++++++++ .../hub/profile/buttons/ButtonStats.java | 55 +++++++++++++++++++ .../mineplex/hub/profile/gui/GUIProfile.java | 48 ++++++++++++++++ 12 files changed, 301 insertions(+), 61 deletions(-) create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonMPS.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonPrefs.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonStats.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/profile/gui/GUIProfile.java diff --git a/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementManager.java b/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementManager.java index 485f5a124..76e58b6fb 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementManager.java @@ -137,15 +137,6 @@ public class AchievementManager extends MiniPlugin _log.remove(event.getPlayer().getName()); } - @EventHandler - public void playerJoin(PlayerJoinEvent event) - { - if (_giveInterfaceItem) - { - giveInterfaceItem(event.getPlayer()); - } - } - public void clearLog(Player player) { _log.remove(player.getName()); @@ -161,22 +152,7 @@ public class AchievementManager extends MiniPlugin _giveInterfaceItem = giveInterfaceItem; } - public void giveInterfaceItem(Player player) - { - if (!UtilGear.isMat(player.getInventory().getItem(_interfaceSlot), Material.SKULL_ITEM)) - { - ItemStack item = ItemStackFactory.Instance.CreateStack(Material.SKULL_ITEM, (byte) 3, 1, ChatColor.RESET + C.cGreen + "/stats"); - SkullMeta meta = ((SkullMeta) item.getItemMeta()); - meta.setOwner(player.getName()); - item.setItemMeta(meta); - - player.getInventory().setItem(_interfaceSlot, item); - - UtilInv.Update(player); - } - } - - @EventHandler + /*@EventHandler public void openShop(PlayerInteractEvent event) { if (!_shopEnabled) @@ -188,7 +164,7 @@ public class AchievementManager extends MiniPlugin openShop(event.getPlayer()); } - } + }*/ public boolean hasCategory(Player player, Achievement[] required) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/personalServer/HostServerCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/personalServer/HostServerCommand.java index b09c4cc54..a087fd3f6 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/personalServer/HostServerCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/personalServer/HostServerCommand.java @@ -10,7 +10,7 @@ public class HostServerCommand extends CommandBase { public HostServerCommand(PersonalServerManager plugin) { - super(plugin, Rank.LEGEND, "hostserver"); + super(plugin, Rank.LEGEND, "hostserver", "mps"); } @Override diff --git a/Plugins/Mineplex.Core/src/mineplex/core/personalServer/PersonalServerManager.java b/Plugins/Mineplex.Core/src/mineplex/core/personalServer/PersonalServerManager.java index 466a26d50..3438849f7 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/personalServer/PersonalServerManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/personalServer/PersonalServerManager.java @@ -59,7 +59,6 @@ public class PersonalServerManager extends MiniPlugin { if (_giveInterfaceItem) { - event.getPlayer().getInventory().setItem(_interfaceSlot, _interfaceItem); } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/preferences/PreferencesManager.java b/Plugins/Mineplex.Core/src/mineplex/core/preferences/PreferencesManager.java index 6a96dcd16..c69ab7bed 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/preferences/PreferencesManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/preferences/PreferencesManager.java @@ -4,6 +4,19 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.Map.Entry; +import mineplex.core.MiniDbClientPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.C; +import mineplex.core.common.util.NautHashMap; +import mineplex.core.common.util.UtilGear; +import mineplex.core.common.util.UtilInv; +import mineplex.core.donation.DonationManager; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.core.preferences.command.PreferencesCommand; +import mineplex.core.preferences.ui.PreferencesShop; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; + import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -11,18 +24,10 @@ 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.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.plugin.java.JavaPlugin; -import mineplex.core.MiniDbClientPlugin; -import mineplex.core.account.CoreClientManager; -import mineplex.core.common.util.NautHashMap; -import mineplex.core.donation.DonationManager; -import mineplex.core.itemstack.ItemStackFactory; -import mineplex.core.preferences.command.PreferencesCommand; -import mineplex.core.preferences.ui.PreferencesShop; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; - public class PreferencesManager extends MiniDbClientPlugin { private PreferencesRepository _repository; @@ -53,6 +58,27 @@ public class PreferencesManager extends MiniDbClientPlugin _saveBuffer.put(caller.getUniqueId().toString(), Get(caller)); } + @EventHandler + public void givePlayerItem(PlayerJoinEvent event) + { + if (!GiveItem) + return; + + Player player = event.getPlayer(); + + if (!UtilGear.isMat(player.getInventory().getItem(8), Material.SKULL_ITEM)) + { + ItemStack item = ItemStackFactory.Instance.CreateStack(Material.SKULL_ITEM, (byte) 3, 1, ChatColor.RESET + C.cGreen + "My Profile"); + SkullMeta meta = ((SkullMeta) item.getItemMeta()); + meta.setOwner(player.getName()); + item.setItemMeta(meta); + + player.getInventory().setItem(8, item); + + UtilInv.Update(player); + } + } + @EventHandler public void storeBuffer(UpdateEvent event) { @@ -76,15 +102,6 @@ public class PreferencesManager extends MiniDbClientPlugin } }); } - - @EventHandler - public void givePlayerItem(PlayerJoinEvent event) - { - if (!GiveItem) - return; - - event.getPlayer().getInventory().setItem(8, ItemStackFactory.Instance.CreateStack(Material.REDSTONE_COMPARATOR.getId(), (byte)0, 1, ChatColor.GREEN + "/prefs")); - } @EventHandler(priority = EventPriority.LOWEST) public void playerInteract(PlayerInteractEvent event) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java index 3da68540b..c99d09044 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java @@ -122,7 +122,9 @@ public class Hub extends JavaPlugin implements IRelation PartyManager partyManager = new PartyManager(this, portal, clientManager, preferenceManager); - HubManager hubManager = new HubManager(this, blockRestore, clientManager, donationManager, new ConditionManager(this), disguiseManager, new TaskManager(this, clientManager, webServerAddress), portal, partyManager, preferenceManager, petManager, pollManager, statsManager, achievementManager, new HologramManager(this), npcManager); + PersonalServerManager personalServerManager = new PersonalServerManager(this, clientManager); + + HubManager hubManager = new HubManager(this, blockRestore, clientManager, donationManager, new ConditionManager(this), disguiseManager, new TaskManager(this, clientManager, webServerAddress), portal, partyManager, preferenceManager, petManager, pollManager, statsManager, achievementManager, new HologramManager(this), npcManager, personalServerManager); QueueManager queueManager = new QueueManager(this, clientManager, donationManager, new EloManager(this, clientManager), partyManager); @@ -141,7 +143,7 @@ public class Hub extends JavaPlugin implements IRelation } }); //new Replay(this, packetHandler); - new PersonalServerManager(this, clientManager); + AprilFoolsManager.Initialize(this, clientManager, disguiseManager); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index 944e7d9b5..03ffee480 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -25,6 +25,7 @@ import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerQuitEvent; @@ -74,6 +75,7 @@ import mineplex.core.notifier.NotificationManager; import mineplex.core.npc.NpcManager; import mineplex.core.party.Party; import mineplex.core.party.PartyManager; +import mineplex.core.personalServer.PersonalServerManager; import mineplex.core.pet.PetManager; import mineplex.core.portal.Portal; import mineplex.core.preferences.PreferencesManager; @@ -97,6 +99,7 @@ import mineplex.hub.modules.ParkourManager; import mineplex.hub.modules.TextManager; import mineplex.hub.modules.WorldManager; import mineplex.hub.poll.PollManager; +import mineplex.hub.profile.gui.GUIProfile; import mineplex.hub.tutorial.TutorialManager; import mineplex.minecraft.game.classcombat.Skill.event.SkillTriggerEvent; import mineplex.minecraft.game.classcombat.item.event.ItemTriggerEvent; @@ -130,6 +133,7 @@ public class HubManager extends MiniClientPlugin private AchievementManager _achievementManager; private TreasureManager _treasureManager; private PetManager _petManager; + private PersonalServerManager _personalServerManager; private Location _spawn; private int _scoreboardTick = 0; @@ -150,7 +154,7 @@ public class HubManager extends MiniClientPlugin //Admin private boolean _gadgetsEnabled = true; - public HubManager(JavaPlugin plugin, BlockRestore blockRestore, CoreClientManager clientManager, DonationManager donationManager, ConditionManager conditionManager, DisguiseManager disguiseManager, TaskManager taskManager, Portal portal, PartyManager partyManager, PreferencesManager preferences, PetManager petManager, PollManager pollManager, StatsManager statsManager, AchievementManager achievementManager, HologramManager hologramManager, NpcManager npcManager) + public HubManager(JavaPlugin plugin, BlockRestore blockRestore, CoreClientManager clientManager, DonationManager donationManager, ConditionManager conditionManager, DisguiseManager disguiseManager, TaskManager taskManager, Portal portal, PartyManager partyManager, PreferencesManager preferences, PetManager petManager, PollManager pollManager, StatsManager statsManager, AchievementManager achievementManager, HologramManager hologramManager, NpcManager npcManager, PersonalServerManager personalServerManager) { super("Hub Manager", plugin); @@ -160,6 +164,7 @@ public class HubManager extends MiniClientPlugin _donationManager = donationManager; _disguiseManager = disguiseManager; _pollManager = pollManager; + _personalServerManager = personalServerManager; _portal = portal; @@ -1094,4 +1099,13 @@ public class HubManager extends MiniClientPlugin UtilPlayer.message(player, F.main("Game Mode", event.getPlayer().getName() + " left the game. Creative Mode: " + F.tf(false))); } } + + @EventHandler + public void openProfile(PlayerInteractEvent event) + { + if(event.getItem().getType() != Material.SKULL_ITEM) + return; + + new GUIProfile(getPlugin(), event.getPlayer(), _preferences, _achievementManager, _personalServerManager).openInventory();; + } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java index 5584e5b65..b5fe9dca1 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java @@ -56,14 +56,14 @@ public class PollButton extends SimpleGui implements GuiItem { if (_poll != null) { - setItem(4, getQuestionItem(_poll.getQuestion())); + setItem(13, getQuestionItem(_poll.getQuestion())); int[] slots = even(9, _poll.getAnswers().length); for (int i = 0; i < slots.length; i++) { AnswerItem item = new AnswerItem(_poll, i); - setItem(9 * 2 + slots[i], item); + setItem(9 * 3 + slots[i], item); } } } @@ -80,16 +80,17 @@ public class PollButton extends SimpleGui implements GuiItem { } else { + lore.add(""); lore.add(C.cWhite + _poll.getQuestion()); lore.add(""); int i = 1; for(String str : _poll.getAnswers()) { - lore.add(C.cAqua + "" + i + ".) " + str); + lore.add(C.cAqua + "" + i + ".) " + C.cWhite + str); i++; } lore.add(""); - lore.add(C.cYellow + C.Bold + "Reward: 500 Gems"); + lore.add(C.cYellow + "Reward:" + C.cWhite + " 500 Gems"); lore.add(""); lore.add(C.cGreen + "Click to go to the vote page!"); return ItemStackFactory.Instance.CreateStack(Material.BOOK_AND_QUILL, (byte) 0, 1, C.cGreen + C.Bold + "Vote on Poll", lore); @@ -112,8 +113,24 @@ public class PollButton extends SimpleGui implements GuiItem { public GuiItem getQuestionItem(String question) { - return new SimpleGuiItem(ItemStackFactory.Instance.CreateStack(Material.BOOK_AND_QUILL, (byte) 0, 1, ChatColor.GREEN + "Question:", - wrap(question))); + + ArrayList lore = new ArrayList<>(); + lore.add(""); + lore.add(C.cWhite + wrap(question)); + lore.add(""); + int i = 1; + for(String str : _poll.getAnswers()) + { + lore.add(C.cAqua + "" + i + ".) " + C.cWhite + str); + i++; + } + lore.add(""); + lore.add(C.cYellow + "Reward:" + C.cWhite + " 500 Gems"); + lore.add(""); + lore.add(C.cGreen + "Click to go to the vote page!"); + + return new SimpleGuiItem(ItemStackFactory.Instance.CreateStack(Material.BOOK_AND_QUILL, (byte) 0, 1, ChatColor.GREEN + C.cGreen + C.Bold + "Vote on Poll", + lore)); } public static String[] wrap(String text) @@ -158,8 +175,10 @@ public class PollButton extends SimpleGui implements GuiItem { @Override public ItemStack getObject() { - return ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, ChatColor.GREEN + "" + (num + 1) + ":", wrap(getPoll() - .getAnswers()[num])); + ArrayList lore = new ArrayList<>(); + lore.add(""); + lore.add(getPoll().getAnswers()[num]); + return ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, ChatColor.GREEN + "Option " + (num + 1), lore); } @Override diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java index 5cfb45207..14f43e9c6 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java @@ -149,9 +149,9 @@ public class RankBonusButton implements GuiItem, Listener { lore.add(" "); lore.add(ChatColor.WHITE + "Players with a Rank get a Monthly Bonus!"); lore.add(ChatColor.WHITE + ""); - lore.add(ChatColor.AQUA + "Ultra: 7500 Coins"); - lore.add(ChatColor.LIGHT_PURPLE + "Hero: 15000 Coins"); - lore.add(ChatColor.GREEN + "Legend: 30000 Coins"); + lore.add(ChatColor.AQUA + "Ultra receives 7500 Coins Monthly"); + lore.add(ChatColor.LIGHT_PURPLE + "Hero receives 15000 Coins Monthly"); + lore.add(ChatColor.GREEN + "Legend receives 30000 Coins Monthly"); lore.add(ChatColor.WHITE + ""); lore.add(ChatColor.WHITE + "Purchase a Rank at;"); lore.add(ChatColor.WHITE + "www.mineplex.com/shop"); @@ -197,7 +197,15 @@ public class RankBonusButton implements GuiItem, Listener { public boolean isAvailable() { if (!hasRank) + { + UtilPlayer.message(getPlayer(), "----------------------------------------"); + UtilPlayer.message(getPlayer(), ""); + UtilPlayer.message(getPlayer(), "Purchase a Rank at the Mineplex Shop:"); + UtilPlayer.message(getPlayer(), C.cGreen + "www.mineplex.com/shop"); + UtilPlayer.message(getPlayer(), ""); + UtilPlayer.message(getPlayer(), "----------------------------------------"); return false; + } return (timeLeft() <= 0); } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonMPS.java b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonMPS.java new file mode 100644 index 000000000..f4e3b506a --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonMPS.java @@ -0,0 +1,51 @@ +package mineplex.hub.profile.buttons; + +import mineplex.core.common.util.C; +import mineplex.core.gui.GuiItem; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.hub.profile.gui.GUIProfile; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; + +public class ButtonMPS implements GuiItem +{ + + private GUIProfile _profile; + private Player _player; + + public ButtonMPS(GUIProfile profile, Player player) + { + _profile = profile; + _player = player; + } + + @Override + public void click(ClickType clickType) + { + _profile.getPersonalManager().showHostMessage(_player); + } + + @Override + public ItemStack getObject() + { + return ItemStackFactory.Instance.CreateStack(Material.SPECKLED_MELON, (byte)0, 1, C.cGreen + "/hostserver"); + } + + @Override + public void setup() + { + + } + + @Override + public void close() + { + + } + +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonPrefs.java b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonPrefs.java new file mode 100644 index 000000000..8795cd2a5 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonPrefs.java @@ -0,0 +1,51 @@ +package mineplex.hub.profile.buttons; + +import mineplex.core.common.util.C; +import mineplex.core.gui.GuiItem; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.hub.profile.gui.GUIProfile; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; + +public class ButtonPrefs implements GuiItem +{ + + private GUIProfile _profile; + private Player _player; + + public ButtonPrefs(GUIProfile profile, Player player) + { + _profile = profile; + _player = player; + } + + @Override + public void click(ClickType clickType) + { + _profile.getPrefManager().openShop(_player); + } + + @Override + public ItemStack getObject() + { + return ItemStackFactory.Instance.CreateStack(Material.REDSTONE_COMPARATOR.getId(), (byte)0, 1, ChatColor.GREEN + "/prefs"); + } + + @Override + public void setup() + { + + } + + @Override + public void close() + { + + } + +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonStats.java b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonStats.java new file mode 100644 index 000000000..d5533a4ed --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonStats.java @@ -0,0 +1,55 @@ +package mineplex.hub.profile.buttons; + +import mineplex.core.common.util.C; +import mineplex.core.gui.GuiItem; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.hub.profile.gui.GUIProfile; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; + +public class ButtonStats implements GuiItem +{ + + private GUIProfile _profile; + private Player _player; + + public ButtonStats(GUIProfile profile, Player player) + { + _profile = profile; + _player = player; + } + + @Override + public void click(ClickType clickType) + { + _profile.getAchievementManager().openShop(_player); + } + + @Override + public ItemStack getObject() + { + ItemStack item = ItemStackFactory.Instance.CreateStack(Material.SKULL_ITEM, (byte) 3, 1, ChatColor.RESET + C.cGreen + "/stats"); + SkullMeta meta = ((SkullMeta) item.getItemMeta()); + meta.setOwner(_player.getName()); + item.setItemMeta(meta); + return item; + } + + @Override + public void setup() + { + + } + + @Override + public void close() + { + + } + +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/gui/GUIProfile.java b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/gui/GUIProfile.java new file mode 100644 index 000000000..35c6ccf65 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/gui/GUIProfile.java @@ -0,0 +1,48 @@ +package mineplex.hub.profile.gui; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import mineplex.core.achievement.AchievementManager; +import mineplex.core.gui.SimpleGui; +import mineplex.core.personalServer.PersonalServerManager; +import mineplex.core.preferences.PreferencesManager; +import mineplex.hub.profile.buttons.ButtonMPS; +import mineplex.hub.profile.buttons.ButtonPrefs; +import mineplex.hub.profile.buttons.ButtonStats; + +public class GUIProfile extends SimpleGui +{ + + private PreferencesManager _preferencesManager; + private AchievementManager _achievementManager; + private PersonalServerManager _personalServerManager; + + public GUIProfile(Plugin plugin, Player player, PreferencesManager preferencesManager, AchievementManager achievementManager, PersonalServerManager personalServerManager) + { + super(plugin, player, "My Profile", 9*3); + _preferencesManager = preferencesManager; + _achievementManager = achievementManager; + _personalServerManager = personalServerManager; + + setItem(11, new ButtonStats(this, player)); + setItem(13, new ButtonMPS(this, player)); + setItem(15, new ButtonPrefs(this, player)); + } + + public PreferencesManager getPrefManager() + { + return _preferencesManager; + } + + public AchievementManager getAchievementManager() + { + return _achievementManager; + } + + public PersonalServerManager getPersonalManager() + { + return _personalServerManager; + } + +} From 41dcc564c9a90b3a5f554b28e4b19d25e6fc642a Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Sun, 9 Aug 2015 19:02:07 +0200 Subject: [PATCH 28/72] polish polish polish MAKE IT SHINE! --- .../src/mineplex/hub/bonuses/gui/SpinGui.java | 23 ++++++++++++++++++- .../hub/profile/buttons/ButtonMPS.java | 11 ++++++++- .../hub/profile/buttons/ButtonPrefs.java | 12 +++++++++- .../hub/profile/buttons/ButtonStats.java | 18 +++++++++++---- .../mineplex/hub/profile/gui/GUIProfile.java | 4 ++-- 5 files changed, 59 insertions(+), 9 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java index fb3355211..7489d4dc3 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java @@ -11,8 +11,13 @@ import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.reward.Reward; import mineplex.core.reward.RewardData; import mineplex.core.reward.RewardManager; +import mineplex.core.reward.RewardRarity; import mineplex.core.reward.RewardType; import mineplex.core.shop.item.ShopItem; +import mineplex.core.treasure.animation.LootLegendaryAnimation; +import mineplex.core.treasure.animation.LootMythicalAnimation; +import mineplex.core.treasure.animation.LootRareAnimation; +import mineplex.core.treasure.animation.LootUncommonAnimation; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.hub.bonuses.BonusManager; @@ -180,7 +185,23 @@ public class SpinGui extends SimpleGui return; _manager.addPendingExplosion(getPlayer(), _reward); - UtilPlayer.message(getPlayer(), F.main("Carl's Spinner", "You got " + _rewardData.getRarity().getColor() + _rewardData.getFriendlyName() + C.cGray + " From Carl's Spinner.")); + + if (_reward.getRarity() == RewardRarity.RARE) + { + Bukkit.broadcastMessage(F.main("Treasure", F.name(event.getPlayer().getName()) + " won " + C.cPurple + "Rare " + _rewardData.getFriendlyName() + C.cGray + " from Carl's Spinner.")); + } + else if (_reward.getRarity() == RewardRarity.LEGENDARY) + { + Bukkit.broadcastMessage(F.main("Treasure", F.name(event.getPlayer().getName()) + " won " + C.cGreen + "Legendary " + _rewardData.getFriendlyName() + C.cGray + " from Carl's Spinner.")); + } + else if (_reward.getRarity() == RewardRarity.MYTHICAL) + { + Bukkit.broadcastMessage(F.main("Treasure", F.name(event.getPlayer().getName()) + " won " + C.cRed + "Mythical " + _rewardData.getFriendlyName() + C.cGray + " from Carl's Spinner.")); + } + else + { + UtilPlayer.message(getPlayer(), F.main("Carl's Spinner", "You won " + _rewardData.getRarity().getColor() + _rewardData.getFriendlyName() + C.cGray + " from Carl's Spinner.")); + } } @EventHandler diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonMPS.java b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonMPS.java index f4e3b506a..00135e777 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonMPS.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonMPS.java @@ -33,7 +33,16 @@ public class ButtonMPS implements GuiItem @Override public ItemStack getObject() { - return ItemStackFactory.Instance.CreateStack(Material.SPECKLED_MELON, (byte)0, 1, C.cGreen + "/hostserver"); + return ItemStackFactory.Instance.CreateStack(Material.SPECKLED_MELON, (byte)0, 1, + ChatColor.RESET + C.cYellow + "Mineplex Player Server", + new String[] + { + "", + C.cWhite + "Create a server where you are the Host.", + C.cWhite + "You can choose the game, map and much more!", + "", + C.cWhite + "Type " + C.cGreen + "/mps" + C.cWhite + " to access this anywhere!" + }); } @Override diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonPrefs.java b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonPrefs.java index 8795cd2a5..38652a7c7 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonPrefs.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonPrefs.java @@ -33,7 +33,17 @@ public class ButtonPrefs implements GuiItem @Override public ItemStack getObject() { - return ItemStackFactory.Instance.CreateStack(Material.REDSTONE_COMPARATOR.getId(), (byte)0, 1, ChatColor.GREEN + "/prefs"); + return ItemStackFactory.Instance.CreateStack(Material.REDSTONE_COMPARATOR.getId(), (byte)0, 1, + ChatColor.RESET + C.cYellow + "Preferences", + new String[] + { + "", + C.cWhite + "Set your preferences to your liking", + C.cWhite + "so you can enjoy the game more!", + + "", + C.cWhite + "Type " + C.cGreen + "/prefs" + C.cWhite + " to access this anywhere!" + }); } @Override diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonStats.java b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonStats.java index d5533a4ed..3e36c712d 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonStats.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonStats.java @@ -17,7 +17,7 @@ public class ButtonStats implements GuiItem private GUIProfile _profile; private Player _player; - + public ButtonStats(GUIProfile profile, Player player) { _profile = profile; @@ -33,7 +33,17 @@ public class ButtonStats implements GuiItem @Override public ItemStack getObject() { - ItemStack item = ItemStackFactory.Instance.CreateStack(Material.SKULL_ITEM, (byte) 3, 1, ChatColor.RESET + C.cGreen + "/stats"); + ItemStack item = ItemStackFactory.Instance.CreateStack(Material.SKULL_ITEM, (byte) 3, 1, + ChatColor.RESET + C.cYellow + "Stats and Achievements", + new String[] + { + "", + C.cWhite + "View your Statistics and Achievements", + C.cWhite + "for all of the games on Mineplex!", + + "", + C.cWhite + "Type " + C.cGreen + "/stats" + C.cWhite + " to access this anywhere!" + }); SkullMeta meta = ((SkullMeta) item.getItemMeta()); meta.setOwner(_player.getName()); item.setItemMeta(meta); @@ -43,13 +53,13 @@ public class ButtonStats implements GuiItem @Override public void setup() { - + } @Override public void close() { - + } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/gui/GUIProfile.java b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/gui/GUIProfile.java index 35c6ccf65..a7dca223b 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/gui/GUIProfile.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/gui/GUIProfile.java @@ -26,8 +26,8 @@ public class GUIProfile extends SimpleGui _personalServerManager = personalServerManager; setItem(11, new ButtonStats(this, player)); - setItem(13, new ButtonMPS(this, player)); - setItem(15, new ButtonPrefs(this, player)); + setItem(13, new ButtonPrefs(this, player)); + setItem(15, new ButtonMPS(this, player)); } public PreferencesManager getPrefManager() From c2d066a576cd4089311743adcc0581f6e6f26734 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Sun, 9 Aug 2015 19:31:24 +0200 Subject: [PATCH 29/72] ui fixes --- .../src/mineplex/hub/bonuses/gui/SpinGui.java | 15 ++++++++------- .../hub/bonuses/gui/buttons/PollButton.java | 9 ++++----- .../hub/bonuses/gui/buttons/RankBonusButton.java | 2 ++ .../hub/bonuses/gui/buttons/VoteButton.java | 4 ++-- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java index 7489d4dc3..9e9bbefa9 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java @@ -40,7 +40,6 @@ public class SpinGui extends SimpleGui private static final int HOPPER_SLOT = 4; private static final int CARL_SLOT = 22; private static final int[] LINE_NUMS = { /*-27, -18,*/ -9, 9/*, 18*/ }; - private static final int STOP_SPINNER_AT = 75; private int _tickCount; private RewardData _rewardData; @@ -76,13 +75,11 @@ public class SpinGui extends SimpleGui for (int i = 0; i < REWARDS_TO_GENERATE; i++) { - _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.Spinner, true); + _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.MythicalChest, true); } _ticksPerSwap = 1; - - _stopSpinnerAt = STOP_SPINNER_AT; - + for (int i=0 ; i<40 ; i++) _ticks.add(1); @@ -92,15 +89,19 @@ public class SpinGui extends SimpleGui for (int i=0 ; i<10 ; i++) _ticks.add(4); - for (int i=0 ; i<5 ; i++) + for (int i=0 ; i<4 ; i++) + _ticks.add(6); + + for (int i=0 ; i<3 ; i++) _ticks.add(8); if (Math.random() > 0.5) { _ticks.add(12); - _stopSpinnerAt++; } + _stopSpinnerAt = _ticks.size(); + _reward = _rewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3]; _rewardData = _reward.giveReward("Carls Spinner", getPlayer()); } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java index b5fe9dca1..008a024ce 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java @@ -75,7 +75,7 @@ public class PollButton extends SimpleGui implements GuiItem { ArrayList lore = new ArrayList<>(); if (_poll == null) { - lore.add(C.cRed + "You've already voted on all of the polls!"); + lore.add(C.cRed + "You've voted on all of the polls!"); return ItemStackFactory.Instance.CreateStack(Material.REDSTONE_BLOCK, (byte) 0, 1, ChatColor.RED + C.Bold + "Vote on Poll", lore); } else @@ -116,7 +116,8 @@ public class PollButton extends SimpleGui implements GuiItem { ArrayList lore = new ArrayList<>(); lore.add(""); - lore.add(C.cWhite + wrap(question)); + for (String string : wrap(question)) + lore.add(C.cWhite + string); lore.add(""); int i = 1; for(String str : _poll.getAnswers()) @@ -126,8 +127,6 @@ public class PollButton extends SimpleGui implements GuiItem { } lore.add(""); lore.add(C.cYellow + "Reward:" + C.cWhite + " 500 Gems"); - lore.add(""); - lore.add(C.cGreen + "Click to go to the vote page!"); return new SimpleGuiItem(ItemStackFactory.Instance.CreateStack(Material.BOOK_AND_QUILL, (byte) 0, 1, ChatColor.GREEN + C.cGreen + C.Bold + "Vote on Poll", lore)); @@ -177,7 +176,7 @@ public class PollButton extends SimpleGui implements GuiItem { { ArrayList lore = new ArrayList<>(); lore.add(""); - lore.add(getPoll().getAnswers()[num]); + lore.add(C.cWhite + getPoll().getAnswers()[num]); return ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, ChatColor.GREEN + "Option " + (num + 1), lore); } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java index 14f43e9c6..b394a398e 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java @@ -204,6 +204,8 @@ public class RankBonusButton implements GuiItem, Listener { UtilPlayer.message(getPlayer(), C.cGreen + "www.mineplex.com/shop"); UtilPlayer.message(getPlayer(), ""); UtilPlayer.message(getPlayer(), "----------------------------------------"); + + getPlayer().closeInventory(); return false; } return (timeLeft() <= 0); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java index 54021b6f2..f7fcb06a1 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java @@ -80,14 +80,14 @@ public class VoteButton implements GuiItem, Listener { getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); - UtilPlayer.message(getPlayer(), C.cRed + "------------------------------------------------"); + UtilPlayer.message(getPlayer(), "----------------------------------------"); UtilPlayer.message(getPlayer(), ""); new JsonMessage("Click to Open in Web Browser").click(ClickEvent.OPEN_URL, _url).sendToPlayer(getPlayer()); new JsonMessage(C.cGreen + _url).click(ClickEvent.OPEN_URL, _url).sendToPlayer(getPlayer()); UtilPlayer.message(getPlayer(), ""); - UtilPlayer.message(getPlayer(), C.cRed + "------------------------------------------------"); + UtilPlayer.message(getPlayer(), "----------------------------------------"); From d20fe5401077a9a150fbdaf4a0067e7e651462d8 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Sun, 9 Aug 2015 16:36:48 -0500 Subject: [PATCH 30/72] Disable carl features when carl can't be found --- .../src/mineplex/core/npc/NpcManager.java | 2 +- .../mineplex/hub/bonuses/BonusManager.java | 55 +++++++++++++------ 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/npc/NpcManager.java b/Plugins/Mineplex.Core/src/mineplex/core/npc/NpcManager.java index f856cda99..d92a8690e 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/npc/NpcManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/npc/NpcManager.java @@ -165,7 +165,7 @@ public class NpcManager extends MiniPlugin { for (Npc npc : _npcs) { - if (npc.getDatabaseRecord().getName() != null && npc.getDatabaseRecord().getName().equalsIgnoreCase(name)) + if (npc.getDatabaseRecord().getName() != null && npc.getDatabaseRecord().getName().contains(name)) return npc; } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index 6bd421b75..08bf386c9 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -16,16 +16,11 @@ import mineplex.core.common.Rank; 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.UtilAction; -import mineplex.core.common.util.UtilBlock; -import mineplex.core.common.util.UtilMath; import mineplex.core.common.util.UtilParticle; import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilParticle.ParticleType; import mineplex.core.common.util.UtilParticle.ViewDist; -import mineplex.core.disguise.disguises.DisguiseCreeper; import mineplex.core.donation.DonationManager; import mineplex.core.hologram.Hologram; import mineplex.core.hologram.HologramManager; @@ -46,7 +41,6 @@ import mineplex.hub.poll.PollManager; import mineplex.serverdata.commands.ServerCommandManager; import org.bukkit.Bukkit; -import org.bukkit.Location; import org.bukkit.Sound; import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; import org.bukkit.entity.Entity; @@ -54,12 +48,10 @@ import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; -import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.util.Vector; import net.minecraft.server.v1_7_R4.DataWatcher; import net.minecraft.server.v1_7_R4.PacketPlayOutEntityMetadata; @@ -116,6 +108,7 @@ public class BonusManager extends MiniClientPlugin implements I private NpcManager _npcManager; private HologramManager _hologramManager; private RewardManager _rewardManager; + public boolean _enabled; private Npc _carlNpc; private AnimationCarl _animation; @@ -137,8 +130,18 @@ public class BonusManager extends MiniClientPlugin implements I // Hope to god this works! _canVote = true; _carlNpc = _npcManager.getNpcByName("Carl the Creeper"); - _animation = new AnimationCarl(_carlNpc.getEntity()); - _animation.setRunning(false); + if (_carlNpc == null) + { + _enabled = false; + } + else + { + _enabled = true; +// _carlNpc.getEntity().setCustomName(""); +// _carlNpc.getEntity().setCustomNameVisible(false); + _animation = new AnimationCarl(_carlNpc.getEntity()); + _animation.setRunning(false); + } clientManager.addStoredProcedureLoginProcessor(this); @@ -223,6 +226,9 @@ public class BonusManager extends MiniClientPlugin implements I if(!_canVote) return; + if (!_enabled) + return; + if(_pendingExplosions.get(0) instanceof String) { String name = (String)_pendingExplosions.get(0); @@ -241,6 +247,9 @@ public class BonusManager extends MiniClientPlugin implements I if(_canVote) return; + + if (!_enabled) + return; Entity creeper = _carlNpc.getEntity(); @@ -281,6 +290,9 @@ public class BonusManager extends MiniClientPlugin implements I { if(event.getType() != UpdateType.TICK) return; + + if (!_enabled) + return; if(!_animation.isRunning()) return; @@ -290,12 +302,18 @@ public class BonusManager extends MiniClientPlugin implements I public void DecreaseSize(Entity player) { + if (!_enabled) + return; + ((CraftEntity)_carlNpc.getEntity()).getHandle().getDataWatcher().watch(16, -1); ((CraftEntity)_carlNpc.getEntity()).getHandle().getDataWatcher().watch(17, 1); } public void IncreaseSize(Entity player) { + if (!_enabled) + return; + ((CraftEntity)_carlNpc.getEntity()).getHandle().getDataWatcher().watch(16, 1); } @@ -643,8 +661,11 @@ public class BonusManager extends MiniClientPlugin implements I @EventHandler public void openGui(PlayerInteractEntityEvent event) { + if (!_enabled) + return; + Entity entity = event.getRightClicked(); - if (entity instanceof LivingEntity && entity.getType().equals(EntityType.CREEPER) && ((LivingEntity) entity).getCustomName().contains("Carl the Creeper")) + if (entity.equals(_carlNpc.getEntity())) { updateDailyStreak(event.getPlayer()); new BonusGui(_plugin, event.getPlayer(), this, _rewardManager).openInventory(); @@ -698,14 +719,11 @@ public class BonusManager extends MiniClientPlugin implements I }, 10); } - @EventHandler - public void join(PlayerInteractEvent event) - { - updateCreeperVisual(event.getPlayer()); - } - public void updateCreeperVisual(Player player) { + if (!_enabled) + return; + BonusClientData client = Get(player); int availableRewards = 0; @@ -719,7 +737,7 @@ public class BonusManager extends MiniClientPlugin implements I if (client.getHologram() == null) { - hologram = new Hologram(_hologramManager, _carlNpc.getLocation().clone().add(0, 2.75, 0), ""); + hologram = new Hologram(_hologramManager, _carlNpc.getLocation().clone().add(0, 2.75 - 0.285 - 0.285, 0), ""); hologram.setHologramTarget(Hologram.HologramTarget.WHITELIST); hologram.addPlayer(player); client.setHologram(hologram); @@ -732,6 +750,7 @@ public class BonusManager extends MiniClientPlugin implements I if (availableRewards > 0) { // Hologram +// String name = "Carl the Creeper"; String text = C.cAqua + availableRewards + " Reward" + (availableRewards > 1 ? "s" : "") + " to Claim"; hologram.setText(text); hologram.start(); From 28806aaf0a2a4b5b4fd4638017900d82a0de626c Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Mon, 10 Aug 2015 00:33:54 -0500 Subject: [PATCH 31/72] Update Bonus amounts, Attempting to fix Votifier plugin for EU/US --- .../src/mineplex/hub/bonuses/BonusAmount.java | 4 +- .../mineplex/hub/bonuses/BonusManager.java | 46 ++++++- .../mineplex/hub/bonuses/BonusRepository.java | 7 +- .../bonuses/gui/buttons/DailyBonusButton.java | 2 + .../hub/bonuses/gui/buttons/VoteButton.java | 2 + .../serverdata/servers/ServerManager.java | 11 +- .../Mineplex.Votifier/Mineplex.Votifier.iml | 4 + .../mineplex/votifier/VotifierManager.java | 130 +++++++++++++++--- 8 files changed, 170 insertions(+), 36 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java index d596a846b..17b12a1c7 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java @@ -150,7 +150,7 @@ public class BonusAmount if (amount > 0) lore.add(C.cYellow + "Reward: " + C.cWhite + amount + " " + suffix); - if (bonus > 0) - lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + bonus + " " + suffix); +// if (bonus > 0) +// lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + bonus + " " + suffix); } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index 08bf386c9..b91ff0527 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -211,6 +211,8 @@ public class BonusManager extends MiniClientPlugin implements I public void handleVote(Player player) { +// _repository.attemptDailyBonus(); + addPendingExplosion(player, player.getName()); } @@ -500,20 +502,54 @@ public class BonusManager extends MiniClientPlugin implements I return calendar.getTimeInMillis(); } + public int getDailyMultiplier(Player player) + { + BonusClientData client = Get(player); + int streak = client.getDailyStreak(); + + int multiplyer = Math.min(200, 5 * streak); + if (streak >= 40) multiplyer += (1 * (streak - 40)); + return multiplyer; + } + + public int getVoteMultiplyer(Player player) + { + BonusClientData client = Get(player); + int streak = client.getVoteStreak(); + + int multiplyer = Math.min(100, 5 * streak); + if (streak >= 20) multiplyer += (1 * (streak - 40)); + return multiplyer; + } + public BonusAmount getDailyBonusAmount(Player player) { + double mult = getDailyMultiplier(player) / 100.0; + BonusAmount amount = new BonusAmount(); - amount.setTickets(1); - amount.setBonusCoins(100); - amount.setBonusExperience(1000); + int coins = 100; + int gems = 100; + int experience = 250; + + amount.setCoins(coins); + amount.setGems(gems); + amount.setExperience(experience); + amount.setBonusCoins((int) (mult * coins)); + amount.setBonusGems((int) (mult * gems)); + amount.setBonusExperience((int) (mult * experience)); + return amount; } public BonusAmount getVoteBonusAmount(Player player) { + double mult = getVoteMultiplyer(player) / 100.0; + BonusAmount amount = new BonusAmount(); amount.setTickets(1); - amount.setGems(500); + amount.setGems(400); + amount.setBonusGems((int) (mult * 400)); + return amount; } @@ -545,7 +581,7 @@ public class BonusManager extends MiniClientPlugin implements I //VOTE - public void atteptVoteBonus(final Player player, final Callback result) + public void attemptVoteBonus(final Player player, final Callback result) { if (timeTillRankBonus(player) > 0) result.run(false); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java index 8fcc95d6d..bed58e3dd 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java @@ -251,13 +251,8 @@ public class BonusRepository extends RepositoryBase }); } - public void voteBonus(final Player player, final Callback result) + public void attemptVoteBonus(final Player player, final Callback result) { - if (!Recharge.Instance.usable(player, "AttemptVoteBonus")) - { - result.run(false); - return; - } final int accountId = _manager.getClientManager().Get(player).getAccountId(); final int coins = _manager.getRankBonusAmount(player).getCoins(); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java index f6534589d..8ee34647f 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java @@ -143,6 +143,8 @@ public class DailyBonusButton implements GuiItem, Listener lore.add(" "); lore.add(C.cYellow + "Current Streak: " + C.cWhite + client.getDailyStreak()); + lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + _bonusManager.getDailyMultiplier(_player) + "%"); + lore.add(" "); lore.add(C.cYellow + "Highest Streak: " + C.cWhite + client.getMaxDailyStreak()); if (client.getDailyTime() != null) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java index f7fcb06a1..969fc2f9d 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java @@ -139,6 +139,8 @@ public class VoteButton implements GuiItem, Listener { lore.add(" "); lore.add(C.cYellow + "Current Streak: " + C.cWhite + client.getVoteStreak()); + lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + _bonusManager.getVoteMultiplyer(_player) + "%"); + lore.add(" "); lore.add(C.cYellow + "Highest Streak: " + C.cWhite + client.getMaxVoteStreak()); if (client.getVoteTime() != null) diff --git a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ServerManager.java b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ServerManager.java index fbf5d563b..4ed251ae4 100644 --- a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ServerManager.java +++ b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ServerManager.java @@ -20,8 +20,9 @@ import mineplex.serverdata.servers.ConnectionData.ConnectionType; * */ public class ServerManager -{ +{ public static final String SERVER_STATUS_LABEL = "ServerStatus"; // Label differentiating ServerStatus related servers + private static final String DEFAULT_CONFIG = "redis-config.dat"; // Configuration determining connection information private static RedisConfig _config; @@ -74,7 +75,7 @@ public class ServerManager public static ConnectionData getConnection(boolean writeable, String name) { - return getConfig().getConnection(writeable, name); + return getConfig(DEFAULT_CONFIG).getConnection(writeable, name); } /** @@ -89,13 +90,13 @@ public class ServerManager /** * @return the {@link RedisConfig} associated with this manager, providing appropriate connections. */ - public static RedisConfig getConfig() + public static RedisConfig getConfig(String fileName) { if (_config == null) { try { - File configFile = new File("redis-config.dat"); + File configFile = new File(fileName); if (configFile.exists()) { @@ -113,7 +114,7 @@ public class ServerManager } else { - log("redis-config.dat not found at " + configFile.toPath().toString()); + log(fileName + " not found at " + configFile.toPath().toString()); _config = new RedisConfig(); } } diff --git a/Plugins/Mineplex.Votifier/Mineplex.Votifier.iml b/Plugins/Mineplex.Votifier/Mineplex.Votifier.iml index b7d71d202..c5e840788 100644 --- a/Plugins/Mineplex.Votifier/Mineplex.Votifier.iml +++ b/Plugins/Mineplex.Votifier/Mineplex.Votifier.iml @@ -19,5 +19,9 @@ + + + + \ No newline at end of file diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java index ecef96339..3ff5e1f0f 100644 --- a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java @@ -1,5 +1,7 @@ package mineplex.votifier; +import java.util.UUID; + import org.bukkit.event.EventHandler; import org.bukkit.plugin.java.JavaPlugin; @@ -7,64 +9,156 @@ import com.vexsoftware.votifier.model.Vote; import com.vexsoftware.votifier.model.VotifierEvent; import mineplex.core.MiniPlugin; import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.UUIDFetcher; +import mineplex.core.database.DBPool; import mineplex.core.donation.DonationManager; import mineplex.core.votifier.VotifierCommand; +import mineplex.database.Tables; import mineplex.serverdata.Region; +import mineplex.serverdata.Utility; +import mineplex.serverdata.commands.ServerCommand; import mineplex.serverdata.commands.ServerCommandManager; import mineplex.serverdata.data.PlayerStatus; +import mineplex.serverdata.redis.RedisConfig; import mineplex.serverdata.redis.RedisDataRepository; import mineplex.serverdata.servers.ServerManager; +import org.jooq.DSLContext; +import org.jooq.SQLDialect; +import org.jooq.impl.DSL; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.exceptions.JedisConnectionException; /** * Created by shaun on 15-08-05. */ public class VotifierManager extends MiniPlugin { + private CoreClientManager _clientManager; + private DonationManager _donationManager; + + private RedisConfig _usConfig; + private RedisConfig _euConfig; private RedisDataRepository _usPlayerRepo; private RedisDataRepository _euPlayerRepo; + private JedisPool _usWritePool; + private JedisPool _euWritePool; public VotifierManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager) { super("Votifier", plugin); - _usPlayerRepo = new RedisDataRepository(ServerManager.getMasterConnection(), ServerManager.getSlaveConnection(), - Region.US, PlayerStatus.class, "playerStatus"); - _euPlayerRepo = new RedisDataRepository(ServerManager.getMasterConnection(), ServerManager.getSlaveConnection(), - Region.EU, PlayerStatus.class, "playerStatus"); + _clientManager = clientManager; + _donationManager = donationManager; - ServerCommandManager.getInstance().registerCommandType("VotifierCommand", VotifierCommand.class); + _usConfig = ServerManager.getConfig("us-redis.dat"); + _euConfig = ServerManager.getConfig("eu-redis.dat"); + + _usPlayerRepo = new RedisDataRepository(_usConfig.getConnection(true, "DefaultConnection"), + _usConfig.getConnection(false, "DefaultConnection"), Region.US, PlayerStatus.class, "playerStatus"); + _euPlayerRepo = new RedisDataRepository(_euConfig.getConnection(true, "DefaultConnection"), + _euConfig.getConnection(false, "DefaultConnection"), Region.EU, PlayerStatus.class, "playerStatus"); + + _usWritePool = Utility.generatePool(_usConfig.getConnection(true, "DefaultConnection")); + _euWritePool = Utility.generatePool(_euConfig.getConnection(true, "DefaultConnection")); } @EventHandler public void handleVote(VotifierEvent event) { Vote vote = event.getVote(); + String playerName = "Phinary"; - System.out.println("New Vote: " + vote.getUsername()); + System.out.println("New Vote: " + playerName); - PlayerStatus usStatus = _usPlayerRepo.getElement(vote.getUsername()); -// VotifierCommand command = new VotifierCommand(vote.getUsername(), "PhiTest-1"); -// command.publish(); +// UUID uuid = UUIDFetcher.getUUIDOf(playerName); + UUID uuid = _clientManager.loadUUIDFromDB(playerName); + if (uuid != null) + { + System.out.println("Found UUID:" + uuid.toString()); +// if (playerName.equalsIgnoreCase("Phinary")) +// { +// System.out.println("award bonus"); +// awardBonus(uuid); +// } + } + else + { + System.out.println("Failed to load UUID for player: " + playerName); + } + notifyServer(playerName); + } + + private boolean notifyServer(String playerName) + { + JedisPool writePool = null; + String serverName = null; + + PlayerStatus usStatus = _usPlayerRepo.getElement(playerName); if (usStatus != null) { System.out.println("Found on US Server: " + usStatus.getServer()); - VotifierCommand command = new VotifierCommand(vote.getUsername(), usStatus.getServer()); - command.publish(); - } - else - { - System.out.println("Not found on US Server!"); + writePool = _usWritePool; + serverName = usStatus.getServer(); } - PlayerStatus euStatus = _euPlayerRepo.getElement(vote.getUsername()); + PlayerStatus euStatus = _euPlayerRepo.getElement(playerName); if (euStatus != null) { System.out.println("Found on EU Server: " + euStatus.getServer()); + writePool = _euWritePool; + serverName = euStatus.getServer(); } - else + + if (writePool != null && serverName != null) { - System.out.println("Not found on EU Server!"); + VotifierCommand command = new VotifierCommand(playerName, serverName); + System.out.println("Publishing Server Command!"); + publishCommand(command, writePool); + + return true; } + + return false; + } + + private void awardBonus(UUID uuid) + { + DSLContext create = DSL.using(DBPool.ACCOUNT, SQLDialect.MYSQL); + int updated = create.update(Tables.bonus).set(Tables.bonus.tickets, Tables.bonus.tickets.add(1)) + .where(Tables.bonus.accountId.eq(DSL.select(Tables.accounts.id).where(Tables.accounts.uuid.eq(uuid.toString())))).execute(); + System.out.println("Ran query with response: " + updated); + } + + private void publishCommand(final ServerCommand serverCommand, final JedisPool writePool) + { + new Thread(new Runnable() + { + public void run() + { + Jedis jedis = writePool.getResource(); + + try + { + String commandType = serverCommand.getClass().getSimpleName(); + String serializedCommand = Utility.serialize(serverCommand); + jedis.publish("commands.server" + ":" + commandType, serializedCommand); + } + catch (JedisConnectionException exception) + { + exception.printStackTrace(); + writePool.returnBrokenResource(jedis); + jedis = null; + } + finally + { + if (writePool != null) + { + writePool.returnResource(jedis); + } + } + } + }).start(); } } \ No newline at end of file From 511cc76befbb3ca1cb81f22501926f76dcd59fe5 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Mon, 10 Aug 2015 00:47:36 -0500 Subject: [PATCH 32/72] Allow servers to process votifier votes, redis command gets sent to all servers (Until I can figure out why EU playertracker isnt working) --- .../core/votifier/VotifierCommand.java | 2 +- .../mineplex/hub/bonuses/BonusManager.java | 22 +++++- .../mineplex/hub/bonuses/BonusRepository.java | 8 -- .../mineplex/votifier/VotifierManager.java | 74 +++++++++---------- 4 files changed, 53 insertions(+), 53 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/votifier/VotifierCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/votifier/VotifierCommand.java index a84087fb0..0d8454d2d 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/votifier/VotifierCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/votifier/VotifierCommand.java @@ -8,7 +8,7 @@ public class VotifierCommand extends ServerCommand { private String _playerName; - public VotifierCommand(String playerName, String targetServer) + public VotifierCommand(String playerName, String... targetServer) { super(targetServer); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index b91ff0527..a63556c77 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -209,11 +209,25 @@ public class BonusManager extends MiniClientPlugin implements I return _voteStreak; } - public void handleVote(Player player) + public void handleVote(final Player player) { -// _repository.attemptDailyBonus(); - - addPendingExplosion(player, player.getName()); + _repository.attemptVoteBonus(player, new Callback() + { + @Override + public void run(Boolean data) + { + if (data) + { + addPendingExplosion(player, player.getName()); + awardBonus(player, getVoteBonusAmount(player)); + UtilPlayer.message(player, F.main("Vote", "Thanks for your vote!")); + } + else + { + UtilPlayer.message(player, F.main("Vote", "There was an error processing your vote. Please contact an admin!")); + } + } + }); } @EventHandler diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java index bed58e3dd..f34c71296 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java @@ -97,10 +97,6 @@ public class BonusRepository extends RepositoryBase public void attemptDailyBonus(final Player player, final Callback result) { - if (!Recharge.Instance.usable(player, "AttemptDailyBonus")) { - result.run(false); - return; - } final int accountId = _manager.getClientManager().Get(player).getAccountId(); final int coins = 0; final int gems = 0; @@ -290,10 +286,6 @@ public class BonusRepository extends RepositoryBase public void run() { _manager.Get(player).setVoteTime(date); - - _donationManager.RewardCoins(null, "Vote bonus", player.getName(), accountId, coins); - _donationManager.RewardGems(null, "Vote bonus", player.getName(), player.getUniqueId(), gems); - result.run(true); } diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java index 3ff5e1f0f..420fb5adf 100644 --- a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java @@ -67,64 +67,58 @@ public class VotifierManager extends MiniPlugin public void handleVote(VotifierEvent event) { Vote vote = event.getVote(); - String playerName = "Phinary"; + String playerName = vote.getUsername(); System.out.println("New Vote: " + playerName); // UUID uuid = UUIDFetcher.getUUIDOf(playerName); - UUID uuid = _clientManager.loadUUIDFromDB(playerName); - if (uuid != null) - { - System.out.println("Found UUID:" + uuid.toString()); +// UUID uuid = _clientManager.loadUUIDFromDB(playerName); +// if (uuid != null) +// { +// System.out.println("Found UUID:" + uuid.toString()); // if (playerName.equalsIgnoreCase("Phinary")) // { // System.out.println("award bonus"); // awardBonus(uuid); // } - } - else - { - System.out.println("Failed to load UUID for player: " + playerName); - } +// } +// else +// { +// System.out.println("Failed to load UUID for player: " + playerName); +// } - notifyServer(playerName); +// PlayerStatus usStatus = _usPlayerRepo.getElement(playerName); +// if (usStatus != null) +// { +// System.out.println("Found on US Server: " + usStatus.getServer()); +// writePool = _usWritePool; +// serverName = usStatus.getServer(); +// } +// +// PlayerStatus euStatus = _euPlayerRepo.getElement(playerName); +// if (euStatus != null) +// { +// System.out.println("Found on EU Server: " + euStatus.getServer()); +// writePool = _euWritePool; +// serverName = euStatus.getServer(); +// } + + // Currently we just notify all servers, and the server with the player on it can deal with it + notifyServer(playerName, false); + notifyServer(playerName, true); } - private boolean notifyServer(String playerName) + private void notifyServer(String playerName, boolean eu) { - JedisPool writePool = null; - String serverName = null; + JedisPool writePool = eu ? _euWritePool : _usWritePool; - PlayerStatus usStatus = _usPlayerRepo.getElement(playerName); - if (usStatus != null) - { - System.out.println("Found on US Server: " + usStatus.getServer()); - writePool = _usWritePool; - serverName = usStatus.getServer(); - } - - PlayerStatus euStatus = _euPlayerRepo.getElement(playerName); - if (euStatus != null) - { - System.out.println("Found on EU Server: " + euStatus.getServer()); - writePool = _euWritePool; - serverName = euStatus.getServer(); - } - - if (writePool != null && serverName != null) - { - VotifierCommand command = new VotifierCommand(playerName, serverName); - System.out.println("Publishing Server Command!"); - publishCommand(command, writePool); - - return true; - } - - return false; + VotifierCommand command = new VotifierCommand(playerName); + publishCommand(command, writePool); } private void awardBonus(UUID uuid) { + // Don't use this right now! DSLContext create = DSL.using(DBPool.ACCOUNT, SQLDialect.MYSQL); int updated = create.update(Tables.bonus).set(Tables.bonus.tickets, Tables.bonus.tickets.add(1)) .where(Tables.bonus.accountId.eq(DSL.select(Tables.accounts.id).where(Tables.accounts.uuid.eq(uuid.toString())))).execute(); From a0be3fa96480a559d804a6d850c04dbab0d59ea8 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Mon, 10 Aug 2015 01:19:10 -0500 Subject: [PATCH 33/72] Use atomic mysql operations for modifying tickets --- .../mineplex/hub/bonuses/BonusManager.java | 42 ++++++++++++--- .../mineplex/hub/bonuses/BonusRepository.java | 4 +- .../hub/bonuses/commands/TicketCommand.java | 54 +++++++++++++++++++ 3 files changed, 90 insertions(+), 10 deletions(-) create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/TicketCommand.java diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index a63556c77..c997deaf8 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -21,6 +21,7 @@ import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilParticle.ParticleType; import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.database.DBPool; import mineplex.core.donation.DonationManager; import mineplex.core.hologram.Hologram; import mineplex.core.hologram.HologramManager; @@ -30,15 +31,20 @@ import mineplex.core.reward.RewardManager; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.core.votifier.VotifierCommand; +import mineplex.database.Tables; import mineplex.hub.bonuses.animations.AnimationCarl; import mineplex.hub.bonuses.commands.AnimationCommand; import mineplex.hub.bonuses.commands.GuiCommand; +import mineplex.hub.bonuses.commands.TicketCommand; import mineplex.hub.bonuses.event.CarlSpinnerEvent; import mineplex.hub.bonuses.gui.BonusGui; import mineplex.database.tables.records.BonusRecord; import mineplex.hub.bonuses.gui.SpinGui; import mineplex.hub.poll.PollManager; import mineplex.serverdata.commands.ServerCommandManager; +import org.jooq.DSLContext; +import org.jooq.SQLDialect; +import org.jooq.impl.DSL; import org.bukkit.Bukkit; import org.bukkit.Sound; @@ -157,6 +163,7 @@ public class BonusManager extends MiniClientPlugin implements I { addCommand(new GuiCommand(this)); addCommand(new AnimationCommand(this)); + addCommand(new TicketCommand(this)); } // Just keeping things up-to-date @@ -411,27 +418,29 @@ public class BonusManager extends MiniClientPlugin implements I if (!event.isCancelled()) { - clientData.setTickets(clientData.getTickets() - 1); + final int accountId = _clientManager.Get(player).getAccountId(); runAsync(new Runnable() { @Override public void run() { - int modified = clientData.getRecord().store(); - - if (modified == 1) + try { + final int newTickets = DSL.using(DBPool.ACCOUNT, SQLDialect.MYSQL).update(Tables.bonus).set(Tables.bonus.tickets, Tables.bonus.tickets.sub(1)). + where(Tables.bonus.accountId.eq(accountId)).returning(Tables.bonus.tickets).fetchOne().getTickets(); + runSync(new Runnable() { @Override public void run() { + clientData.setTickets(newTickets); new SpinGui(getPlugin(), player, _rewardManager, manager).openInventory(); } }); } - else + catch (Exception e) { UtilPlayer.message(player, F.main("Carl", "There was an error processing your request")); } @@ -689,16 +698,33 @@ public class BonusManager extends MiniClientPlugin implements I if (tickets > 0) { - bonusClient.setTickets(tickets + bonusClient.getTickets()); + final int accountId = _clientManager.Get(player).getAccountId(); runAsync(new Runnable() { @Override public void run() { - bonusClient.getRecord().store(); + try + { + final int newTickets = DSL.using(DBPool.ACCOUNT, SQLDialect.MYSQL).update(Tables.bonus).set(Tables.bonus.tickets, Tables.bonus.tickets.add(tickets)). + where(Tables.bonus.accountId.eq(accountId)).returning(Tables.bonus.tickets).fetchOne().getTickets(); + runSync(new Runnable() + { + @Override + public void run() + { + bonusClient.setTickets(newTickets); + UtilPlayer.message(player, F.main("Bonus", "Rewarded " + F.elem(tickets + " Carl Spin Ticket"))); + } + }); + } + catch (Exception e) + { + System.out.println("Failed to award ticket to player: " + player); + e.printStackTrace(); + } } }); - UtilPlayer.message(player, F.main("Bonus", "Rewarded " + F.elem(tickets + " Carl Spin Ticket"))); } if (experience > 0) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java index f34c71296..2f53ae3ac 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java @@ -53,7 +53,7 @@ public class BonusRepository extends RepositoryBase record.setVoteStreak(0); record.setMaxVoteStreak(0); record.setTickets(0); -// record.store(); // Todo - is this necessary? + record.store(); // Todo - is this necessary? } System.out.println("Loaded record. Daily time: " + record.getDailytime()); return record; @@ -158,7 +158,7 @@ public class BonusRepository extends RepositoryBase } @Deprecated - public void attemptPurchaseSpin(final Player player, final Callback result) + public void giveTickets(final Player player, final Callback result) { final int accountId = _manager.getClientManager().Get(player).getAccountId(); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/TicketCommand.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/TicketCommand.java new file mode 100644 index 000000000..14afed1e8 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/TicketCommand.java @@ -0,0 +1,54 @@ +package mineplex.hub.bonuses.commands; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.Rank; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.hub.bonuses.BonusManager; + +import org.bukkit.entity.Player; + +public class TicketCommand extends CommandBase +{ + public TicketCommand(BonusManager plugin) + { + super(plugin, Rank.DEVELOPER, "ticket"); + } + + @Override + public void Execute(final Player caller, String[] args) + { + if (args.length < 2) + { + UtilPlayer.message(caller, F.main("Carl", "Missing Args: " + F.elem("/ticket "))); + return; + } + + final String targetName = args[0]; + final String ticketString = args[1]; + Player target = UtilPlayer.searchExact(targetName); + + + rewardTickets(caller, target, target.getName(), ticketString); + } + + private void rewardTickets(final Player caller, final Player target, final String targetName, String ticketString) + { + try + { + int tickets = Integer.parseInt(ticketString); + Plugin.Get(target).setTickets(Plugin.Get(targetName).getTickets() + tickets); + + UtilPlayer.message(caller, F.main("Carl", "You gave " + F.elem(tickets + " Carl Tickets") + " to " + F.name(targetName) + ".")); + + if (target != null) + { + UtilPlayer.message(target, F.main("Carl", F.name(caller.getName()) + " gave you " + F.elem(tickets + " Carl Tickets") + ".")); + } + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main("Carl", "Invalid Ticket Amount")); + } + } +} From 6f8d6f8a407c1f9b96297949d2d1559167e7a2e8 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Mon, 10 Aug 2015 01:55:50 -0500 Subject: [PATCH 34/72] Move Bonus and Poll to core --- .../mineplex/core}/bonuses/BonusAmount.java | 2 +- .../core}/bonuses/BonusClientData.java | 2 +- .../mineplex/core}/bonuses/BonusManager.java | 45 +++++++++---------- .../core}/bonuses/BonusRepository.java | 2 +- .../mineplex/core}/bonuses/StreakRecord.java | 2 +- .../mineplex/core}/bonuses/VoteHandler.java | 2 +- .../bonuses/animations/AnimationCarl.java | 3 +- .../bonuses/commands/AnimationCommand.java | 4 +- .../core}/bonuses/commands/GuiCommand.java | 7 ++- .../core}/bonuses/commands/TicketCommand.java | 4 +- .../core}/bonuses/event/CarlSpinnerEvent.java | 2 +- .../mineplex/core}/bonuses/gui/BonusGui.java | 15 +++---- .../mineplex/core}/bonuses/gui/SpinGui.java | 10 ++--- .../bonuses/gui/buttons/CarlSpinButton.java | 6 +-- .../bonuses/gui/buttons/DailyBonusButton.java | 10 ++--- .../core}/bonuses/gui/buttons/PollButton.java | 6 +-- .../bonuses/gui/buttons/RankBonusButton.java | 6 +-- .../bonuses/gui/buttons/RewardButton.java | 3 +- .../core}/bonuses/gui/buttons/VoteButton.java | 18 +++----- .../src/mineplex/core}/poll/DisplayType.java | 2 +- .../mineplex/core}/poll/PlayerPollData.java | 2 +- .../src/mineplex/core}/poll/Poll.java | 4 +- .../src/mineplex/core}/poll/PollManager.java | 6 +-- .../mineplex/core}/poll/PollRepository.java | 2 +- .../src/mineplex/core}/poll/PollStats.java | 2 +- .../core}/poll/command/PollCommand.java | 10 ++--- .../Mineplex.Hub/src/mineplex/hub/Hub.java | 3 +- .../src/mineplex/hub/HubManager.java | 6 +-- 28 files changed, 82 insertions(+), 104 deletions(-) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/BonusAmount.java (98%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/BonusClientData.java (98%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/BonusManager.java (94%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/BonusRepository.java (99%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/StreakRecord.java (90%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/VoteHandler.java (95%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/animations/AnimationCarl.java (96%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/commands/AnimationCommand.java (87%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/commands/GuiCommand.java (71%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/commands/TicketCommand.java (94%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/event/CarlSpinnerEvent.java (95%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/gui/BonusGui.java (71%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/gui/SpinGui.java (94%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/gui/buttons/CarlSpinButton.java (93%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/gui/buttons/DailyBonusButton.java (96%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/gui/buttons/PollButton.java (97%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/gui/buttons/RankBonusButton.java (97%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/gui/buttons/RewardButton.java (90%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/gui/buttons/VoteButton.java (89%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/poll/DisplayType.java (91%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/poll/PlayerPollData.java (97%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/poll/Poll.java (95%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/poll/PollManager.java (97%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/poll/PollRepository.java (99%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/poll/PollStats.java (97%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/poll/command/PollCommand.java (96%) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java similarity index 98% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java index 17b12a1c7..76e746f43 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses; +package mineplex.core.bonuses; import java.util.List; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusClientData.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusClientData.java similarity index 98% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusClientData.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusClientData.java index d145a7e35..08cccac7f 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusClientData.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusClientData.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses; +package mineplex.core.bonuses; import java.sql.Date; import java.sql.Timestamp; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java similarity index 94% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index c997deaf8..268664bdf 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -1,10 +1,9 @@ -package mineplex.hub.bonuses; +package mineplex.core.bonuses; import java.sql.Date; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Calendar; -import java.util.Iterator; import java.util.TimeZone; import mineplex.core.MiniClientPlugin; @@ -28,21 +27,21 @@ import mineplex.core.hologram.HologramManager; import mineplex.core.npc.Npc; import mineplex.core.npc.NpcManager; import mineplex.core.reward.RewardManager; +import mineplex.core.stats.StatsManager; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.core.votifier.VotifierCommand; import mineplex.database.Tables; -import mineplex.hub.bonuses.animations.AnimationCarl; -import mineplex.hub.bonuses.commands.AnimationCommand; -import mineplex.hub.bonuses.commands.GuiCommand; -import mineplex.hub.bonuses.commands.TicketCommand; -import mineplex.hub.bonuses.event.CarlSpinnerEvent; -import mineplex.hub.bonuses.gui.BonusGui; +import mineplex.core.bonuses.animations.AnimationCarl; +import mineplex.core.bonuses.commands.AnimationCommand; +import mineplex.core.bonuses.commands.GuiCommand; +import mineplex.core.bonuses.commands.TicketCommand; +import mineplex.core.bonuses.event.CarlSpinnerEvent; +import mineplex.core.bonuses.gui.BonusGui; import mineplex.database.tables.records.BonusRecord; -import mineplex.hub.bonuses.gui.SpinGui; -import mineplex.hub.poll.PollManager; +import mineplex.core.bonuses.gui.SpinGui; +import mineplex.core.poll.PollManager; import mineplex.serverdata.commands.ServerCommandManager; -import org.jooq.DSLContext; import org.jooq.SQLDialect; import org.jooq.impl.DSL; @@ -50,12 +49,9 @@ import org.bukkit.Bukkit; import org.bukkit.Sound; import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerInteractEntityEvent; -import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.plugin.java.JavaPlugin; @@ -114,6 +110,7 @@ public class BonusManager extends MiniClientPlugin implements I private NpcManager _npcManager; private HologramManager _hologramManager; private RewardManager _rewardManager; + private StatsManager _statsManager; public boolean _enabled; private Npc _carlNpc; private AnimationCarl _animation; @@ -122,7 +119,7 @@ public class BonusManager extends MiniClientPlugin implements I private StreakRecord _dailyStreak; private StreakRecord _voteStreak; - public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, PollManager pollManager, NpcManager npcManager, HologramManager hologramManager, RewardManager rewardManager) + public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, PollManager pollManager, NpcManager npcManager, HologramManager hologramManager, RewardManager rewardManager, StatsManager statsManager) { super("Bonus", plugin); _repository = new BonusRepository(plugin, this, donationManager); @@ -132,6 +129,7 @@ public class BonusManager extends MiniClientPlugin implements I _hologramManager = hologramManager; _rewardManager = rewardManager; _pollManager = pollManager; + _statsManager = statsManager; // Hope to god this works! _canVote = true; @@ -648,11 +646,11 @@ public class BonusManager extends MiniClientPlugin implements I { if (data) { - UtilPlayer.message(player, F.main("Bonus", "Rewarded " + F.elem(gems + " Gems"))); + UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(gems + " Gems"))); } else { - UtilPlayer.message(player, F.main("Bonus", "Failed to process Gems")); + UtilPlayer.message(player, F.main("Carl", "Failed to process Gems")); } } }, "BonusManager", player.getName(), player.getUniqueId(), gems, true); @@ -667,11 +665,11 @@ public class BonusManager extends MiniClientPlugin implements I { if (data) { - UtilPlayer.message(player, F.main("Bonus", "Rewarded " + F.elem(gold + " Gold"))); + UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(gold + " Gold"))); } else { - UtilPlayer.message(player, F.main("Bonus", "Failed to process Gold")); + UtilPlayer.message(player, F.main("Carl", "Failed to process Gold")); } } }, "BonusManager", player.getName(), coreClient.getAccountId(), gold, true); @@ -686,11 +684,11 @@ public class BonusManager extends MiniClientPlugin implements I { if (data) { - UtilPlayer.message(player, F.main("Bonus", "Rewarded " + F.elem(coins + " Coins"))); + UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(coins + " Coins"))); } else { - UtilPlayer.message(player, F.main("Bonus", "Failed to process Coins")); + UtilPlayer.message(player, F.main("Carl", "Failed to process Coins")); } } }, "BonusManager", player.getName(), coreClient.getAccountId(), coins, true); @@ -714,7 +712,7 @@ public class BonusManager extends MiniClientPlugin implements I public void run() { bonusClient.setTickets(newTickets); - UtilPlayer.message(player, F.main("Bonus", "Rewarded " + F.elem(tickets + " Carl Spin Ticket"))); + UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(tickets + " Carl Spin Ticket"))); } }); } @@ -729,7 +727,8 @@ public class BonusManager extends MiniClientPlugin implements I if (experience > 0) { - // TODO + _statsManager.incrementStat(player, "Global.ExpEarned", experience); + UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(experience + " Experience"))); } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java similarity index 99% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java index 2f53ae3ac..ea14f4141 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses; +package mineplex.core.bonuses; import java.sql.CallableStatement; import java.sql.Connection; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/StreakRecord.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/StreakRecord.java similarity index 90% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/StreakRecord.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/StreakRecord.java index 901ef4ad6..7757a2c8c 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/StreakRecord.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/StreakRecord.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses; +package mineplex.core.bonuses; public class StreakRecord { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/VoteHandler.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/VoteHandler.java similarity index 95% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/VoteHandler.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/VoteHandler.java index 73e11305b..4dec15845 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/VoteHandler.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/VoteHandler.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses; +package mineplex.core.bonuses; import org.bukkit.entity.Player; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/animations/AnimationCarl.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java similarity index 96% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/animations/AnimationCarl.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java index 02783c89a..89ec4d85d 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/animations/AnimationCarl.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java @@ -1,7 +1,6 @@ -package mineplex.hub.bonuses.animations; +package mineplex.core.bonuses.animations; import mineplex.core.common.util.UtilAction; -import mineplex.core.common.util.UtilMath; import mineplex.core.reward.Reward; import mineplex.core.reward.RewardData; import mineplex.core.treasure.animation.Animation; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/AnimationCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java similarity index 87% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/AnimationCommand.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java index 28e2f493a..0494fc2f0 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/AnimationCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java @@ -1,10 +1,10 @@ -package mineplex.hub.bonuses.commands; +package mineplex.core.bonuses.commands; import org.bukkit.entity.Player; import mineplex.core.command.CommandBase; import mineplex.core.common.Rank; -import mineplex.hub.bonuses.BonusManager; +import mineplex.core.bonuses.BonusManager; public class AnimationCommand extends CommandBase{ diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/GuiCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/GuiCommand.java similarity index 71% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/GuiCommand.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/GuiCommand.java index 655a94199..c3ef35edd 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/GuiCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/GuiCommand.java @@ -1,12 +1,11 @@ -package mineplex.hub.bonuses.commands; +package mineplex.core.bonuses.commands; import org.bukkit.entity.Player; import mineplex.core.command.CommandBase; import mineplex.core.common.Rank; -import mineplex.core.reward.RewardManager; -import mineplex.hub.bonuses.BonusManager; -import mineplex.hub.bonuses.gui.BonusGui; +import mineplex.core.bonuses.BonusManager; +import mineplex.core.bonuses.gui.BonusGui; public class GuiCommand extends CommandBase{ diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/TicketCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java similarity index 94% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/TicketCommand.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java index 14afed1e8..20aa7ad66 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/TicketCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java @@ -1,10 +1,10 @@ -package mineplex.hub.bonuses.commands; +package mineplex.core.bonuses.commands; import mineplex.core.command.CommandBase; import mineplex.core.common.Rank; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilPlayer; -import mineplex.hub.bonuses.BonusManager; +import mineplex.core.bonuses.BonusManager; import org.bukkit.entity.Player; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/event/CarlSpinnerEvent.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/event/CarlSpinnerEvent.java similarity index 95% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/event/CarlSpinnerEvent.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/event/CarlSpinnerEvent.java index fed71229b..a07e1770e 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/event/CarlSpinnerEvent.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/event/CarlSpinnerEvent.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses.event; +package mineplex.core.bonuses.event; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java similarity index 71% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java index ea7978621..48b2e0a6e 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java @@ -1,17 +1,16 @@ -package mineplex.hub.bonuses.gui; +package mineplex.core.bonuses.gui; import mineplex.core.gui.SimpleGui; import mineplex.core.reward.RewardManager; -import mineplex.hub.bonuses.BonusManager; -import mineplex.hub.bonuses.gui.buttons.CarlSpinButton; -import mineplex.hub.bonuses.gui.buttons.DailyBonusButton; -import mineplex.hub.bonuses.gui.buttons.PollButton; -import mineplex.hub.bonuses.gui.buttons.RankBonusButton; -import mineplex.hub.bonuses.gui.buttons.VoteButton; +import mineplex.core.bonuses.BonusManager; +import mineplex.core.bonuses.gui.buttons.CarlSpinButton; +import mineplex.core.bonuses.gui.buttons.DailyBonusButton; +import mineplex.core.bonuses.gui.buttons.PollButton; +import mineplex.core.bonuses.gui.buttons.RankBonusButton; +import mineplex.core.bonuses.gui.buttons.VoteButton; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; -import org.omg.CORBA._PolicyStub; public class BonusGui extends SimpleGui { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java similarity index 94% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java index 9e9bbefa9..80268a046 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses.gui; +package mineplex.core.bonuses.gui; import java.util.ArrayList; @@ -14,14 +14,10 @@ import mineplex.core.reward.RewardManager; import mineplex.core.reward.RewardRarity; import mineplex.core.reward.RewardType; import mineplex.core.shop.item.ShopItem; -import mineplex.core.treasure.animation.LootLegendaryAnimation; -import mineplex.core.treasure.animation.LootMythicalAnimation; -import mineplex.core.treasure.animation.LootRareAnimation; -import mineplex.core.treasure.animation.LootUncommonAnimation; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; -import mineplex.hub.bonuses.BonusManager; -import mineplex.hub.bonuses.gui.buttons.RewardButton; +import mineplex.core.bonuses.BonusManager; +import mineplex.core.bonuses.gui.buttons.RewardButton; import org.bukkit.Bukkit; import org.bukkit.ChatColor; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/CarlSpinButton.java similarity index 93% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/CarlSpinButton.java index 4c295f5dd..006135c5d 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/CarlSpinButton.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses.gui.buttons; +package mineplex.core.bonuses.gui.buttons; import java.util.ArrayList; @@ -13,8 +13,8 @@ import mineplex.core.common.util.C; import mineplex.core.gui.GuiItem; import mineplex.core.reward.RewardManager; import mineplex.core.shop.item.ShopItem; -import mineplex.hub.bonuses.BonusClientData; -import mineplex.hub.bonuses.BonusManager; +import mineplex.core.bonuses.BonusClientData; +import mineplex.core.bonuses.BonusManager; public class CarlSpinButton implements GuiItem { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java similarity index 96% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java index 8ee34647f..897852d8d 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses.gui.buttons; +package mineplex.core.bonuses.gui.buttons; import java.util.ArrayList; @@ -16,10 +16,10 @@ import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.shop.item.ShopItem; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; -import mineplex.hub.bonuses.BonusAmount; -import mineplex.hub.bonuses.BonusClientData; -import mineplex.hub.bonuses.BonusManager; -import mineplex.hub.bonuses.StreakRecord; +import mineplex.core.bonuses.BonusAmount; +import mineplex.core.bonuses.BonusClientData; +import mineplex.core.bonuses.BonusManager; +import mineplex.core.bonuses.StreakRecord; import org.bukkit.Bukkit; import org.bukkit.ChatColor; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java similarity index 97% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java index 008a024ce..e669f2ad3 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses.gui.buttons; +package mineplex.core.bonuses.gui.buttons; import java.util.ArrayList; import java.util.HashMap; @@ -13,8 +13,8 @@ import mineplex.core.gui.SimpleGuiItem; import mineplex.core.gui.botton.BackBotton; import mineplex.core.gui.pages.TimedMessageWindow; import mineplex.core.itemstack.ItemStackFactory; -import mineplex.hub.poll.Poll; -import mineplex.hub.poll.PollManager; +import mineplex.core.poll.Poll; +import mineplex.core.poll.PollManager; import org.bukkit.ChatColor; import org.bukkit.Material; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java similarity index 97% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java index b394a398e..21e6fd318 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses.gui.buttons; +package mineplex.core.bonuses.gui.buttons; import java.util.ArrayList; @@ -16,8 +16,8 @@ import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.shop.item.ShopItem; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; -import mineplex.hub.bonuses.BonusAmount; -import mineplex.hub.bonuses.BonusManager; +import mineplex.core.bonuses.BonusAmount; +import mineplex.core.bonuses.BonusManager; import org.bukkit.Bukkit; import org.bukkit.ChatColor; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RewardButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RewardButton.java similarity index 90% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RewardButton.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RewardButton.java index 5f7b0050b..73ff6c9cc 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RewardButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RewardButton.java @@ -1,11 +1,10 @@ -package mineplex.hub.bonuses.gui.buttons; +package mineplex.core.bonuses.gui.buttons; import org.bukkit.event.inventory.ClickType; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import mineplex.core.gui.GuiItem; -import mineplex.core.reward.Reward; import mineplex.core.reward.RewardData; public class RewardButton implements GuiItem diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java similarity index 89% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java index 969fc2f9d..da9360afc 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses.gui.buttons; +package mineplex.core.bonuses.gui.buttons; import java.util.ArrayList; @@ -10,25 +10,17 @@ import mineplex.core.common.util.UtilTime; import mineplex.core.common.util.UtilTime.TimeUnit; import mineplex.core.gui.GuiItem; import mineplex.core.gui.ItemRefresher; -import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.shop.item.ShopItem; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.hub.bonuses.BonusAmount; -import mineplex.hub.bonuses.BonusClientData; -import mineplex.hub.bonuses.BonusManager; -import mineplex.hub.bonuses.StreakRecord; - -import net.minecraft.server.v1_7_R4.ChatSerializer; -import net.minecraft.server.v1_7_R4.IChatBaseComponent; -import net.minecraft.server.v1_7_R4.PacketPlayOutChat; +import mineplex.core.bonuses.BonusAmount; +import mineplex.core.bonuses.BonusClientData; +import mineplex.core.bonuses.BonusManager; +import mineplex.core.bonuses.StreakRecord; 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.EventHandler; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.event.inventory.ClickType; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/DisplayType.java b/Plugins/Mineplex.Core/src/mineplex/core/poll/DisplayType.java similarity index 91% rename from Plugins/Mineplex.Hub/src/mineplex/hub/poll/DisplayType.java rename to Plugins/Mineplex.Core/src/mineplex/core/poll/DisplayType.java index 3045f5277..c593307e9 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/DisplayType.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/poll/DisplayType.java @@ -1,4 +1,4 @@ -package mineplex.hub.poll; +package mineplex.core.poll; import mineplex.core.common.Rank; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PlayerPollData.java b/Plugins/Mineplex.Core/src/mineplex/core/poll/PlayerPollData.java similarity index 97% rename from Plugins/Mineplex.Hub/src/mineplex/hub/poll/PlayerPollData.java rename to Plugins/Mineplex.Core/src/mineplex/core/poll/PlayerPollData.java index e0de0ec32..3465fae3b 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PlayerPollData.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/poll/PlayerPollData.java @@ -1,4 +1,4 @@ -package mineplex.hub.poll; +package mineplex.core.poll; import mineplex.core.common.util.NautHashMap; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/Poll.java b/Plugins/Mineplex.Core/src/mineplex/core/poll/Poll.java similarity index 95% rename from Plugins/Mineplex.Hub/src/mineplex/hub/poll/Poll.java rename to Plugins/Mineplex.Core/src/mineplex/core/poll/Poll.java index 1998173ff..715b1f275 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/Poll.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/poll/Poll.java @@ -1,6 +1,4 @@ -package mineplex.hub.poll; - -import mineplex.core.common.Rank; +package mineplex.core.poll; /** * Created by Shaun on 8/16/2014. diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollManager.java b/Plugins/Mineplex.Core/src/mineplex/core/poll/PollManager.java similarity index 97% rename from Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollManager.java rename to Plugins/Mineplex.Core/src/mineplex/core/poll/PollManager.java index 7fb0e00fd..5fa00cf3d 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/poll/PollManager.java @@ -1,4 +1,4 @@ -package mineplex.hub.poll; +package mineplex.core.poll; import java.sql.ResultSet; import java.sql.SQLException; @@ -23,9 +23,7 @@ import mineplex.core.common.util.Callback; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilPlayer; import mineplex.core.donation.DonationManager; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.hub.poll.command.PollCommand; +import mineplex.core.poll.command.PollCommand; public class PollManager extends MiniDbClientPlugin { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/poll/PollRepository.java similarity index 99% rename from Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollRepository.java rename to Plugins/Mineplex.Core/src/mineplex/core/poll/PollRepository.java index e38e980ec..53884c66f 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/poll/PollRepository.java @@ -1,4 +1,4 @@ -package mineplex.hub.poll; +package mineplex.core.poll; import java.sql.ResultSet; import java.sql.SQLException; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollStats.java b/Plugins/Mineplex.Core/src/mineplex/core/poll/PollStats.java similarity index 97% rename from Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollStats.java rename to Plugins/Mineplex.Core/src/mineplex/core/poll/PollStats.java index 591302c01..5f3ecdb2a 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollStats.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/poll/PollStats.java @@ -1,4 +1,4 @@ -package mineplex.hub.poll; +package mineplex.core.poll; /** * Created by Shaun on 8/26/2014. diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/command/PollCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/poll/command/PollCommand.java similarity index 96% rename from Plugins/Mineplex.Hub/src/mineplex/hub/poll/command/PollCommand.java rename to Plugins/Mineplex.Core/src/mineplex/core/poll/command/PollCommand.java index fe5997c79..bafdb1dbe 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/command/PollCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/poll/command/PollCommand.java @@ -1,4 +1,4 @@ -package mineplex.hub.poll.command; +package mineplex.core.poll.command; import java.text.DecimalFormat; import java.util.List; @@ -13,10 +13,10 @@ import mineplex.core.common.jsonchat.JsonMessage; import mineplex.core.common.util.C; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilPlayer; -import mineplex.hub.poll.PlayerPollData; -import mineplex.hub.poll.Poll; -import mineplex.hub.poll.PollManager; -import mineplex.hub.poll.PollStats; +import mineplex.core.poll.PlayerPollData; +import mineplex.core.poll.Poll; +import mineplex.core.poll.PollManager; +import mineplex.core.poll.PollStats; /** * Created by Shaun on 8/17/2014. diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java index c99d09044..f5a62d294 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java @@ -39,7 +39,6 @@ import mineplex.core.recharge.Recharge; import mineplex.core.resourcepack.ResUnloadCheck; import mineplex.core.resourcepack.ResPackManager; import mineplex.core.serverConfig.ServerConfiguration; -import mineplex.core.spawn.Spawn; import mineplex.core.stats.StatsManager; import mineplex.core.status.ServerStatusManager; import mineplex.core.task.TaskManager; @@ -49,7 +48,7 @@ import mineplex.core.updater.Updater; import mineplex.core.velocity.VelocityFix; import mineplex.core.visibility.VisibilityManager; import mineplex.hub.modules.StackerManager; -import mineplex.hub.poll.PollManager; +import mineplex.core.poll.PollManager; import mineplex.hub.queue.QueueManager; import mineplex.hub.server.ServerManager; import mineplex.minecraft.game.classcombat.Class.ClassManager; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index 03ffee480..bfb01019f 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -86,7 +86,7 @@ import mineplex.core.task.TaskManager; import mineplex.core.treasure.TreasureManager; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; -import mineplex.hub.bonuses.BonusManager; +import mineplex.core.bonuses.BonusManager; import mineplex.hub.commands.ForcefieldRadius; import mineplex.hub.commands.GadgetToggle; import mineplex.hub.commands.GameModeCommand; @@ -98,7 +98,7 @@ import mineplex.hub.modules.NewsManager; import mineplex.hub.modules.ParkourManager; import mineplex.hub.modules.TextManager; import mineplex.hub.modules.WorldManager; -import mineplex.hub.poll.PollManager; +import mineplex.core.poll.PollManager; import mineplex.hub.profile.gui.GUIProfile; import mineplex.hub.tutorial.TutorialManager; import mineplex.minecraft.game.classcombat.Skill.event.SkillTriggerEvent; @@ -214,7 +214,7 @@ public class HubManager extends MiniClientPlugin ((CraftWorld)Bukkit.getWorlds().get(0)).getHandle().pvpMode = true; - new BonusManager(plugin, clientManager, donationManager, pollManager , npcManager, hologramManager, rewardManager); + new BonusManager(plugin, clientManager, donationManager, pollManager , npcManager, hologramManager, rewardManager, statsManager); // NotificationManager notificationManager = new NotificationManager(plugin, clientManager, donationManager); From 87458841531babfba76a50505244d5697f53c6ef Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Mon, 10 Aug 2015 04:51:11 -0500 Subject: [PATCH 35/72] Various fixes --- .../src/mineplex/core/bonuses/BonusManager.java | 15 ++++++++++++++- .../Mineplex.Hub/src/mineplex/hub/HubManager.java | 14 ++++++++++---- .../src/mineplex/votifier/VotifierManager.java | 2 +- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 268664bdf..51af791c8 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -223,6 +223,7 @@ public class BonusManager extends MiniClientPlugin implements I { if (data) { + incrementVoteStreak(player); addPendingExplosion(player, player.getName()); awardBonus(player, getVoteBonusAmount(player)); UtilPlayer.message(player, F.main("Vote", "Thanks for your vote!")); @@ -493,6 +494,16 @@ public class BonusManager extends MiniClientPlugin implements I data.setMaxDailyStreak(data.getDailyStreak()); } + public void incrementVoteStreak(Player player) + { + BonusClientData data = Get(player); + + data.setVoteStreak(data.getVoteStreak() + 1); + + if (data.getVoteStreak() > data.getMaxVoteStreak()) + data.setMaxVoteStreak(data.getVoteStreak()); + } + public boolean continueStreak(long localLastBonus, long extendTime) { long maxTime = localLastBonus + TIME_BETWEEN_BONUSES + extendTime; @@ -884,7 +895,9 @@ public class BonusManager extends MiniClientPlugin implements I public void UnloadPlayer(final ClientUnloadEvent event) { final BonusClientData clientData = Get(event.GetName()); - clientData.getHologram().stop(); + + if (clientData.getHologram() != null) + clientData.getHologram().stop(); runAsync(new Runnable() { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index 0ab6560d3..f09e21e1f 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -25,6 +25,7 @@ import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerQuitEvent; @@ -66,12 +67,12 @@ import mineplex.core.gadget.event.GadgetActivateEvent; import mineplex.core.gadget.event.GadgetCollideEntityEvent; import mineplex.core.hologram.HologramManager; import mineplex.core.inventory.InventoryManager; -import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.message.PrivateMessageEvent; import mineplex.core.mount.MountManager; import mineplex.core.mount.event.MountActivateEvent; import mineplex.core.notifier.NotificationManager; import mineplex.core.npc.NpcManager; +import mineplex.core.packethandler.PacketHandler; import mineplex.core.party.Party; import mineplex.core.party.PartyManager; import mineplex.core.personalServer.PersonalServerManager; @@ -86,6 +87,7 @@ import mineplex.core.treasure.TreasureManager; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.core.bonuses.BonusManager; +import mineplex.hub.commands.DisguiseCommand; import mineplex.hub.commands.ForcefieldRadius; import mineplex.hub.commands.GadgetToggle; import mineplex.hub.commands.GameModeCommand; @@ -93,8 +95,10 @@ import mineplex.hub.commands.NewsCommand; import mineplex.hub.modules.ForcefieldManager; import mineplex.hub.modules.HubVisibilityManager; import mineplex.hub.modules.JumpManager; +import mineplex.hub.modules.KothManager; import mineplex.hub.modules.NewsManager; import mineplex.hub.modules.ParkourManager; +import mineplex.hub.modules.SoccerManager; import mineplex.hub.modules.TextManager; import mineplex.hub.modules.WorldManager; import mineplex.core.poll.PollManager; @@ -102,6 +106,8 @@ import mineplex.hub.profile.gui.GUIProfile; import mineplex.hub.tutorial.TutorialManager; import mineplex.minecraft.game.classcombat.Skill.event.SkillTriggerEvent; import mineplex.minecraft.game.classcombat.item.event.ItemTriggerEvent; +import mineplex.minecraft.game.core.combat.DeathMessageType; +import mineplex.minecraft.game.core.combat.event.CombatDeathEvent; import mineplex.minecraft.game.core.condition.ConditionManager; import mineplex.minecraft.game.core.damage.CustomDamageEvent; @@ -151,7 +157,7 @@ public class HubManager extends MiniClientPlugin //Admin private boolean _gadgetsEnabled = true; - public HubManager(JavaPlugin plugin, BlockRestore blockRestore, CoreClientManager clientManager, DonationManager donationManager, ConditionManager conditionManager, DisguiseManager disguiseManager, TaskManager taskManager, Portal portal, PartyManager partyManager, PreferencesManager preferences, PetManager petManager, PollManager pollManager, StatsManager statsManager, AchievementManager achievementManager, HologramManager hologramManager, NpcManager npcManager, PersonalServerManager personalServerManager) + public HubManager(JavaPlugin plugin, BlockRestore blockRestore, CoreClientManager clientManager, DonationManager donationManager, ConditionManager conditionManager, DisguiseManager disguiseManager, TaskManager taskManager, Portal portal, PartyManager partyManager, PreferencesManager preferences, PetManager petManager, PollManager pollManager, StatsManager statsManager, AchievementManager achievementManager, HologramManager hologramManager, NpcManager npcManager, PersonalServerManager personalServerManager, PacketHandler packetHandler) { super("Hub Manager", plugin); @@ -182,7 +188,7 @@ public class HubManager extends MiniClientPlugin _mountManager = new MountManager(_plugin, clientManager, donationManager, blockRestore, _disguiseManager); _inventoryManager = new InventoryManager(plugin, clientManager); new BenefitManager(plugin, clientManager, _inventoryManager); - _gadgetManager = new GadgetManager(_plugin, clientManager, donationManager, _inventoryManager, _mountManager, petManager, preferences, disguiseManager, blockRestore, new ProjectileManager(plugin)); + _gadgetManager = new GadgetManager(_plugin, clientManager, donationManager, _inventoryManager, _mountManager, petManager, preferences, disguiseManager, blockRestore, new ProjectileManager(plugin), achievementManager); RewardManager rewardManager = new RewardManager(clientManager, donationManager, _inventoryManager, petManager, statsManager, 100, 250, @@ -984,7 +990,7 @@ public class HubManager extends MiniClientPlugin @EventHandler public void openProfile(PlayerInteractEvent event) { - if(event.getItem().getType() != Material.SKULL_ITEM) + if(event.getItem() == null || event.getItem().getType() != Material.SKULL_ITEM) return; new GUIProfile(getPlugin(), event.getPlayer(), _preferences, _achievementManager, _personalServerManager).openInventory();; diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java index 420fb5adf..98f685a68 100644 --- a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java @@ -105,7 +105,7 @@ public class VotifierManager extends MiniPlugin // Currently we just notify all servers, and the server with the player on it can deal with it notifyServer(playerName, false); - notifyServer(playerName, true); +// notifyServer(playerName, true); } private void notifyServer(String playerName, boolean eu) From adb76b0681e07e1d742ab322ab8cdd9c4b42c362 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Mon, 10 Aug 2015 04:51:46 -0500 Subject: [PATCH 36/72] Fix giving out gold --- .../Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java index 76e746f43..d2cfef1f8 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java @@ -93,7 +93,7 @@ public class BonusAmount public int getTotalGold() { - return getGems() + getBonusGems(); + return getGold() + getBonusGold(); } public int getExperience() From aa13bcf5c6668e76976f5e12547a619358763126 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Mon, 10 Aug 2015 04:54:01 -0500 Subject: [PATCH 37/72] Bug fix! --- .../src/mineplex/core/bonuses/BonusManager.java | 7 ------- .../src/mineplex/core/bonuses/BonusRepository.java | 8 +------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 51af791c8..d309308bd 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -613,13 +613,6 @@ public class BonusManager extends MiniClientPlugin implements I //VOTE - public void attemptVoteBonus(final Player player, final Callback result) - { - if (timeTillRankBonus(player) > 0) - result.run(false); - getRepository().attemptRankBonus(player, result); - } - public long timeTillVoteBonus(Player player) { return nextVoteTime(player) - getLocalTime(); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java index ea14f4141..d97a76cc5 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java @@ -250,15 +250,9 @@ public class BonusRepository extends RepositoryBase public void attemptVoteBonus(final Player player, final Callback result) { final int accountId = _manager.getClientManager().Get(player).getAccountId(); - final int coins = _manager.getRankBonusAmount(player).getCoins(); - + final int coins = 0; final int gems = 0; - if (coins == 0/* && gems == 0 */) { - result.run(false); - return; - } - final JavaPlugin plug = _manager.getPlugin(); Bukkit.getScheduler().runTaskAsynchronously(plug, new Runnable() { From bd2c9aa5e6d133e569524b6ac6b19dbf7017f496 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Mon, 10 Aug 2015 14:00:02 +0200 Subject: [PATCH 38/72] hub stuff --- .../mineplex/hub/modules/SoccerManager.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java index bafd2df86..0eacb7d77 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java @@ -3,16 +3,20 @@ package mineplex.hub.modules; import java.util.ArrayList; import java.util.HashSet; +import org.bukkit.EntityEffect; import org.bukkit.FireworkEffect.Type; import org.bukkit.Color; import org.bukkit.Location; import org.bukkit.Sound; +import org.bukkit.entity.Bat; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.entity.Slime; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerVelocityEvent; @@ -349,6 +353,12 @@ public class SoccerManager extends MiniPlugin if (_ball != null && _ball.equals(ent)) continue; + + if (ent instanceof Bat) + { + ent.remove(); + continue; + } if (inPlayerArena(ent)) { @@ -491,4 +501,30 @@ public class SoccerManager extends MiniPlugin { _active.remove(event.getPlayer()); } + + @EventHandler(priority = EventPriority.HIGHEST) + public void allowDamage(EntityDamageByEntityEvent event) + { + if (!(event.getEntity() instanceof Player) || !(event.getDamager() instanceof Player)) + return; + + Player damager = (Player)event.getDamager(); + Player damagee = (Player)event.getEntity(); + + if (!_active.contains(damager) || !_active.contains(damagee)) + return; + + if (getTeamColor(damager) == null || getTeamColor(damagee) == null) + return; + + if (getTeamColor(damager) == getTeamColor(damagee)) + return; + + if (Recharge.Instance.use(damagee, "Football Damage", 800, false, false)) + { + UtilAction.velocity(damagee, UtilAlg.getTrajectory2d(damager, damagee), 0.6, false, 0, 0.3, 1, true); + + damagee.playEffect(EntityEffect.HURT); + } + } } From 5781009f4e3f405bd84756834aeed959d5cf939e Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 10 Aug 2015 14:00:40 +0200 Subject: [PATCH 39/72] Improving animations and some text. --- .../mineplex/core/bonuses/BonusManager.java | 5 +- .../bonuses/animations/AnimationCarl.java | 50 +++++++++++++------ .../bonuses/commands/AnimationCommand.java | 3 ++ .../mineplex/core/bonuses/gui/BonusGui.java | 2 +- .../bonuses/gui/buttons/DailyBonusButton.java | 5 +- .../core/bonuses/gui/buttons/PollButton.java | 9 +++- .../bonuses/gui/buttons/RankBonusButton.java | 3 +- .../core/bonuses/gui/buttons/VoteButton.java | 4 +- 8 files changed, 58 insertions(+), 23 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index d309308bd..2ad67f4b9 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -251,7 +251,10 @@ public class BonusManager extends MiniClientPlugin implements I if (!_enabled) return; - if(_pendingExplosions.get(0) instanceof String) + if(_pendingExplosions.get(0) instanceof String + && !((String)_pendingExplosions.get(0)).contentEquals("RANK") + && !((String)_pendingExplosions.get(0)).contentEquals("DAILY") + && !((String)_pendingExplosions.get(0)).contentEquals("VOTE")) { String name = (String)_pendingExplosions.get(0); Bukkit.broadcastMessage("Recieved Vote: " + name); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java index 89ec4d85d..3f1d4a43c 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java @@ -1,6 +1,7 @@ package mineplex.core.bonuses.animations; import mineplex.core.common.util.UtilAction; +import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.reward.Reward; import mineplex.core.reward.RewardData; import mineplex.core.treasure.animation.Animation; @@ -32,22 +33,43 @@ public class AnimationCarl extends Animation { if(_type instanceof String) { - if (getTicks() < 40) - { - Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), new ItemStack(Material.EMERALD)); - - //Velocity - long passed = System.currentTimeMillis() - _startTime; - Vector vel = new Vector(Math.sin(passed/5d), 0, Math.cos(passed/5d)); - - UtilAction.velocity(gem, vel, Math.abs(Math.sin(passed/3000d)), false, 0, 0.2 + Math.abs(Math.cos(passed/3000d))*0.6, 1, false); - - gem.setTicksLived(1170); - } - else + if(((String) _type).contentEquals("DAILY")) { - finish(); + for (int i = 1; i < 60; i++) + { + Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, "" + i)); + Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, "" + i)); + Vector vel = new Vector(Math.sin(i * 7/5d), 0, Math.cos(i * 7/5d)); + UtilAction.velocity(gem, vel, Math.abs(Math.sin(i * 7/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 7/3000d))*0.6, 1, false); + UtilAction.velocity(coin, vel, Math.abs(Math.sin(i * 8/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 8/3000d))*0.6, 1, false); + coin.setTicksLived(1160); + gem.setTicksLived(1160); + } } + if(((String) _type).contentEquals("RANK")) + { + for (int i = 1; i < 100; i++) + { + Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, "" + i)); + Vector vel = new Vector(Math.sin(i * 7/5d), 0, Math.cos(i * 7/5d)); + UtilAction.velocity(coin, vel, Math.abs(Math.sin(i * 7/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 7/3000d))*0.6, 1, false); + coin.setTicksLived(1160); + } + } + if(!((String) _type).contentEquals("DAILY")&& !((String) _type).contentEquals("RANK")) + { + for (int i = 1; i < 60; i++) + { + Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, "" + i)); + Item paper = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), ItemStackFactory.Instance.CreateStack(Material.PAPER, (byte) 0, 1, "" + i)); + Vector vel = new Vector(Math.sin(i * 7/5d), 0, Math.cos(i * 7/5d)); + UtilAction.velocity(gem, vel, Math.abs(Math.sin(i * 7/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i + 7/3000d))*0.6, 1, false); + UtilAction.velocity(paper, vel, Math.abs(Math.sin(i * 8/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i + 8/3000d))*0.6, 1, false); + paper.setTicksLived(1160); + gem.setTicksLived(1160); + } + } + finish(); } if(_type instanceof Reward) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java index 0494fc2f0..262dbff1c 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java @@ -23,6 +23,9 @@ public class AnimationCommand extends CommandBase{ _plugin.addPendingExplosion(caller, "Chiss"); _plugin.addPendingExplosion(caller, "Phinary"); _plugin.addPendingExplosion(caller, "xXVevzZXx"); + + _plugin.addPendingExplosion(caller, "RANK"); + _plugin.addPendingExplosion(caller, "DAILY"); } } \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java index 48b2e0a6e..e54887dc8 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java @@ -29,7 +29,7 @@ public class BonusGui extends SimpleGui setItem(14, new DailyBonusButton(getPlugin(), player, this, manager)); - setItem(16, new PollButton(getPlugin(), player, manager.getPollManager(), manager.getClientManager(), this)); + setItem(16, new PollButton(getPlugin(), player, manager.getPollManager(), manager.getClientManager(), this, manager)); setItem(31, new CarlSpinButton(getPlugin(), player, manager, rewardManager)); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java index 897852d8d..8efb10fa5 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java @@ -86,6 +86,7 @@ public class DailyBonusButton implements GuiItem, Listener } else { UtilPlayer.message(getPlayer(), F.main("Bonus", "Bonus collected!")); } + _bonusManager.addPendingExplosion(getPlayer(), "DAILY"); getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); } else { if (getPlayer().getOpenInventory() != null) { @@ -120,7 +121,7 @@ public class DailyBonusButton implements GuiItem, Listener if (isAvailable()) { material = Material.CHEST; - itemName = C.cGreen + C.Bold + "Daily Bonus"; + itemName = C.cGreen + C.Bold + "Daily Reward"; lore.add(" "); lore.add(ChatColor.RESET + "Click to Claim!"); @@ -128,7 +129,7 @@ public class DailyBonusButton implements GuiItem, Listener else { material = Material.REDSTONE_BLOCK; - itemName = C.cRed + C.Bold + "Daily Bonus"; + itemName = C.cRed + C.Bold + "Daily Reward"; lore.add(" "); lore.add(ChatColor.RESET + "Next reward in " + UtilTime.convertString(timeLeft(), 0, TimeUnit.FIT) + "!"); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java index e669f2ad3..417a6b556 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.HashMap; import mineplex.core.account.CoreClientManager; +import mineplex.core.bonuses.BonusManager; import mineplex.core.common.util.C; import mineplex.core.common.util.UtilText; import mineplex.core.gui.GuiInventory; @@ -29,6 +30,7 @@ public class PollButton extends SimpleGui implements GuiItem { protected boolean _create; private PollManager _pollManager; + private BonusManager _bonusManager; private CoreClientManager _clientManager; private GuiInventory _master; @@ -36,7 +38,7 @@ public class PollButton extends SimpleGui implements GuiItem { private Poll _poll; - public PollButton(Plugin plugin, Player player, PollManager pollManager, CoreClientManager clientManager, GuiInventory master) + public PollButton(Plugin plugin, Player player, PollManager pollManager, CoreClientManager clientManager, GuiInventory master, BonusManager bonusManager) { super(plugin, player, "Poll:", 6 * 9); this._create = true; @@ -44,6 +46,7 @@ public class PollButton extends SimpleGui implements GuiItem { this._clientManager = clientManager; this._pollManager = pollManager; hard.put(0, new BackBotton(master)); + _bonusManager = bonusManager; } @Override @@ -75,7 +78,8 @@ public class PollButton extends SimpleGui implements GuiItem { ArrayList lore = new ArrayList<>(); if (_poll == null) { - lore.add(C.cRed + "You've voted on all of the polls!"); + lore.add(""); + lore.add(C.cWhite + "You've voted on all of the polls!"); return ItemStackFactory.Instance.CreateStack(Material.REDSTONE_BLOCK, (byte) 0, 1, ChatColor.RED + C.Bold + "Vote on Poll", lore); } else @@ -190,6 +194,7 @@ public class PollButton extends SimpleGui implements GuiItem { getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); new TimedMessageWindow(getPlugin(), getPlayer(), ItemStackFactory.Instance.CreateStack(Material.EMERALD_BLOCK, (byte) 0, 1, ChatColor.GREEN + "Your anwser:", wrap(getPoll().getAnswers()[num])), ChatColor.GREEN + "Moo", 6 * 9, 50, getMaster()).openInventory(); + _bonusManager.addPendingExplosion(getPlayer(), "VOTE"); getPlayer().closeInventory(); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java index 21e6fd318..501840411 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java @@ -99,6 +99,7 @@ public class RankBonusButton implements GuiItem, Listener { { UtilPlayer.message(getPlayer(), F.main("Bonus", "Bonus collected!")); } + _bonusManager.addPendingExplosion(getPlayer(), "RANK"); getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); } else @@ -144,7 +145,7 @@ public class RankBonusButton implements GuiItem, Listener { if (!hasRank) { - material = Material.COAL_BLOCK; + material = Material.REDSTONE_BLOCK; itemName = C.cRed + ChatColor.BOLD + "Rank Monthly Bonus"; lore.add(" "); lore.add(ChatColor.WHITE + "Players with a Rank get a Monthly Bonus!"); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java index da9360afc..b05c3dad0 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java @@ -108,7 +108,7 @@ public class VoteButton implements GuiItem, Listener { if (isAvailable()) { material = Material.JUKEBOX; - itemName = C.cGreen + C.Bold + "Vote Bonus"; + itemName = C.cGreen + C.Bold + "Vote for Mineplex"; lore.add(" "); lore.add(ChatColor.RESET + "Click to Vote!"); @@ -116,7 +116,7 @@ public class VoteButton implements GuiItem, Listener { else { material = Material.REDSTONE_BLOCK; - itemName = C.cRed + C.Bold + "Vote Bonus"; + itemName = C.cRed + C.Bold + "Vote for Mineplex"; lore.add(" "); lore.add(ChatColor.RESET + "Next vote in " + UtilTime.convertString(timeLeft(), 0, TimeUnit.FIT) + "!"); From 65b51a137c4211469322bb3ceb681c1cc4c8e049 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Mon, 10 Aug 2015 14:50:44 +0200 Subject: [PATCH 40/72] new party tute room --- .../hub/tutorial/types/PartyTutorial.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/tutorial/types/PartyTutorial.java b/Plugins/Mineplex.Hub/src/mineplex/hub/tutorial/types/PartyTutorial.java index e8c7d1a8c..8b995220b 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/tutorial/types/PartyTutorial.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/tutorial/types/PartyTutorial.java @@ -17,8 +17,8 @@ public class PartyTutorial extends Tutorial double y = -manager.GetSpawn().getY(); _phases.add(new TutorialPhase( - manager.GetSpawn().add(84, y+69, 10), - manager.GetSpawn().add(81, y+68.5, 10), + manager.GetSpawn().add(0, 65 + y, 0), + manager.GetSpawn().add(4, 66.5 + y, 0), "Parties", new String[] { @@ -32,8 +32,8 @@ public class PartyTutorial extends Tutorial )); _phases.add(new TutorialPhase( - manager.GetSpawn().add(84, y+69, 9), - manager.GetSpawn().add(81, y+68.5, 9), + manager.GetSpawn().add(0, 65 + y, 0), + manager.GetSpawn().add(4, 66.5 + y, 0), "Creating a Party", new String[] { @@ -47,8 +47,8 @@ public class PartyTutorial extends Tutorial )); _phases.add(new TutorialPhase( - manager.GetSpawn().add(84, y+69, 9), - manager.GetSpawn().add(81, y+68.5, 9), + manager.GetSpawn().add(0, 65 + y, 0), + manager.GetSpawn().add(4, 66.5 + y, 0), "Inviting and Suggesting Players", new String[] { @@ -61,8 +61,8 @@ public class PartyTutorial extends Tutorial )); _phases.add(new TutorialPhase( - manager.GetSpawn().add(84, y+69, 9), - manager.GetSpawn().add(81, y+68.5, 9), + manager.GetSpawn().add(0, 65 + y, 0), + manager.GetSpawn().add(4, 66.5 + y, 0), "Leaving Parties", new String[] { @@ -73,8 +73,8 @@ public class PartyTutorial extends Tutorial )); _phases.add(new TutorialPhase( - manager.GetSpawn().add(84, y+69, 9), - manager.GetSpawn().add(81, y+68.5, 9), + manager.GetSpawn().add(0, 65 + y, 0), + manager.GetSpawn().add(4, 66.5 + y, 0), "Kicking Players from Party", new String[] { @@ -87,8 +87,8 @@ public class PartyTutorial extends Tutorial )); _phases.add(new TutorialPhase( - manager.GetSpawn().add(84, y+69, 9), - manager.GetSpawn().add(81, y+68.5, 9), + manager.GetSpawn().add(0, 65 + y, 0), + manager.GetSpawn().add(4, 66.5 + y, 0), "Joining Games Together", new String[] { @@ -103,8 +103,8 @@ public class PartyTutorial extends Tutorial )); _phases.add(new TutorialPhase( - manager.GetSpawn().add(84, y+69, 9), - manager.GetSpawn().add(81, y+68.5, 9), + manager.GetSpawn().add(0, 65 + y, 0), + manager.GetSpawn().add(4, 66.5 + y, 0), "Party Chat", new String[] { From 65fc81a2aaea6db76faa2c41c4f8b43318c03ccd Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 10 Aug 2015 15:33:00 +0200 Subject: [PATCH 41/72] improving animations again. --- .../mineplex/core/bonuses/BonusManager.java | 27 ++++++++++++- .../bonuses/animations/AnimationCarl.java | 38 +++++++++++-------- 2 files changed, 48 insertions(+), 17 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 2ad67f4b9..e1109137b 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -42,17 +42,20 @@ import mineplex.database.tables.records.BonusRecord; import mineplex.core.bonuses.gui.SpinGui; import mineplex.core.poll.PollManager; import mineplex.serverdata.commands.ServerCommandManager; + import org.jooq.SQLDialect; import org.jooq.impl.DSL; - import org.bukkit.Bukkit; import org.bukkit.Sound; +import org.bukkit.block.Dropper; import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; import org.bukkit.entity.Entity; +import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.java.JavaPlugin; import net.minecraft.server.v1_7_R4.DataWatcher; @@ -444,6 +447,7 @@ public class BonusManager extends MiniClientPlugin implements I } catch (Exception e) { + new SpinGui(getPlugin(), player, _rewardManager, manager).openInventory(); UtilPlayer.message(player, F.main("Carl", "There was an error processing your request")); } } @@ -925,4 +929,25 @@ public class BonusManager extends MiniClientPlugin implements I { return _pollManager; } + + @EventHandler + public void ItemDecay(UpdateEvent event) + { + if(event.getType() != UpdateType.TICK) + return; + + for(Entity entity : _carlNpc.getEntity().getNearbyEntities(3, -0.5, 3)) + { + if(!(entity instanceof Item)) + continue; + + if(!((Item) entity).getItemStack().hasItemMeta()) + continue; + + if(!((Item) entity).getItemStack().getItemMeta().getDisplayName().startsWith(" ")) + continue; + + entity.remove(); + } + } } \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java index 3f1d4a43c..e994165c9 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java @@ -11,6 +11,7 @@ import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.Item; import org.bukkit.entity.Player; +import org.bukkit.event.Listener; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; @@ -35,22 +36,22 @@ public class AnimationCarl extends Animation { if(((String) _type).contentEquals("DAILY")) { - for (int i = 1; i < 60; i++) + for (int i = 1; i < 40; i++) { - Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, "" + i)); - Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, "" + i)); - Vector vel = new Vector(Math.sin(i * 7/5d), 0, Math.cos(i * 7/5d)); - UtilAction.velocity(gem, vel, Math.abs(Math.sin(i * 7/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 7/3000d))*0.6, 1, false); - UtilAction.velocity(coin, vel, Math.abs(Math.sin(i * 8/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 8/3000d))*0.6, 1, false); + Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, " " + i)); + Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, " " + i)); + Vector vel = new Vector(Math.sin(i * 9/5d), 0, Math.cos(i * 9/5d)); + UtilAction.velocity(gem, vel, Math.abs(Math.sin(i * 9/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 9/3000d))*0.6, 1, false); + UtilAction.velocity(coin, vel, Math.abs(Math.sin(i * 9/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 9/3000d))*0.6, 1, false); coin.setTicksLived(1160); gem.setTicksLived(1160); } } if(((String) _type).contentEquals("RANK")) { - for (int i = 1; i < 100; i++) + for (int i = 1; i < 50; i++) { - Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, "" + i)); + Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, " " + i)); Vector vel = new Vector(Math.sin(i * 7/5d), 0, Math.cos(i * 7/5d)); UtilAction.velocity(coin, vel, Math.abs(Math.sin(i * 7/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 7/3000d))*0.6, 1, false); coin.setTicksLived(1160); @@ -58,13 +59,13 @@ public class AnimationCarl extends Animation } if(!((String) _type).contentEquals("DAILY")&& !((String) _type).contentEquals("RANK")) { - for (int i = 1; i < 60; i++) + for (int i = 1; i < 40; i++) { - Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, "" + i)); - Item paper = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), ItemStackFactory.Instance.CreateStack(Material.PAPER, (byte) 0, 1, "" + i)); - Vector vel = new Vector(Math.sin(i * 7/5d), 0, Math.cos(i * 7/5d)); - UtilAction.velocity(gem, vel, Math.abs(Math.sin(i * 7/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i + 7/3000d))*0.6, 1, false); - UtilAction.velocity(paper, vel, Math.abs(Math.sin(i * 8/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i + 8/3000d))*0.6, 1, false); + Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, " " + i)); + Item paper = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.PAPER, (byte) 0, 1, " " + i)); + Vector vel = new Vector(Math.sin(i * 8/5d), 0, Math.cos(i * 8/5d)); + UtilAction.velocity(gem, vel, Math.abs(Math.sin(i * 8/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i + 8/3000d))*0.6, 1, false); + UtilAction.velocity(paper, vel, Math.abs(Math.sin(i * 9/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i + 9/3000d))*0.6, 1, false); paper.setTicksLived(1160); gem.setTicksLived(1160); } @@ -79,13 +80,18 @@ public class AnimationCarl extends Animation { itemStack = new ItemStack(Material.NETHER_STAR); } - Item item = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), itemStack); + Item item = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.7, 0.5), itemStack); Vector vel = new Vector(_player.getLocation().getX() - _creeper.getLocation().getX(), 0, _player.getLocation().getZ() - _creeper.getLocation().getZ()); UtilAction.velocity(item, vel, 0.1, false, 0, 0.2 + 1*0.4, 1, false); - item.setTicksLived(1170); + item.setTicksLived(1160); + + + + + finish(); } } From 18d11f7d68e23afa2fe2d0c35295d27382119a2d Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Mon, 10 Aug 2015 16:13:17 +0200 Subject: [PATCH 42/72] new enums --- .../src/mineplex/core/reward/RewardType.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java index b06cdcec6..90b201c08 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java @@ -3,11 +3,14 @@ package mineplex.core.reward; public enum RewardType { //% Chances Mythic Legend Rare Uncommon - GameLoot( 0.000001, 0.00001, 0.0001, 3, 10), - Spinner( 0.000001, 0.2, 0.8, 10, 10), + GameLoot( 0.000001, 0.00001, 0.0001, 3, 10), + OldChest( 0, 0.05, 0.4, 5, 0), AncientChest( 0, 1, 4, 25, 0), - MythicalChest( 0.4, 3, 12, 75, 0); + MythicalChest( 0.4, 3, 12, 75, 0), + + SpinnerFiller( 0.1, 1, 4, 20, 30), + SpinnerReal( 0.000001, 0.05, 0.4, 5, 10); private double _mythicalChance; private double _legendaryChance; From c6beb122e31c7119c86d111c0aab480a835551d8 Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 10 Aug 2015 16:42:43 +0200 Subject: [PATCH 43/72] Adding firework animations for spinner. --- .../bonuses/animations/AnimationCarl.java | 172 ++++++++++++++++-- .../bonuses/commands/AnimationCommand.java | 1 + 2 files changed, 157 insertions(+), 16 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java index e994165c9..3090c9754 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java @@ -1,12 +1,23 @@ package mineplex.core.bonuses.animations; +import java.util.Random; + import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilParticle.ViewDist; import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.reward.Reward; import mineplex.core.reward.RewardData; +import mineplex.core.reward.RewardRarity; import mineplex.core.treasure.animation.Animation; +import org.bukkit.Color; +import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.FireworkEffect.Type; import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.Item; @@ -23,6 +34,7 @@ public class AnimationCarl extends Animation private long _startTime; private Object _type; private Player _player; + private Random _random = new Random(); public AnimationCarl(Entity creeper) { @@ -74,25 +86,35 @@ public class AnimationCarl extends Animation } if(_type instanceof Reward) { - RewardData rewardData = ((Reward)_type).getFakeRewardData(null); - ItemStack itemStack = rewardData.getDisplayItem(); - if(itemStack.getType() == Material.PAPER) + if(getTicks() == 0) { - itemStack = new ItemStack(Material.NETHER_STAR); + RewardData rewardData = ((Reward)_type).getFakeRewardData(_player); + ItemStack itemStack = rewardData.getDisplayItem(); + Item item = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.7, 0.5), itemStack); + + Vector vel = new Vector(_player.getLocation().getX() - _creeper.getLocation().getX(), 0, _player.getLocation().getZ() - _creeper.getLocation().getZ()); + + UtilAction.velocity(item, vel, 0.1, false, 0, 0.2 + 1*0.4, 1, false); + + item.setTicksLived(1160); } - Item item = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.7, 0.5), itemStack); - Vector vel = new Vector(_player.getLocation().getX() - _creeper.getLocation().getX(), 0, _player.getLocation().getZ() - _creeper.getLocation().getZ()); - - UtilAction.velocity(item, vel, 0.1, false, 0, 0.2 + 1*0.4, 1, false); - - item.setTicksLived(1160); - - - - - - finish(); + if(((Reward)_type).getRarity() == RewardRarity.RARE) + { + RareAnimation(); + } + else if(((Reward)_type).getRarity() == RewardRarity.LEGENDARY) + { + LegendAnimation(); + } + else if(((Reward)_type).getRarity() == RewardRarity.MYTHICAL) + { + MythicalAnimation(); + } + else + { + finish(); + } } } @@ -126,4 +148,122 @@ public class AnimationCarl extends Animation { _player = player; } + + public void LegendAnimation() + { + if (getTicks() < 1) + { + UtilFirework.playFirework(_creeper.getLocation().add(0.5, 0.5, 0.5), Type.BALL_LARGE, Color.LIME, true, true); + } + + if (getTicks() == 1) + { + _creeper.getLocation().getWorld().playSound(_creeper.getLocation().add(0.5, 0.5, 0.5), Sound.ENDERDRAGON_DEATH, 10F, 2.0F); + } + else if (getTicks() < 35) + { + double radius = 2 - (getTicks() / 10D * 2); + int particleAmount = 20 - (getTicks() * 2); + Location _centerLocation = _creeper.getLocation().add(0.5, 0.1, 0.5); + for (int i = 0; i < particleAmount; i++) + { + double xDiff = Math.sin(i/(double)particleAmount * 2 * Math.PI) * radius; + double zDiff = Math.cos(i/(double)particleAmount * 2 * Math.PI) * radius; + for(double e = 0.1 ; e < 3 ; e += 0.6) + { + Location location = _centerLocation.clone().add(xDiff, e, zDiff); + UtilParticle.PlayParticle(UtilParticle.ParticleType.HAPPY_VILLAGER, location, 0, 0, 0, 0, 1, ViewDist.NORMAL, UtilServer.getPlayers()); + } + } + } + else + { + finish(); + } + } + + public void MythicalAnimation() + { + if (getTicks() < 30 && getTicks() % 3 == 0) + { + UtilFirework.playFirework(_creeper.getLocation().add(0.5, 0.5, 0.5), Type.BALL_LARGE, Color.RED, true, true); + } + + if (getTicks() == 1) + { + _creeper.getLocation().getWorld().playSound(_creeper.getLocation().add(0.5, 0.5, 0.5), Sound.PORTAL_TRAVEL, 10F, 2.0F); + _creeper.getLocation().getWorld().playSound(_creeper.getLocation().add(0.5, 0.5, 0.5), Sound.ZOMBIE_UNFECT, 10F, 0.1F); + } + else if (getTicks() < 60) + { + UtilFirework.launchFirework(_creeper.getLocation().add(0.5, 0.5, 0.5), Type.BALL_LARGE, Color.RED, true, true, + new Vector((Math.random()-0.5)*0.05, 0.1, (Math.random()-0.5)*0.05), 1); + + //Particle Spiral Up + double radius = getTicks() / 20D; + int particleAmount = getTicks() / 2; + for (int i = 0; i < particleAmount; i++) + { + double xDiff = Math.sin(i/(double)particleAmount * 2 * Math.PI) * radius; + double zDiff = Math.cos(i/(double)particleAmount * 2 * Math.PI) * radius; + + Location location = _creeper.getLocation().add(0.5, 0, 0.5).clone().add(xDiff, -1.3, zDiff); + UtilParticle.PlayParticle(UtilParticle.ParticleType.WITCH_MAGIC, location, 0, 0, 0, 0, 1, + ViewDist.NORMAL, UtilServer.getPlayers()); + } + } + else if (getTicks() < 60) + { + double radius = 2 - (getTicks() / 10D * 2); + int particleAmount = 20 - (getTicks() * 2); + Location _centerLocation = _creeper.getLocation().add(0.5, 0.1, 0.5); + for (int i = 0; i < particleAmount; i++) + { + double xDiff = Math.sin(i/(double)particleAmount * 2 * Math.PI) * radius; + double zDiff = Math.cos(i/(double)particleAmount * 2 * Math.PI) * radius; + for(double e = 0.1 ; e < 3 ; e += 0.5) + { + Location location = _centerLocation.clone().add(xDiff, e, zDiff); + UtilParticle.PlayParticle(UtilParticle.ParticleType.WITCH_MAGIC, location, 0, 0, 0, 0, 1, ViewDist.NORMAL, UtilServer.getPlayers()); + } + } + } + else + { + finish(); + } + } + + public void RareAnimation() + { + if (getTicks() == 1) + { + for(int i = 0; i < 3; i++) + { + UtilFirework.playFirework(_creeper.getLocation().add(0.5, i, 0.5), Type.BALL, Color.FUCHSIA, false, false); + } + _creeper.getWorld().playSound(_creeper.getLocation(), Sound.WITHER_SPAWN, 10F, 1.2F); + } + else if (getTicks() >= 60) + { + finish(); + } + + else if (getTicks() < 35) + { + double radius = 2 - (getTicks() / 10D * 2); + int particleAmount = 20 - (getTicks() * 2); + Location _centerLocation = _creeper.getLocation().add(0.5, 0.1, 0.5); + for (int i = 0; i < particleAmount; i++) + { + double xDiff = Math.sin(i/(double)particleAmount * 2 * Math.PI) * radius; + double zDiff = Math.cos(i/(double)particleAmount * 2 * Math.PI) * radius; + for(double e = 0.1 ; e < 3 ; e += 0.6) + { + Location location = _centerLocation.clone().add(xDiff, e, zDiff); + UtilParticle.PlayParticle(UtilParticle.ParticleType.WITCH_MAGIC, location, 0, 0, 0, 0, 1, ViewDist.NORMAL, UtilServer.getPlayers()); + } + } + } + } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java index 262dbff1c..4dbea71d2 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java @@ -26,6 +26,7 @@ public class AnimationCommand extends CommandBase{ _plugin.addPendingExplosion(caller, "RANK"); _plugin.addPendingExplosion(caller, "DAILY"); + } } \ No newline at end of file From ed7b8949bb0376762bace087f63fbfd2b6cb3dbf Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 10 Aug 2015 17:04:47 +0200 Subject: [PATCH 44/72] Adding SpinnerFiller and SpinnerRewards. --- .../src/mineplex/core/bonuses/gui/SpinGui.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java index 80268a046..e9d7221bb 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java @@ -46,6 +46,7 @@ public class SpinGui extends SimpleGui private int _ticksPerSwap; private int _swapCount; private Reward[] _rewards; + private Reward[] _fakeRewards; private boolean _stopped; private boolean _rewarded; private ArrayList _ticks; @@ -65,13 +66,18 @@ public class SpinGui extends SimpleGui //setItem(CARL_SLOT, new DisplayItem(carlItem)); _rewards = new Reward[REWARDS_TO_GENERATE]; + _fakeRewards = new Reward[REWARDS_TO_GENERATE]; _ticks = new ArrayList<>(); _frame = 0; _pitch = 1; for (int i = 0; i < REWARDS_TO_GENERATE; i++) { - _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.MythicalChest, true); + _fakeRewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerFiller, true); + } + for (int i = 0; i < REWARDS_TO_GENERATE; i++) + { + _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerReal, true); } _ticksPerSwap = 1; @@ -98,7 +104,8 @@ public class SpinGui extends SimpleGui _stopSpinnerAt = _ticks.size(); - _reward = _rewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3]; + _fakeRewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3] = _rewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3]; + _reward = _fakeRewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3]; _rewardData = _reward.giveReward("Carls Spinner", getPlayer()); } @@ -147,7 +154,7 @@ public class SpinGui extends SimpleGui index = index % REWARDS_TO_GENERATE; int slot = 9 + i; - RewardData data = _rewards[index].getFakeRewardData(getPlayer()); + RewardData data = _fakeRewards[index].getFakeRewardData(getPlayer()); setItem(slot, new RewardButton(data)); // Glass Panes From 3be811e480bb6a6743f12655fa93e10c17314b90 Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 10 Aug 2015 17:08:03 +0200 Subject: [PATCH 45/72] Fixing Spinner announcements. --- .../src/mineplex/core/bonuses/gui/SpinGui.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java index e9d7221bb..16c8fcba3 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java @@ -253,9 +253,24 @@ public class SpinGui extends SimpleGui return; _manager.addPendingExplosion(getPlayer(), _reward); + if (_reward.getRarity() == RewardRarity.RARE) + { + Bukkit.broadcastMessage(F.main("Treasure", F.name(getPlayer().getName()) + " won " + C.cPurple + "Rare " + _rewardData.getFriendlyName() + C.cGray + " from Carl's Spinner.")); + } + else if (_reward.getRarity() == RewardRarity.LEGENDARY) + { + Bukkit.broadcastMessage(F.main("Treasure", F.name(getPlayer().getName()) + " won " + C.cGreen + "Legendary " + _rewardData.getFriendlyName() + C.cGray + " from Carl's Spinner.")); + } + else if (_reward.getRarity() == RewardRarity.MYTHICAL) + { + Bukkit.broadcastMessage(F.main("Treasure", F.name(getPlayer().getName()) + " won " + C.cRed + "Mythical " + _rewardData.getFriendlyName() + C.cGray + " from Carl's Spinner.")); + } + else + { + UtilPlayer.message(getPlayer(), F.main("Carl's Spinner", "You won " + _rewardData.getRarity().getColor() + _rewardData.getFriendlyName() + C.cGray + " from Carl's Spinner.")); + } ItemStack item = getInventory().getItem(13); getInventory().setItem(13, ItemStackFactory.Instance.CreateStack(item.getType(), (byte) 0, 1, _rewardData.getFriendlyName())); - UtilPlayer.message(getPlayer(), F.main("Carl's Spinner", "You got " + _rewardData.getRarity().getColor() + _rewardData.getFriendlyName() + C.cGray + " From Carl's Spinner.")); _rewarded = true; } From 186e3028c29556ddd0780ac81e5c95064ab1c3d1 Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 10 Aug 2015 17:15:56 +0200 Subject: [PATCH 46/72] removing temp fix "there was an error processing your request" for the Spinner. --- .../Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index e1109137b..9b4a4ee52 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -447,7 +447,6 @@ public class BonusManager extends MiniClientPlugin implements I } catch (Exception e) { - new SpinGui(getPlugin(), player, _rewardManager, manager).openInventory(); UtilPlayer.message(player, F.main("Carl", "There was an error processing your request")); } } From 3bedc4ce841e637dec3d1ae81ed30a87aee383dc Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 11 Aug 2015 05:37:58 +0200 Subject: [PATCH 47/72] Improving animation timing. --- .../bonuses/animations/AnimationCarl.java | 10 +++------- .../bonuses/commands/AnimationCommand.java | 19 ++++++++++++------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java index 3090c9754..a98977521 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java @@ -184,7 +184,7 @@ public class AnimationCarl extends Animation public void MythicalAnimation() { - if (getTicks() < 30 && getTicks() % 3 == 0) + if (getTicks() < 30) { UtilFirework.playFirework(_creeper.getLocation().add(0.5, 0.5, 0.5), Type.BALL_LARGE, Color.RED, true, true); } @@ -194,7 +194,7 @@ public class AnimationCarl extends Animation _creeper.getLocation().getWorld().playSound(_creeper.getLocation().add(0.5, 0.5, 0.5), Sound.PORTAL_TRAVEL, 10F, 2.0F); _creeper.getLocation().getWorld().playSound(_creeper.getLocation().add(0.5, 0.5, 0.5), Sound.ZOMBIE_UNFECT, 10F, 0.1F); } - else if (getTicks() < 60) + else if (getTicks() < 40) { UtilFirework.launchFirework(_creeper.getLocation().add(0.5, 0.5, 0.5), Type.BALL_LARGE, Color.RED, true, true, new Vector((Math.random()-0.5)*0.05, 0.1, (Math.random()-0.5)*0.05), 1); @@ -211,11 +211,7 @@ public class AnimationCarl extends Animation UtilParticle.PlayParticle(UtilParticle.ParticleType.WITCH_MAGIC, location, 0, 0, 0, 0, 1, ViewDist.NORMAL, UtilServer.getPlayers()); } - } - else if (getTicks() < 60) - { - double radius = 2 - (getTicks() / 10D * 2); - int particleAmount = 20 - (getTicks() * 2); + Location _centerLocation = _creeper.getLocation().add(0.5, 0.1, 0.5); for (int i = 0; i < particleAmount; i++) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java index 4dbea71d2..c3356c9b7 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java @@ -1,14 +1,16 @@ package mineplex.core.bonuses.commands; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import mineplex.core.command.CommandBase; import mineplex.core.common.Rank; +import mineplex.core.reward.RewardType; import mineplex.core.bonuses.BonusManager; public class AnimationCommand extends CommandBase{ - BonusManager _plugin; + private BonusManager _plugin; public AnimationCommand(BonusManager plugin) { @@ -19,13 +21,16 @@ public class AnimationCommand extends CommandBase{ @Override public void Execute(Player caller, String[] args) { - _plugin.addPendingExplosion(caller, "Test"); - _plugin.addPendingExplosion(caller, "Chiss"); - _plugin.addPendingExplosion(caller, "Phinary"); - _plugin.addPendingExplosion(caller, "xXVevzZXx"); - _plugin.addPendingExplosion(caller, "RANK"); - _plugin.addPendingExplosion(caller, "DAILY"); + if(args != null) + { + caller = Bukkit.getPlayer(args[0]); + _plugin.addPendingExplosion(caller, _plugin.getRewardManager().nextReward(caller, null, false, RewardType.SpinnerFiller, true)); + } + if(args.length >= 2) + { + _plugin.addPendingExplosion(caller, args[1]); + } } From b4e8b4f1ac2c7cefbcdd45125e8b3620b48a85d0 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 08:24:28 +0200 Subject: [PATCH 48/72] cant go spinnin while its a countin! --- .../nautilus/game/arcade/managers/GameManager.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameManager.java index cfed7e11b..ab07870ab 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameManager.java @@ -3,6 +3,7 @@ package nautilus.game.arcade.managers; import java.util.ArrayList; import java.util.Iterator; +import mineplex.core.bonuses.event.CarlSpinnerEvent; import mineplex.core.common.util.C; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilFirework; @@ -130,7 +131,17 @@ public class GameManager implements Listener UtilTextBottom.displayProgress("Game Start", percentage, UtilTime.MakeStr(Math.max(0, game.PrepareTime - (System.currentTimeMillis() - game.GetStateTime()))), player); } - + + @EventHandler + public void cancelCarlSpinner(CarlSpinnerEvent event) + { + Game game = Manager.GetGame(); + if (game == null) return; + + if (game.GetCountdown() <= 0) + event.setCancelled(true); + } + @EventHandler public void StateUpdate(UpdateEvent event) { From 66f2a5df5e0b2233b49537aa198a3e490e509765 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 08:32:12 +0200 Subject: [PATCH 49/72] renamed GAME --- .../Mineplex.Core/src/mineplex/core/reward/RewardManager.java | 4 ++-- .../Mineplex.Core/src/mineplex/core/reward/RewardRarity.java | 2 +- .../Mineplex.Core/src/mineplex/core/reward/RewardType.java | 4 ++-- .../src/mineplex/core/reward/rewards/ExperienceReward.java | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java index 386eba7ad..1b49623f7 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java @@ -66,8 +66,8 @@ public class RewardManager public void addGame(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager) { - addReward(new GemReward(donationManager, 100, 500, 100, RewardRarity.GAME)); - addReward(new ExperienceReward(statsManager, 100, 5000, 100, RewardRarity.GAME)); + addReward(new GemReward(donationManager, 100, 500, 100, RewardRarity.CARL_EXTRA)); + addReward(new ExperienceReward(statsManager, 100, 5000, 100, RewardRarity.CARL_EXTRA)); } public void addCommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java index 1f56de46a..971084562 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java @@ -20,7 +20,7 @@ public enum RewardRarity OTHER("Other", cWhite, Material.STAINED_GLASS_PANE, (byte) 0), COMMON("Common", cWhite, Material.STAINED_GLASS_PANE, (byte) 0), - GAME("Game", cYellow, Material.STAINED_GLASS_PANE, (byte) 4), + CARL_EXTRA("Game", cYellow, Material.STAINED_GLASS_PANE, (byte) 4), UNCOMMON("Uncommon", cAqua, Material.STAINED_GLASS_PANE, (byte) 3), RARE("Rare", cPurple, Material.STAINED_GLASS_PANE, (byte) 10), LEGENDARY("Legendary", cGreen, Material.STAINED_GLASS_PANE, (byte) 5), diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java index 90b201c08..6d9234391 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java @@ -3,7 +3,7 @@ package mineplex.core.reward; public enum RewardType { //% Chances Mythic Legend Rare Uncommon - GameLoot( 0.000001, 0.00001, 0.0001, 3, 10), + GameLoot( 0.000001, 0.00001, 0.0001, 3, 0), OldChest( 0, 0.05, 0.4, 5, 0), AncientChest( 0, 1, 4, 25, 0), @@ -37,7 +37,7 @@ public enum RewardType else if (rand <= _legendaryChance) rarity = RewardRarity.LEGENDARY; else if (rand <= _rareChance) rarity = RewardRarity.RARE; else if (rand <= _uncommonChance || requiresUncommon) rarity = RewardRarity.UNCOMMON; - else if (rand <= _gameChance) rarity = RewardRarity.GAME; + else if (rand <= _gameChance) rarity = RewardRarity.CARL_EXTRA; return rarity; } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java index a96245c6f..7c2811608 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java @@ -35,13 +35,13 @@ public class ExperienceReward extends Reward _statsManager.incrementStat(player, "Global.ExpEarned", experience); - return new RewardData(getRarity().getColor() + experience + " Experience", new ItemStack(Material.EXP_BOTTLE), RewardRarity.GAME); + return new RewardData(getRarity().getColor() + experience + " Experience", new ItemStack(Material.EXP_BOTTLE), RewardRarity.CARL_EXTRA); } @Override public RewardData getFakeRewardData(Player player) { - return new RewardData(getRarity().getColor() + "Experience", new ItemStack(Material.EXP_BOTTLE), RewardRarity.GAME); + return new RewardData(getRarity().getColor() + "Experience", new ItemStack(Material.EXP_BOTTLE), RewardRarity.CARL_EXTRA); } @Override From d833385df425197436eaf58f9a196b91d2d6a7aa Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Tue, 11 Aug 2015 00:35:02 -0600 Subject: [PATCH 50/72] Fix carl spinner and ticket command, Fix polls not displaying in available count, Visual fixes --- Plugins/.idea/misc.xml | 2 +- Plugins/.idea/modules.xml | 1 - .../mineplex/core/bonuses/BonusAmount.java | 5 ++- .../mineplex/core/bonuses/BonusManager.java | 43 ++++++++----------- .../core/bonuses/BonusRepository.java | 42 ++++++++++++++++++ .../core/bonuses/commands/TicketCommand.java | 30 +++++++++---- .../bonuses/gui/buttons/DailyBonusButton.java | 6 +-- .../core/bonuses/gui/buttons/VoteButton.java | 10 ++--- 8 files changed, 94 insertions(+), 45 deletions(-) diff --git a/Plugins/.idea/misc.xml b/Plugins/.idea/misc.xml index 3a9b4c67e..aeea575e6 100644 --- a/Plugins/.idea/misc.xml +++ b/Plugins/.idea/misc.xml @@ -16,7 +16,7 @@ - + \ No newline at end of file diff --git a/Plugins/.idea/modules.xml b/Plugins/.idea/modules.xml index bcc0470f4..f7936ba2e 100644 --- a/Plugins/.idea/modules.xml +++ b/Plugins/.idea/modules.xml @@ -11,7 +11,6 @@ - diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java index d2cfef1f8..bb6d8c9f3 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java @@ -2,6 +2,8 @@ package mineplex.core.bonuses; import java.util.List; +import org.bukkit.ChatColor; + import mineplex.core.common.util.C; public class BonusAmount @@ -138,6 +140,7 @@ public class BonusAmount public void addLore(List lore) { + lore.add(C.cYellow + "Rewards"); addLore(lore, getTickets(), 0, "Carl Spin Ticket" + (getTickets() > 1 ? "s" : "")); addLore(lore, getCoins(), getBonusCoins(), "Coins"); addLore(lore, getGems(), getBonusGems(), "Gems"); @@ -148,7 +151,7 @@ public class BonusAmount private void addLore(List lore, int amount, int bonus, String suffix) { if (amount > 0) - lore.add(C.cYellow + "Reward: " + C.cWhite + amount + " " + suffix); + lore.add(" " + C.cWhite + amount + " " + suffix); // if (bonus > 0) // lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + bonus + " " + suffix); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 9b4a4ee52..81121d59e 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -43,6 +43,7 @@ import mineplex.core.bonuses.gui.SpinGui; import mineplex.core.poll.PollManager; import mineplex.serverdata.commands.ServerCommandManager; +import org.jooq.DSLContext; import org.jooq.SQLDialect; import org.jooq.impl.DSL; import org.bukkit.Bukkit; @@ -419,35 +420,23 @@ public class BonusManager extends MiniClientPlugin implements I { CarlSpinnerEvent event = new CarlSpinnerEvent(player); Bukkit.getServer().getPluginManager().callEvent(event); - final BonusManager manager = this; if (!event.isCancelled()) { final int accountId = _clientManager.Get(player).getAccountId(); - runAsync(new Runnable() + _repository.attemptAddTickets(accountId, clientData, -1, new Callback() { @Override - public void run() + public void run(Boolean data) { - try + if (data) { - final int newTickets = DSL.using(DBPool.ACCOUNT, SQLDialect.MYSQL).update(Tables.bonus).set(Tables.bonus.tickets, Tables.bonus.tickets.sub(1)). - where(Tables.bonus.accountId.eq(accountId)).returning(Tables.bonus.tickets).fetchOne().getTickets(); - - runSync(new Runnable() - { - @Override - public void run() - { - clientData.setTickets(newTickets); - new SpinGui(getPlugin(), player, _rewardManager, manager).openInventory(); - } - }); + new SpinGui(_plugin, player, _rewardManager, BonusManager.this).openInventory(); } - catch (Exception e) + else { - UtilPlayer.message(player, F.main("Carl", "There was an error processing your request")); + UtilPlayer.message(player, F.main("Carl", "There waa an error processing your request. Try again later")); } } }); @@ -816,6 +805,7 @@ public class BonusManager extends MiniClientPlugin implements I if (canVote(player)) availableRewards++; if (canRank(player)) availableRewards++; if (canDaily(player)) availableRewards++; + if (getPollManager().getNextPoll(_pollManager.Get(player), _clientManager.Get(player).GetRank()) != null) availableRewards++; Hologram hologram; @@ -898,14 +888,15 @@ public class BonusManager extends MiniClientPlugin implements I if (clientData.getHologram() != null) clientData.getHologram().stop(); - runAsync(new Runnable() - { - @Override - public void run() - { - clientData.getRecord().store(); - } - }); + // This shouldnt be necessary anymore +// runAsync(new Runnable() +// { +// @Override +// public void run() +// { +// clientData.getRecord().store(); +// } +// }); super.UnloadPlayer(event); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java index d97a76cc5..2606705df 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java @@ -7,7 +7,11 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; +import com.sun.org.apache.xpath.internal.operations.Bool; +import mineplex.core.bonuses.gui.SpinGui; import mineplex.core.common.util.Callback; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; import mineplex.core.database.DBPool; import mineplex.core.database.RepositoryBase; import mineplex.core.database.ResultSetCallable; @@ -17,7 +21,9 @@ import mineplex.database.Tables; import mineplex.database.tables.records.BonusRecord; import org.jooq.DSLContext; import org.jooq.Record2; +import org.jooq.SQLDialect; import org.jooq.TableField; +import org.jooq.impl.DSL; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -95,6 +101,42 @@ public class BonusRepository extends RepositoryBase }); } + public void attemptAddTickets(final int accountId, final BonusClientData client, final int tickets, final Callback callback) + { + if (client.getTickets() + tickets < 0) + callback.run(false); + + Bukkit.getScheduler().runTaskAsynchronously(_manager.getPlugin(), new Runnable() + { + @Override + public void run() + { + try + { + DSLContext create = DSL.using(DBPool.ACCOUNT, SQLDialect.MYSQL); + create.update(Tables.bonus).set(Tables.bonus.tickets, Tables.bonus.tickets.add(tickets)). + where(Tables.bonus.accountId.eq(accountId)).execute(); + final int newTickets = create.select(Tables.bonus.tickets).from(Tables.bonus).where(Tables.bonus.accountId.eq(accountId)).fetchOne().value1(); + + Bukkit.getScheduler().runTask(_manager.getPlugin(), new Runnable() + { + @Override + public void run() + { + client.setTickets(newTickets); + callback.run(true); + } + }); + } + catch (Exception e) + { + e.printStackTrace(); + callback.run(false); + } + } + }); + } + public void attemptDailyBonus(final Player player, final Callback result) { final int accountId = _manager.getClientManager().Get(player).getAccountId(); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java index 20aa7ad66..62cefef27 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java @@ -2,6 +2,7 @@ package mineplex.core.bonuses.commands; import mineplex.core.command.CommandBase; import mineplex.core.common.Rank; +import mineplex.core.common.util.Callback; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilPlayer; import mineplex.core.bonuses.BonusManager; @@ -36,15 +37,28 @@ public class TicketCommand extends CommandBase { try { - int tickets = Integer.parseInt(ticketString); - Plugin.Get(target).setTickets(Plugin.Get(targetName).getTickets() + tickets); - - UtilPlayer.message(caller, F.main("Carl", "You gave " + F.elem(tickets + " Carl Tickets") + " to " + F.name(targetName) + ".")); - - if (target != null) + final int tickets = Integer.parseInt(ticketString); + int accountId = Plugin.getClientManager().getAccountId(target); + Plugin.getRepository().attemptAddTickets(accountId, Plugin.Get(target), tickets, new Callback() { - UtilPlayer.message(target, F.main("Carl", F.name(caller.getName()) + " gave you " + F.elem(tickets + " Carl Tickets") + ".")); - } + @Override + public void run(Boolean data) + { + if (data) + { + UtilPlayer.message(caller, F.main("Carl", "You gave " + F.elem(tickets + " Carl Tickets") + " to " + F.name(targetName) + ".")); + + if (target != null && !target.equals(caller)) + { + UtilPlayer.message(target, F.main("Carl", F.name(caller.getName()) + " gave you " + F.elem(tickets + " Carl Tickets") + ".")); + } + } + else + { + UtilPlayer.message(caller, F.main("Carl", "Failed to give tickets. Try again later!")); + } + } + }); } catch (Exception e) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java index 8efb10fa5..2c09f41c4 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java @@ -144,9 +144,7 @@ public class DailyBonusButton implements GuiItem, Listener lore.add(" "); lore.add(C.cYellow + "Current Streak: " + C.cWhite + client.getDailyStreak()); - lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + _bonusManager.getDailyMultiplier(_player) + "%"); - lore.add(" "); - lore.add(C.cYellow + "Highest Streak: " + C.cWhite + client.getMaxDailyStreak()); + lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + "+" + _bonusManager.getDailyMultiplier(_player) + "%"); if (client.getDailyTime() != null) { @@ -159,6 +157,8 @@ public class DailyBonusButton implements GuiItem, Listener } } + lore.add(" "); + lore.add(C.cYellow + "Highest Streak: " + C.cWhite + client.getMaxDailyStreak()); StreakRecord streakRecord = _bonusManager.getDailyStreak(); if (streakRecord != null) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java index b05c3dad0..50ed5afee 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java @@ -131,10 +131,7 @@ public class VoteButton implements GuiItem, Listener { lore.add(" "); lore.add(C.cYellow + "Current Streak: " + C.cWhite + client.getVoteStreak()); - lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + _bonusManager.getVoteMultiplyer(_player) + "%"); - lore.add(" "); - lore.add(C.cYellow + "Highest Streak: " + C.cWhite + client.getMaxVoteStreak()); - + lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + "+" + _bonusManager.getVoteMultiplyer(_player) + "%"); if (client.getVoteTime() != null) { long lastBonus = _bonusManager.getLocalTime(client.getVoteTime().getTime()); @@ -146,6 +143,9 @@ public class VoteButton implements GuiItem, Listener { } } + lore.add(" "); + lore.add(C.cYellow + "Highest Streak: " + C.cWhite + client.getMaxVoteStreak()); + StreakRecord streakRecord = _bonusManager.getVoteStreak(); if (streakRecord != null) { @@ -185,4 +185,4 @@ public class VoteButton implements GuiItem, Listener { { return _gui; } -} +} \ No newline at end of file From 5d3503b73306ef8be4ab45fd1fbb87a145f8678a Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Tue, 11 Aug 2015 01:55:27 -0500 Subject: [PATCH 51/72] Carl rewards --- .../mineplex/core/bonuses/BonusManager.java | 13 ++++- .../mineplex/core/reward/RewardManager.java | 56 +++++++++++++------ .../mineplex/core/reward/RewardRarity.java | 2 +- .../src/mineplex/core/reward/RewardType.java | 2 +- .../core/reward/rewards/ExperienceReward.java | 4 +- .../core/treasure/TreasureManager.java | 10 +++- .../src/mineplex/hub/HubManager.java | 11 +--- .../game/arcade/managers/GameLootManager.java | 2 +- 8 files changed, 65 insertions(+), 35 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 81121d59e..eb98b5137 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -24,8 +24,10 @@ import mineplex.core.database.DBPool; import mineplex.core.donation.DonationManager; import mineplex.core.hologram.Hologram; import mineplex.core.hologram.HologramManager; +import mineplex.core.inventory.InventoryManager; import mineplex.core.npc.Npc; import mineplex.core.npc.NpcManager; +import mineplex.core.pet.PetManager; import mineplex.core.reward.RewardManager; import mineplex.core.stats.StatsManager; import mineplex.core.updater.UpdateType; @@ -123,7 +125,7 @@ public class BonusManager extends MiniClientPlugin implements I private StreakRecord _dailyStreak; private StreakRecord _voteStreak; - public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, PollManager pollManager, NpcManager npcManager, HologramManager hologramManager, RewardManager rewardManager, StatsManager statsManager) + public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, PollManager pollManager, NpcManager npcManager, HologramManager hologramManager, StatsManager statsManager, InventoryManager inventoryManager, PetManager petManager) { super("Bonus", plugin); _repository = new BonusRepository(plugin, this, donationManager); @@ -131,7 +133,14 @@ public class BonusManager extends MiniClientPlugin implements I _donationManager = donationManager; _npcManager = npcManager; _hologramManager = hologramManager; - _rewardManager = rewardManager; + + _rewardManager = new RewardManager(clientManager, donationManager, inventoryManager, petManager, statsManager, + 100, 250, + 500, 1000, + 4000, 6000, + 12000, 32000, + true, true); + _pollManager = pollManager; _statsManager = statsManager; diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java index 1b49623f7..61db7e1eb 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java @@ -32,6 +32,7 @@ public class RewardManager private JavaPlugin _plugin; private HashMap> _treasureMap; private Random _random; + private boolean _carlSpinner; private CoreClientManager _clientManager; @@ -42,7 +43,7 @@ public class RewardManager int uncommonValueMin, int uncommonValueMax, int rareValueMin, int rareValueMax, int legendValueMin, int legendValueMax, - boolean doubleGadgetValue) + boolean doubleGadgetValue, boolean carlSpinner) { _plugin = donationManager.getPlugin(); _treasureMap = new HashMap>(); @@ -56,21 +57,15 @@ public class RewardManager _clientManager = clientManager; _doubleGadgetValue = doubleGadgetValue; + _carlSpinner = carlSpinner; - addGame(donationManager, inventoryManager, petManager, statsManager); - addCommon(donationManager, inventoryManager, petManager, commonValueMin, commonValueMax); - addUncommon(donationManager, inventoryManager, petManager, uncommonValueMin, uncommonValueMax); - addRare(donationManager, inventoryManager, petManager, rareValueMin, rareValueMax); - addLegendary(donationManager, inventoryManager, petManager, legendValueMin, legendValueMax); + addCommon(donationManager, inventoryManager, petManager, statsManager, commonValueMin, commonValueMax); + addUncommon(donationManager, inventoryManager, petManager, statsManager, uncommonValueMin, uncommonValueMax); + addRare(donationManager, inventoryManager, petManager, statsManager, rareValueMin, rareValueMax); + addLegendary(donationManager, inventoryManager, petManager, statsManager, legendValueMin, legendValueMax); } - public void addGame(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager) - { - addReward(new GemReward(donationManager, 100, 500, 100, RewardRarity.CARL_EXTRA)); - addReward(new ExperienceReward(statsManager, 100, 5000, 100, RewardRarity.CARL_EXTRA)); - } - - public void addCommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) + public void addCommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) { RewardRarity rarity = RewardRarity.COMMON; @@ -112,9 +107,16 @@ public class RewardManager addReward(new InventoryReward(inventoryManager, "TNT", "TNT", (int)(20*(minValue/500)), (int)(20*(maxValue/500)), new ItemStack(Material.TNT), rarity, 10)); + + if (_carlSpinner) + { + addReward(new GemReward(donationManager, 0, 0, 25, rarity)); + addReward(new CoinReward(donationManager, 0, 0, 25, rarity)); + addReward(new ExperienceReward(statsManager, 0, 0, 25, rarity)); + } } - public void addUncommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) + public void addUncommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) { RewardRarity rarity = RewardRarity.UNCOMMON; @@ -198,9 +200,16 @@ public class RewardManager // new ItemStack(2266), rarity, 25)); addReward(new UnknownPackageReward(donationManager, "Wait Disc", "Wait Disc", new ItemStack(2267), rarity, 25)); + + if (_carlSpinner) + { + addReward(new GemReward(donationManager, 0, 0, 1300, rarity)); + addReward(new CoinReward(donationManager, 0, 0, 1300, rarity)); + addReward(new ExperienceReward(statsManager, 0, 0, 1300, rarity)); + } } - public void addRare(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) + public void addRare(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) { RewardRarity rarity = RewardRarity.RARE; @@ -250,14 +259,20 @@ public class RewardManager addReward(new UnknownPackageReward(donationManager, "Space Boots", "Space Boots", new ItemStack(Material.GOLD_BOOTS), rarity, 50)); + if (_carlSpinner) + { + addReward(new GemReward(donationManager, 0, 0, 390, rarity)); + addReward(new CoinReward(donationManager, 0, 0, 390, rarity)); + addReward(new ExperienceReward(statsManager, 0, 0, 390, rarity)); + } } - public void addLegendary(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) + public void addLegendary(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) { RewardRarity rarity = RewardRarity.LEGENDARY; // Coins - addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 25, RewardRarity.LEGENDARY)); + addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 25, rarity)); // Mounts addReward(new UnknownPackageReward(donationManager, "Infernal Horror", "Infernal Horror", @@ -286,6 +301,13 @@ public class RewardManager new ItemStack(Material.APPLE), rarity, 4)); addReward(new UnknownPackageReward(donationManager, "Heart Particles", "I Heart You", new ItemStack(Material.BLAZE_POWDER), rarity, 2)); + + if (_carlSpinner) + { + addReward(new GemReward(donationManager, 0, 0, 70, rarity)); + addReward(new CoinReward(donationManager, 0, 0, 70, rarity)); + addReward(new ExperienceReward(statsManager, 0, 0, 70, rarity)); + } } public void addReward(Reward reward) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java index 971084562..43072cbe4 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java @@ -20,7 +20,7 @@ public enum RewardRarity OTHER("Other", cWhite, Material.STAINED_GLASS_PANE, (byte) 0), COMMON("Common", cWhite, Material.STAINED_GLASS_PANE, (byte) 0), - CARL_EXTRA("Game", cYellow, Material.STAINED_GLASS_PANE, (byte) 4), +// CARL_EXTRA("Game", cYellow, Material.STAINED_GLASS_PANE, (byte) 4), UNCOMMON("Uncommon", cAqua, Material.STAINED_GLASS_PANE, (byte) 3), RARE("Rare", cPurple, Material.STAINED_GLASS_PANE, (byte) 10), LEGENDARY("Legendary", cGreen, Material.STAINED_GLASS_PANE, (byte) 5), diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java index 6d9234391..4cbc5f6ec 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java @@ -37,7 +37,7 @@ public enum RewardType else if (rand <= _legendaryChance) rarity = RewardRarity.LEGENDARY; else if (rand <= _rareChance) rarity = RewardRarity.RARE; else if (rand <= _uncommonChance || requiresUncommon) rarity = RewardRarity.UNCOMMON; - else if (rand <= _gameChance) rarity = RewardRarity.CARL_EXTRA; +// else if (rand <= _gameChance) rarity = RewardRarity.CARL_EXTRA; return rarity; } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java index 7c2811608..ad1ad3b5b 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java @@ -35,13 +35,13 @@ public class ExperienceReward extends Reward _statsManager.incrementStat(player, "Global.ExpEarned", experience); - return new RewardData(getRarity().getColor() + experience + " Experience", new ItemStack(Material.EXP_BOTTLE), RewardRarity.CARL_EXTRA); + return new RewardData(getRarity().getColor() + experience + " Experience", new ItemStack(Material.EXP_BOTTLE), getRarity()); } @Override public RewardData getFakeRewardData(Player player) { - return new RewardData(getRarity().getColor() + "Experience", new ItemStack(Material.EXP_BOTTLE), RewardRarity.CARL_EXTRA); + return new RewardData(getRarity().getColor() + "Experience", new ItemStack(Material.EXP_BOTTLE), getRarity()); } @Override diff --git a/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java b/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java index 5746bc978..2afbb1ca3 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java @@ -20,6 +20,7 @@ import mineplex.core.pet.PetManager; import mineplex.core.reward.Reward; import mineplex.core.reward.RewardManager; import mineplex.core.reward.RewardType; +import mineplex.core.stats.StatsManager; /** * Created by Shaun on 8/27/2014. @@ -32,14 +33,19 @@ public class TreasureManager extends MiniPlugin private HologramManager _hologramManager; private List _treasureLocations; - public TreasureManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, BlockRestore blockRestore, HologramManager hologramManager, RewardManager rewardManager) + public TreasureManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, BlockRestore blockRestore, HologramManager hologramManager, StatsManager statsManager) { super("Treasure", plugin); _inventoryManager = inventoryManager; _blockRestore = blockRestore; _hologramManager = hologramManager; - _rewardManager = rewardManager; + _rewardManager = new RewardManager(clientManager, donationManager, _inventoryManager, petManager, statsManager, + 100, 250, + 500, 1000, + 4000, 6000, + 12000, 32000, + true, false);; World world = Bukkit.getWorlds().get(0); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index f09e21e1f..8d58d26b1 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -190,14 +190,7 @@ public class HubManager extends MiniClientPlugin new BenefitManager(plugin, clientManager, _inventoryManager); _gadgetManager = new GadgetManager(_plugin, clientManager, donationManager, _inventoryManager, _mountManager, petManager, preferences, disguiseManager, blockRestore, new ProjectileManager(plugin), achievementManager); - RewardManager rewardManager = new RewardManager(clientManager, donationManager, _inventoryManager, petManager, statsManager, - 100, 250, - 500, 1000, - 4000, 6000, - 12000, 32000, - true); - - _treasureManager = new TreasureManager(_plugin, clientManager, donationManager, _inventoryManager, petManager, _blockRestore, hologramManager, rewardManager); + _treasureManager = new TreasureManager(_plugin, clientManager, donationManager, _inventoryManager, petManager, _blockRestore, hologramManager, statsManager); new CosmeticManager(_plugin, clientManager, donationManager, _inventoryManager, _gadgetManager, _mountManager, petManager, _treasureManager); new SoccerManager(this, _gadgetManager); @@ -222,7 +215,7 @@ public class HubManager extends MiniClientPlugin ((CraftWorld)Bukkit.getWorlds().get(0)).getHandle().pvpMode = true; - new BonusManager(plugin, clientManager, donationManager, pollManager , npcManager, hologramManager, rewardManager, statsManager); + new BonusManager(plugin, clientManager, donationManager, pollManager , npcManager, hologramManager, statsManager, _inventoryManager, petManager); // NotificationManager notificationManager = new NotificationManager(plugin, clientManager, donationManager); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java index 91e3ae9ec..e018a834d 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java @@ -55,7 +55,7 @@ public class GameLootManager implements Listener 500, 1000, 1500, 2500, 6000, 12000, - false); + false, false); //Chest _rewardManager.addReward(new InventoryReward(Manager.getInventoryManager(), "Old Chest", "Old Chest", 1, 1, From b99c52616918e2581bd4c115f134ccd9ec97b842 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 11 Aug 2015 09:09:16 +0200 Subject: [PATCH 52/72] Implementing Carl message. --- .../mineplex/core/bonuses/BonusManager.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 9b4a4ee52..7c0f9b13d 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -4,6 +4,7 @@ import java.sql.Date; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Calendar; +import java.util.HashMap; import java.util.TimeZone; import mineplex.core.MiniClientPlugin; @@ -26,6 +27,7 @@ import mineplex.core.hologram.Hologram; import mineplex.core.hologram.HologramManager; import mineplex.core.npc.Npc; import mineplex.core.npc.NpcManager; +import mineplex.core.recharge.Recharge; import mineplex.core.reward.RewardManager; import mineplex.core.stats.StatsManager; import mineplex.core.updater.UpdateType; @@ -70,6 +72,7 @@ public class BonusManager extends MiniClientPlugin implements I private ArrayList _pendingExplosions = new ArrayList<>(); private ArrayList _pendingExplosionsPlayers = new ArrayList<>(); + private HashMap _showCarl = new HashMap<>(); private long _explode; private boolean _canVote; @@ -949,4 +952,36 @@ public class BonusManager extends MiniClientPlugin implements I entity.remove(); } } + + @EventHandler + public void Join(final PlayerJoinEvent event) + { + runSyncLater(new Runnable() + { + @Override + public void run() + { + _showCarl.put(event.getPlayer().getName(), true); + } + }, 200); + } + + @EventHandler + public void carlUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + return; + + for (Player player : UtilServer.getPlayers()) + { + if (Recharge.Instance.use(player, "Carl Inform", 240000, false, false)) + { + if(_pollManager.Get(player).shouldPoll() || canVote(player) || canRank(player) || canDaily(player)) + { + if(_showCarl.containsKey(player.getName())) + UtilPlayer.message(player, C.cDGreen + C.Bold + "Carl the Creeper)" + C.cGreen + " Hey " + player.getName().replace("s", "sss") + "! I have sssome amazing rewardsss for you! Come sssee me!"); + } + } + } + } } \ No newline at end of file From c177307f70e510a138f56974977e13c070754c47 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Tue, 11 Aug 2015 02:53:54 -0500 Subject: [PATCH 53/72] Votifier fixes --- .../mineplex/core/bonuses/BonusManager.java | 83 +++++++++++------- .../core/bonuses/gui/buttons/VoteButton.java | 2 +- .../src/mineplex/votifier/Votifier.java | 4 +- .../mineplex/votifier/VotifierManager.java | 87 +++++++++++++++++-- 4 files changed, 138 insertions(+), 38 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index eb98b5137..75233ccba 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -125,6 +125,21 @@ public class BonusManager extends MiniClientPlugin implements I private StreakRecord _dailyStreak; private StreakRecord _voteStreak; + /** + * THIS SHOULD ONLY BE USED FOR VOTIFIER! + */ + public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager) + { + super("Bonus", plugin); + _enabled = false; + + _repository = new BonusRepository(plugin, this, donationManager); + _clientManager = clientManager; + _donationManager = donationManager; + + updateOffSet(); + } + public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, PollManager pollManager, NpcManager npcManager, HologramManager hologramManager, StatsManager statsManager, InventoryManager inventoryManager, PetManager petManager) { super("Bonus", plugin); @@ -146,18 +161,26 @@ public class BonusManager extends MiniClientPlugin implements I // Hope to god this works! _canVote = true; - _carlNpc = _npcManager.getNpcByName("Carl the Creeper"); - if (_carlNpc == null) + + if (npcManager != null) { - _enabled = false; + _carlNpc = _npcManager.getNpcByName("Carl the Creeper"); + if (_carlNpc == null) + { + _enabled = false; + } + else + { + _enabled = true; +// _carlNpc.getEntity().setCustomName(""); +// _carlNpc.getEntity().setCustomNameVisible(false); + _animation = new AnimationCarl(_carlNpc.getEntity()); + _animation.setRunning(false); + } } else { - _enabled = true; -// _carlNpc.getEntity().setCustomName(""); -// _carlNpc.getEntity().setCustomNameVisible(false); - _animation = new AnimationCarl(_carlNpc.getEntity()); - _animation.setRunning(false); + _enabled = false; } clientManager.addStoredProcedureLoginProcessor(this); @@ -229,24 +252,24 @@ public class BonusManager extends MiniClientPlugin implements I public void handleVote(final Player player) { - _repository.attemptVoteBonus(player, new Callback() + runAsync(new Runnable() { @Override - public void run(Boolean data) + public void run() { - if (data) + Get(player).getRecord().refresh(); + runSync(new Runnable() { - incrementVoteStreak(player); - addPendingExplosion(player, player.getName()); - awardBonus(player, getVoteBonusAmount(player)); - UtilPlayer.message(player, F.main("Vote", "Thanks for your vote!")); - } - else - { - UtilPlayer.message(player, F.main("Vote", "There was an error processing your vote. Please contact an admin!")); - } + @Override + public void run() + { + addPendingExplosion(player, player.getName()); + UtilPlayer.message(player, F.main("Vote", "Thanks for your vote!")); + } + }); } }); + } @EventHandler @@ -498,14 +521,12 @@ public class BonusManager extends MiniClientPlugin implements I data.setMaxDailyStreak(data.getDailyStreak()); } - public void incrementVoteStreak(Player player) + public void incrementVoteStreak(BonusClientData client) { - BonusClientData data = Get(player); + client.setVoteStreak(client.getVoteStreak() + 1); - data.setVoteStreak(data.getVoteStreak() + 1); - - if (data.getVoteStreak() > data.getMaxVoteStreak()) - data.setMaxVoteStreak(data.getVoteStreak()); + if (client.getVoteStreak() > client.getMaxVoteStreak()) + client.setMaxVoteStreak(client.getVoteStreak()); } public boolean continueStreak(long localLastBonus, long extendTime) @@ -548,9 +569,8 @@ public class BonusManager extends MiniClientPlugin implements I return multiplyer; } - public int getVoteMultiplyer(Player player) + public int getVoteMultiplyer(BonusClientData client) { - BonusClientData client = Get(player); int streak = client.getVoteStreak(); int multiplyer = Math.min(100, 5 * streak); @@ -579,7 +599,12 @@ public class BonusManager extends MiniClientPlugin implements I public BonusAmount getVoteBonusAmount(Player player) { - double mult = getVoteMultiplyer(player) / 100.0; + return getVoteBonusAmount(Get(player)); + } + + public BonusAmount getVoteBonusAmount(BonusClientData client) + { + double mult = getVoteMultiplyer(client) / 100.0; BonusAmount amount = new BonusAmount(); amount.setTickets(1); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java index 50ed5afee..7b6118f70 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java @@ -131,7 +131,7 @@ public class VoteButton implements GuiItem, Listener { lore.add(" "); lore.add(C.cYellow + "Current Streak: " + C.cWhite + client.getVoteStreak()); - lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + "+" + _bonusManager.getVoteMultiplyer(_player) + "%"); + lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + "+" + _bonusManager.getVoteMultiplyer(client) + "%"); if (client.getVoteTime() != null) { long lastBonus = _bonusManager.getLocalTime(client.getVoteTime().getTime()); diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/Votifier.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/Votifier.java index 5ebb77b02..f3fd02c9a 100644 --- a/Plugins/Mineplex.Votifier/src/mineplex/votifier/Votifier.java +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/Votifier.java @@ -3,6 +3,7 @@ package mineplex.votifier; import org.bukkit.plugin.java.JavaPlugin; import mineplex.core.account.CoreClientManager; +import mineplex.core.bonuses.BonusManager; import mineplex.core.command.CommandCenter; import mineplex.core.donation.DonationManager; @@ -25,8 +26,9 @@ public class Votifier extends JavaPlugin CommandCenter.Initialize(this); CoreClientManager clientManager = new CoreClientManager(this, webServerAddress); DonationManager donationManager = new DonationManager(this, clientManager, webServerAddress); + BonusManager bonusManager = new BonusManager(this, clientManager, donationManager); - VotifierManager vote = new VotifierManager(this, clientManager, donationManager); + VotifierManager vote = new VotifierManager(this, clientManager, donationManager, bonusManager); } } diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java index 98f685a68..4791202f9 100644 --- a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java @@ -1,5 +1,6 @@ package mineplex.votifier; +import java.sql.Date; import java.util.UUID; import org.bukkit.event.EventHandler; @@ -9,6 +10,10 @@ import com.vexsoftware.votifier.model.Vote; import com.vexsoftware.votifier.model.VotifierEvent; import mineplex.core.MiniPlugin; import mineplex.core.account.CoreClientManager; +import mineplex.core.bonuses.BonusAmount; +import mineplex.core.bonuses.BonusClientData; +import mineplex.core.bonuses.BonusManager; +import mineplex.core.common.util.Callback; import mineplex.core.common.util.UUIDFetcher; import mineplex.core.database.DBPool; import mineplex.core.donation.DonationManager; @@ -23,6 +28,7 @@ import mineplex.serverdata.redis.RedisConfig; import mineplex.serverdata.redis.RedisDataRepository; import mineplex.serverdata.servers.ServerManager; import org.jooq.DSLContext; +import org.jooq.Record1; import org.jooq.SQLDialect; import org.jooq.impl.DSL; import redis.clients.jedis.Jedis; @@ -36,6 +42,7 @@ public class VotifierManager extends MiniPlugin { private CoreClientManager _clientManager; private DonationManager _donationManager; + private BonusManager _bonusManager; private RedisConfig _usConfig; private RedisConfig _euConfig; @@ -44,12 +51,13 @@ public class VotifierManager extends MiniPlugin private JedisPool _usWritePool; private JedisPool _euWritePool; - public VotifierManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager) + public VotifierManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, BonusManager bonusManager) { super("Votifier", plugin); _clientManager = clientManager; _donationManager = donationManager; + _bonusManager = bonusManager; _usConfig = ServerManager.getConfig("us-redis.dat"); _euConfig = ServerManager.getConfig("eu-redis.dat"); @@ -71,7 +79,24 @@ public class VotifierManager extends MiniPlugin System.out.println("New Vote: " + playerName); -// UUID uuid = UUIDFetcher.getUUIDOf(playerName); + UUID uuid = UUIDFetcher.getUUIDOf(playerName); + if (uuid == null) + { + System.out.println("Failed to load UUID of " + playerName + " from UUIDFetcher. Trying with database"); + uuid = _clientManager.loadUUIDFromDB(playerName); + + if (uuid == null) + { + System.out.println("Failed to load UUID from database. Giving up on " + playerName); + } + } + + System.out.println("Loaded " + playerName + " with uuid " + uuid); + System.out.println("Attempting to award bonus"); + awardBonus(playerName, uuid); + System.out.println(); + System.out.println(); + // UUID uuid = _clientManager.loadUUIDFromDB(playerName); // if (uuid != null) // { @@ -116,13 +141,61 @@ public class VotifierManager extends MiniPlugin publishCommand(command, writePool); } - private void awardBonus(UUID uuid) + private void awardBonus(final String playerName, UUID uuid) { - // Don't use this right now! DSLContext create = DSL.using(DBPool.ACCOUNT, SQLDialect.MYSQL); - int updated = create.update(Tables.bonus).set(Tables.bonus.tickets, Tables.bonus.tickets.add(1)) - .where(Tables.bonus.accountId.eq(DSL.select(Tables.accounts.id).where(Tables.accounts.uuid.eq(uuid.toString())))).execute(); - System.out.println("Ran query with response: " + updated); + + Record1 idRecord = create.select(Tables.accounts.id).from(Tables.accounts).where(Tables.accounts.uuid.eq(uuid.toString())).fetchOne(); + if (idRecord != null) + { + final int accountId = idRecord.value1(); + final BonusClientData client = new BonusClientData(_bonusManager.getRepository().loadRecord(playerName, accountId)); + + final BonusAmount amount = _bonusManager.getVoteBonusAmount(client); + + // Reward Amount + if (amount.getTickets() > 0) + client.setTickets(client.getTickets() + amount.getTickets()); + + if (amount.getGems() > 0) + { + _donationManager.RewardGems(new Callback() + { + @Override + public void run(Boolean data) + { + if (data) + System.out.println("Gave " + amount.getGems() + " gems to " + playerName); + else + System.out.println("Failed to give " + amount.getGems() + " gems to " + playerName); + } + }, "Votifier", playerName, uuid, amount.getGems()); + } + + if (amount.getCoins() > 0) + { + _donationManager.RewardCoins(new Callback() + { + @Override + public void run(Boolean data) + { + if (data) + System.out.println("Gave " + amount.getGems() + " coins to " + playerName); + else + System.out.println("Failed to give " + amount.getGems() + " coins to " + playerName); + } + }, "Votifier", playerName, accountId, amount.getCoins()); + } + + // Update time + client.getRecord().setVotetime(new Date(_bonusManager.getSqlTime())); + + // Update Streak + _bonusManager.incrementVoteStreak(client); + + client.getRecord().store(); + System.out.println("Awarded carl ticket to " + playerName); + } } private void publishCommand(final ServerCommand serverCommand, final JedisPool writePool) From 13e7e58986488050ee337df979490b208dbbde65 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Tue, 11 Aug 2015 03:09:21 -0500 Subject: [PATCH 54/72] Creeper visual! --- .../mineplex/core/bonuses/BonusManager.java | 72 ++++++++++++------- 1 file changed, 47 insertions(+), 25 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 75233ccba..2edf3ef60 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -120,6 +120,7 @@ public class BonusManager extends MiniClientPlugin implements I public boolean _enabled; private Npc _carlNpc; private AnimationCarl _animation; + private int _visualTick; // Streak private StreakRecord _dailyStreak; @@ -397,7 +398,7 @@ public class BonusManager extends MiniClientPlugin implements I { incrementDailyStreak(player); awardBonus(player, amount); - updateCreeperVisual(player); + updateCreeperVisual(player, true, C.cAqua); } result.run(r); @@ -436,7 +437,7 @@ public class BonusManager extends MiniClientPlugin implements I if (aBoolean) { awardBonus(player, getRankBonusAmount(player)); - updateCreeperVisual(player); + updateCreeperVisual(player, true, C.cAqua); } result.run(aBoolean); @@ -822,12 +823,12 @@ public class BonusManager extends MiniClientPlugin implements I public void run() { if (event.getPlayer().isOnline()) - updateCreeperVisual(event.getPlayer()); + updateCreeperVisual(event.getPlayer(), true, C.cAqua); } }, 10); } - public void updateCreeperVisual(Player player) + public void updateCreeperVisual(Player player, boolean updateDataWatcher, String rewardPrefix) { if (!_enabled) return; @@ -846,10 +847,12 @@ public class BonusManager extends MiniClientPlugin implements I if (client.getHologram() == null) { - hologram = new Hologram(_hologramManager, _carlNpc.getLocation().clone().add(0, 2.75 - 0.285 - 0.285, 0), ""); + double yAdd = UtilPlayer.is1_8(player) ? 2.18 : 2.3; + hologram = new Hologram(_hologramManager, _carlNpc.getLocation().clone().add(0, yAdd, 0), ""); hologram.setHologramTarget(Hologram.HologramTarget.WHITELIST); hologram.addPlayer(player); client.setHologram(hologram); + hologram.start(); } else { @@ -860,34 +863,53 @@ public class BonusManager extends MiniClientPlugin implements I { // Hologram // String name = "Carl the Creeper"; - String text = C.cAqua + availableRewards + " Reward" + (availableRewards > 1 ? "s" : "") + " to Claim"; + String text = rewardPrefix + availableRewards + " Reward" + (availableRewards > 1 ? "s" : "") + " to Claim"; hologram.setText(text); - hologram.start(); - // Charged - DataWatcher watcher = new DataWatcher(null); - watcher.a(0, (byte) 0); - watcher.a(1, (short) 300); - watcher.a(17, (byte) 1); - PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(); - packet.a = _carlNpc.getEntity().getEntityId(); - packet.b = watcher.c(); + if (updateDataWatcher) + { + // Charged + DataWatcher watcher = new DataWatcher(null); + watcher.a(0, (byte) 0); + watcher.a(1, (short) 300); + watcher.a(17, (byte) 1); + PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(); + packet.a = _carlNpc.getEntity().getEntityId(); + packet.b = watcher.c(); - UtilPlayer.sendPacket(player, packet); + UtilPlayer.sendPacket(player, packet); + } } else { - // Hologram - hologram.stop(); + String text = C.cGray + "No Rewards"; + hologram.setText(text); - // Charged - DataWatcher watcher = new DataWatcher(null); - watcher.a(17, (byte) 0); - PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(); - packet.a = _carlNpc.getEntity().getEntityId(); - packet.b = watcher.c(); + if (updateDataWatcher) + { + // Charged + DataWatcher watcher = new DataWatcher(null); + watcher.a(17, (byte) 0); + PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(); + packet.a = _carlNpc.getEntity().getEntityId(); + packet.b = watcher.c(); - UtilPlayer.sendPacket(player, packet); + UtilPlayer.sendPacket(player, packet); + } + } + } + + @EventHandler + public void updateCreeper(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC || !_enabled) + return; + + for (Player player : UtilServer.getPlayers()) + { + String prefix = _visualTick % 2 == 0 ? C.cAqua : C.cDAqua; + updateCreeperVisual(player, false, prefix); + _visualTick++; } } From fe153bee11d9902547ac8887aa667de24f194b2c Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Tue, 11 Aug 2015 03:19:27 -0500 Subject: [PATCH 55/72] Fix revert issues --- .../mineplex/core/bonuses/BonusManager.java | 2 + .../core/bonuses/BonusRepository.java | 48 +++++++++++++- .../mineplex/core/reward/RewardManager.java | 64 +++++++++++++------ .../core/treasure/TreasureManager.java | 10 ++- .../src/mineplex/hub/HubManager.java | 11 +--- .../game/arcade/managers/GameLootManager.java | 2 +- 6 files changed, 101 insertions(+), 36 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index bb95d2722..ecdd769fd 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -25,8 +25,10 @@ import mineplex.core.database.DBPool; import mineplex.core.donation.DonationManager; import mineplex.core.hologram.Hologram; import mineplex.core.hologram.HologramManager; +import mineplex.core.inventory.InventoryManager; import mineplex.core.npc.Npc; import mineplex.core.npc.NpcManager; +import mineplex.core.pet.PetManager; import mineplex.core.recharge.Recharge; import mineplex.core.reward.RewardManager; import mineplex.core.stats.StatsManager; diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java index d97a76cc5..c33d49e19 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java @@ -7,7 +7,11 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; +import com.sun.org.apache.xpath.internal.operations.Bool; +import mineplex.core.bonuses.gui.SpinGui; import mineplex.core.common.util.Callback; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; import mineplex.core.database.DBPool; import mineplex.core.database.RepositoryBase; import mineplex.core.database.ResultSetCallable; @@ -17,7 +21,9 @@ import mineplex.database.Tables; import mineplex.database.tables.records.BonusRecord; import org.jooq.DSLContext; import org.jooq.Record2; +import org.jooq.SQLDialect; import org.jooq.TableField; +import org.jooq.impl.DSL; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -95,6 +101,42 @@ public class BonusRepository extends RepositoryBase }); } + public void attemptAddTickets(final int accountId, final BonusClientData client, final int tickets, final Callback callback) + { + if (client.getTickets() + tickets < 0) + callback.run(false); + + Bukkit.getScheduler().runTaskAsynchronously(_manager.getPlugin(), new Runnable() + { + @Override + public void run() + { + try + { + DSLContext create = DSL.using(DBPool.ACCOUNT, SQLDialect.MYSQL); + create.update(Tables.bonus).set(Tables.bonus.tickets, Tables.bonus.tickets.add(tickets)). + where(Tables.bonus.accountId.eq(accountId)).execute(); + final int newTickets = create.select(Tables.bonus.tickets).from(Tables.bonus).where(Tables.bonus.accountId.eq(accountId)).fetchOne().value1(); + + Bukkit.getScheduler().runTask(_manager.getPlugin(), new Runnable() + { + @Override + public void run() + { + client.setTickets(newTickets); + callback.run(true); + } + }); + } + catch (Exception e) + { + e.printStackTrace(); + callback.run(false); + } + } + }); + } + public void attemptDailyBonus(final Player player, final Callback result) { final int accountId = _manager.getClientManager().Get(player).getAccountId(); @@ -207,7 +249,7 @@ public class BonusRepository extends RepositoryBase { try (Connection connection = getConnection(); - CallableStatement callableStatement = connection.prepareCall("{call check_rank(?, ?, ?, ?, ?)}")) { + CallableStatement callableStatement = connection.prepareCall("{call check_rank(?, ?, ?, ?, ?)}")) { callableStatement.setInt(1, accountId); callableStatement.setInt(2, coins); callableStatement.setInt(3, 0); @@ -262,7 +304,7 @@ public class BonusRepository extends RepositoryBase { try (Connection connection = getConnection(); - CallableStatement callableStatement = connection.prepareCall("{call check_vote(?, ?, ?, ?, ?)}")) { + CallableStatement callableStatement = connection.prepareCall("{call check_vote(?, ?, ?, ?, ?)}")) { callableStatement.setInt(1, accountId); callableStatement.setInt(2, coins); callableStatement.setInt(3, gems); @@ -281,7 +323,7 @@ public class BonusRepository extends RepositoryBase { _manager.Get(player).setVoteTime(date); result.run(true); - + } }); } catch (Exception e) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java index 386eba7ad..056d5c901 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java @@ -32,17 +32,18 @@ public class RewardManager private JavaPlugin _plugin; private HashMap> _treasureMap; private Random _random; + private boolean _carlSpinner; private CoreClientManager _clientManager; private boolean _doubleGadgetValue; public RewardManager(CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, - int commonValueMin, int commonValueMax, - int uncommonValueMin, int uncommonValueMax, - int rareValueMin, int rareValueMax, - int legendValueMin, int legendValueMax, - boolean doubleGadgetValue) + int commonValueMin, int commonValueMax, + int uncommonValueMin, int uncommonValueMax, + int rareValueMin, int rareValueMax, + int legendValueMin, int legendValueMax, + boolean doubleGadgetValue, boolean carlSpinner) { _plugin = donationManager.getPlugin(); _treasureMap = new HashMap>(); @@ -56,21 +57,15 @@ public class RewardManager _clientManager = clientManager; _doubleGadgetValue = doubleGadgetValue; + _carlSpinner = carlSpinner; - addGame(donationManager, inventoryManager, petManager, statsManager); - addCommon(donationManager, inventoryManager, petManager, commonValueMin, commonValueMax); - addUncommon(donationManager, inventoryManager, petManager, uncommonValueMin, uncommonValueMax); - addRare(donationManager, inventoryManager, petManager, rareValueMin, rareValueMax); - addLegendary(donationManager, inventoryManager, petManager, legendValueMin, legendValueMax); + addCommon(donationManager, inventoryManager, petManager, statsManager, commonValueMin, commonValueMax); + addUncommon(donationManager, inventoryManager, petManager, statsManager, uncommonValueMin, uncommonValueMax); + addRare(donationManager, inventoryManager, petManager, statsManager, rareValueMin, rareValueMax); + addLegendary(donationManager, inventoryManager, petManager, statsManager, legendValueMin, legendValueMax); } - public void addGame(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager) - { - addReward(new GemReward(donationManager, 100, 500, 100, RewardRarity.GAME)); - addReward(new ExperienceReward(statsManager, 100, 5000, 100, RewardRarity.GAME)); - } - - public void addCommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) + public void addCommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) { RewardRarity rarity = RewardRarity.COMMON; @@ -112,9 +107,16 @@ public class RewardManager addReward(new InventoryReward(inventoryManager, "TNT", "TNT", (int)(20*(minValue/500)), (int)(20*(maxValue/500)), new ItemStack(Material.TNT), rarity, 10)); + + if (_carlSpinner) + { + addReward(new GemReward(donationManager, 0, 0, 25, rarity)); + addReward(new CoinReward(donationManager, 0, 0, 25, rarity)); + addReward(new ExperienceReward(statsManager, 0, 0, 25, rarity)); + } } - public void addUncommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) + public void addUncommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) { RewardRarity rarity = RewardRarity.UNCOMMON; @@ -198,9 +200,16 @@ public class RewardManager // new ItemStack(2266), rarity, 25)); addReward(new UnknownPackageReward(donationManager, "Wait Disc", "Wait Disc", new ItemStack(2267), rarity, 25)); + + if (_carlSpinner) + { + addReward(new GemReward(donationManager, 0, 0, 1300, rarity)); + addReward(new CoinReward(donationManager, 0, 0, 1300, rarity)); + addReward(new ExperienceReward(statsManager, 0, 0, 1300, rarity)); + } } - public void addRare(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) + public void addRare(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) { RewardRarity rarity = RewardRarity.RARE; @@ -250,14 +259,20 @@ public class RewardManager addReward(new UnknownPackageReward(donationManager, "Space Boots", "Space Boots", new ItemStack(Material.GOLD_BOOTS), rarity, 50)); + if (_carlSpinner) + { + addReward(new GemReward(donationManager, 0, 0, 390, rarity)); + addReward(new CoinReward(donationManager, 0, 0, 390, rarity)); + addReward(new ExperienceReward(statsManager, 0, 0, 390, rarity)); + } } - public void addLegendary(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) + public void addLegendary(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) { RewardRarity rarity = RewardRarity.LEGENDARY; // Coins - addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 25, RewardRarity.LEGENDARY)); + addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 25, rarity)); // Mounts addReward(new UnknownPackageReward(donationManager, "Infernal Horror", "Infernal Horror", @@ -286,6 +301,13 @@ public class RewardManager new ItemStack(Material.APPLE), rarity, 4)); addReward(new UnknownPackageReward(donationManager, "Heart Particles", "I Heart You", new ItemStack(Material.BLAZE_POWDER), rarity, 2)); + + if (_carlSpinner) + { + addReward(new GemReward(donationManager, 0, 0, 70, rarity)); + addReward(new CoinReward(donationManager, 0, 0, 70, rarity)); + addReward(new ExperienceReward(statsManager, 0, 0, 70, rarity)); + } } public void addReward(Reward reward) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java b/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java index 5746bc978..fbd14ea54 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java @@ -20,6 +20,7 @@ import mineplex.core.pet.PetManager; import mineplex.core.reward.Reward; import mineplex.core.reward.RewardManager; import mineplex.core.reward.RewardType; +import mineplex.core.stats.StatsManager; /** * Created by Shaun on 8/27/2014. @@ -32,14 +33,19 @@ public class TreasureManager extends MiniPlugin private HologramManager _hologramManager; private List _treasureLocations; - public TreasureManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, BlockRestore blockRestore, HologramManager hologramManager, RewardManager rewardManager) + public TreasureManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, BlockRestore blockRestore, HologramManager hologramManager, StatsManager statsManager) { super("Treasure", plugin); _inventoryManager = inventoryManager; _blockRestore = blockRestore; _hologramManager = hologramManager; - _rewardManager = rewardManager; + _rewardManager = new RewardManager(clientManager, donationManager, _inventoryManager, petManager, statsManager, + 100, 250, + 500, 1000, + 4000, 6000, + 12000, 32000, + true, false); World world = Bukkit.getWorlds().get(0); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index f09e21e1f..8d58d26b1 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -190,14 +190,7 @@ public class HubManager extends MiniClientPlugin new BenefitManager(plugin, clientManager, _inventoryManager); _gadgetManager = new GadgetManager(_plugin, clientManager, donationManager, _inventoryManager, _mountManager, petManager, preferences, disguiseManager, blockRestore, new ProjectileManager(plugin), achievementManager); - RewardManager rewardManager = new RewardManager(clientManager, donationManager, _inventoryManager, petManager, statsManager, - 100, 250, - 500, 1000, - 4000, 6000, - 12000, 32000, - true); - - _treasureManager = new TreasureManager(_plugin, clientManager, donationManager, _inventoryManager, petManager, _blockRestore, hologramManager, rewardManager); + _treasureManager = new TreasureManager(_plugin, clientManager, donationManager, _inventoryManager, petManager, _blockRestore, hologramManager, statsManager); new CosmeticManager(_plugin, clientManager, donationManager, _inventoryManager, _gadgetManager, _mountManager, petManager, _treasureManager); new SoccerManager(this, _gadgetManager); @@ -222,7 +215,7 @@ public class HubManager extends MiniClientPlugin ((CraftWorld)Bukkit.getWorlds().get(0)).getHandle().pvpMode = true; - new BonusManager(plugin, clientManager, donationManager, pollManager , npcManager, hologramManager, rewardManager, statsManager); + new BonusManager(plugin, clientManager, donationManager, pollManager , npcManager, hologramManager, statsManager, _inventoryManager, petManager); // NotificationManager notificationManager = new NotificationManager(plugin, clientManager, donationManager); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java index 91e3ae9ec..e018a834d 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java @@ -55,7 +55,7 @@ public class GameLootManager implements Listener 500, 1000, 1500, 2500, 6000, 12000, - false); + false, false); //Chest _rewardManager.addReward(new InventoryReward(Manager.getInventoryManager(), "Old Chest", "Old Chest", 1, 1, From 1c40478e6ee2f78f7716dc3ed1eae6a6f2e402b7 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 10:32:49 +0200 Subject: [PATCH 56/72] SPIN DOGGY SPIN --- .../mineplex/core/bonuses/gui/SpinGui.java | 6 +- .../mineplex/core/reward/RewardManager.java | 73 +++++++++++-------- 2 files changed, 44 insertions(+), 35 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java index 16c8fcba3..6739f1294 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java @@ -75,10 +75,6 @@ public class SpinGui extends SimpleGui { _fakeRewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerFiller, true); } - for (int i = 0; i < REWARDS_TO_GENERATE; i++) - { - _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerReal, true); - } _ticksPerSwap = 1; @@ -104,7 +100,7 @@ public class SpinGui extends SimpleGui _stopSpinnerAt = _ticks.size(); - _fakeRewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3] = _rewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3]; + _fakeRewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3] = rewardManager.nextReward(player, null, false, RewardType.SpinnerReal, true); _reward = _fakeRewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3]; _rewardData = _reward.giveReward("Carls Spinner", getPlayer()); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java index 056d5c901..8932c3658 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java @@ -70,7 +70,16 @@ public class RewardManager RewardRarity rarity = RewardRarity.COMMON; // Coins - addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 1, rarity)); + if (_carlSpinner) + { + addReward(new GemReward(donationManager, (int)minValue, (int)maxValue, 25, rarity)); + addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 25, rarity)); + addReward(new ExperienceReward(statsManager, (int)minValue*5, (int)maxValue*5, 25, rarity)); + } + else + { + addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 5, rarity)); + } //Increase Value if (_doubleGadgetValue) @@ -108,12 +117,7 @@ public class RewardManager (int)(20*(minValue/500)), (int)(20*(maxValue/500)), new ItemStack(Material.TNT), rarity, 10)); - if (_carlSpinner) - { - addReward(new GemReward(donationManager, 0, 0, 25, rarity)); - addReward(new CoinReward(donationManager, 0, 0, 25, rarity)); - addReward(new ExperienceReward(statsManager, 0, 0, 25, rarity)); - } + } public void addUncommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) @@ -121,7 +125,16 @@ public class RewardManager RewardRarity rarity = RewardRarity.UNCOMMON; // Coins - addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 250, RewardRarity.UNCOMMON)); + if (_carlSpinner) + { + addReward(new GemReward(donationManager, (int)minValue, (int)maxValue, 1200, rarity)); + addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 1200, rarity)); + addReward(new ExperienceReward(statsManager, (int)minValue*5, (int)maxValue*5, 1200, rarity)); + } + else + { + addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 250, RewardRarity.UNCOMMON)); + } //Increase Value if (_doubleGadgetValue) @@ -200,13 +213,6 @@ public class RewardManager // new ItemStack(2266), rarity, 25)); addReward(new UnknownPackageReward(donationManager, "Wait Disc", "Wait Disc", new ItemStack(2267), rarity, 25)); - - if (_carlSpinner) - { - addReward(new GemReward(donationManager, 0, 0, 1300, rarity)); - addReward(new CoinReward(donationManager, 0, 0, 1300, rarity)); - addReward(new ExperienceReward(statsManager, 0, 0, 1300, rarity)); - } } public void addRare(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) @@ -214,7 +220,17 @@ public class RewardManager RewardRarity rarity = RewardRarity.RARE; // Coins - addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 100, RewardRarity.RARE)); + if (_carlSpinner) + { + addReward(new GemReward(donationManager, (int)minValue, (int)maxValue, 150, rarity)); + addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 150, rarity)); + addReward(new ExperienceReward(statsManager, (int)minValue*5, (int)maxValue*5, 150, rarity)); + } + else + { + addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 100, RewardRarity.RARE)); + } + // Mounts addReward(new UnknownPackageReward(donationManager, "Mount Mule", "Mount Mule", @@ -258,13 +274,6 @@ public class RewardManager new ItemStack(Material.GOLD_LEGGINGS), rarity, 50)); addReward(new UnknownPackageReward(donationManager, "Space Boots", "Space Boots", new ItemStack(Material.GOLD_BOOTS), rarity, 50)); - - if (_carlSpinner) - { - addReward(new GemReward(donationManager, 0, 0, 390, rarity)); - addReward(new CoinReward(donationManager, 0, 0, 390, rarity)); - addReward(new ExperienceReward(statsManager, 0, 0, 390, rarity)); - } } public void addLegendary(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) @@ -272,7 +281,16 @@ public class RewardManager RewardRarity rarity = RewardRarity.LEGENDARY; // Coins - addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 25, rarity)); + if (_carlSpinner) + { + addReward(new GemReward(donationManager, (int)minValue, (int)maxValue, 10, rarity)); + addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 10, rarity)); + addReward(new ExperienceReward(statsManager, (int)minValue*5, (int)maxValue*5, 10, rarity)); + } + else + { + addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 25, rarity)); + } // Mounts addReward(new UnknownPackageReward(donationManager, "Infernal Horror", "Infernal Horror", @@ -302,12 +320,7 @@ public class RewardManager addReward(new UnknownPackageReward(donationManager, "Heart Particles", "I Heart You", new ItemStack(Material.BLAZE_POWDER), rarity, 2)); - if (_carlSpinner) - { - addReward(new GemReward(donationManager, 0, 0, 70, rarity)); - addReward(new CoinReward(donationManager, 0, 0, 70, rarity)); - addReward(new ExperienceReward(statsManager, 0, 0, 70, rarity)); - } + } public void addReward(Reward reward) From a1c10a7ec5ac39616723966b5c5b302152931dc6 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 10:33:44 +0200 Subject: [PATCH 57/72] clean up --- .../src/mineplex/core/bonuses/gui/SpinGui.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java index 6739f1294..fe989337a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java @@ -46,7 +46,6 @@ public class SpinGui extends SimpleGui private int _ticksPerSwap; private int _swapCount; private Reward[] _rewards; - private Reward[] _fakeRewards; private boolean _stopped; private boolean _rewarded; private ArrayList _ticks; @@ -66,14 +65,13 @@ public class SpinGui extends SimpleGui //setItem(CARL_SLOT, new DisplayItem(carlItem)); _rewards = new Reward[REWARDS_TO_GENERATE]; - _fakeRewards = new Reward[REWARDS_TO_GENERATE]; _ticks = new ArrayList<>(); _frame = 0; _pitch = 1; for (int i = 0; i < REWARDS_TO_GENERATE; i++) { - _fakeRewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerFiller, true); + _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerFiller, true); } _ticksPerSwap = 1; @@ -100,8 +98,8 @@ public class SpinGui extends SimpleGui _stopSpinnerAt = _ticks.size(); - _fakeRewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3] = rewardManager.nextReward(player, null, false, RewardType.SpinnerReal, true); - _reward = _fakeRewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3]; + _rewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3] = rewardManager.nextReward(player, null, false, RewardType.SpinnerReal, true); + _reward = _rewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3]; _rewardData = _reward.giveReward("Carls Spinner", getPlayer()); } @@ -150,7 +148,7 @@ public class SpinGui extends SimpleGui index = index % REWARDS_TO_GENERATE; int slot = 9 + i; - RewardData data = _fakeRewards[index].getFakeRewardData(getPlayer()); + RewardData data = _rewards[index].getFakeRewardData(getPlayer()); setItem(slot, new RewardButton(data)); // Glass Panes From f66a0439e8b5601a7b12b3bcaac66b1a642ff5d2 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 10:34:33 +0200 Subject: [PATCH 58/72] no need to gen so many --- .../Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java index fe989337a..bea18f676 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java @@ -32,7 +32,7 @@ import org.bukkit.plugin.Plugin; public class SpinGui extends SimpleGui { - private static final int REWARDS_TO_GENERATE = 1000; + private static final int REWARDS_TO_GENERATE = 200; private static final int HOPPER_SLOT = 4; private static final int CARL_SLOT = 22; private static final int[] LINE_NUMS = { /*-27, -18,*/ -9, 9/*, 18*/ }; From 184feec875a7b7b5b05df01d069d5f51947f2e15 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 10:54:24 +0200 Subject: [PATCH 59/72] cleany and logic --- .../mineplex/core/bonuses/gui/SpinGui.java | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java index bea18f676..1daab79ea 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java @@ -32,7 +32,6 @@ import org.bukkit.plugin.Plugin; public class SpinGui extends SimpleGui { - private static final int REWARDS_TO_GENERATE = 200; private static final int HOPPER_SLOT = 4; private static final int CARL_SLOT = 22; private static final int[] LINE_NUMS = { /*-27, -18,*/ -9, 9/*, 18*/ }; @@ -64,15 +63,12 @@ public class SpinGui extends SimpleGui setItem(HOPPER_SLOT, new DisplayItem(new ItemStack(Material.HOPPER))); //setItem(CARL_SLOT, new DisplayItem(carlItem)); - _rewards = new Reward[REWARDS_TO_GENERATE]; + _ticks = new ArrayList<>(); _frame = 0; _pitch = 1; - for (int i = 0; i < REWARDS_TO_GENERATE; i++) - { - _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerFiller, true); - } + _ticksPerSwap = 1; @@ -98,8 +94,19 @@ public class SpinGui extends SimpleGui _stopSpinnerAt = _ticks.size(); - _rewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3] = rewardManager.nextReward(player, null, false, RewardType.SpinnerReal, true); - _reward = _rewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3]; + //Create Fake Rewards + _rewards = new Reward[_stopSpinnerAt+5]; + for (int i = 0; i < _stopSpinnerAt+5 ; i++) + { + if (i != _stopSpinnerAt) + _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerFiller, true); + else + { + _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerReal, true); + _reward = _rewards[i]; + } + } + _rewardData = _reward.giveReward("Carls Spinner", getPlayer()); } From 74b83d6851b59a94d3bcfdbc31ae30791f69cc5f Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 10:56:07 +0200 Subject: [PATCH 60/72] fixed! --- .../src/mineplex/core/bonuses/gui/SpinGui.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java index 1daab79ea..89f69a782 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java @@ -94,9 +94,9 @@ public class SpinGui extends SimpleGui _stopSpinnerAt = _ticks.size(); - //Create Fake Rewards - _rewards = new Reward[_stopSpinnerAt+5]; - for (int i = 0; i < _stopSpinnerAt+5 ; i++) + //Create Rewards + _rewards = new Reward[_stopSpinnerAt+10]; //Adding 10, so theres items to the right still. + for (int i = 0; i < _stopSpinnerAt+10 ; i++) { if (i != _stopSpinnerAt) _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerFiller, true); @@ -152,7 +152,6 @@ public class SpinGui extends SimpleGui for (int i = 0; i < 9; i++) { int index = _currentRewardIndex + i; - index = index % REWARDS_TO_GENERATE; int slot = 9 + i; RewardData data = _rewards[index].getFakeRewardData(getPlayer()); From 4c32f32ced5e6997a7735c33aae99c3eb0409dfa Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 11:17:20 +0200 Subject: [PATCH 61/72] removed game reward type --- .../src/mineplex/core/reward/RewardType.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java index 90b201c08..b226448c2 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java @@ -3,28 +3,26 @@ package mineplex.core.reward; public enum RewardType { //% Chances Mythic Legend Rare Uncommon - GameLoot( 0.000001, 0.00001, 0.0001, 3, 10), + GameLoot( 0.000001, 0.00001, 0.0001, 3), - OldChest( 0, 0.05, 0.4, 5, 0), - AncientChest( 0, 1, 4, 25, 0), - MythicalChest( 0.4, 3, 12, 75, 0), + OldChest( 0, 0.05, 0.4, 5), + AncientChest( 0, 1, 4, 25), + MythicalChest( 0.4, 3, 12, 75), - SpinnerFiller( 0.1, 1, 4, 20, 30), - SpinnerReal( 0.000001, 0.05, 0.4, 5, 10); + SpinnerFiller( 0.1, 1, 4, 20), + SpinnerReal( 0.000001, 0.05, 0.4, 5); private double _mythicalChance; private double _legendaryChance; private double _rareChance; private double _uncommonChance; - private double _gameChance; - RewardType(double mythical, double legend, double rare, double uncommon, double game) + RewardType(double mythical, double legend, double rare, double uncommon) { _mythicalChance = (mythical / 100d); _legendaryChance = _mythicalChance + (legend / 100d); //Add previous chance to prep for generateRarity random values. _rareChance = _legendaryChance + (rare / 100d); _uncommonChance = _rareChance + (uncommon / 100d); - _gameChance = _uncommonChance + (game / 100d); } public RewardRarity generateRarity(boolean requiresUncommon) @@ -37,7 +35,6 @@ public enum RewardType else if (rand <= _legendaryChance) rarity = RewardRarity.LEGENDARY; else if (rand <= _rareChance) rarity = RewardRarity.RARE; else if (rand <= _uncommonChance || requiresUncommon) rarity = RewardRarity.UNCOMMON; - else if (rand <= _gameChance) rarity = RewardRarity.GAME; return rarity; } From 8abefaf856f333b0a985ad8b986a63e460ca0d19 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 11 Aug 2015 11:31:51 +0200 Subject: [PATCH 62/72] The magical +3. --- .../Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java index 89f69a782..0dfee278a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java @@ -98,8 +98,10 @@ public class SpinGui extends SimpleGui _rewards = new Reward[_stopSpinnerAt+10]; //Adding 10, so theres items to the right still. for (int i = 0; i < _stopSpinnerAt+10 ; i++) { - if (i != _stopSpinnerAt) + if (i != _stopSpinnerAt + 3) + { _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerFiller, true); + } else { _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerReal, true); From 3eb7e91fbb9be7c5f2d64785a5895c9aacef4fb1 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Tue, 11 Aug 2015 04:38:37 -0500 Subject: [PATCH 63/72] Removing the magical 3 --- Plugins/.idea/misc.xml | 2 +- .../Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Plugins/.idea/misc.xml b/Plugins/.idea/misc.xml index 3a9b4c67e..aeea575e6 100644 --- a/Plugins/.idea/misc.xml +++ b/Plugins/.idea/misc.xml @@ -16,7 +16,7 @@ - + \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java index 0dfee278a..18310ab5a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java @@ -98,7 +98,7 @@ public class SpinGui extends SimpleGui _rewards = new Reward[_stopSpinnerAt+10]; //Adding 10, so theres items to the right still. for (int i = 0; i < _stopSpinnerAt+10 ; i++) { - if (i != _stopSpinnerAt + 3) + if (i != _stopSpinnerAt + 4) { _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerFiller, true); } @@ -126,7 +126,6 @@ public class SpinGui extends SimpleGui _ticksThisSwap = 0; _swapCount++; - updateGui(); if(_pitch == 1) _pitch = (float) 1.5; else if(_pitch == 1.5) @@ -138,6 +137,8 @@ public class SpinGui extends SimpleGui _currentRewardIndex++; + updateGui(); + // Slow _ticksPerSwap = _ticks.get(_currentRewardIndex - 1); From 1c484367a136547616b5d21859eb7b88efa823fb Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Tue, 11 Aug 2015 04:57:45 -0500 Subject: [PATCH 64/72] Add hasPoll --- .../src/mineplex/core/bonuses/BonusManager.java | 2 +- .../Mineplex.Core/src/mineplex/core/poll/PollManager.java | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index ecdd769fd..e262083a0 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -1022,7 +1022,7 @@ public class BonusManager extends MiniClientPlugin implements I { if (Recharge.Instance.use(player, "Carl Inform", 240000, false, false)) { - if(_pollManager.Get(player).shouldPoll() || canVote(player) || canRank(player) || canDaily(player)) + if(_pollManager.hasPoll(player) || canVote(player) || canRank(player) || canDaily(player)) { if(_showCarl.containsKey(player.getName())) UtilPlayer.message(player, C.cDGreen + C.Bold + "Carl the Creeper)" + C.cGreen + " Hey " + player.getName().replace("s", "sss") + "! I have sssome amazing rewardsss for you! Come sssee me!"); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/poll/PollManager.java b/Plugins/Mineplex.Core/src/mineplex/core/poll/PollManager.java index 5fa00cf3d..fa0b5daa0 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/poll/PollManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/poll/PollManager.java @@ -99,6 +99,11 @@ public class PollManager extends MiniDbClientPlugin return null; } + public boolean hasPoll(Player player) + { + return getNextPoll(Get(player), getClientManager().Get(player).GetRank()) != null; + } + public void displayPoll(Player player, Poll poll) { String[] answers = poll.getAnswers(); From c82152324032c812eb06e64a3f0b3c6061081ac6 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 11 Aug 2015 12:04:54 +0200 Subject: [PATCH 65/72] removed vote broadcast. --- .../src/mineplex/core/bonuses/BonusManager.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index ecdd769fd..380a909e7 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -289,15 +289,7 @@ public class BonusManager extends MiniClientPlugin implements I if (!_enabled) return; - - if(_pendingExplosions.get(0) instanceof String - && !((String)_pendingExplosions.get(0)).contentEquals("RANK") - && !((String)_pendingExplosions.get(0)).contentEquals("DAILY") - && !((String)_pendingExplosions.get(0)).contentEquals("VOTE")) - { - String name = (String)_pendingExplosions.get(0); - Bukkit.broadcastMessage("Recieved Vote: " + name); - } + _explode = System.currentTimeMillis(); _animation.setTicks(0); _canVote = false; From 2d7d7f6ddecd123578116d7e2bb34897260578e9 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 11 Aug 2015 13:01:20 +0200 Subject: [PATCH 66/72] Improving messages, animations and some Items. --- .../src/mineplex/core/bonuses/BonusManager.java | 15 ++++++++++++--- .../core/bonuses/animations/AnimationCarl.java | 6 +++--- .../core/bonuses/commands/GuiCommand.java | 2 +- .../bonuses/gui/buttons/DailyBonusButton.java | 1 + .../core/bonuses/gui/buttons/RankBonusButton.java | 3 ++- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 8fd3d6d54..a719ba172 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -59,6 +59,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.java.JavaPlugin; @@ -267,7 +268,8 @@ public class BonusManager extends MiniClientPlugin implements I public void run() { addPendingExplosion(player, player.getName()); - UtilPlayer.message(player, F.main("Vote", "Thanks for your vote!")); + UtilPlayer.message(player, F.main("Carl", "Thanks for voting for Mineplex!")); + UtilPlayer.message(player, F.main("Carl", "You received 500 Gems and 1 Carls Spinner Ticket!")); } }); } @@ -362,7 +364,6 @@ public class BonusManager extends MiniClientPlugin implements I return; ((CraftEntity)_carlNpc.getEntity()).getHandle().getDataWatcher().watch(16, -1); - ((CraftEntity)_carlNpc.getEntity()).getHandle().getDataWatcher().watch(17, 1); } public void IncreaseSize(Entity player) @@ -758,6 +759,8 @@ public class BonusManager extends MiniClientPlugin implements I _statsManager.incrementStat(player, "Global.ExpEarned", experience); UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(experience + " Experience"))); } + + UtilPlayer.message(player, F.main("Carl", "Come back tomorrow for more!")); } @@ -1004,6 +1007,12 @@ public class BonusManager extends MiniClientPlugin implements I }, 200); } + @EventHandler + public void Quit(PlayerQuitEvent event) + { + _showCarl.remove(event.getPlayer().getName()); + } + @EventHandler public void carlUpdate(UpdateEvent event) { @@ -1017,7 +1026,7 @@ public class BonusManager extends MiniClientPlugin implements I if(_pollManager.hasPoll(player) || canVote(player) || canRank(player) || canDaily(player)) { if(_showCarl.containsKey(player.getName())) - UtilPlayer.message(player, C.cDGreen + C.Bold + "Carl the Creeper)" + C.cGreen + " Hey " + player.getName().replace("s", "sss") + "! I have sssome amazing rewardsss for you! Come sssee me!"); + UtilPlayer.message(player, C.cDGreen + C.Bold + "Carl the Creeper>" + C.cGreen + " Hey " + player.getName().replace("s", "sss") + "! I have sssome amazing rewardsss for you! Come sssee me!"); } } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java index a98977521..0fc8fd838 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java @@ -48,7 +48,7 @@ public class AnimationCarl extends Animation { if(((String) _type).contentEquals("DAILY")) { - for (int i = 1; i < 40; i++) + for (int i = 1; i < 8; i++) { Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, " " + i)); Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, " " + i)); @@ -61,7 +61,7 @@ public class AnimationCarl extends Animation } if(((String) _type).contentEquals("RANK")) { - for (int i = 1; i < 50; i++) + for (int i = 1; i < 8; i++) { Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, " " + i)); Vector vel = new Vector(Math.sin(i * 7/5d), 0, Math.cos(i * 7/5d)); @@ -71,7 +71,7 @@ public class AnimationCarl extends Animation } if(!((String) _type).contentEquals("DAILY")&& !((String) _type).contentEquals("RANK")) { - for (int i = 1; i < 40; i++) + for (int i = 1; i < 8; i++) { Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, " " + i)); Item paper = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.PAPER, (byte) 0, 1, " " + i)); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/GuiCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/GuiCommand.java index c3ef35edd..ccc55a251 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/GuiCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/GuiCommand.java @@ -11,7 +11,7 @@ public class GuiCommand extends CommandBase{ public GuiCommand(BonusManager plugin) { - super(plugin, Rank.ALL, "bonus"); + super(plugin, Rank.DEVELOPER, "bonus"); } @Override diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java index 8efb10fa5..76d58c807 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java @@ -96,6 +96,7 @@ public class DailyBonusButton implements GuiItem, Listener } getPlayer().playSound(getPlayer().getLocation(), Sound.ENDERDRAGON_GROWL, 1, 10); } + getPlayer().closeInventory(); } }); } else diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java index 501840411..fe3e20322 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java @@ -114,6 +114,7 @@ public class RankBonusButton implements GuiItem, Listener { } getPlayer().playSound(getPlayer().getLocation(), Sound.ENDERDRAGON_GROWL, 1, 10); } + getPlayer().closeInventory(); } }); } else @@ -177,7 +178,7 @@ public class RankBonusButton implements GuiItem, Listener { } lore.add(" "); - + lore.add(C.cYellow + "Rank:" + C.cWhite + _bonusManager.getClientManager().Get(_player).GetRank().Name); BonusAmount bonusAmount = _bonusManager.getRankBonusAmount(_player); bonusAmount.addLore(lore); } From 49d54d4dd395bdd4fb231ae91d89357bab264a5f Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 13:22:58 +0200 Subject: [PATCH 67/72] doesnt count rank thingy as reward if no rank. yknow --- .../Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index a719ba172..3985cc1d3 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -835,7 +835,7 @@ public class BonusManager extends MiniClientPlugin implements I int availableRewards = 0; if (canVote(player)) availableRewards++; - if (canRank(player)) availableRewards++; + if (canRank(player) && _clientManager.hasRank(player, Rank.ULTRA)) availableRewards++; if (canDaily(player)) availableRewards++; if (getPollManager().getNextPoll(_pollManager.Get(player), _clientManager.Get(player).GetRank()) != null) availableRewards++; From cfcfbbed3bc9d5fc979b5739df94f581e30c81a6 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 13:34:32 +0200 Subject: [PATCH 68/72] removed double gem --- .../src/nautilus/game/arcade/managers/GameGemManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameGemManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameGemManager.java index 07bb93f7a..53f8173c3 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameGemManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameGemManager.java @@ -36,7 +36,7 @@ public class GameGemManager implements Listener { ArcadeManager Manager; - boolean DoubleGem = true; + boolean DoubleGem = false; public GameGemManager(ArcadeManager manager) { From e25558fc91f88b77c7359a2d9002c980538573c3 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 11 Aug 2015 13:49:06 +0200 Subject: [PATCH 69/72] Animation improvements. --- .../mineplex/core/bonuses/BonusManager.java | 4 +++ .../bonuses/animations/AnimationCarl.java | 31 ++++++++++--------- .../core/bonuses/gui/buttons/PollButton.java | 2 +- .../bonuses/gui/buttons/RankBonusButton.java | 2 +- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index a719ba172..af93fc985 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -50,6 +50,7 @@ import mineplex.serverdata.commands.ServerCommandManager; import org.jooq.SQLDialect; import org.jooq.impl.DSL; import org.bukkit.Bukkit; +import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.block.Dropper; import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; @@ -984,6 +985,9 @@ public class BonusManager extends MiniClientPlugin implements I if(!(entity instanceof Item)) continue; + if(((Item)entity).getItemStack().getType() == Material.MONSTER_EGG) + entity.remove(); + if(!((Item) entity).getItemStack().hasItemMeta()) continue; diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java index 0fc8fd838..160b2e14c 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java @@ -4,6 +4,7 @@ import java.util.Random; import mineplex.core.common.util.UtilAction; import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilMath; import mineplex.core.common.util.UtilParticle; import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilParticle.ViewDist; @@ -46,39 +47,41 @@ public class AnimationCarl extends Animation { if(_type instanceof String) { - if(((String) _type).contentEquals("DAILY")) + if(((String) _type).contentEquals("DAILY") || ((String) _type).contentEquals("POLL")) { - for (int i = 1; i < 8; i++) + for (int i = 50; i < 60; i++) { Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, " " + i)); Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, " " + i)); Vector vel = new Vector(Math.sin(i * 9/5d), 0, Math.cos(i * 9/5d)); - UtilAction.velocity(gem, vel, Math.abs(Math.sin(i * 9/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 9/3000d))*0.6, 1, false); - UtilAction.velocity(coin, vel, Math.abs(Math.sin(i * 9/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 9/3000d))*0.6, 1, false); + UtilAction.velocity(gem, vel, Math.abs(Math.sin(i * 12/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 12/3000d))*0.6, 1, false); + UtilAction.velocity(coin, vel, Math.abs(Math.sin(UtilMath.r(i) * 30/3000d)), false, 0, 0.2 + Math.abs(Math.cos(UtilMath.r(i) * 30/3000d))*0.6, 1, false); coin.setTicksLived(1160); gem.setTicksLived(1160); } } if(((String) _type).contentEquals("RANK")) { - for (int i = 1; i < 8; i++) + for (int i = 50; i < 60; i++) { Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, " " + i)); - Vector vel = new Vector(Math.sin(i * 7/5d), 0, Math.cos(i * 7/5d)); - UtilAction.velocity(coin, vel, Math.abs(Math.sin(i * 7/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 7/3000d))*0.6, 1, false); + Vector vel = new Vector(Math.sin(UtilMath.r(i) * 7/5d), 0, Math.cos(UtilMath.r(i) * 7/5d)); + UtilAction.velocity(coin, vel, Math.abs(Math.sin(UtilMath.r(i) * 7/3000d)), false, 0, 0.2 + Math.abs(Math.cos(UtilMath.r(i) * 7/3000d))*0.6, 1, false); coin.setTicksLived(1160); } } - if(!((String) _type).contentEquals("DAILY")&& !((String) _type).contentEquals("RANK")) + if(!((String) _type).contentEquals("DAILY")&& !((String) _type).contentEquals("RANK")&& !((String) _type).contentEquals("POLL")) { - for (int i = 1; i < 8; i++) + + Item paper = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.PAPER, (byte) 0, 1, " " + 64)); + Vector vel = new Vector(Math.sin(64 * 8/5d), 0, Math.cos(64 * 8/5d)); + UtilAction.velocity(paper, vel, Math.abs(Math.sin(64 * 9/3000d)), false, 0, 0.2 + Math.abs(Math.cos(64 + 9/3000d))*0.6, 1, false); + paper.setTicksLived(1160); + for (int i = 50; i < 60; i++) { Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, " " + i)); - Item paper = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.PAPER, (byte) 0, 1, " " + i)); - Vector vel = new Vector(Math.sin(i * 8/5d), 0, Math.cos(i * 8/5d)); - UtilAction.velocity(gem, vel, Math.abs(Math.sin(i * 8/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i + 8/3000d))*0.6, 1, false); - UtilAction.velocity(paper, vel, Math.abs(Math.sin(i * 9/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i + 9/3000d))*0.6, 1, false); - paper.setTicksLived(1160); + Vector velo = new Vector(Math.sin(i * 8/5d), 0, Math.cos(i * 8/5d)); + UtilAction.velocity(gem, velo, Math.abs(Math.sin(i * 8/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i + 8/3000d))*0.6, 1, false); gem.setTicksLived(1160); } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java index 417a6b556..8124e6292 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java @@ -194,7 +194,7 @@ public class PollButton extends SimpleGui implements GuiItem { getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); new TimedMessageWindow(getPlugin(), getPlayer(), ItemStackFactory.Instance.CreateStack(Material.EMERALD_BLOCK, (byte) 0, 1, ChatColor.GREEN + "Your anwser:", wrap(getPoll().getAnswers()[num])), ChatColor.GREEN + "Moo", 6 * 9, 50, getMaster()).openInventory(); - _bonusManager.addPendingExplosion(getPlayer(), "VOTE"); + _bonusManager.addPendingExplosion(getPlayer(), "POLL"); getPlayer().closeInventory(); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java index fe3e20322..489b257fd 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java @@ -178,7 +178,7 @@ public class RankBonusButton implements GuiItem, Listener { } lore.add(" "); - lore.add(C.cYellow + "Rank:" + C.cWhite + _bonusManager.getClientManager().Get(_player).GetRank().Name); + lore.add(C.cYellow + "Rank: " + C.cWhite + _bonusManager.getClientManager().Get(_player).GetRank().Name); BonusAmount bonusAmount = _bonusManager.getRankBonusAmount(_player); bonusAmount.addLore(lore); } From f7d94761911c46fb371b7da592f3e2765cda20f2 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 11 Aug 2015 13:53:36 +0200 Subject: [PATCH 70/72] Hidden egg fix --- .../Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 176057ab7..fe37f5a42 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -985,7 +985,7 @@ public class BonusManager extends MiniClientPlugin implements I if(!(entity instanceof Item)) continue; - if(((Item)entity).getItemStack().getType() == Material.MONSTER_EGG) + if(((Item)entity).getItemStack().getType() == Material.MONSTER_EGG && ((Item)entity).getItemStack().hasItemMeta() && !((Item)entity).getItemStack().getItemMeta().getDisplayName().startsWith("Hidden")) entity.remove(); if(!((Item) entity).getItemStack().hasItemMeta()) From 89dab7ec8531ca4885e9f6725e0e8076abf2c60c Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 16:33:32 +0200 Subject: [PATCH 71/72] some little fixes --- .../mineplex/core/gadget/GadgetManager.java | 2 +- .../core/gadget/gadgets/ItemPaintballGun.java | 39 ------------------- .../gui/privateServer/page/MenuPage.java | 4 +- .../game/arcade/managers/GameChatManager.java | 4 +- .../game/arcade/managers/GameHostManager.java | 8 +++- 5 files changed, 11 insertions(+), 46 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java index 3c518f35a..54a3ea799 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java @@ -92,7 +92,7 @@ public class GadgetManager extends MiniPlugin addGadget(new ItemTNT(this)); addGadget(new ItemMelonLauncher(this)); addGadget(new ItemFleshHook(this)); - //addGadget(new ItemPaintballGun(this)); + addGadget(new ItemPaintballGun(this)); addGadget(new ItemBatGun(this)); addGadget(new ItemCoinBomb(this)); addGadget(new ItemPaintbrush(this)); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintballGun.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintballGun.java index 34d4ed557..e1b1b6c39 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintballGun.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintballGun.java @@ -61,45 +61,6 @@ public class ItemPaintballGun extends ItemGadget Location loc = event.getEntity().getLocation().add(event.getEntity().getVelocity()); loc.getWorld().playEffect(loc, Effect.STEP_SOUND, 49); - - byte color = 2; - double r = Math.random(); - if (r > 0.8) color = 4; - else if (r > 0.6) color = 5; - else if (r > 0.4) color = 9; - else if (r > 0.2) color = 14; - - for (Block block : UtilBlock.getInRadius(loc, 3d).keySet()) - { - if (block.getType() == Material.PORTAL) - return; - - if (block.getType() == Material.CACTUS) - return; - - if (block.getType() == Material.SUGAR_CANE_BLOCK) - return; - } - - List blocks = new ArrayList(); - blocks.addAll(UtilBlock.getInRadius(loc, 1.5d).keySet()); - - GadgetBlockEvent gadgetEvent = new GadgetBlockEvent(this, blocks); - Bukkit.getServer().getPluginManager().callEvent(gadgetEvent); - - if (gadgetEvent.isCancelled()) - return; - - for (Block block : gadgetEvent.getBlocks()) - { - if (!UtilBlock.solid(block)) - continue; - - if (block.getType() == Material.CARPET) - Manager.getBlockRestore().Add(block, 171, color, 4000); - else - Manager.getBlockRestore().Add(block, 35, color, 4000); - } } @EventHandler diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gui/privateServer/page/MenuPage.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gui/privateServer/page/MenuPage.java index c24a31d78..26adc68ba 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gui/privateServer/page/MenuPage.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gui/privateServer/page/MenuPage.java @@ -89,10 +89,10 @@ public class MenuPage extends BasePage if (host) { GiveAdminButton giveAdminButton = new GiveAdminButton(getPlugin(), getShop()); - addButton(4 + 9, new ShopItem(Material.DIAMOND_SWORD, "Give Admin", new String[]{}, 1, false), giveAdminButton); + addButton(4 + 9, new ShopItem(Material.DIAMOND_SWORD, "Give Co-Host", new String[]{}, 1, false), giveAdminButton); RemoveAdminButton removeAdminButton = new RemoveAdminButton(getPlugin(), getShop()); - addButton(4 + 18, new ShopItem(Material.GOLD_SWORD, "Remove Admin", new String[]{}, 1, false), removeAdminButton); + addButton(4 + 18, new ShopItem(Material.GOLD_SWORD, "Remove Co-Host", new String[]{}, 1, false), removeAdminButton); KillButton killButton = new KillButton(getPlugin()); addButton(8 + 18, new ShopItem(Material.TNT, "Kill Private Server", diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameChatManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameChatManager.java index 4aed91a8a..5f949845c 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameChatManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameChatManager.java @@ -90,9 +90,9 @@ public class GameChatManager implements Listener else if (Manager.GetGameHostManager().isAdmin(event.getPlayer(), false)) { if (Manager.GetGameHostManager().isEventServer()) - rankStr = C.cDGreen + C.Bold + "Event Admin "; + rankStr = C.cDGreen + C.Bold + "Event Co-Host "; else - rankStr = C.cDGreen + C.Bold + "MPS Admin "; + rankStr = C.cDGreen + C.Bold + "MPS Co-Host "; } else { diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java index 2dfc1c151..20a10ed71 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java @@ -230,6 +230,10 @@ public class GameHostManager implements Listener _hostRank = Manager.GetClients().Get(_host).GetRank(); System.out.println("Game Host Joined."); + //Limit player count! + if (Manager.GetServerConfig().MaxPlayers > getMaxPlayerCap()) + Manager.GetServerConfig().MaxPlayers = getMaxPlayerCap(); + if (isEventServer()) worldeditPermissionSet(event.getPlayer(), true); } @@ -642,7 +646,7 @@ public class GameHostManager implements Listener { _adminList.add(player.getName()); _onlineAdmins.add(player); - UtilPlayer.message(player, F.main("Server", "You were given admin privileges.")); + UtilPlayer.message(player, F.main("Server", "You were given Co-Host privileges.")); if (isEventServer()) worldeditPermissionSet(player, true); @@ -660,7 +664,7 @@ public class GameHostManager implements Listener { player.closeInventory(); } - UtilPlayer.message(player, F.main("Server", "Your admin privileges were removed.")); + UtilPlayer.message(player, F.main("Server", "Your Co-Host privileges were removed.")); player.setGameMode(GameMode.SURVIVAL); From 83a010c2151bd0dcec7179ca69b957195abbdd81 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 17:05:41 +0200 Subject: [PATCH 72/72] enabled summer sale msg --- .../mineplex/core/notifier/NotificationManager.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/notifier/NotificationManager.java b/Plugins/Mineplex.Core/src/mineplex/core/notifier/NotificationManager.java index 342d7b840..a2214adb2 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/notifier/NotificationManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/notifier/NotificationManager.java @@ -42,8 +42,8 @@ public class NotificationManager extends MiniPlugin if (!_enabled) return; -// if (event.getType() == UpdateType.MIN_08) -// hugeSale(); + if (event.getType() == UpdateType.MIN_08) + hugeSale(); // if (event.getType() == UpdateType.MIN_16) // sale(); @@ -95,17 +95,17 @@ public class NotificationManager extends MiniPlugin if (rank == Rank.ALL) { UtilPlayer.message(player, C.cWhite + " " + player.getName() + ", you can get 75% Off " + C.cAqua + C.Bold + "All Lifetime Ranks" + C.cWhite + "!"); - UtilPlayer.message(player, C.cWhite + " This is our biggest sale ever, available " + C.cRed + C.Line + "this weekend only" + C.cWhite + "!"); + UtilPlayer.message(player, C.cWhite + " This is our biggest sale ever, " + C.cRed + C.Line + "ends Sunday 16th" + C.cWhite + "!"); } else if (rank == Rank.ULTRA) { UtilPlayer.message(player, C.cWhite + " Hello " + player.getName() + ", upgrade to " + C.cPurple + C.Bold + "HERO RANK" + C.cWhite + " for only $7.50!"); - UtilPlayer.message(player, C.cWhite + " This is our biggest sale ever, available " + C.cRed + C.Line + "this weekend only" + C.cWhite + "!"); + UtilPlayer.message(player, C.cWhite + " This is our biggest sale ever, " + C.cRed + C.Line + "ends Sunday 16th" + C.cWhite + "!"); } else if (rank == Rank.HERO) { UtilPlayer.message(player, C.cWhite + " Hello " + player.getName() + ", upgrade to " + C.cGreen + C.Bold + "LEGEND RANK" + C.cWhite + " for only $7.50!"); - UtilPlayer.message(player, C.cWhite + " This is our biggest sale ever, available " + C.cRed + C.Line + "this weekend only" + C.cWhite + "!"); + UtilPlayer.message(player, C.cWhite + " This is our biggest sale ever, " + C.cRed + C.Line + "ends Sunday 16th" + C.cWhite + "!"); } UtilPlayer.message(player, " ");