Make boss portals open where the boss spawned
This commit is contained in:
parent
c30d30b2e7
commit
4efe1fe76d
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue