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 52a8b9356..427b61e35 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 @@ -7,6 +7,7 @@ import java.util.List; import mineplex.core.MiniPlugin; import mineplex.core.common.Rank; +import mineplex.core.common.generator.VoidGenerator; import mineplex.core.common.util.C; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilItem; @@ -24,12 +25,12 @@ import mineplex.game.clans.clans.ClansManager; import mineplex.game.clans.clans.event.ClansCommandExecutedEvent; import mineplex.game.clans.clans.nether.command.PortalCommand; import mineplex.game.clans.clans.nether.data.ClaimData; +import mineplex.game.clans.clans.nether.miniboss.NetherMinibossManager; import mineplex.game.clans.spawn.Spawn; import mineplex.minecraft.game.core.boss.EventCreatureDeathEvent; import mineplex.minecraft.game.core.boss.broodmother.SpiderCreature; import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature; import mineplex.minecraft.game.core.boss.skeletonking.SkeletonCreature; -import mineplex.minecraft.game.core.condition.Condition.ConditionType; import org.bukkit.Bukkit; import org.bukkit.GameMode; @@ -47,7 +48,6 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.entity.EntityPortalEvent; import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerInteractEvent; @@ -59,18 +59,19 @@ import com.google.common.collect.Lists; public class NetherManager extends MiniPlugin { - private static final long PORTAL_OPEN_DURATION = UtilTime.convert(30, TimeUnit.MINUTES, TimeUnit.MILLISECONDS); - private static final long NETHER_SLOW_WARMUP = UtilTime.convert(17, TimeUnit.MINUTES, TimeUnit.MILLISECONDS); - private static final long NETHER_BLIND_WARMUP = UtilTime.convert(18, TimeUnit.MINUTES, TimeUnit.MILLISECONDS); - private static final long NETHER_ALLOWED_DURATION = UtilTime.convert(20, TimeUnit.MINUTES, TimeUnit.MILLISECONDS); + private static final long PORTAL_OPEN_DURATION = UtilTime.convert(5, TimeUnit.MINUTES, TimeUnit.MILLISECONDS); + private static final long NETHER_ALLOWED_DURATION = UtilTime.convert(5, TimeUnit.MINUTES, TimeUnit.MILLISECONDS); private static final String CLAIM_WAND_NAME = C.cRedB + "Portal Claim Wand"; private static final String[] CLAIM_WAND_LORE = new String[] {C.cYellow + "Left Click to select the Portal's first corner", C.cYellow + "Right Click to select the Portal's second corner"}; private static final ItemStack CLAIM_WAND = new ItemBuilder(Material.WOOD_AXE).setTitle(CLAIM_WAND_NAME).setLore(CLAIM_WAND_LORE).build(); + private NetherMinibossManager _miniboss; private World _netherWorld; public List Portals = Lists.newArrayList(); + private List _returnPortals = Lists.newArrayList(); private File _portalCfg; private YamlConfiguration _portalConfig; public HashMap InNether = new HashMap<>(); + public HashMap OverworldOrigins = new HashMap<>(); public HashMap Claiming = new HashMap<>(); public NetherManager(ClansManager manager) @@ -93,6 +94,7 @@ public class NetherManager extends MiniPlugin } begin(); + _miniboss = new NetherMinibossManager(this); addCommand(new PortalCommand(this)); } @@ -100,7 +102,9 @@ public class NetherManager extends MiniPlugin { if (Bukkit.getWorld("nether") == null) { - Bukkit.createWorld(new WorldCreator("nether")); + WorldCreator creator = new WorldCreator("nether"); + creator.generator(new VoidGenerator()); + Bukkit.createWorld(creator); } _netherWorld = Bukkit.getWorld("nether"); @@ -129,12 +133,18 @@ public class NetherManager extends MiniPlugin log("Loading " + _portalConfig.getInt("PortalCount") + " Nether Portals!"); for (String portalSectionPath : _portalConfig.getConfigurationSection("Portals").getValues(false).keySet()) { + log("Loading Portal"); ConfigurationSection portal = _portalConfig.getConfigurationSection("Portals." + portalSectionPath); Location firstCorner = UtilWorld.strToLoc(portal.getString("CornerOne")); Location secondCorner = UtilWorld.strToLoc(portal.getString("CornerTwo")); + boolean returnPortal = portal.getBoolean("ReturnPortal"); - NetherPortal netherPortal = new NetherPortal(firstCorner, secondCorner); + NetherPortal netherPortal = new NetherPortal(firstCorner, secondCorner, returnPortal); Portals.add(netherPortal); + if (returnPortal) + { + _returnPortals.add(netherPortal); + } } } catch (Exception e) @@ -162,6 +172,97 @@ public class NetherManager extends MiniPlugin InNether.clear(); } + public NetherMinibossManager getMinibossManager() + { + return _miniboss; + } + + public World getNetherWorld() + { + return _netherWorld; + } + + public boolean isInNether(Player player) + { + return player.getWorld().equals(_netherWorld); + } + + public Location getReturnLocation(Player player) + { + return OverworldOrigins.getOrDefault(player, Spawn.getNorthSpawn()); + } + + public void spawnPortal(long duration) + { + if (Portals.isEmpty()) + { + return; + } + NetherPortal portal = Portals.get(UtilMath.r(Portals.size())); + portal.open(); + 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(duration)) + "!")); + runSyncLater(() -> + { + portal.close(); + }, (duration / 1000) * 20); + } + + public void spawnPortal() + { + spawnPortal(PORTAL_OPEN_DURATION); + } + + public void createPortal(Player creator, boolean returnPortal) + { + if (Claiming.getOrDefault(creator, new ClaimData()).getTotalSelected() < 2) + { + UtilPlayer.message(creator, F.main(getName(), "You do not have a top and bottom corner selected!")); + return; + } + + ClaimData data = Claiming.remove(creator); + NetherPortal portal = new NetherPortal(data.getFirstCorner().getLocation(), data.getSecondCorner().getLocation(), returnPortal); + Portals.add(portal); + + try + { + savePortals(); + UtilPlayer.message(creator, F.main(getName(), "Portal successfully created!")); + } + catch (Exception e) + { + UtilPlayer.message(creator, F.main(getName(), "An error occurred while creating that portal! Please report this immediately!")); + return; + } + } + + public void closePortals() + { + for (NetherPortal portal : Portals) + { + portal.close(); + } + } + + public void showPortalList(Player player) + { + UtilPlayer.message(player, F.main(getName(), "Portal List:")); + for (int i = 0; i < Portals.size(); i++) + { + int id = i + 1; + NetherPortal portal = Portals.get(i); + + UtilPlayer.message(player, C.cBlue + "- " + F.elem("Portal " + id + ": " + C.cGray + UtilWorld.locToStrClean(portal.getLocation()).replace("(", "").replace(")", ""))); + } + } + + public void giveWand(Player player) + { + player.getInventory().addItem(CLAIM_WAND.clone()); + UtilPlayer.message(player, F.main(getName(), "You have been given a Portal Claim Wand!")); + } + public void savePortals() throws IOException { _portalConfig.set("PortalCount", Portals.size()); @@ -169,9 +270,10 @@ public class NetherManager extends MiniPlugin _portalConfig.createSection("Portals"); for (int i = 0; i < Portals.size(); i++) { - int id = i + 1; - _portalConfig.set("Portals." + id + ".CornerOne", UtilWorld.locToStr(Portals.get(i).getCorners()[0])); - _portalConfig.set("Portals." + id + ".CornerTwo", UtilWorld.locToStr(Portals.get(i).getCorners()[1])); + Integer id = i + 1; + _portalConfig.set("Portals." + id.toString() + ".CornerOne", UtilWorld.locToStr(Portals.get(i).getCorners()[0])); + _portalConfig.set("Portals." + id.toString() + ".CornerTwo", UtilWorld.locToStr(Portals.get(i).getCorners()[1])); + _portalConfig.set("Portals." + id.toString() + ".ReturnPortal", Portals.get(i).isReturnPortal()); } _portalConfig.save(_portalCfg); @@ -238,8 +340,8 @@ public class NetherManager extends MiniPlugin runSyncLater(() -> { InNether.remove(event.getPlayer()); - ClansManager.getInstance().getCondition().Clean(event.getPlayer()); - event.getPlayer().teleport(Spawn.getNorthSpawn()); + event.getPlayer().teleport(getReturnLocation(event.getPlayer())); + OverworldOrigins.remove(event.getPlayer()); UtilPlayer.message(event.getPlayer(), F.main(getName(), "You have escaped " + F.clansNether("The Nether") + "!")); }, 1); } @@ -264,24 +366,9 @@ public class NetherManager extends MiniPlugin InNether.remove(player); if (isInNether(player)) { - ClansManager.getInstance().getCondition().Clean(player); - UtilPlayer.message(player, F.main(getName(), "You have failed to escape " + F.clansNether("The Nether") + " and have been destroyed by its demonic poisons!")); - ClansManager.getInstance().getDamageManager().NewDamageEvent(player, null, null, DamageCause.CUSTOM, 9999, false, true, true, C.cDRed + "The Nether", "Nether Poison"); - } - continue; - } - if (UtilTime.elapsed(InNether.get(player), NETHER_SLOW_WARMUP)) - { - if (!ClansManager.getInstance().getCondition().HasCondition(player, ConditionType.SLOW, "Nether Corruption")) - { - ClansManager.getInstance().getCondition().Factory().Slow("Nether Corruption", player, null, 9999, 1, false, true, false, false); - } - } - if (UtilTime.elapsed(InNether.get(player), NETHER_BLIND_WARMUP)) - { - if (!ClansManager.getInstance().getCondition().HasCondition(player, ConditionType.BLINDNESS, "Nether Corruption")) - { - ClansManager.getInstance().getCondition().Factory().Blind("Nether Corruption", player, null, 9999, 1, false, true, false); + player.teleport(getReturnLocation(player)); + OverworldOrigins.remove(player); + UtilPlayer.message(player, F.main(getName(), "You have been forced to escape " + F.clansNether("The Nether") + " to survive its demonic poisons!")); } } } @@ -302,8 +389,8 @@ public class NetherManager extends MiniPlugin if (isInNether(event.getPlayer())) { InNether.remove(event.getPlayer()); - ClansManager.getInstance().getCondition().Clean(event.getPlayer()); - ClansManager.getInstance().getDamageManager().NewDamageEvent(event.getPlayer(), null, null, DamageCause.CUSTOM, 9999, false, true, true, C.cDRed + "The Nether", "Nether Poison"); + event.getPlayer().teleport(getReturnLocation(event.getPlayer())); + OverworldOrigins.remove(event.getPlayer()); } Claiming.remove(event.getPlayer()); } @@ -380,84 +467,4 @@ public class NetherManager extends MiniPlugin spawnPortal(); } } - - public World getNetherWorld() - { - return _netherWorld; - } - - public boolean isInNether(Player player) - { - return player.getWorld().equals(_netherWorld); - } - - public void spawnPortal(long duration) - { - if (Portals.isEmpty()) - { - return; - } - NetherPortal portal = Portals.get(UtilMath.r(Portals.size())); - portal.open(); - 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(duration)) + "!")); - runSyncLater(() -> - { - portal.close(); - }, (duration / 1000) * 20); - } - - public void spawnPortal() - { - spawnPortal(PORTAL_OPEN_DURATION); - } - - public void createPortal(Player creator) - { - if (Claiming.getOrDefault(creator, new ClaimData()).getTotalSelected() < 2) - { - UtilPlayer.message(creator, F.main(getName(), "You do not have a top and bottom corner selected!")); - return; - } - - ClaimData data = Claiming.remove(creator); - NetherPortal portal = new NetherPortal(data.getFirstCorner().getLocation(), data.getSecondCorner().getLocation()); - Portals.add(portal); - - try - { - savePortals(); - } - catch (Exception e) - { - UtilPlayer.message(creator, F.main(getName(), "An error occurred while creating that portal! Please report this immediately!")); - return; - } - } - - public void closePortals() - { - for (NetherPortal portal : Portals) - { - portal.close(); - } - } - - public void showPortalList(Player player) - { - UtilPlayer.message(player, F.main(getName(), "Portal List:")); - for (int i = 0; i < Portals.size(); i++) - { - int id = i + 1; - NetherPortal portal = Portals.get(i); - - UtilPlayer.message(player, C.cBlue + "- " + F.elem("Portal " + id + ": " + C.cGray + UtilWorld.locToStrClean(portal.getLocation()).replace("(", "").replace(")", ""))); - } - } - - public void giveWand(Player player) - { - player.getInventory().addItem(CLAIM_WAND.clone()); - UtilPlayer.message(player, F.main(getName(), "You have been given a Portal Claim Wand!")); - } } \ No newline at end of file diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherPortal.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherPortal.java index d6d9b0aa5..8db21cebf 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherPortal.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherPortal.java @@ -6,18 +6,18 @@ import mineplex.core.common.util.F; import mineplex.core.common.util.UtilPlayer; import mineplex.game.clans.clans.ClanTips.TipType; import mineplex.game.clans.clans.ClansManager; -import mineplex.game.clans.spawn.Spawn; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.block.BlockState; 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.BlockBreakEvent; +import org.bukkit.event.block.BlockDamageEvent; import org.bukkit.event.block.BlockPhysicsEvent; import org.bukkit.event.entity.EntityPortalEnterEvent; import org.bukkit.event.entity.EntityPortalEvent; @@ -33,6 +33,7 @@ public class NetherPortal implements Listener private Location _loc; private Location[] _corners; private boolean _returnPortal; + private byte _portalFacing; public NetherPortal(Location firstCorner, Location secondCorner, boolean returnPortal) { @@ -78,6 +79,15 @@ public class NetherPortal implements Listener _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) @@ -100,6 +110,7 @@ public class NetherPortal implements Listener return _returnPortal; } + @SuppressWarnings("deprecation") public void open() { Bukkit.getPluginManager().registerEvents(this, ClansManager.getInstance().getPlugin()); @@ -110,6 +121,7 @@ public class NetherPortal implements Listener for (Block block : _portal) { block.setType(Material.PORTAL); + block.setData(_portalFacing); Bukkit.broadcastMessage("Creating Portal Piece"); } } @@ -121,13 +133,18 @@ public class NetherPortal implements Listener { block.setType(Material.AIR); } + for (Block block : _frame) + { + block.setType(Material.AIR); + } } @EventHandler(priority = EventPriority.HIGHEST) - public void onBreak(BlockBreakEvent event) + 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"))); } @@ -165,8 +182,8 @@ public class NetherPortal implements Listener if (isReturnPortal()) { ClansManager.getInstance().getNetherManager().InNether.remove((Player)event.getEntity()); - ClansManager.getInstance().getCondition().Clean((Player)event.getEntity()); - event.getEntity().teleport(Spawn.getNorthSpawn()); + event.getEntity().teleport(ClansManager.getInstance().getNetherManager().getReturnLocation((Player)event.getEntity())); + ClansManager.getInstance().getNetherManager().OverworldOrigins.remove((Player)event.getEntity()); UtilPlayer.message(event.getEntity(), F.main(ClansManager.getInstance().getNetherManager().getName(), "You have escaped " + F.clansNether("The Nether") + "!")); } else diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/CreateCommand.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/CreateCommand.java index 2697b97ac..0fe76df8b 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/CreateCommand.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/CreateCommand.java @@ -2,6 +2,8 @@ package mineplex.game.clans.clans.nether.command; import mineplex.core.command.CommandBase; import mineplex.core.common.Rank; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; import mineplex.game.clans.clans.nether.NetherManager; import org.bukkit.entity.Player; @@ -16,6 +18,19 @@ public class CreateCommand extends CommandBase @Override public void Execute(Player caller, String[] args) { - Plugin.createPortal(caller); + Boolean returnPortal = null; + try + { + returnPortal = Boolean.parseBoolean(args[0]); + } + catch (Exception e) {} + + if (returnPortal == null) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Usage: " + F.elem("/portal " + _aliasUsed + " "))); + return; + } + + Plugin.createPortal(caller, returnPortal); } } \ No newline at end of file diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/DeleteCommand.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/DeleteCommand.java index ed5f70ac0..ebbc9dec8 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/DeleteCommand.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/DeleteCommand.java @@ -29,7 +29,7 @@ public class DeleteCommand extends CommandBase UtilPlayer.message(caller, F.main(Plugin.getName(), "Usage: " + F.elem("/portal " + _aliasUsed + " "))); return; } - UtilPlayer.message(caller, F.main(Plugin.getName(), "Deleting the " + F.clansNether("Nether Portal" + " with ID " + id + "!"))); + UtilPlayer.message(caller, F.main(Plugin.getName(), "Deleting the " + F.clansNether("Nether Portal") + " with ID " + id + "!")); Plugin.Portals.remove(id - 1); try { diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/MinibossFireball.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/MinibossFireball.java new file mode 100644 index 000000000..2df5fe663 --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/MinibossFireball.java @@ -0,0 +1,71 @@ +package mineplex.game.clans.clans.nether.miniboss; + +import java.util.HashMap; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilEnt; +import mineplex.game.clans.clans.ClansManager; + +import org.bukkit.Bukkit; +import org.bukkit.Sound; +import org.bukkit.entity.LargeFireball; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Projectile; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.ProjectileHitEvent; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.Vector; + +public class MinibossFireball implements Listener +{ + public MinibossFireball() + { + Bukkit.getPluginManager().registerEvents(this, ClansManager.getInstance().getPlugin()); + } + + @EventHandler + public void onHit(ProjectileHitEvent event) + { + Projectile proj = event.getEntity(); + + if (!(proj instanceof LargeFireball)) + { + return; + } + if (!proj.hasMetadata("MINIBOSS_FIREBALL")) + { + return; + } + + HashMap hitMap = UtilEnt.getInRadius(proj.getLocation(), 5); + for (LivingEntity cur : hitMap.keySet()) + { + double range = hitMap.get(cur); + + ClansManager.getInstance().getCondition().Factory().Ignite("Fireball", cur, ((LivingEntity)proj.getMetadata("MINIBOSS_FIREBALL").get(0)), 7 * range, false, false); + ClansManager.getInstance().getCondition().Factory().Falling("Fireball", cur, ((LivingEntity)proj.getMetadata("MINIBOSS_FIREBALL").get(0)), 10, false, true); + UtilAction.velocity(cur, UtilAlg.getTrajectory(proj.getLocation().add(0, -0.5, 0), cur.getEyeLocation()), + 1.6 * range, false, 0, 0.8 * range, 1.2, true); + } + } + + public static boolean isFireball(Projectile entity) + { + return entity.hasMetadata("MINIBOSS_FIREBALL"); + } + + public static void launchFireball(LivingEntity shooter) + { + LargeFireball ball = shooter.launchProjectile(LargeFireball.class); + ball.setShooter(shooter); + ball.setIsIncendiary(false); + ball.setYield(0); + ball.setBounce(false); + ball.teleport(shooter.getEyeLocation().add(shooter.getLocation().getDirection().multiply(1))); + ball.setVelocity(new Vector(0,0,0)); + ball.setMetadata("MINIBOSS_FIREBALL", new FixedMetadataValue(ClansManager.getInstance().getPlugin(), shooter)); + shooter.getWorld().playSound(shooter.getLocation(), Sound.GHAST_FIREBALL, 1f, 0.8f); + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/NetherMiniBoss.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/NetherMiniBoss.java index c698d0546..dad0324d5 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/NetherMiniBoss.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/NetherMiniBoss.java @@ -51,7 +51,7 @@ public abstract class NetherMiniBoss implements Listen public void customSpawn() {}; - public void customDeath() {}; + public void customDeath(Location deathLocation) {}; public void customDespawn() {}; @@ -62,8 +62,10 @@ public abstract class NetherMiniBoss implements Listen { if (event.getEntity().equals(_entity)) { + event.setDroppedExp(0); + event.getDrops().clear(); HandlerList.unregisterAll(this); - customDeath(); + customDeath(event.getEntity().getLocation()); } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/NetherMinibossManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/NetherMinibossManager.java index 1e5ae3352..e52e58967 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/NetherMinibossManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/NetherMinibossManager.java @@ -9,30 +9,46 @@ import mineplex.core.updater.event.UpdateEvent; import mineplex.game.clans.clans.nether.NetherManager; import org.bukkit.Bukkit; -import org.bukkit.Location; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntitySpawnEvent; import com.google.common.collect.Lists; public class NetherMinibossManager implements Listener { - private static final long TIME_BETWEEN_MINIBOSS_TARGET_PLAYER = 30000; + private static final long TIME_BETWEEN_MINIBOSS_TARGET_PLAYER = 5000; private NetherManager _manager; + private boolean _allowSpawn = false; public NetherMinibossManager(NetherManager manager) { _manager = manager; + new MinibossFireball(); Bukkit.getPluginManager().registerEvents(this, manager.getPlugin()); } private void spawnAttacker(Player player) { - Location toSpawn = new Location(_manager.getNetherWorld(), player.getLocation().getX() + UtilMath.random(6, 10), player.getLocation().getY(), player.getLocation().getZ() + UtilMath.random(6, 10)); NetherMinibossType bossType = NetherMinibossType.values()[UtilMath.r(NetherMinibossType.values().length)]; - bossType.getNewInstance(toSpawn); + _allowSpawn = true; + bossType.getNewInstance(player.getLocation()); + _allowSpawn = false; + } + + @EventHandler + public void onSpawnNormal(EntitySpawnEvent event) + { + if (event.getEntity() instanceof LivingEntity && _manager.getNetherWorld().equals(event.getLocation().getWorld())) + { + if (!_allowSpawn) + { + event.setCancelled(true); + } + } } @EventHandler diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/NetherMinibossType.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/NetherMinibossType.java index c158596a4..36d2e79f0 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/NetherMinibossType.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/NetherMinibossType.java @@ -1,7 +1,8 @@ package mineplex.game.clans.clans.nether.miniboss; -import mineplex.game.clans.clans.nether.miniboss.ghast.GhastMiniboss; -import mineplex.game.clans.clans.nether.miniboss.ghast.PigmanMiniboss; +import mineplex.game.clans.clans.nether.miniboss.bosses.ArcherMiniboss; +import mineplex.game.clans.clans.nether.miniboss.bosses.GhastMiniboss; +import mineplex.game.clans.clans.nether.miniboss.bosses.WarriorMiniboss; import org.bukkit.Location; import org.bukkit.entity.EntityType; @@ -9,7 +10,9 @@ import org.bukkit.entity.EntityType; public enum NetherMinibossType { GHAST("Ghast", 25D, EntityType.GHAST, GhastMiniboss.class), - PIGMAN("Zombie Pigman", 30D, EntityType.PIG_ZOMBIE, PigmanMiniboss.class) + WARRIOR("Undead Warrior", 30D, EntityType.ZOMBIE, WarriorMiniboss.class), + ARCHER("Undead Archer", 25D, EntityType.SKELETON, ArcherMiniboss.class) + //PIGMAN("Zombie Pigman", 30D, EntityType.PIG_ZOMBIE, PigmanMiniboss.class) ; private Class _code; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/bosses/ArcherMiniboss.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/bosses/ArcherMiniboss.java new file mode 100644 index 000000000..73b6841db --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/bosses/ArcherMiniboss.java @@ -0,0 +1,192 @@ +package mineplex.game.clans.clans.nether.miniboss.bosses; + +import java.util.Random; + +import mineplex.core.common.util.UtilMath; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.nether.miniboss.NetherMiniBoss; +import mineplex.game.clans.items.runes.RuneManager.RuneAttribute; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.Skeleton; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityShootBowEvent; +import org.bukkit.event.entity.EntityTargetLivingEntityEvent; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public class ArcherMiniboss extends NetherMiniBoss +{ + private static final int BARBED_LEVEL = 1; + + public ArcherMiniboss(String displayName, Double maxHealth, Location spawn, EntityType type) + { + super(displayName, maxHealth, spawn, type); + } + + @Override + public void customSpawn() + { + Skeleton entity = getEntity(); + EntityEquipment eq = entity.getEquipment(); + eq.setItemInHand(new ItemStack(Material.BOW)); + eq.setHelmet(new ItemStack(Material.CHAINMAIL_HELMET)); + eq.setChestplate(new ItemStack(Material.CHAINMAIL_CHESTPLATE)); + eq.setLeggings(new ItemStack(Material.CHAINMAIL_LEGGINGS)); + eq.setBoots(new ItemStack(Material.CHAINMAIL_BOOTS)); + eq.setItemInHandDropChance(0.f); + eq.setHelmetDropChance(0.f); + eq.setChestplateDropChance(0.f); + eq.setLeggingsDropChance(0.f); + eq.setBootsDropChance(0.f); + entity.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 999999, 0)); + } + + @Override + public void customDeath(Location deathLocation) + { + deathLocation.getWorld().dropItemNaturally(deathLocation, new ItemStack(Material.DIAMOND, UtilMath.r(5) + 1)); + if (new Random().nextDouble() <= .1) + { + RuneAttribute runeType = RuneAttribute.values()[UtilMath.r(RuneAttribute.values().length)]; + deathLocation.getWorld().dropItemNaturally(deathLocation, ClansManager.getInstance().getGearManager().getRuneManager().getRune(runeType)); + } + } + + @EventHandler + public void onTarget(EntityTargetLivingEntityEvent event) + { + if (getEntity().equals(event.getEntity())) + { + if (!(event.getTarget() instanceof Player)) + { + event.setCancelled(true); + } + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void bowShoot(EntityShootBowEvent event) + { + if (BARBED_LEVEL == 0) + { + return; + } + + if (!(event.getProjectile() instanceof Arrow)) + { + return; + } + + if (event.getEntity().getEntityId() != getEntity().getEntityId()) + { + return; + } + + event.getProjectile().setMetadata("BARBED_ARROW", new FixedMetadataValue(ClansManager.getInstance().getPlugin(), 2)); + } + + @EventHandler(priority = EventPriority.HIGH) + public void damage(CustomDamageEvent event) + { + if (event.IsCancelled()) + { + return; + } + + if (event.GetCause() != DamageCause.PROJECTILE) + { + return; + } + + Projectile projectile = event.GetProjectile(); + LivingEntity damagee = event.GetDamageeEntity(); + LivingEntity damager = event.GetDamagerEntity(true); + + if (projectile == null) + { + return; + } + + if (!projectile.hasMetadata("BARBED_ARROW")) + { + return; + } + + if (damagee == null) + { + return; + } + + if (damager == null) + { + return; + } + + if (!getEntity().equals(damager)) + { + return; + } + + // Level + if (BARBED_LEVEL == 0) + { + return; + } + + Player damageePlayer = event.GetDamageePlayer(); + + if (damageePlayer != null) + { + damageePlayer.setSprinting(false); + } + + // Damage + event.AddMod(damager.getName(), "Barbed Arrows", projectile.getMetadata("BARBED_ARROW").get(0).asDouble(), false); + + // Condition + ClansManager.getInstance().getCondition().Factory().Slow("Barbed Arrows", damagee, damager, (projectile.getVelocity().length() / 3) * (2 + BARBED_LEVEL), 0, false, true, true, true); + } + + @EventHandler(priority = EventPriority.HIGH) + public void protect(CustomDamageEvent event) + { + if (event.IsCancelled()) + { + return; + } + + LivingEntity damagee = event.GetDamageeEntity(); + LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE); + + if (damagee == null) + { + return; + } + + if (damager == null) + { + return; + } + + if (getEntity().equals(damagee)) + { + if (!(damager instanceof Player)) + { + event.SetCancelled("Allied Attacker"); + } + } + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/bosses/GhastMiniboss.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/bosses/GhastMiniboss.java new file mode 100644 index 000000000..15c642384 --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/bosses/GhastMiniboss.java @@ -0,0 +1,91 @@ +package mineplex.game.clans.clans.nether.miniboss.bosses; + +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.nether.miniboss.MinibossFireball; +import mineplex.game.clans.clans.nether.miniboss.NetherMiniBoss; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Ghast; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.ProjectileLaunchEvent; +import org.bukkit.inventory.ItemStack; + +public class GhastMiniboss extends NetherMiniBoss +{ + private static final long MAIN_FIREBALL_COOLDOWN = 5000; + private static final long FIREBALL_LAUNCH_RATE = 500; + private static final int FIREBALLS_PER_USE = 5; + private long _lastFireballUse; + private int _fireballsRemaining; + + public GhastMiniboss(String displayName, Double maxHealth, Location spawn, EntityType type) + { + super(displayName, maxHealth, spawn, type); + } + + private void tryFireballVolley() + { + if (_fireballsRemaining > 0) + { + if (UtilTime.elapsed(_lastFireballUse, FIREBALL_LAUNCH_RATE)) + { + _fireballsRemaining--; + _lastFireballUse = System.currentTimeMillis(); + MinibossFireball.launchFireball(getEntity()); + } + } + else + { + if (UtilTime.elapsed(_lastFireballUse, MAIN_FIREBALL_COOLDOWN)) + { + _fireballsRemaining = FIREBALLS_PER_USE; + } + } + } + + @Override + public void customSpawn() + { + _lastFireballUse = System.currentTimeMillis(); + _fireballsRemaining = 0; + } + + @Override + public void customDeath(Location deathLocation) + { + deathLocation.getWorld().dropItemNaturally(deathLocation, new ItemStack(Material.DIAMOND, UtilMath.r(5) + 1)); + } + + @Override + public void update() + { + tryFireballVolley(); + } + + @EventHandler + public void onShoot(ProjectileLaunchEvent event) + { + if (event.getEntity().getShooter() != null && event.getEntity().getShooter().equals(getEntity())) + { + if (!MinibossFireball.isFireball(event.getEntity())) + { + event.setCancelled(true); + } + ClansManager.getInstance().runSyncLater(() -> + { + if (event.getEntity() == null || event.getEntity().isDead() || !event.getEntity().isValid()) + { + return; + } + if (!MinibossFireball.isFireball(event.getEntity())) + { + event.getEntity().remove(); + } + }, 1L); + } + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/ghast/PigmanMiniboss.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/bosses/PigmanMiniboss.java similarity index 94% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/ghast/PigmanMiniboss.java rename to Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/bosses/PigmanMiniboss.java index ed073f23e..2cc84b4aa 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/ghast/PigmanMiniboss.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/bosses/PigmanMiniboss.java @@ -1,4 +1,4 @@ -package mineplex.game.clans.clans.nether.miniboss.ghast; +package mineplex.game.clans.clans.nether.miniboss.bosses; import java.util.Random; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/bosses/WarriorMiniboss.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/bosses/WarriorMiniboss.java new file mode 100644 index 000000000..8d8a8fc17 --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/bosses/WarriorMiniboss.java @@ -0,0 +1,133 @@ +package mineplex.game.clans.clans.nether.miniboss.bosses; + +import java.util.Random; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilMath; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.nether.miniboss.NetherMiniBoss; +import mineplex.game.clans.items.runes.RuneManager.RuneAttribute; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Zombie; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityTargetLivingEntityEvent; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public class WarriorMiniboss extends NetherMiniBoss +{ + public WarriorMiniboss(String displayName, Double maxHealth, Location spawn, EntityType type) + { + super(displayName, maxHealth, spawn, type); + } + + @Override + public void customSpawn() + { + Zombie entity = getEntity(); + EntityEquipment eq = entity.getEquipment(); + eq.setHelmet(new ItemStack(Material.IRON_HELMET)); + eq.setChestplate(new ItemStack(Material.IRON_CHESTPLATE)); + eq.setLeggings(new ItemStack(Material.IRON_LEGGINGS)); + eq.setBoots(new ItemStack(Material.IRON_BOOTS)); + eq.setItemInHand(new ItemStack(Material.STONE_SWORD)); + eq.setHelmetDropChance(0.f); + eq.setChestplateDropChance(0.f); + eq.setLeggingsDropChance(0.f); + eq.setBootsDropChance(0.f); + eq.setItemInHandDropChance(0.f); + entity.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 999999, 0)); + } + + @Override + public void customDeath(Location deathLocation) + { + deathLocation.getWorld().dropItemNaturally(deathLocation, new ItemStack(Material.DIAMOND, UtilMath.r(5) + 1)); + if (new Random().nextDouble() <= .1) + { + RuneAttribute runeType = RuneAttribute.values()[UtilMath.r(RuneAttribute.values().length)]; + deathLocation.getWorld().dropItemNaturally(deathLocation, ClansManager.getInstance().getGearManager().getRuneManager().getRune(runeType)); + } + } + + @Override + public void update() + { + if (Math.random() < 0.9) + return; + + Zombie zombie = getEntity(); + + if (zombie.getTarget() == null) + return; + + double dist = UtilMath.offset(zombie.getTarget(), zombie); + + if (dist <= 3 || dist > 16) + return; + + + double power = 0.8 + (1.2 * ((dist-3)/13d)); + + //Leap + UtilAction.velocity(zombie, UtilAlg.getTrajectory(zombie, zombie.getTarget()), + power, false, 0, 0.2, 1, true); + + //Effect + zombie.getWorld().playSound(zombie.getLocation(), Sound.ZOMBIE_HURT, 1f, 2f); + } + + @EventHandler + public void onTarget(EntityTargetLivingEntityEvent event) + { + if (getEntity().equals(event.getEntity())) + { + if (!(event.getTarget() instanceof Player)) + { + event.setCancelled(true); + } + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void protect(CustomDamageEvent event) + { + if (event.IsCancelled()) + { + return; + } + + LivingEntity damagee = event.GetDamageeEntity(); + LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE); + + if (damagee == null) + { + return; + } + + if (damager == null) + { + return; + } + + if (getEntity().equals(damagee)) + { + if (!(damager instanceof Player)) + { + event.SetCancelled("Allied Attacker"); + } + } + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/ghast/GhastMiniboss.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/ghast/GhastMiniboss.java deleted file mode 100644 index e510f752f..000000000 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/ghast/GhastMiniboss.java +++ /dev/null @@ -1,56 +0,0 @@ -package mineplex.game.clans.clans.nether.miniboss.ghast; - -import mineplex.core.common.util.UtilTime; -import mineplex.game.clans.clans.nether.miniboss.NetherMiniBoss; - -import org.bukkit.Location; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Ghast; -import org.bukkit.entity.SmallFireball; - -public class GhastMiniboss extends NetherMiniBoss -{ - private static final long MAIN_FIREBALL_COOLDOWN = 15000; - private static final long FIREBALL_LAUNCH_RATE = 500; - private static final int FIREBALLS_PER_USE = 5; - private long _lastFireballUse; - private int _fireballsRemaining; - - public GhastMiniboss(String displayName, Double maxHealth, Location spawn, EntityType type) - { - super(displayName, maxHealth, spawn, type); - } - - private void tryFireballVolley() - { - if (_fireballsRemaining > 0) - { - if (UtilTime.elapsed(_lastFireballUse, FIREBALL_LAUNCH_RATE)) - { - _fireballsRemaining--; - _lastFireballUse = System.currentTimeMillis(); - getEntity().launchProjectile(SmallFireball.class); - } - } - else - { - if (UtilTime.elapsed(_lastFireballUse, MAIN_FIREBALL_COOLDOWN)) - { - _fireballsRemaining = FIREBALLS_PER_USE; - } - } - } - - @Override - public void customSpawn() - { - _lastFireballUse = System.currentTimeMillis(); - _fireballsRemaining = 0; - } - - @Override - public void update() - { - tryFireballVolley(); - } -} \ No newline at end of file