From 4efe1fe76d3063e8ac9edf4e49a2f2a40606b118 Mon Sep 17 00:00:00 2001 From: AlexTheCoder Date: Thu, 28 Jul 2016 05:46:26 -0400 Subject: [PATCH] Make boss portals open where the boss spawned --- .../clans/clans/nether/BossNetherPortal.java | 279 ++++++++++++++++++ .../clans/clans/nether/NetherManager.java | 28 +- 2 files changed, 306 insertions(+), 1 deletion(-) create mode 100644 Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/BossNetherPortal.java diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/BossNetherPortal.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/BossNetherPortal.java new file mode 100644 index 000000000..d09407609 --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/BossNetherPortal.java @@ -0,0 +1,279 @@ +package mineplex.game.clans.clans.nether; + +import java.util.List; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClanTips.TipType; +import mineplex.game.clans.clans.ClansManager; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockDamageEvent; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.bukkit.event.entity.EntityPortalEnterEvent; +import org.bukkit.event.entity.EntityPortalEvent; +import org.bukkit.event.player.PlayerPortalEvent; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.bukkit.potion.PotionEffectType; + +import com.google.common.collect.Lists; + +/** + * Data and listener class for individual nether portals opened by bosses + */ +public class BossNetherPortal implements Listener +{ + private static final int SECONDS_UNTIL_PORTAL = 5; + private List _frame = Lists.newArrayList(); + private List _portal = Lists.newArrayList(); + private Location _loc; + private Location[] _corners; + private boolean _returnPortal; + private byte _portalFacing; + + public boolean Open = false; + public long Expire = -1; + + public BossNetherPortal(Location firstCorner, Location secondCorner, boolean returnPortal) + { + int maxX = Math.max(firstCorner.getBlockX(), secondCorner.getBlockX()); + int minX = Math.min(firstCorner.getBlockX(), secondCorner.getBlockX()); + int maxY = Math.max(firstCorner.getBlockY(), secondCorner.getBlockY()); + int minY = Math.min(firstCorner.getBlockY(), secondCorner.getBlockY()); + int maxZ = Math.max(firstCorner.getBlockZ(), secondCorner.getBlockZ()); + int minZ = Math.min(firstCorner.getBlockZ(), secondCorner.getBlockZ()); + + for (int x = minX; x <= maxX; x++) + { + for (int y = minY; y <= maxY; y++) + { + for (int z = minZ; z <= maxZ; z++) + { + if (minX == maxX) + { + if ((y != minY && y != maxY) && (z != minZ && z != maxZ)) + { + _portal.add(firstCorner.getWorld().getBlockAt(x, y, z)); + } + else + { + _frame.add(firstCorner.getWorld().getBlockAt(x, y, z)); + } + } + else + { + if ((x != minX && x != maxX) && (y != minY && y != maxY)) + { + _portal.add(firstCorner.getWorld().getBlockAt(x, y, z)); + } + else + { + _frame.add(firstCorner.getWorld().getBlockAt(x, y, z)); + } + } + } + } + } + + _loc = new Location(firstCorner.getWorld(), minX + ((maxX - minX) / 2), maxY, minZ + ((maxZ - minZ) / 2)); + _corners = new Location[] {firstCorner, secondCorner}; + _returnPortal = returnPortal; + + if (maxX == minX) + { + _portalFacing = (byte)2; + } + else + { + _portalFacing = (byte)0; + } + } + + private boolean isInPortal(Block block) + { + return _frame.contains(block) || _portal.contains(block); + } + + /** + * Gets the center location of this portal + * @return The center location of this portal + */ + public Location getLocation() + { + return _loc; + } + + /** + * Gets the corners of this portal + * @return An array of the corners of this portal + */ + public Location[] getCorners() + { + return _corners; + } + + /** + * Checks if this portal is a return portal + * @return Whether this portal is a return portal + */ + public boolean isReturnPortal() + { + return _returnPortal; + } + + /** + * Opens this portal for a given duration + * @param duration The duration to hold the portal open for + */ + @SuppressWarnings("deprecation") + public void open(long duration) + { + if (Open) + { + if (Expire != -1) + { + Expire = Expire + duration; + } + } + else + { + if (!_returnPortal) + { + Expire = System.currentTimeMillis() + duration; + } + Open = true; + Bukkit.getPluginManager().registerEvents(this, ClansManager.getInstance().getPlugin()); + for (Block block : _frame) + { + block.setType(Material.OBSIDIAN); + } + for (Block block : _portal) + { + block.setType(Material.PORTAL); + block.setData(_portalFacing); + } + } + } + + /** + * Closes this portal and clears away its blocks + */ + public void close() + { + Open = false; + Expire = -1; + for (Block block : _portal) + { + block.setType(Material.AIR); + } + for (Block block : _frame) + { + block.setType(Material.AIR); + } + HandlerList.unregisterAll(this); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onBreak(BlockDamageEvent event) + { + if (isInPortal(event.getBlock())) + { + event.setInstaBreak(false); + event.setCancelled(true); + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You cannot destroy a " + F.clansNether("Nether Portal"))); + } + } + + @EventHandler(priority = EventPriority.LOW) + public void playerPortalEvent(PlayerPortalEvent event) + { + if (isInPortal(event.getFrom().getBlock())) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOW) + public void entityPortalEvent(EntityPortalEvent event) + { + if (isInPortal(event.getFrom().getBlock())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void onEnterPortal(EntityPortalEnterEvent event) + { + if (event.getEntity() instanceof Player) + { + if (isInPortal(event.getLocation().getBlock())) + { + Bukkit.getScheduler().runTaskLater(ClansManager.getInstance().getPlugin(), () -> + { + if (isInPortal(event.getEntity().getLocation().getBlock())) + { + if (isReturnPortal()) + { + ClansManager.getInstance().getNetherManager().InNether.remove((Player)event.getEntity()); + event.getEntity().teleport(ClansManager.getInstance().getNetherManager().getReturnLocation((Player)event.getEntity())); + ClansManager.getInstance().getNetherManager().OverworldOrigins.remove((Player)event.getEntity()); + ((Player)event.getEntity()).removePotionEffect(PotionEffectType.NIGHT_VISION); + UtilPlayer.message(event.getEntity(), F.main(ClansManager.getInstance().getNetherManager().getName(), "You have escaped " + F.clansNether("The Nether") + "!")); + } + else + { + ClansManager.getInstance().getNetherManager().InNether.put((Player)event.getEntity(), Expire); + Location from = event.getEntity().getLocation(); + ClansManager.getInstance().getNetherManager().OverworldOrigins.put((Player)event.getEntity(), from); + event.getEntity().teleport(ClansManager.getInstance().getNetherManager().getNetherWorld().getSpawnLocation()); + ClansManager.getInstance().ClanTips.displayTip(TipType.ENTER_NETHER, (Player)event.getEntity()); + } + } + }, SECONDS_UNTIL_PORTAL * 20); + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBlockPhysics(BlockPhysicsEvent event) + { + if (isInPortal(event.getBlock())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void handleExpiration(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + { + return; + } + if (Open && Expire != -1 && System.currentTimeMillis() >= Expire) + { + close(); + ClansManager.getInstance().getNetherManager().BossPortals.remove(this); + } + } + + @EventHandler + public void onUnload(ChunkUnloadEvent event) + { + if (event.getChunk().getX() == _loc.getChunk().getX() && event.getChunk().getZ() == _loc.getChunk().getZ()) + { + event.setCancelled(true); + } + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherManager.java index b50fb56b7..b872f9984 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherManager.java @@ -70,6 +70,7 @@ public class NetherManager extends MiniPlugin private NetherMinibossManager _miniboss; private World _netherWorld; private List _portals = Lists.newArrayList(); + public List BossPortals = Lists.newArrayList(); private List _returnPortals = Lists.newArrayList(); public HashMap InNether = new HashMap<>(); public HashMap OverworldOrigins = new HashMap<>(); @@ -249,6 +250,26 @@ public class NetherManager extends MiniPlugin spawnPortal(PORTAL_OPEN_DURATION); } + /** + * Spawns a nether portal when a boss dies + * @param bossSpawn The location where the boss spawned in + */ + public void spawnBossPortal(Location bossSpawn) + { + if (_returnPortals.isEmpty()) + { + return; + } + BossNetherPortal portal = new BossNetherPortal(bossSpawn.clone().add(-2, 5, 0), bossSpawn.clone().add(0, 0, 2), false); + portal.open(PORTAL_OPEN_DURATION); + for (NetherPortal returnPortal : _returnPortals) + { + returnPortal.open(-1); + } + UtilTextMiddle.display(F.clansNether("Nether Portal"), "Has opened at " + F.elem(UtilWorld.locToStrClean(portal.getLocation()))); + Bukkit.broadcastMessage(F.main(getName(), "A " + F.clansNether("Nether Portal") + " has opened at " + F.elem(UtilWorld.locToStrClean(portal.getLocation())) + " for " + F.elem(UtilTime.MakeStr(PORTAL_OPEN_DURATION)) + "!")); + } + /** * Creates a portal with the player's stored corners * @param creator The creator of the portal @@ -276,6 +297,11 @@ public class NetherManager extends MiniPlugin { portal.close(); } + for (BossNetherPortal portal : BossPortals) + { + portal.close(); + } + BossPortals.clear(); } /** @@ -495,7 +521,7 @@ public class NetherManager extends MiniPlugin { if (event.getCreature() instanceof GolemCreature || event.getCreature() instanceof SkeletonCreature || event.getCreature() instanceof SpiderCreature) { - spawnPortal(); + spawnBossPortal(event.getCreature().getSpawnLocation()); } } } \ No newline at end of file