From 3fab186c09fbc31096cc9199ab74fcf033395dce Mon Sep 17 00:00:00 2001 From: AlexTheCoder Date: Wed, 6 Sep 2017 04:48:12 -0400 Subject: [PATCH] Implement supply drops --- .../game/clans/clans/ClansManager.java | 2 +- .../game/clans/clans/loot/LootManager.java | 7 +- .../clans/clans/supplyDrop/SupplyDrop.java | 246 ++++++++------- .../clans/supplyDrop/SupplyDropManager.java | 286 ++++++++++++------ 4 files changed, 328 insertions(+), 213 deletions(-) diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java index 52928ef33..8c739a2a3 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java @@ -326,7 +326,7 @@ public class ClansManager extends MiniClientPlugin implements IRelat _tutorial = new TutorialManager(plugin, clientManager, donationManager, chat, hologramManager, this, _npcManager, _taskManager); // _itemMapManager = new ItemMapManager(this, _tutorial, _worldEvent); new TntGeneratorManager(plugin, this); - new SupplyDropManager(plugin, this); + new SupplyDropManager(plugin); new InvseeManager(this); new MenuManager(plugin); diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/LootManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/LootManager.java index d6186d980..ee83dac4f 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/LootManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/LootManager.java @@ -25,8 +25,11 @@ public class LootManager _gearManager = gearManager; _goldManager = goldManager; - _commonSet = new WeightSet(); - _rareSet = new WeightSet(); + _commonSet = new WeightSet<>(); + _rareSet = new WeightSet<>(); + _bossSet = new WeightSet<>(); + _undeadCitySet = new WeightSet<>(); + _raidSet = new WeightSet<>(); populateCommon(); populateRare(); diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/supplyDrop/SupplyDrop.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/supplyDrop/SupplyDrop.java index 9aa27baff..1d9989549 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/supplyDrop/SupplyDrop.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/supplyDrop/SupplyDrop.java @@ -1,91 +1,172 @@ package mineplex.game.clans.clans.supplyDrop; import java.lang.reflect.Field; -import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; import org.bukkit.Bukkit; +import org.bukkit.Chunk; import org.bukkit.Color; import org.bukkit.FireworkEffect; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.Chest; import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.Pair; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.hologram.Hologram; +import mineplex.core.hologram.HologramManager; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.supplyDrop.SupplyDropManager.SupplyDropType; import net.minecraft.server.v1_8_R3.BlockPosition; import net.minecraft.server.v1_8_R3.TileEntity; import net.minecraft.server.v1_8_R3.TileEntityBeacon; -import mineplex.core.common.util.C; -import mineplex.core.common.util.UtilFirework; -import mineplex.core.common.util.UtilTime; -import mineplex.core.hologram.Hologram; -import mineplex.core.hologram.HologramManager; -import mineplex.game.clans.clans.ClansManager; - -public class SupplyDrop implements Listener +public class SupplyDrop { - private static int DROP_TICKS = 20 * 10; - private static int REMOVE_TICKS = DROP_TICKS + (20 * 120); // 2 Minutes - public static Material SUPPLY_DROP_MATERIAL = Material.BEACON; - - private ClansManager _clansManager; - - private Block _block; - private Player _owner; - private int _ticks; - private boolean _running; - private Hologram _hologram; - private Random _random; - - protected SupplyDrop(Player owner, Block block, ClansManager clansManager, HologramManager hologramManager) + private static Field BEACON_LEVEL; + private static Field BEACON_ENABLED; + + static { - _owner = owner; + try + { + BEACON_LEVEL = TileEntityBeacon.class.getDeclaredField("j"); + BEACON_LEVEL.setAccessible(true); + BEACON_ENABLED = TileEntityBeacon.class.getDeclaredField("i"); + BEACON_ENABLED.setAccessible(true); + } + catch (NoSuchFieldException | SecurityException e) + { + e.printStackTrace(); + } + } + + private static final int DROP_TICKS = 20 * 10; + private static final int REMOVE_TICKS = DROP_TICKS + (20 * 120); // 2 Minutes + public static final Material SUPPLY_DROP_MATERIAL = Material.BEACON; + + private final SupplyDropType _type; + private final mineplex.game.clans.clans.supplyDrop.SupplyDropManager.BlockPosition _position; + private final Block _block; + private final Block[] _below = new Block[9]; + @SuppressWarnings("unchecked") + private final Pair[] _oldBelow = new Pair[9]; + private int _ticks; + private boolean _ended; + private final Hologram _hologram; + + @SuppressWarnings("deprecation") + protected SupplyDrop(SupplyDropType type, Block block, HologramManager hologramManager) + { + _type = type; + _position = new mineplex.game.clans.clans.supplyDrop.SupplyDropManager.BlockPosition(block); _block = block; _ticks = 0; - _running = true; + _ended = false; _hologram = new Hologram(hologramManager, _block.getLocation().add(0.5, 1.5, 0.5)); _hologram.start(); - _random = new Random(); - _clansManager = clansManager; - - System.out.println("supply drop"); - + block.setType(SUPPLY_DROP_MATERIAL); - + + int index = 0; for (int x = -1; x <= 1; x++) { for (int z = -1; z <= 1; z++) { Block b = block.getRelative(x, -1, z); - clansManager.getBlockRestore().add(b, Material.DIAMOND_BLOCK.getId(), (byte) 0, 60000); + _below[index] = b; + _oldBelow[index] = Pair.create(b.getType(), b.getData()); + b.setType(Material.DIAMOND_BLOCK); + index++; } } } + + private String getChatColor(long millis) + { + if (millis > 30000) + { + return C.cAqua; + } + else if (millis > 10000) + { + return C.cYellow; + } + else + { + return C.cRed; + } + } + + private void placeChest() + { + _block.setType(Material.CHEST); + + ClansManager.getInstance().runSyncLater(() -> + { + Chest chest = (Chest) _block.getState(); + + Inventory inventory = chest.getBlockInventory(); + int drops = ThreadLocalRandom.current().nextInt(_type.getMinItems(), _type.getMaxItems() + 1); + + for (int i = 0; i < drops; i++) + { + ItemStack item = ClansManager.getInstance().getLootManager().getRareItemStack(); + inventory.setItem(i, item); + } + }, 5); + } + + public boolean isDropping() + { + return _ticks < DROP_TICKS; + } + + public boolean isActive() + { + return _ticks < REMOVE_TICKS && !_ended; + } + + public Chunk getChunk() + { + return _block.getChunk(); + } + + public mineplex.game.clans.clans.supplyDrop.SupplyDropManager.BlockPosition getPosition() + { + return _position; + } + + public int getTicks() + { + return _ticks; + } public void tick() { + if (_ended) + { + return; + } if (getTicks() < DROP_TICKS) { if (getTicks() == 10) { - /* try { TileEntity tileEntity = ((CraftWorld) _block.getWorld()).getHandle().getTileEntity(new BlockPosition(_block.getX(), _block.getY(), _block.getZ())); - Field k = TileEntityBeacon.class.getDeclaredField("k"); - k.setAccessible(true); - - Field l = TileEntityBeacon.class.getDeclaredField("l"); - l.setAccessible(true); if (tileEntity instanceof TileEntityBeacon) { - k.set(tileEntity, true); - l.set(tileEntity, 3); + BEACON_ENABLED.set(tileEntity, true); + BEACON_LEVEL.set(tileEntity, 3); tileEntity.update(); } } @@ -93,7 +174,6 @@ public class SupplyDrop implements Listener { e.printStackTrace(); } - */ } if (getTicks() > 15 && getTicks() % 10 == 0) @@ -105,13 +185,14 @@ public class SupplyDrop implements Listener if (getTicks() % 20 == 0) { long millis = (DROP_TICKS - getTicks()) * 50; // Multiply by 50 to convert ticks to ms - _hologram.setText(getChatColor(millis) + UtilTime.convertString(millis, 0, UtilTime.TimeUnit.SECONDS) + " Until Drop"); + _hologram.setText(getChatColor(millis) + UtilTime.MakeStr(millis) + " Until Drop"); } } else { if (getTicks() == DROP_TICKS) { + Bukkit.broadcastMessage(F.main("Supply Drop", "A supply drop has landed at " + F.elem(UtilWorld.locToStrClean(_block.getLocation())))); placeChest(); } @@ -119,7 +200,7 @@ public class SupplyDrop implements Listener if (getTicks() % 20 == 0) { long millis = (REMOVE_TICKS - getTicks()) * 50; // Multiply by 50 to convert ticks to ms - _hologram.setText(getChatColor(millis) + UtilTime.convertString(millis, 0, UtilTime.TimeUnit.SECONDS) + " Remaining"); + _hologram.setText(getChatColor(millis) + UtilTime.MakeStr(millis) + " Remaining"); } if (getTicks() >= REMOVE_TICKS) @@ -131,70 +212,15 @@ public class SupplyDrop implements Listener _ticks++; } - private void placeChest() + @SuppressWarnings("deprecation") + public void finish() { - getBlock().setType(Material.CHEST); - - _clansManager.runSyncLater(new Runnable() - { - @Override - public void run() - { - Chest chest = (Chest) getBlock().getState(); - - Inventory inventory = chest.getBlockInventory(); - int slots = inventory.getSize(); - int drops = 5 + _random.nextInt(11); // 5 -> 15 - - for (int i = 0; i < drops; i++) - { - int slot = _random.nextInt(slots); - ItemStack item = _clansManager.getLootManager().getRareItemStack(); - inventory.setItem(slot, item); - } - } - }, 5); - } - - private void finish() - { - _running = false; + _ended = true; _hologram.stop(); - getBlock().setType(Material.AIR); + _block.breakNaturally(null); + for (int i = 0; i < 9; i++) + { + _below[i].setTypeIdAndData(_oldBelow[i].getLeft().getId(), _oldBelow[i].getRight(), false); + } } - - private String getChatColor(long millis) - { - if (millis > 30000) - return C.cAqua; - else if (millis > 10000) - return C.cYellow; - else - return C.cRed; - } - - public boolean isRunning() - { - return _running; - } - - public Block getBlock() - { - return _block; - } - - public Player getOwner() - { - return _owner; - } - - public int getTicks() - { - return _ticks; - } - - public boolean contains(Block block) - { - return _block.equals(block); - } -} +} \ No newline at end of file diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/supplyDrop/SupplyDropManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/supplyDrop/SupplyDropManager.java index 2a0c69166..58de07fea 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/supplyDrop/SupplyDropManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/supplyDrop/SupplyDropManager.java @@ -1,99 +1,53 @@ package mineplex.game.clans.clans.supplyDrop; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; +import java.util.Objects; import org.bukkit.Bukkit; -import org.bukkit.Material; +import org.bukkit.GameMode; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; -import org.bukkit.event.HandlerList; -import org.bukkit.event.block.Action; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.inventory.ItemStack; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.world.ChunkUnloadEvent; import org.bukkit.plugin.java.JavaPlugin; import mineplex.core.MiniPlugin; import mineplex.core.common.util.C; import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilEvent; +import mineplex.core.common.util.UtilEvent.ActionType; import mineplex.core.common.util.UtilPlayer; -import mineplex.core.common.util.UtilWorld; -import mineplex.core.itemstack.ItemStackFactory; +import mineplex.core.common.util.UtilTextMiddle; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.game.clans.clans.ClansManager; -import mineplex.game.clans.core.repository.ClanTerritory; public class SupplyDropManager extends MiniPlugin { - private ClansManager _clansManager; - private List _supplyDrops; + private SupplyDrop _active = null; + private final Block _dropBlock = Bukkit.getWorld("world").getBlockAt(0, 0, 0); - public SupplyDropManager(JavaPlugin plugin, ClansManager clansManager) + public SupplyDropManager(JavaPlugin plugin) { - super("Supply Drops", plugin); - - _clansManager = clansManager; - _supplyDrops = new LinkedList(); + super("Supply Drop", plugin); } - @EventHandler - public void placeSupplyDrop(BlockPlaceEvent event) - { - ItemStack item = event.getItemInHand(); - - if (isSupplyDropItem(item)) - { - ClanTerritory claim = _clansManager.getClanUtility().getClaim(event.getBlock().getLocation()); - if (claim != null) - { - UtilPlayer.message(event.getPlayer(), F.main("Clans", "You can only place " + F.elem("Supply Drop") + " in the Wilderness")); - event.setCancelled(true); - return; - } - - event.getPlayer().setItemInHand(null); - placeSupplyDrop(event.getPlayer(), event.getBlock()); - - Bukkit.broadcastMessage(F.main("Clans", F.name(event.getPlayer().getName()) + " placed a supply drop at " + F.elem(UtilWorld.blockToStrClean(event.getBlock())))); - } - } - -// @EventHandler -// public void debug(PlayerCommandPreprocessEvent event) -// { -// if (event.getMessage().equalsIgnoreCase("/supplydrop")) -// { -// UtilPlayer.message(event.getPlayer(), F.main("Clans", "You received a " + F.elem("Supply Drop"))); -// giveSupplyDropItem(event.getPlayer()); -// } -// } - @EventHandler public void update(UpdateEvent event) { if (event.getType() != UpdateType.TICK) return; - - Iterator iterator = _supplyDrops.iterator(); - - while (iterator.hasNext()) + + if (_active != null) { - SupplyDrop supplyDrop = iterator.next(); - - if (supplyDrop.isRunning()) + if (_active.isActive()) { - supplyDrop.tick(); + _active.tick(); } else { -// supplyDrop.getBlock().setType(Material.AIR); - HandlerList.unregisterAll(supplyDrop); - iterator.remove(); + _active = null; } } } @@ -101,56 +55,188 @@ public class SupplyDropManager extends MiniPlugin @EventHandler public void cancelInteract(PlayerInteractEvent event) { - if (event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_BLOCK) + if (UtilPlayer.isSpectator(event.getPlayer()) || event.getPlayer().getGameMode() == GameMode.CREATIVE) { - if (event.getClickedBlock() != null && event.getClickedBlock().getType() == SupplyDrop.SUPPLY_DROP_MATERIAL) - { - event.setCancelled(true); - } + return; + } + if (!event.hasBlock()) + { + return; + } + if (!UtilEvent.isAction(event, ActionType.ANY)) + { + return; + } + if (_active == null) + { + return; + } + if (!_active.isActive() || _active.isDropping()) + { + return; + } + if (new BlockPosition(event.getClickedBlock()).equals(_active.getPosition())) + { + event.setCancelled(true); + _active.finish(); + _active = null; } } - + @EventHandler - public void cancelBreak(BlockBreakEvent event) + public void onChunkUnload(ChunkUnloadEvent event) { - for (SupplyDrop supplyDrop : _supplyDrops) + if (_active != null && _active.getChunk().getX() == event.getChunk().getX() && _active.getChunk().getZ() == event.getChunk().getZ()) { - if (supplyDrop.contains(event.getBlock())) - { - event.setCancelled(true); - } + event.setCancelled(true); } } - - private void placeSupplyDrop(Player player, Block block) + + @EventHandler + public void onJoin(PlayerJoinEvent event) { - SupplyDrop supplyDrop = new SupplyDrop(player, block, _clansManager, _clansManager.getHologramManager()); - getPlugin().getServer().getPluginManager().registerEvents(supplyDrop, getPlugin()); - _supplyDrops.add(supplyDrop); + if (_active != null) + { + boolean landed = !_active.isDropping(); + runSyncLater(() -> + { + if (_active != null) + { + if (_active.isDropping()) + { + UtilPlayer.message(event.getPlayer(), F.main(getName(), "A supply drop is landing at " + F.elem("(" + _active.getPosition()._x + ", " + _active.getPosition()._z + ")") + "!")); + } + else if (landed) + { + UtilPlayer.message(event.getPlayer(), F.main(getName(), "A supply drop has landed at " + F.elem("(" + _active.getPosition()._x + ", " + _active.getPosition()._z + ")") + "!")); + } + } + }, 40L); + } } - - private void giveSupplyDropItem(Player player) + + /** + * Checks whether there is a supply drop active on this server + * @return Whether there is a supply drop active on this server + */ + public boolean hasActiveSupplyDrop() { - ItemStack item = ItemStackFactory.Instance.CreateStack(Material.BEACON, (byte) 0, 1, C.cGold + "Supply Drop"); - player.getInventory().addItem(item); + return _active != null; } - - private boolean isSupplyDropItem(ItemStack item) + + /** + * Checks how many of a certain supply drop type a player owns + * @param player The player to check + * @param type The type of supply drop to check for + * @return The amount of supply drops of that type owned + */ + public int getAmountOwned(Player player, SupplyDropType type) { - if (item == null) + return ClansManager.getInstance().getInventoryManager().Get(player).getItemCount(type.getItemName()); + } + + /** + * Makes a player use a supply drop + * @param user The player to use the supply drop + * @param type The type of supply drop to use + */ + public void useSupplyDrop(Player user, SupplyDropType type) + { + if (getAmountOwned(user, type) < 1) + { + return; + } + if (hasActiveSupplyDrop()) + { + return; + } + _dropBlock.getChunk().load(); + _active = new SupplyDrop(type, _dropBlock, ClansManager.getInstance().getHologramManager()); + ClansManager.getInstance().getInventoryManager().addItemToInventory(user, type.getItemName(), -1); + UtilTextMiddle.display(C.cRed + "Supply Drop", "(" + _active.getPosition()._x + ", " + _active.getPosition()._z + ")"); + Bukkit.broadcastMessage(F.main(getName(), "A supply drop has been summoned by " + F.elem(user.getName()) + " at " + F.elem("(" + _active.getPosition()._x + ", " + _active.getPosition()._z + ")") + "!")); + } + + protected static class BlockPosition + { + private final int _x, _y, _z; + + public BlockPosition(Block block) + { + _x = block.getX(); + _y = block.getY(); + _z = block.getZ(); + } + + @Override + public int hashCode() + { + return Objects.hash(_x, _y, _z); + } + + @Override + public boolean equals(Object o) + { + if (o instanceof BlockPosition) + { + BlockPosition pos = (BlockPosition) o; + return pos._x == _x && pos._y == _y && pos._z == _z; + } + return false; - - return item.getType() == SupplyDrop.SUPPLY_DROP_MATERIAL && item.getItemMeta().hasDisplayName() && item.getItemMeta().getDisplayName().contains("Supply"); - -// if (item.getType() == SUPPLY_DROP_MATERIAL) -// { -// CustomItem customItem = GearManager.parseItem(item); -// if (customItem != null && customItem instanceof SupplyDropItem) -// { -// return true; -// } -// } -// -// return false; + } } -} + + public static enum SupplyDropType + { + NORMAL("Clans Supply Drop", C.cGray + "Supply Drop", 5, 15), + GILDED("Clans Gilded Supply Drop", C.cGoldB + "Gilded Supply Drop", 20, 25); + + private final String _item, _display; + private final int _min, _max; + + private SupplyDropType(String itemName, String displayName, int minItems, int maxItems) + { + _item = itemName; + _display = displayName; + _min = minItems; + _max = maxItems; + } + + /** + * Gets the name of this supply drop as recognized by the inventory database + * @return The name of this supply drop as recognized by the inventory database + */ + public String getItemName() + { + return _item; + } + + /** + * Gets the display name for this supply drop + * @return The display name for this supply drop + */ + public String getDisplayName() + { + return _display; + } + + /** + * Gets the minimum items for this type of supply drop + * @return The minimum items for this type of supply drop + */ + public int getMinItems() + { + return _min; + } + + /** + * Gets the maximum items for this type of supply drop + * @return The maximum items for this type of supply drop + */ + public int getMaxItems() + { + return _max; + } + } +} \ No newline at end of file