diff --git a/src/main/java/com/songoda/ultimatekits/UltimateKits.java b/src/main/java/com/songoda/ultimatekits/UltimateKits.java index 7c60a5a..f5819ee 100644 --- a/src/main/java/com/songoda/ultimatekits/UltimateKits.java +++ b/src/main/java/com/songoda/ultimatekits/UltimateKits.java @@ -483,6 +483,10 @@ public class UltimateKits extends SongodaPlugin { return commandManager; } + public GuiManager getGuiManager() { + return guiManager; + } + /** * Grab instance of the item serializer * diff --git a/src/main/java/com/songoda/ultimatekits/animation/Animation.java b/src/main/java/com/songoda/ultimatekits/animation/Animation.java deleted file mode 100644 index a3be5ea..0000000 --- a/src/main/java/com/songoda/ultimatekits/animation/Animation.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.songoda.ultimatekits.animation; - -public abstract class Animation { - - public abstract void start(); - public abstract void stop(); - public abstract boolean isDone(); - public abstract void tick(); -} diff --git a/src/main/java/com/songoda/ultimatekits/animation/RouletteAnimation.java b/src/main/java/com/songoda/ultimatekits/animation/RouletteAnimation.java deleted file mode 100644 index 8bc5d02..0000000 --- a/src/main/java/com/songoda/ultimatekits/animation/RouletteAnimation.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.songoda.ultimatekits.animation; - -public class RouletteAnimation extends Animation { - - boolean _done = false; - @Override - public void start() { - } - - @Override - public void stop() { - } - - @Override - public boolean isDone() { - return _done; - } - - @Override - public void tick() { - } - -} diff --git a/src/main/java/com/songoda/ultimatekits/gui/AnimatedKitGui.java b/src/main/java/com/songoda/ultimatekits/gui/AnimatedKitGui.java index 665c9bc..dfcabd0 100644 --- a/src/main/java/com/songoda/ultimatekits/gui/AnimatedKitGui.java +++ b/src/main/java/com/songoda/ultimatekits/gui/AnimatedKitGui.java @@ -1,14 +1,129 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ package com.songoda.ultimatekits.gui; -/** - * - * @author Jacob - */ -public class AnimatedKitGui { - +import com.songoda.core.compatibility.CompatibleMaterial; +import com.songoda.core.compatibility.CompatibleSound; +import com.songoda.core.gui.Gui; +import com.songoda.core.gui.GuiUtils; +import com.songoda.ultimatekits.UltimateKits; +import com.songoda.ultimatekits.kit.Kit; +import com.songoda.ultimatekits.kit.KitItem; +import com.songoda.ultimatekits.settings.Settings; +import com.songoda.ultimatekits.utils.ArmorType; +import java.util.ArrayDeque; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; +import org.apache.commons.lang.WordUtils; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class AnimatedKitGui extends Gui { + + static final Random rand = new Random(); + + private final UltimateKits plugin; + private final Player player; + private final ItemStack give; + private final ArrayDeque items = new ArrayDeque(); + private boolean finish = false; + private boolean done = false; + private int tick = 0, updateTick = 0; + private int ticksPerUpdate = 4; + private final int updatesPerSlow = 5; + private final int ticksPerUpdateSlow = 15; + private int task; + + public AnimatedKitGui(UltimateKits plugin, Player player, Kit kit, ItemStack give) { + this.plugin = plugin; + this.player = player; + this.give = give; + setRows(3); + setAllowClose(false); + setTitle(kit.getShowableName()); + setDefaultItem(GuiUtils.getBorderItem(CompatibleMaterial.GRAY_STAINED_GLASS_PANE)); + + // ideally, we'd populate the items in such a way that the end item isn't far from the center when the animation is complete + // would be something to do if people have large kit loot tables. + List kitItems = kit.getContents(); + if(kitItems.isEmpty()) { + throw new RuntimeException("Cannot give an empty kit!"); + } + Collections.shuffle(kitItems); + this.items.addAll(kitItems); + while (this.items.size() < 10) { + items.addAll(kitItems); + } + + setItem(4, GuiUtils.getBorderItem(CompatibleMaterial.TRIPWIRE_HOOK)); + setItem(22, GuiUtils.getBorderItem(CompatibleMaterial.TRIPWIRE_HOOK)); + tick(); + setOnOpen(event -> { + task = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, () -> tick(), 1L, 5L); + }); + } + + void tick() { + if (++tick < ticksPerUpdate) { + return; + } + tick = 0; + if (++updateTick >= updatesPerSlow) { + updateTick = 0; + if (++ticksPerUpdate >= ticksPerUpdateSlow) { + finish = true; + } + } + // now update the display + // rainbow disco! + for (int col = 0; col < 9; ++col) { + if(col == 4) continue; + setItem(0, col, GuiUtils.getBorderItem(CompatibleMaterial.getGlassPaneColor(rand.nextInt(16)))); + setItem(2, col, GuiUtils.getBorderItem(CompatibleMaterial.getGlassPaneColor(rand.nextInt(16)))); + } + + // item slider + if (!done) { + CompatibleSound.UI_BUTTON_CLICK.play(player, 5F, 5F); + items.addFirst(items.getLast()); + items.removeLast(); + Iterator itemIter = items.iterator(); + for (int i = 0; i < 9; i++) { + setItem(0, i, itemIter.next().getItem()); + } + } + + // should we try to wrap it up? + if (finish) { + ItemStack item = getItem(13); + if(item == null) { + done = true; // idk. + } else if (item.isSimilar(give)) { + if (!done) { + done = true; + if (!Settings.AUTO_EQUIP_ARMOR_ROULETTE.getBoolean() || !ArmorType.equip(player, give)) { + Map overfilled = player.getInventory().addItem(give); + for (ItemStack item2 : overfilled.values()) { + player.getWorld().dropItemNaturally(player.getLocation(), item2); + } + } + + CompatibleSound.ENTITY_PLAYER_LEVELUP.play(player, 10f, 10f); + plugin.getLocale().getMessage("event.create.won") + .processPlaceholder("item", WordUtils.capitalize(give.getType().name().toLowerCase().replace("_", " "))) + .sendPrefixedMessage(player); + Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, this::finish, 50); + setAllowClose(true); + } + + } + } + + } + private void finish() { + Bukkit.getScheduler().cancelTask(task); + exit(); + } } diff --git a/src/main/java/com/songoda/ultimatekits/kit/Kit.java b/src/main/java/com/songoda/ultimatekits/kit/Kit.java index d5ea319..7398fc2 100644 --- a/src/main/java/com/songoda/ultimatekits/kit/Kit.java +++ b/src/main/java/com/songoda/ultimatekits/kit/Kit.java @@ -8,6 +8,7 @@ import com.songoda.core.gui.GuiManager; import com.songoda.core.hooks.EconomyManager; import com.songoda.core.utils.TextUtils; import com.songoda.ultimatekits.UltimateKits; +import com.songoda.ultimatekits.gui.AnimatedKitGui; import com.songoda.ultimatekits.gui.PreviewKitGui; import com.songoda.ultimatekits.gui.ConfirmBuyGui; import com.songoda.ultimatekits.key.Key; @@ -15,7 +16,6 @@ import com.songoda.ultimatekits.kit.type.KitContentCommand; import com.songoda.ultimatekits.kit.type.KitContentEconomy; import com.songoda.ultimatekits.kit.type.KitContentItem; import com.songoda.ultimatekits.settings.Settings; -import com.songoda.ultimatekits.tasks.CrateAnimateTask; import com.songoda.ultimatekits.utils.ArmorType; import com.songoda.ultimatekits.utils.Methods; import org.bukkit.Bukkit; @@ -294,14 +294,12 @@ public class Kit { } private boolean generateRandomItem(List innerContents, int amtToGive, Player player, int forceSelect) { - boolean chosenItem = false; int canChoose = 0; for (KitItem item : innerContents) { - if (amtToGive == 0) continue; + if (amtToGive == 0) break; int ch = canChoose++ == forceSelect || item.getChance() == 0 ? 100 : item.getChance(); double rand = Math.random() * 100; if (rand - ch < 0 || ch == 100) { - chosenItem = true; if (item.getContent() instanceof KitContentEconomy) { try { @@ -340,7 +338,9 @@ public class Kit { amtToGive--; if (kitAnimation != KitAnimation.NONE) { - new CrateAnimateTask(plugin, player, this, item.getItem()); + // TODO: this is a very bad way to solve this problem. + // Giving the player kit rewards really should be done outside of the Kit class. + plugin.getGuiManager().showGUI(player, new AnimatedKitGui(plugin, player, this, item.getItem())); return true; } else { if (Settings.AUTO_EQUIP_ARMOR.getBoolean() && ArmorType.equip(player, item.getItem())) continue; @@ -353,9 +353,9 @@ public class Kit { } } - if (!chosenItem && canChoose != 0 && forceSelect == -1) { + if (amtToGive != 0 && canChoose != 0 && forceSelect == -1) { return generateRandomItem(innerContents, amtToGive, player, (int) (Math.random() * canChoose)); - } else if (!chosenItem) { + } else if (amtToGive != 0) { return false; } diff --git a/src/main/java/com/songoda/ultimatekits/tasks/CrateAnimateTask.java b/src/main/java/com/songoda/ultimatekits/tasks/CrateAnimateTask.java deleted file mode 100644 index 8fa1db7..0000000 --- a/src/main/java/com/songoda/ultimatekits/tasks/CrateAnimateTask.java +++ /dev/null @@ -1,140 +0,0 @@ -package com.songoda.ultimatekits.tasks; - -import com.songoda.ultimatekits.UltimateKits; -import com.songoda.ultimatekits.kit.Kit; -import com.songoda.ultimatekits.kit.KitItem; -import com.songoda.ultimatekits.utils.ArmorType; -import com.songoda.ultimatekits.utils.Methods; -import com.songoda.ultimatekits.settings.Settings; -import org.apache.commons.lang.WordUtils; -import org.bukkit.Bukkit; -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.InventoryClickEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.scheduler.BukkitRunnable; - -import java.util.*; - -public class CrateAnimateTask extends BukkitRunnable { - - private final UltimateKits plugin; - private final Player player; - private final Inventory inventory; - private final ArrayDeque items; - private final ItemStack give; - private CrateAnimateTask instance; - private boolean slow = false; - private boolean finish = false; - private boolean done = false; - private int num = 0; - - private Listener listener; - - public CrateAnimateTask(UltimateKits plugin, Player player, Kit kit, ItemStack give) { - this.plugin = plugin; - this.player = player; - this.give = give; - this.inventory = Bukkit.createInventory(null, 27, kit.getShowableName()); - - List items = kit.getContents(); - Collections.shuffle(items); - this.items = new ArrayDeque<>(items); - while (this.items.size() < 10) { - for (KitItem item : items) { - if (this.items.size() < 10) - this.items.addLast(item); - } - } - - this.listener = new Listener() { - @EventHandler - public void onInventoryClick(InventoryClickEvent event) { - if (!(event.getWhoClicked() instanceof Player) || event.getWhoClicked() != player) return; - - event.setCancelled(true); - } - }; - - Bukkit.getPluginManager().registerEvents(listener, UltimateKits.getInstance()); - start(); - } - - private void start() { - if (instance == null) instance = this; - instance.runTaskTimer(plugin, 0, 3); - - Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () -> { - slow = true; - Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () -> finish = true, 20); - }, 60); - } - - @Override - public void run() { - if (slow && num == 1) { - num = 0; - return; - } - num = slow ? 1 : 0; - - for (int i = 0; i < 27; i++) { - inventory.setItem(i, Methods.getGlass(true, 0)); - } - - for (int i = 9; i < 18; i++) { - inventory.setItem(i, new ItemStack(plugin.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) ? Material.GRAY_STAINED_GLASS_PANE : Material.valueOf("STAINED_GLASS_PANE"))); - } - - - inventory.setItem(4, new ItemStack(Material.TRIPWIRE_HOOK)); - inventory.setItem(22, new ItemStack(Material.TRIPWIRE_HOOK)); - - if (!done) { - player.playSound(player.getLocation(), plugin.getInstance().isServerVersionAtLeast(ServerVersion.V1_9) ? Sound.UI_BUTTON_CLICK : Sound.valueOf("CLICK"), 5f, 5f); - this.items.addFirst(this.items.getLast()); - this.items.removeLast(); - } - - List items = new ArrayList<>(this.items); - for (int i = 0; i < 9; i++) { - inventory.setItem(9 + i, items.get(i).getItem()); - } - - if (finish) { - if (inventory.getItem(13).isSimilar(give)) { - if (!done) { - if (!Settings.AUTO_EQUIP_ARMOR_ROULETTE.getBoolean() - || !ArmorType.equip(player, give)) { - Map overfilled = player.getInventory().addItem(give); - for (ItemStack item2 : overfilled.values()) { - player.getWorld().dropItemNaturally(player.getLocation(), item2); - } - } - - player.playSound(player.getLocation(), UltimateKits.getInstance().isServerVersionAtLeast(ServerVersion.V1_9) ? Sound.ENTITY_PLAYER_LEVELUP : Sound.valueOf("LEVEL_UP"), 10f, 10f); - plugin.getLocale().getMessage("event.create.won") - .processPlaceholder("item", WordUtils.capitalize(give.getType().name().toLowerCase().replace("_", " "))) - .sendPrefixedMessage(player); - Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, this::finish, 50); - } - done = true; - - } - } - player.openInventory(inventory); - - } - - private void finish() { - instance.cancel(); - HandlerList.unregisterAll(listener); - listener = null; - player.closeInventory(); - } -} \ No newline at end of file