Make boss portals open where the boss spawned

This commit is contained in:
AlexTheCoder 2016-07-28 05:46:26 -04:00
parent c30d30b2e7
commit 4efe1fe76d
2 changed files with 306 additions and 1 deletions

View File

@ -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<Block> _frame = Lists.newArrayList();
private List<Block> _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);
}
}
}

View File

@ -70,6 +70,7 @@ public class NetherManager extends MiniPlugin
private NetherMinibossManager _miniboss;
private World _netherWorld;
private List<NetherPortal> _portals = Lists.newArrayList();
public List<BossNetherPortal> BossPortals = Lists.newArrayList();
private List<NetherPortal> _returnPortals = Lists.newArrayList();
public HashMap<Player, Long> InNether = new HashMap<>();
public HashMap<Player, Location> 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());
}
}
}