Implement tweaks and finalize implementations for bosses and fix loot dropping bugs
This commit is contained in:
parent
8c93f92a92
commit
0be317e5be
@ -190,13 +190,29 @@ public class Schematic
|
||||
return index < _blocks.length;
|
||||
}
|
||||
|
||||
public short getBlock(int x, int y, int z)
|
||||
public Short getBlock(int x, int y, int z)
|
||||
{
|
||||
if (getIndex(x, y, z) >= _blocks.length)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (getIndex(x, y, z) < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return _blocks[getIndex(x, y, z)];
|
||||
}
|
||||
|
||||
public byte getData(int x, int y, int z)
|
||||
public Byte getData(int x, int y, int z)
|
||||
{
|
||||
if (getIndex(x, y, z) >= _blocks.length)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (getIndex(x, y, z) < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return _blockData[getIndex(x, y, z)];
|
||||
}
|
||||
|
||||
|
@ -99,10 +99,13 @@ public class SchematicRunnable implements Runnable
|
||||
|
||||
private void setBlock(Block block, int x, int y, int z)
|
||||
{
|
||||
|
||||
int materialId = _schematic.getBlock(x, y, z);
|
||||
byte data = _schematic.getData(x, y, z);
|
||||
|
||||
Short materialId = _schematic.getBlock(x, y, z);
|
||||
Byte data = _schematic.getData(x, y, z);
|
||||
|
||||
if (materialId == null || data == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Material material = Material.getMaterial(materialId);
|
||||
if (material == null)
|
||||
{
|
||||
|
@ -41,9 +41,14 @@ public class BlockRestoreMap
|
||||
public void addBlockData(BlockData blockData)
|
||||
{
|
||||
Block block = blockData.Block;
|
||||
|
||||
if (!_blocks[block.getY()].containsKey(block))
|
||||
_blocks[block.getY()].put(block, blockData);
|
||||
|
||||
if (block.getY() > 0 && block.getY() < _blocks.length)
|
||||
{
|
||||
if (!_blocks[block.getY()].containsKey(block))
|
||||
{
|
||||
_blocks[block.getY()].put(block, blockData);
|
||||
}
|
||||
}
|
||||
|
||||
_changedBlocks.add(blockData.Block);
|
||||
}
|
||||
|
@ -226,8 +226,8 @@ public class ClanTips extends MiniPlugin
|
||||
}),
|
||||
ENTER_NETHER(
|
||||
new String[] {
|
||||
C.cDAqua + "The Nether",
|
||||
C.cAqua + "Welcome to the Nether. This is a very scary place full of fire and is a place for people to battle to the death! TODO: Write something better about the nether here"
|
||||
C.cDRedB + "The Nether",
|
||||
C.cRed + "The Nether is the home of all that is evil and monstrous, the true origin of demonic power. While here you can slay terrible creatures to find amazing loot, but remember that its darkness will slowly poison your body and kill you after 20 minutes!"
|
||||
}),
|
||||
;
|
||||
|
||||
|
@ -1,8 +1,36 @@
|
||||
package mineplex.game.clans.clans.nether;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.common.Rank;
|
||||
import mineplex.core.common.util.C;
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.UtilItem;
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.core.common.util.UtilTextMiddle;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.core.common.util.UtilTime.TimeUnit;
|
||||
import mineplex.core.common.util.UtilWorld;
|
||||
import mineplex.core.itemstack.ItemBuilder;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
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.spawn.Spawn;
|
||||
import mineplex.minecraft.game.core.boss.EventCreatureDeathEvent;
|
||||
import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonCreature;
|
||||
import mineplex.minecraft.game.core.boss.spider.SpiderCreature;
|
||||
import mineplex.minecraft.game.core.condition.Condition.ConditionType;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
@ -10,56 +38,64 @@ import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldBorder;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
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.player.PlayerCommandPreprocessEvent;
|
||||
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;
|
||||
import org.bukkit.event.player.PlayerPortalEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.common.Rank;
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.UtilAlg;
|
||||
import mineplex.core.common.util.UtilBlock;
|
||||
import mineplex.core.common.util.UtilCollections;
|
||||
import mineplex.core.common.util.UtilFile;
|
||||
import mineplex.core.common.util.UtilItem;
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.core.common.util.UtilWorld;
|
||||
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 mineplex.game.clans.core.repository.ClanTerritory;
|
||||
|
||||
public class NetherManager extends MiniPlugin
|
||||
{
|
||||
private ClansManager _clansManager;
|
||||
|
||||
private static final long PORTAL_OPEN_DURATION = UtilTime.convert(30, TimeUnit.MINUTES, TimeUnit.SECONDS) * 20;
|
||||
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 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 World _netherWorld;
|
||||
|
||||
private List<Portal> _portals = Lists.newArrayList();
|
||||
|
||||
public List<NetherPortal> Portals = Lists.newArrayList();
|
||||
private File _portalCfg;
|
||||
private YamlConfiguration _portalConfig;
|
||||
public HashMap<Player, Long> InNether = new HashMap<>();
|
||||
public HashMap<Player, ClaimData> Claiming = new HashMap<>();
|
||||
|
||||
public NetherManager(ClansManager clansManager)
|
||||
public NetherManager(ClansManager manager)
|
||||
{
|
||||
super("Nether Manager", clansManager.getPlugin());
|
||||
_clansManager = clansManager;
|
||||
super("Nether Manager", manager.getPlugin());
|
||||
|
||||
_portalCfg = new File(UtilServer.getServer().getWorlds().get(0).getWorldFolder().getPath() + File.separator + ".." + File.separator + "nether.cfg");
|
||||
_portalCfg = new File(UtilServer.getServer().getWorlds().get(0).getWorldFolder().getPath() + File.separator + ".." + File.separator + "portals.yml");
|
||||
|
||||
try
|
||||
{
|
||||
if (!_portalCfg.exists())
|
||||
{
|
||||
_portalCfg.createNewFile();
|
||||
}
|
||||
_portalConfig = YamlConfiguration.loadConfiguration(_portalCfg);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
begin();
|
||||
addCommand(new PortalCommand(this));
|
||||
}
|
||||
|
||||
public void begin()
|
||||
private void begin()
|
||||
{
|
||||
_netherWorld = Bukkit.getWorld("world_nether");
|
||||
|
||||
@ -67,52 +103,54 @@ public class NetherManager extends MiniPlugin
|
||||
worldBorder.setCenter(0, 0);
|
||||
worldBorder.setSize(200 * 2);
|
||||
|
||||
parsePortals();
|
||||
loadPortals();
|
||||
}
|
||||
|
||||
private void parsePortals()
|
||||
private void loadPortals()
|
||||
{
|
||||
String data = UtilFile.read(_portalCfg);
|
||||
|
||||
if (data.length() < 5)
|
||||
try
|
||||
{
|
||||
return;
|
||||
if (!_portalConfig.isInt("PortalCount"))
|
||||
{
|
||||
_portalConfig.set("PortalCount", 0);
|
||||
_portalConfig.save(_portalCfg);
|
||||
}
|
||||
if (!_portalConfig.isConfigurationSection("Portals"));
|
||||
{
|
||||
_portalConfig.createSection("Portals");
|
||||
_portalConfig.save(_portalCfg);
|
||||
}
|
||||
|
||||
log("Loading " + _portalConfig.getInt("PortalCount") + " Nether Portals!");
|
||||
for (String portalSectionPath : _portalConfig.getConfigurationSection("Portals").getValues(false).keySet())
|
||||
{
|
||||
ConfigurationSection portal = _portalConfig.getConfigurationSection("Portals." + portalSectionPath);
|
||||
Location firstCorner = UtilWorld.strToLoc(portal.getString("CornerOne"));
|
||||
Location secondCorner = UtilWorld.strToLoc(portal.getString("CornerTwo"));
|
||||
|
||||
NetherPortal netherPortal = new NetherPortal(firstCorner, secondCorner);
|
||||
Portals.add(netherPortal);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
UtilCollections.forEach(data.split("\n"), string -> string.trim(), sPortal -> {
|
||||
|
||||
String[] destinations = sPortal.split(">>");
|
||||
|
||||
Location from = UtilWorld.strToLoc(destinations[0]);
|
||||
Location to = UtilWorld.strToLoc(destinations[1].split(":")[0]);
|
||||
|
||||
Portal portal = Portal.create(from, to, UtilWorld.strToLoc(to.getWorld().getName() + "," + destinations[1].split(":")[1]));
|
||||
|
||||
if (portal == null)
|
||||
{
|
||||
log("FAILED TO LOAD PORTAL [" + sPortal + "]");
|
||||
}
|
||||
else
|
||||
{
|
||||
_portals.add(portal);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void cmd(PlayerCommandPreprocessEvent event)
|
||||
|
||||
public void savePortals() throws IOException
|
||||
{
|
||||
if (!_clansManager.getClientManager().hasRank(event.getPlayer(), Rank.JNR_DEV))
|
||||
_portalConfig.set("PortalCount", Portals.size());
|
||||
_portalConfig.set("Portals", null);
|
||||
_portalConfig.createSection("Portals");
|
||||
for (int i = 0; i < Portals.size(); i++)
|
||||
{
|
||||
return;
|
||||
int id = i + 1;
|
||||
_portalConfig.set("Portals." + id + ".CornerOne", Portals.get(0).getCorners()[0]);
|
||||
_portalConfig.set("Portals." + id + ".CornerTwo", Portals.get(0).getCorners()[1]);
|
||||
}
|
||||
|
||||
if (event.getMessage().startsWith("/nether"))
|
||||
{
|
||||
event.getPlayer().teleport(new Location(_netherWorld, 0, 90, 0));
|
||||
event.setCancelled(true);
|
||||
}
|
||||
_portalConfig.save(_portalCfg);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@ -132,28 +170,12 @@ public class NetherManager extends MiniPlugin
|
||||
return;
|
||||
}
|
||||
|
||||
_portals
|
||||
.stream()
|
||||
.filter(portal -> UtilAlg.getAverageBlockLocation(portal.getToBlocks()).distance(block.getLocation()) < 15)
|
||||
.limit(1)
|
||||
.forEach(portal -> {
|
||||
UtilPlayer.message(player, F.main("Clans", "You are not allowed to break this block."));
|
||||
event.setCancelled(true);
|
||||
});
|
||||
|
||||
if (!item.getType().equals(Material.GOLD_PICKAXE))
|
||||
{
|
||||
UtilPlayer.message(player, F.main("Clans", "You can only break blocks in the Nether with a " + F.elem("Golden Pickaxe") + "."));
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (block.getType().equals(Material.OBSIDIAN) || block.getType().equals(Material.PORTAL))
|
||||
{
|
||||
UtilPlayer.message(player, F.main("Clans", "You are not allowed to break this block."));
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@ -179,22 +201,29 @@ public class NetherManager extends MiniPlugin
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
_portals
|
||||
.stream()
|
||||
.filter(portal -> UtilAlg.getAverageBlockLocation(portal.getToBlocks()).distance(block.getLocation()) < 15)
|
||||
.limit(1)
|
||||
.forEach(portal -> {
|
||||
UtilPlayer.message(player, F.main("Clans", "You are not allowed to place blocks here."));
|
||||
event.setCancelled(true);
|
||||
});
|
||||
|
||||
if (block.getType().equals(Material.OBSIDIAN) || block.getType().equals(Material.PORTAL))
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPortal(PlayerPortalEvent event)
|
||||
{
|
||||
if (event.getTo().getWorld().equals(_netherWorld))
|
||||
{
|
||||
UtilPlayer.message(player, F.main("Clans", "You are not allowed to place blocks here."));
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
event.setCancelled(true);
|
||||
runSyncLater(() ->
|
||||
{
|
||||
InNether.remove(event.getPlayer());
|
||||
ClansManager.getInstance().getCondition().Clean(event.getPlayer());
|
||||
event.getPlayer().teleport(Spawn.getNorthSpawn());
|
||||
UtilPlayer.message(event.getPlayer(), F.main(getName(), "You have escaped " + F.clansNether("The Nether") + "!"));
|
||||
}, 1);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPortal(EntityPortalEvent event)
|
||||
{
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@ -202,66 +231,129 @@ public class NetherManager extends MiniPlugin
|
||||
{
|
||||
if (event.getType() == UpdateType.FAST)
|
||||
{
|
||||
List<Player> netherKeys = Lists.newArrayList();
|
||||
netherKeys.addAll(InNether.keySet());
|
||||
for (Player player : netherKeys)
|
||||
{
|
||||
if (UtilTime.elapsed(InNether.get(player), NETHER_ALLOWED_DURATION))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UtilServer.getPlayersCollection()
|
||||
.stream()
|
||||
.filter(player -> player.getWorld().equals(_netherWorld))
|
||||
.filter(player -> isInNether(player))
|
||||
.forEach(player -> {
|
||||
player.setCompassTarget(new Location(_netherWorld, -200.d + UtilMath.r(400), player.getLocation().getY(), -200.d + UtilMath.r(400)));
|
||||
_clansManager.getItemMapManager().removeMap(player);
|
||||
ClansManager.getInstance().getItemMapManager().removeMap(player);
|
||||
});
|
||||
}
|
||||
|
||||
if (event.getType() == UpdateType.SLOW)
|
||||
{
|
||||
_portals.forEach(portal -> {
|
||||
portal.getFromObsidianBlocks().forEach(block -> UtilBlock.setSilent(block, Material.OBSIDIAN));
|
||||
portal.getFromPortalBlocks().forEach(block -> UtilBlock.setSilent(block, Material.PORTAL));
|
||||
|
||||
portal.getToObsidianBlocks().forEach(block -> UtilBlock.setSilent(block, Material.OBSIDIAN));
|
||||
portal.getToPortalBlocks().forEach(block -> UtilBlock.setSilent(block, Material.PORTAL));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPortal(PlayerPortalEvent event)
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onQuit(PlayerQuitEvent event)
|
||||
{
|
||||
Player player = event.getPlayer();
|
||||
Location location = player.getLocation();
|
||||
|
||||
ClanTerritory territory = _clansManager.getClanUtility().getClaim(location);
|
||||
|
||||
if (event.getTo().getWorld().equals(_netherWorld))
|
||||
if (isInNether(event.getPlayer()))
|
||||
{
|
||||
if (territory != null && territory.Owner.equals("Borderlands"))
|
||||
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");
|
||||
}
|
||||
Claiming.remove(event.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onTpHome(ClansCommandExecutedEvent event)
|
||||
{
|
||||
if (event.getCommand().equalsIgnoreCase("tphome"))
|
||||
{
|
||||
if (isInNether(event.getPlayer()))
|
||||
{
|
||||
_portals
|
||||
.stream()
|
||||
.filter(portal ->
|
||||
portal.getFromPortalBlocks()
|
||||
.stream()
|
||||
.filter(block -> player.getLocation().distance(block.getLocation()) <= 2)
|
||||
.iterator().hasNext()
|
||||
).limit(1)
|
||||
.forEach(portal -> {
|
||||
event.setTo(portal.getToOut());
|
||||
_clansManager.ClanTips.displayTip(TipType.ENTER_NETHER, player);
|
||||
});
|
||||
event.setCancelled(true);
|
||||
UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot teleport to your Clan home while in " + F.clansNether("The Nether") + "!"));
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDropWand(PlayerDropItemEvent event)
|
||||
{
|
||||
ItemStack item = event.getItemDrop().getItemStack();
|
||||
if (item.getItemMeta().hasDisplayName() && item.getItemMeta().getDisplayName().equalsIgnoreCase(CLAIM_WAND_NAME))
|
||||
{
|
||||
_portals
|
||||
.stream()
|
||||
.filter(portal ->
|
||||
portal.getToPortalBlocks()
|
||||
.stream()
|
||||
.filter(block -> player.getLocation().distance(block.getLocation()) <= 2)
|
||||
.iterator().hasNext()
|
||||
).limit(1)
|
||||
.forEach(portal -> {
|
||||
event.setTo(UtilAlg.getAverageBlockLocation(portal.getFromPortalBlocks()));
|
||||
});
|
||||
runSyncLater(() ->
|
||||
{
|
||||
event.getItemDrop().remove();
|
||||
}, 1L);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onUseWand(PlayerInteractEvent event)
|
||||
{
|
||||
if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.LEFT_CLICK_BLOCK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!event.hasBlock() || !event.hasItem())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!ClansManager.getInstance().getClientManager().hasRank(event.getPlayer(), Rank.ADMIN))
|
||||
{
|
||||
return;
|
||||
}
|
||||
ItemStack item = event.getItem();
|
||||
if (item.getItemMeta().hasDisplayName() && item.getItemMeta().getDisplayName().equalsIgnoreCase(CLAIM_WAND_NAME))
|
||||
{
|
||||
Block block = event.getClickedBlock();
|
||||
if (!Claiming.containsKey(event.getPlayer()))
|
||||
{
|
||||
Claiming.put(event.getPlayer(), new ClaimData());
|
||||
}
|
||||
ClaimData data = Claiming.get(event.getPlayer());
|
||||
if (event.getAction() == Action.RIGHT_CLICK_BLOCK)
|
||||
{
|
||||
data.setSecondCorner(block);
|
||||
UtilPlayer.message(event.getPlayer(), F.main(getName(), "You have selected the Portal's second corner!"));
|
||||
}
|
||||
else
|
||||
{
|
||||
data.setFirstCorner(block);
|
||||
UtilPlayer.message(event.getPlayer(), F.main(getName(), "You have selected the Portal's first corner!"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBossDeath(EventCreatureDeathEvent event)
|
||||
{
|
||||
if (event.getCreature() instanceof GolemCreature || event.getCreature() instanceof SkeletonCreature || event.getCreature() instanceof SpiderCreature)
|
||||
{
|
||||
//spawnPortal();
|
||||
Bukkit.broadcastMessage("A PORTAL SPAWN WOULD BE CALLED HERE IF IT WASN'T DISABLED");
|
||||
}
|
||||
}
|
||||
|
||||
@ -274,4 +366,61 @@ public class NetherManager extends MiniPlugin
|
||||
{
|
||||
return player.getWorld().equals(_netherWorld);
|
||||
}
|
||||
}
|
||||
|
||||
public void spawnPortal()
|
||||
{
|
||||
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()))));
|
||||
runSyncLater(() ->
|
||||
{
|
||||
portal.close();
|
||||
}, 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 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!"));
|
||||
}
|
||||
}
|
@ -0,0 +1,166 @@
|
||||
package mineplex.game.clans.clans.nether;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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 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.BlockBreakEvent;
|
||||
import org.bukkit.event.entity.EntityPortalEnterEvent;
|
||||
import org.bukkit.event.entity.EntityPortalEvent;
|
||||
import org.bukkit.event.player.PlayerPortalEvent;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
public class NetherPortal implements Listener
|
||||
{
|
||||
private List<Block> _frame = Lists.newArrayList();
|
||||
private List<Block> _portal = Lists.newArrayList();
|
||||
private Location _loc;
|
||||
private Location[] _corners;
|
||||
|
||||
public NetherPortal(Location firstCorner, Location secondCorner)
|
||||
{
|
||||
int maxX = Math.max(firstCorner.getBlockX(), secondCorner.getBlockX());
|
||||
int minX = Math.min(firstCorner.getBlockX(), secondCorner.getBlockX());
|
||||
int maxY = Math.max(firstCorner.getBlockX(), secondCorner.getBlockX());
|
||||
int minY = Math.min(firstCorner.getBlockX(), secondCorner.getBlockX());
|
||||
int maxZ = Math.max(firstCorner.getBlockX(), secondCorner.getBlockX());
|
||||
int minZ = Math.min(firstCorner.getBlockX(), secondCorner.getBlockX());
|
||||
|
||||
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};
|
||||
}
|
||||
|
||||
private boolean isInPortal(Block block)
|
||||
{
|
||||
return _frame.contains(block) || _portal.contains(block);
|
||||
}
|
||||
|
||||
public Location getLocation()
|
||||
{
|
||||
return _loc;
|
||||
}
|
||||
|
||||
public Location[] getCorners()
|
||||
{
|
||||
return _corners;
|
||||
}
|
||||
|
||||
public void open()
|
||||
{
|
||||
for (Block block : _frame)
|
||||
{
|
||||
block.setType(Material.OBSIDIAN);
|
||||
}
|
||||
for (Block block : _portal)
|
||||
{
|
||||
block.setType(Material.PORTAL);
|
||||
}
|
||||
Bukkit.getPluginManager().registerEvents(this, ClansManager.getInstance().getPlugin());
|
||||
}
|
||||
|
||||
public void close()
|
||||
{
|
||||
HandlerList.unregisterAll(this);
|
||||
for (Block block : _frame)
|
||||
{
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
for (Block block : _portal)
|
||||
{
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBreak(BlockBreakEvent event)
|
||||
{
|
||||
if (isInPortal(event.getBlock()))
|
||||
{
|
||||
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()))
|
||||
{
|
||||
ClansManager.getInstance().getNetherManager().InNether.put((Player)event.getEntity(), System.currentTimeMillis());
|
||||
event.getEntity().teleport(event.getLocation()); //MAKE NETHER SPAWN
|
||||
ClansManager.getInstance().ClanTips.displayTip(TipType.ENTER_NETHER, (Player)event.getEntity());
|
||||
}
|
||||
}, 5 * 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
package mineplex.game.clans.clans.nether;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import mineplex.core.common.util.UtilBlock;
|
||||
|
||||
public class Portal
|
||||
{
|
||||
private List<Block> _fromPortalBlocks;
|
||||
private List<Block> _fromObsidianBlocks;
|
||||
|
||||
private List<Block> _toPortalBlocks;
|
||||
private List<Block> _toObsidianBlocks;
|
||||
|
||||
private List<Block> _fromBlocks;
|
||||
private List<Block> _toBlocks;
|
||||
|
||||
private Location _toOut;
|
||||
|
||||
public final boolean Success;
|
||||
|
||||
public Portal(Location from, Location to, Location toOut)
|
||||
{
|
||||
_fromPortalBlocks = Lists.newArrayList();
|
||||
_fromObsidianBlocks = Lists.newArrayList();
|
||||
|
||||
_toPortalBlocks = Lists.newArrayList();
|
||||
_toObsidianBlocks = Lists.newArrayList();
|
||||
|
||||
_toOut = toOut;
|
||||
|
||||
if (!isValidPortalBlock(from.getBlock()) || !isValidPortalBlock(to.getBlock()))
|
||||
{
|
||||
if (!isValidPortalBlock(from.getBlock()))
|
||||
from = UtilBlock.getInRadius(from.getBlock(), 4).keySet().stream().filter(this::isValidPortalBlock).limit(1).iterator().next().getLocation();
|
||||
|
||||
if (!isValidPortalBlock(to.getBlock()))
|
||||
to = UtilBlock.getInRadius(to.getBlock(), 4).keySet().stream().filter(this::isValidPortalBlock).limit(1).iterator().next().getLocation();
|
||||
|
||||
if (to == null || from == null)
|
||||
{
|
||||
System.out.println("[PORTAL] INVALID PORTAL PROVIDED (" + from + " --> " + to + ")");
|
||||
|
||||
Success = false;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (Block other : UtilBlock.getInRadius(from, 25).keySet())
|
||||
{
|
||||
if (other.getType() == Material.OBSIDIAN)
|
||||
{
|
||||
_fromObsidianBlocks.add(other);
|
||||
}
|
||||
else if (other.getType() == Material.PORTAL)
|
||||
{
|
||||
_fromPortalBlocks.add(other);
|
||||
}
|
||||
}
|
||||
|
||||
for (Block other : UtilBlock.getInRadius(to, 7.5d).keySet())
|
||||
{
|
||||
if (other.getType() == Material.OBSIDIAN)
|
||||
{
|
||||
_toObsidianBlocks.add(other);
|
||||
}
|
||||
else if (other.getType() == Material.PORTAL)
|
||||
{
|
||||
_toPortalBlocks.add(other);
|
||||
}
|
||||
}
|
||||
|
||||
_fromBlocks = new ArrayList<>();
|
||||
_toBlocks = new ArrayList<>();
|
||||
|
||||
_fromBlocks.addAll(_fromObsidianBlocks);
|
||||
_fromBlocks.addAll(_fromPortalBlocks);
|
||||
_toBlocks.addAll(_toObsidianBlocks);
|
||||
_toBlocks.addAll(_toPortalBlocks);
|
||||
|
||||
Success = true;
|
||||
}
|
||||
|
||||
public Location getToOut()
|
||||
{
|
||||
return _toOut;
|
||||
}
|
||||
|
||||
public List<Block> getFromPortalBlocks()
|
||||
{
|
||||
return _fromPortalBlocks;
|
||||
}
|
||||
|
||||
public List<Block> getFromObsidianBlocks()
|
||||
{
|
||||
return _fromObsidianBlocks;
|
||||
}
|
||||
|
||||
public List<Block> getToPortalBlocks()
|
||||
{
|
||||
return _toPortalBlocks;
|
||||
}
|
||||
|
||||
public List<Block> getToObsidianBlocks()
|
||||
{
|
||||
return _toObsidianBlocks;
|
||||
}
|
||||
|
||||
public List<Block> getFromBlocks()
|
||||
{
|
||||
return _fromBlocks;
|
||||
}
|
||||
|
||||
public List<Block> getToBlocks()
|
||||
{
|
||||
return _toBlocks;
|
||||
}
|
||||
|
||||
private boolean isValidPortalBlock(Block block)
|
||||
{
|
||||
return block.getType() == Material.OBSIDIAN || block.getType() == Material.PORTAL;
|
||||
}
|
||||
|
||||
public static Portal create(Location from, Location to, Location toOut)
|
||||
{
|
||||
Portal portal = new Portal(from, to, toOut);
|
||||
|
||||
if (!portal.Success)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return portal;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package mineplex.game.clans.clans.nether.command;
|
||||
|
||||
import mineplex.core.command.CommandBase;
|
||||
import mineplex.core.common.Rank;
|
||||
import mineplex.game.clans.clans.nether.NetherManager;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class CreateCommand extends CommandBase<NetherManager>
|
||||
{
|
||||
public CreateCommand(NetherManager plugin)
|
||||
{
|
||||
super(plugin, Rank.ADMIN, "create");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
Plugin.createPortal(caller);
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
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;
|
||||
|
||||
public class DeleteCommand extends CommandBase<NetherManager>
|
||||
{
|
||||
public DeleteCommand(NetherManager plugin)
|
||||
{
|
||||
super(plugin, Rank.ADMIN, "delete", "remove");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
Integer id = null;
|
||||
try
|
||||
{
|
||||
id = Integer.parseInt(args[0]);
|
||||
}
|
||||
catch (Exception e) {}
|
||||
if (id == null || id >= Plugin.Portals.size() || id < 1)
|
||||
{
|
||||
UtilPlayer.message(caller, F.main(Plugin.getName(), "Usage: " + F.elem("/portal " + _aliasUsed + " <ID>")));
|
||||
return;
|
||||
}
|
||||
UtilPlayer.message(caller, F.main(Plugin.getName(), "Deleting the " + F.clansNether("Nether Portal" + " with ID " + id + "!")));
|
||||
Plugin.Portals.remove(id - 1);
|
||||
try
|
||||
{
|
||||
Plugin.savePortals();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UtilPlayer.message(caller, F.main(Plugin.getName(), "An error occurred while deleting that portal! Please report this immediately!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package mineplex.game.clans.clans.nether.command;
|
||||
|
||||
import mineplex.core.command.CommandBase;
|
||||
import mineplex.core.common.Rank;
|
||||
import mineplex.game.clans.clans.nether.NetherManager;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class ListCommand extends CommandBase<NetherManager>
|
||||
{
|
||||
public ListCommand(NetherManager plugin)
|
||||
{
|
||||
super(plugin, Rank.ADMIN, "list");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
Plugin.showPortalList(caller);
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package mineplex.game.clans.clans.nether.command;
|
||||
|
||||
import mineplex.core.command.MultiCommandBase;
|
||||
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;
|
||||
|
||||
public class PortalCommand extends MultiCommandBase<NetherManager>
|
||||
{
|
||||
public PortalCommand(NetherManager plugin)
|
||||
{
|
||||
super(plugin, Rank.ADMIN, "netherportal", "portal");
|
||||
AddCommand(new CreateCommand(plugin));
|
||||
AddCommand(new DeleteCommand(plugin));
|
||||
AddCommand(new ListCommand(plugin));
|
||||
AddCommand(new SpawnCommand(plugin));
|
||||
AddCommand(new WandCommand(plugin));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void Help(Player caller, String[] args)
|
||||
{
|
||||
UtilPlayer.message(caller, F.help("/" + _aliasUsed + " spawn", "Forces a Nether Portal to spawn", Rank.ADMIN));
|
||||
UtilPlayer.message(caller, F.help("/" + _aliasUsed + " lists", "Lists all loaded Nether Portals", Rank.ADMIN));
|
||||
UtilPlayer.message(caller, F.help("/" + _aliasUsed + " wand", "Gives you a Nether Portal claim wand", Rank.ADMIN));
|
||||
UtilPlayer.message(caller, F.help("/" + _aliasUsed + " create", "Creates a Nether Portal with the corners you have selected", Rank.ADMIN));
|
||||
UtilPlayer.message(caller, F.help("/" + _aliasUsed + " delete", "Deletes a loaded Nether Portal", Rank.ADMIN));
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package mineplex.game.clans.clans.nether.command;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
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;
|
||||
|
||||
public class SpawnCommand extends CommandBase<NetherManager>
|
||||
{
|
||||
public SpawnCommand(NetherManager plugin)
|
||||
{
|
||||
super(plugin, Rank.ADMIN, "spawn");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
UtilPlayer.message(caller, F.main(Plugin.getName(), "Spawning a " + F.clansNether("Nether Portal" + "!")));
|
||||
Plugin.spawnPortal();
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package mineplex.game.clans.clans.nether.command;
|
||||
|
||||
import mineplex.core.command.CommandBase;
|
||||
import mineplex.core.common.Rank;
|
||||
import mineplex.game.clans.clans.nether.NetherManager;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class WandCommand extends CommandBase<NetherManager>
|
||||
{
|
||||
public WandCommand(NetherManager plugin)
|
||||
{
|
||||
super(plugin, Rank.ADMIN, "wand");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
Plugin.giveWand(caller);
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package mineplex.game.clans.clans.nether.data;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
public class ClaimData
|
||||
{
|
||||
private Block _first, _second;
|
||||
|
||||
public Block getFirstCorner()
|
||||
{
|
||||
return _first;
|
||||
}
|
||||
|
||||
public Block getSecondCorner()
|
||||
{
|
||||
return _second;
|
||||
}
|
||||
|
||||
public int getTotalSelected()
|
||||
{
|
||||
int total = 2;
|
||||
if (_first == null)
|
||||
{
|
||||
total--;
|
||||
}
|
||||
if (_second == null)
|
||||
{
|
||||
total--;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setFirstCorner(Block block)
|
||||
{
|
||||
_first = block;
|
||||
}
|
||||
|
||||
public void setSecondCorner(Block block)
|
||||
{
|
||||
_second = block;
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package mineplex.game.clans.clans.nether.miniboss;
|
||||
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.game.clans.clans.ClansManager;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
|
||||
public abstract class NetherMiniBoss<Mob extends LivingEntity> implements Listener
|
||||
{
|
||||
private Mob _entity;
|
||||
private EntityType _type;
|
||||
private String _name;
|
||||
private double _maxHealth;
|
||||
private Location _spawn;
|
||||
|
||||
public NetherMiniBoss(String displayName, Double maxHealth, Location spawn, EntityType type)
|
||||
{
|
||||
_name = displayName;
|
||||
_maxHealth = maxHealth;
|
||||
_spawn = spawn;
|
||||
_type = type;
|
||||
|
||||
spawn();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void spawn()
|
||||
{
|
||||
_entity = (Mob) _spawn.getWorld().spawnEntity(_spawn, _type);
|
||||
_entity.setMaxHealth(_maxHealth);
|
||||
_entity.setHealth(_maxHealth);
|
||||
_entity.setCustomName(_name);
|
||||
_entity.setCustomNameVisible(true);
|
||||
|
||||
customSpawn();
|
||||
Bukkit.getPluginManager().registerEvents(this, ClansManager.getInstance().getPlugin());
|
||||
}
|
||||
|
||||
public abstract void customSpawn();
|
||||
|
||||
public abstract void customDeath();
|
||||
|
||||
public abstract void customDespawn();
|
||||
|
||||
public void update() {};
|
||||
|
||||
@EventHandler
|
||||
public void onDeath(EntityDeathEvent event)
|
||||
{
|
||||
if (event.getEntity().equals(_entity))
|
||||
{
|
||||
HandlerList.unregisterAll(this);
|
||||
customDeath();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onUpdate(UpdateEvent event)
|
||||
{
|
||||
if (event.getType() != UpdateType.FAST)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!_entity.isValid())
|
||||
{
|
||||
HandlerList.unregisterAll(this);
|
||||
customDespawn();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_entity.getFireTicks() > 0)
|
||||
{
|
||||
_entity.setFireTicks(-1);
|
||||
}
|
||||
update();
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package mineplex.game.clans.clans.nether.miniboss;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
import mineplex.core.recharge.Recharge;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
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.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
public class NetherMinibossManager implements Listener
|
||||
{
|
||||
private static final long TIME_BETWEEN_MINIBOSS_TARGET_PLAYER = 30000;
|
||||
private NetherManager _manager;
|
||||
|
||||
public NetherMinibossManager(NetherManager manager)
|
||||
{
|
||||
_manager = manager;
|
||||
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);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onSpawnThreat(UpdateEvent event)
|
||||
{
|
||||
if (event.getType() != UpdateType.FAST)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<Player> targets = Lists.newArrayList();
|
||||
targets.addAll(_manager.InNether.keySet());
|
||||
|
||||
for (Player player : targets)
|
||||
{
|
||||
if (player.isDead() || !player.isValid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (_manager.isInNether(player) && Recharge.Instance.use(player, "Nether Miniboss Spawn", TIME_BETWEEN_MINIBOSS_TARGET_PLAYER, false, false))
|
||||
{
|
||||
spawnAttacker(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package mineplex.game.clans.clans.nether.miniboss;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
public enum NetherMinibossType
|
||||
{
|
||||
;
|
||||
|
||||
private Class<? extends NetherMiniBoss> _code;
|
||||
private String _name;
|
||||
private Double _maxHealth;
|
||||
private EntityType _type;
|
||||
|
||||
private NetherMinibossType(String name, Double maxHealth, EntityType type, Class<? extends NetherMiniBoss> code)
|
||||
{
|
||||
_name = name;
|
||||
_maxHealth = maxHealth;
|
||||
_type = type;
|
||||
_code = code;
|
||||
}
|
||||
|
||||
public NetherMiniBoss getNewInstance(Location spawn)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _code.getConstructor(String.class, Double.class, Location.class, EntityType.class).newInstance(_name, _maxHealth, spawn, _type);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -6,13 +6,6 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.blockrestore.BlockRestore;
|
||||
import mineplex.core.common.util.C;
|
||||
@ -26,10 +19,22 @@ import mineplex.game.clans.clans.loot.LootManager;
|
||||
import mineplex.game.clans.clans.regions.ClansRegions;
|
||||
import mineplex.game.clans.clans.worldevent.command.WorldEventCommand;
|
||||
import mineplex.minecraft.game.classcombat.Skill.SkillFactory;
|
||||
import mineplex.minecraft.game.classcombat.Skill.event.SkillTriggerEvent;
|
||||
import mineplex.minecraft.game.core.boss.EventCreatureDeathEvent;
|
||||
import mineplex.minecraft.game.core.boss.EventState;
|
||||
import mineplex.minecraft.game.core.boss.WorldEvent;
|
||||
import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonCreature;
|
||||
import mineplex.minecraft.game.core.boss.spider.SpiderCreature;
|
||||
import mineplex.minecraft.game.core.damage.DamageManager;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class WorldEventManager extends MiniPlugin implements ScoreboardElement
|
||||
{
|
||||
private final List<WorldEvent> _runningEvents;
|
||||
@ -90,6 +95,37 @@ public class WorldEventManager extends MiniPlugin implements ScoreboardElement
|
||||
return false;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onIcePrison(SkillTriggerEvent event)
|
||||
{
|
||||
if (event.GetSkillName().equalsIgnoreCase("Ice Prison"))
|
||||
{
|
||||
for (WorldEvent e : _runningEvents)
|
||||
{
|
||||
if (e.isInBounds(event.GetPlayer().getLocation()))
|
||||
{
|
||||
event.SetCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBossDeath(EventCreatureDeathEvent event)
|
||||
{
|
||||
if (event.getCreature() instanceof GolemCreature || event.getCreature() instanceof SkeletonCreature || event.getCreature() instanceof SpiderCreature)
|
||||
{
|
||||
Location drop = event.getCreature().getLastKnownLocation();
|
||||
if (drop != null)
|
||||
{
|
||||
runSyncLater(() ->
|
||||
{
|
||||
ClansManager.getInstance().getLootManager().dropRare(drop);
|
||||
}, 20 * 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void update(UpdateEvent event)
|
||||
{
|
||||
|
@ -7,7 +7,7 @@ import mineplex.game.clans.clans.worldevent.undead.UndeadCamp;
|
||||
import mineplex.minecraft.game.classcombat.Skill.SkillFactory;
|
||||
import mineplex.minecraft.game.core.boss.WorldEvent;
|
||||
import mineplex.minecraft.game.core.boss.ironwizard.GolemBoss;
|
||||
import mineplex.minecraft.game.core.boss.necromancer.NecromancerBoss;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonBoss;
|
||||
import mineplex.minecraft.game.core.boss.slimeking.SlimeBoss;
|
||||
import mineplex.minecraft.game.core.boss.spider.SpiderBoss;
|
||||
|
||||
@ -20,7 +20,7 @@ public enum WorldEventType
|
||||
UNDEAD_CAMP("Undead Camp", UndeadCamp.class, 30),
|
||||
IRON_WIZARD("Iron Wizard",GolemBoss.class, 30),
|
||||
BROOD_MOTHER("Brood Mother", SpiderBoss.class, 30),
|
||||
NECROMANCER("Necromancer", NecromancerBoss.class, 30);
|
||||
SKELETON_KING("Skeleton King", SkeletonBoss.class, 30);
|
||||
|
||||
private String _name;
|
||||
private Class<? extends WorldEvent> _clazz;
|
||||
|
@ -13,12 +13,14 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import mineplex.core.account.CoreClient;
|
||||
import mineplex.core.common.Rank;
|
||||
import mineplex.game.clans.clans.ClansManager;
|
||||
import net.minecraft.server.v1_8_R3.NBTBase;
|
||||
import net.minecraft.server.v1_8_R3.NBTTagByte;
|
||||
import net.minecraft.server.v1_8_R3.NBTTagString;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
@ -36,6 +38,7 @@ import com.google.gson.GsonBuilder;
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.account.CoreClientManager;
|
||||
import mineplex.core.common.util.C;
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.core.common.weight.Weight;
|
||||
import mineplex.core.common.weight.WeightSet;
|
||||
@ -303,8 +306,7 @@ public class GearManager extends MiniPlugin implements IPacketHandler, Runnable
|
||||
factory.setType(Material.BOW);
|
||||
}
|
||||
|
||||
if (itemType != ItemType.LEGENDARY) // Only non-legendaries have
|
||||
// attributes
|
||||
if (itemType != ItemType.LEGENDARY || (UtilMath.random.nextDouble() <= .35 && factory.getMaterial() != Material.RECORD_6)) // Melee Legendaries have a chance to spawn with attributes
|
||||
{
|
||||
AttributeContainer attributes = new AttributeContainer();
|
||||
generateAttributes(attributes, itemType, attributeCount);
|
||||
@ -352,6 +354,9 @@ public class GearManager extends MiniPlugin implements IPacketHandler, Runnable
|
||||
case WEAPON:
|
||||
sampleAttribute = instantiate(WEAPON_ATTRIBUTES.generateRandom());
|
||||
break;
|
||||
case LEGENDARY:
|
||||
sampleAttribute = instantiate(WEAPON_ATTRIBUTES.generateRandom());
|
||||
break;
|
||||
case BOW:
|
||||
sampleAttribute = instantiate(BOW_ATTRIBUTES.generateRandom());
|
||||
break;
|
||||
@ -366,8 +371,11 @@ public class GearManager extends MiniPlugin implements IPacketHandler, Runnable
|
||||
|
||||
attempts++;
|
||||
}
|
||||
|
||||
container.addAttribute(attribute);
|
||||
|
||||
if (attribute != null)
|
||||
{
|
||||
container.addAttribute(attribute);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,41 @@
|
||||
package mineplex.minecraft.game.core.boss;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
public abstract class BossPassive<T extends EventCreature, Y extends Entity> implements Listener
|
||||
{
|
||||
private T _creature;
|
||||
|
||||
public BossPassive(T creature)
|
||||
{
|
||||
_creature = creature;
|
||||
Bukkit.getPluginManager().registerEvents(this, creature.getEvent().getPlugin());
|
||||
}
|
||||
|
||||
public int getCooldown()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
public Y getEntity()
|
||||
{
|
||||
return (Y) getBoss().getEntity();
|
||||
}
|
||||
|
||||
public T getBoss()
|
||||
{
|
||||
return _creature;
|
||||
}
|
||||
|
||||
public Location getLocation()
|
||||
{
|
||||
return getEntity().getLocation();
|
||||
}
|
||||
|
||||
public abstract boolean isProgressing();
|
||||
|
||||
public abstract void tick();
|
||||
}
|
@ -28,7 +28,7 @@ public abstract class EventCreature<T extends LivingEntity> implements Listener
|
||||
// Spawn Data
|
||||
private T _entity;
|
||||
private Class<? extends T> _entityClass;
|
||||
private Location _spawnLocation;
|
||||
private Location _spawnLocation, _lastLocation;
|
||||
|
||||
// Creature Data
|
||||
private String _name;
|
||||
@ -183,6 +183,11 @@ public abstract class EventCreature<T extends LivingEntity> implements Listener
|
||||
{
|
||||
return _spawnLocation;
|
||||
}
|
||||
|
||||
public Location getLastKnownLocation()
|
||||
{
|
||||
return _lastLocation;
|
||||
}
|
||||
|
||||
public void setSpawnLocation(Location spawnLocation)
|
||||
{
|
||||
@ -275,10 +280,12 @@ public abstract class EventCreature<T extends LivingEntity> implements Listener
|
||||
spawnEntity();
|
||||
}
|
||||
|
||||
if (UtilMath.offset2d(_entity.getLocation(), _spawnLocation) > 24)
|
||||
if (UtilMath.offset2d(_entity.getLocation(), _spawnLocation) > 44)
|
||||
{
|
||||
_entity.setVelocity(UtilAlg.getTrajectory(_entity.getLocation(), _spawnLocation).normalize().multiply(2));
|
||||
}
|
||||
|
||||
_lastLocation = _entity.getLocation();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
|
@ -0,0 +1,31 @@
|
||||
package mineplex.minecraft.game.core.boss;
|
||||
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
public class EventCreatureDeathEvent extends Event
|
||||
{
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private EventCreature _creature;
|
||||
|
||||
public EventCreatureDeathEvent(EventCreature creature)
|
||||
{
|
||||
_creature = creature;
|
||||
}
|
||||
|
||||
public EventCreature getCreature()
|
||||
{
|
||||
return _creature;
|
||||
}
|
||||
|
||||
public HandlerList getHandlers()
|
||||
{
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList()
|
||||
{
|
||||
return handlers;
|
||||
}
|
||||
}
|
@ -7,16 +7,6 @@ import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
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.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import mineplex.core.blockrestore.BlockRestore;
|
||||
import mineplex.core.blockrestore.BlockRestoreMap;
|
||||
import mineplex.core.common.block.BlockData;
|
||||
@ -40,6 +30,17 @@ import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.minecraft.game.core.condition.ConditionManager;
|
||||
import mineplex.minecraft.game.core.damage.DamageManager;
|
||||
|
||||
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.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public abstract class WorldEvent implements Listener, ScoreboardElement
|
||||
{
|
||||
// 20 Minutes
|
||||
@ -269,6 +270,7 @@ public abstract class WorldEvent implements Listener, ScoreboardElement
|
||||
|
||||
public void removeCreature(EventCreature<?> creature)
|
||||
{
|
||||
Bukkit.getPluginManager().callEvent(new EventCreatureDeathEvent(creature));
|
||||
HandlerList.unregisterAll(creature);
|
||||
_creatures.remove(creature);
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public class GolemBoss extends WorldEvent
|
||||
|
||||
private GolemCreature spawnGolem(Location location)
|
||||
{
|
||||
GolemCreature golemCreature = new GolemCreature(this, location, 2500);
|
||||
GolemCreature golemCreature = new GolemCreature(this, location, 3000);
|
||||
registerCreature(golemCreature);
|
||||
return golemCreature;
|
||||
}
|
||||
|
@ -45,6 +45,11 @@ import org.bukkit.util.Vector;
|
||||
|
||||
public class GolemCreature extends EventCreature<IronGolem>
|
||||
{
|
||||
//private static final double HEALTH_PER_REGEN = 5;
|
||||
//private static final long HEALTH_REGEN_DELAY = 1000;
|
||||
//private static final long REGEN_SAFE_TIME_NEED = 10000;
|
||||
//private static final double CROWD_CONTROL_DAMAGE_REDUCTION = .70;
|
||||
//private final double MAX_HEALTH;
|
||||
private GolemBoss _boss;
|
||||
// private GolemAbility _currentAbility;
|
||||
private int _lastAbility;
|
||||
@ -59,10 +64,14 @@ public class GolemCreature extends EventCreature<IronGolem>
|
||||
private double _canDeadlyTremor = 225;
|
||||
private Vector _afkWalk = new Vector();
|
||||
private long _lastSlam;
|
||||
//private long _lastHit;
|
||||
//private long _lastRegenerate;
|
||||
|
||||
public GolemCreature(GolemBoss boss, Location location, double maxHealth)
|
||||
{
|
||||
super(boss, location, "Iron Wizard", true, maxHealth, IronGolem.class);
|
||||
//MAX_HEALTH = maxHealth;
|
||||
//_lastRegenerate = System.currentTimeMillis() + 20000;
|
||||
_boss = boss;
|
||||
|
||||
spawnEntity();
|
||||
@ -87,6 +96,10 @@ public class GolemCreature extends EventCreature<IronGolem>
|
||||
{
|
||||
GolemBlockShot.class
|
||||
});
|
||||
_preferedCombos.put(GolemBlockHail.class, new Class[]
|
||||
{
|
||||
GolemDeadlyTremor.class
|
||||
});
|
||||
}
|
||||
|
||||
private boolean hasFurther(HashMap<Player, Double> distances, double range)
|
||||
@ -130,6 +143,13 @@ public class GolemCreature extends EventCreature<IronGolem>
|
||||
_standing = getEntity().getLocation();
|
||||
return;
|
||||
}
|
||||
|
||||
/*if (UtilTime.elapsed(_lastHit, REGEN_SAFE_TIME_NEED) && UtilTime.elapsed(_lastRegenerate, HEALTH_REGEN_DELAY))
|
||||
{
|
||||
_lastRegenerate = System.currentTimeMillis();
|
||||
super.setHealth(Math.min(MAX_HEALTH, getHealth() + HEALTH_PER_REGEN));
|
||||
setHealth(getHealth() + HEALTH_PER_REGEN);
|
||||
}*/
|
||||
|
||||
// if (_currentAbility == null || _currentAbility.hasFinished())
|
||||
// {
|
||||
@ -277,7 +297,7 @@ public class GolemCreature extends EventCreature<IronGolem>
|
||||
|
||||
if (!players.isEmpty())
|
||||
{
|
||||
int we = _lastAttack == GolemEarthquake.class ? 5 : UtilMath.r(4) - 2;
|
||||
int we = _lastAttack == GolemEarthquake.class ? 20 : UtilMath.r(15) - 2;
|
||||
|
||||
if (we > 0)
|
||||
{
|
||||
@ -528,6 +548,11 @@ public class GolemCreature extends EventCreature<IronGolem>
|
||||
if (event.GetDamageeEntity().equals(getEntity()))
|
||||
{
|
||||
event.AddKnockback("Heavy Golem", 0.3);
|
||||
//_lastHit = System.currentTimeMillis();
|
||||
/*if (UtilPlayer.getInRadius(getEntity().getLocation(), 10).size() >= 3)
|
||||
{
|
||||
event.AddMult(getEntity().getName(), "Level Field", CROWD_CONTROL_DAMAGE_REDUCTION, false);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -587,9 +612,7 @@ public class GolemCreature extends EventCreature<IronGolem>
|
||||
public void setHealth(double health)
|
||||
{
|
||||
_canDeadlyTremor -= getHealth() - health;
|
||||
|
||||
super.setHealth(health);
|
||||
|
||||
if (getHealth() <= 100 && !_usedFinalAttack)
|
||||
{
|
||||
endAbility();
|
||||
|
@ -407,7 +407,7 @@ public class GolemBlockHail extends BossAbility<GolemCreature, IronGolem>
|
||||
|
||||
for (int i = 1; i <= _currentLevel; i++)
|
||||
{
|
||||
if (_floatingBlocks.containsKey(i))
|
||||
if (_floatingBlocks.containsKey(i) && !_floatingBlocks.get(i).isEmpty())
|
||||
{
|
||||
floatingBlock = _floatingBlocks.get(i).remove(0);
|
||||
|
||||
|
@ -20,7 +20,7 @@ import org.bukkit.util.Vector;
|
||||
|
||||
public class GolemDeadlyTremor extends BossAbility<GolemCreature, IronGolem>
|
||||
{
|
||||
private static final long ATTACK_DURATION = 16000;
|
||||
private static final long ATTACK_DURATION = 10000;
|
||||
private long _start;
|
||||
|
||||
public GolemDeadlyTremor(GolemCreature creature)
|
||||
@ -56,7 +56,7 @@ public class GolemDeadlyTremor extends BossAbility<GolemCreature, IronGolem>
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
for (Player player : UtilPlayer.getInRadius(getLocation(), 80).keySet())
|
||||
for (Player player : UtilPlayer.getInRadius(getLocation(), 40).keySet())
|
||||
{
|
||||
player.playSound(player.getLocation(), Sound.MINECART_BASE, 0.2f, 0.2f);
|
||||
|
||||
|
@ -1,33 +0,0 @@
|
||||
package mineplex.minecraft.game.core.boss.necromancer.abilities;
|
||||
|
||||
import mineplex.minecraft.game.core.boss.necromancer.minion.WraithCreature;
|
||||
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
public class WraithDeathEvent extends Event
|
||||
{
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private WraithCreature _wraith;
|
||||
|
||||
public WraithDeathEvent(WraithCreature wraith)
|
||||
{
|
||||
_wraith = wraith;
|
||||
}
|
||||
|
||||
public WraithCreature getWraith()
|
||||
{
|
||||
return _wraith;
|
||||
}
|
||||
|
||||
public HandlerList getHandlers()
|
||||
{
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList()
|
||||
{
|
||||
return handlers;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package mineplex.minecraft.game.core.boss.necromancer;
|
||||
package mineplex.minecraft.game.core.boss.skeletonking;
|
||||
|
||||
import mineplex.core.blockrestore.BlockRestore;
|
||||
import mineplex.core.common.util.F;
|
||||
@ -7,20 +7,20 @@ import mineplex.core.projectile.ProjectileManager;
|
||||
import mineplex.minecraft.game.core.boss.EventCreature;
|
||||
import mineplex.minecraft.game.core.boss.EventState;
|
||||
import mineplex.minecraft.game.core.boss.WorldEvent;
|
||||
import mineplex.minecraft.game.core.boss.necromancer.abilities.WraithDeathEvent;
|
||||
import mineplex.minecraft.game.core.boss.necromancer.minion.MinionType;
|
||||
import mineplex.minecraft.game.core.boss.necromancer.minion.WraithCreature;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.minion.MinionType;
|
||||
import mineplex.minecraft.game.core.condition.ConditionManager;
|
||||
import mineplex.minecraft.game.core.damage.DamageManager;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
|
||||
public class NecromancerBoss extends WorldEvent
|
||||
public class SkeletonBoss extends WorldEvent
|
||||
{
|
||||
public NecromancerBoss(DamageManager damageManager, BlockRestore blockRestore, ConditionManager conditionManager, ProjectileManager projectileManager, Location cornerLocation)
|
||||
protected boolean canMove = false;
|
||||
|
||||
public SkeletonBoss(DamageManager damageManager, BlockRestore blockRestore, ConditionManager conditionManager, ProjectileManager projectileManager, Location cornerLocation)
|
||||
{
|
||||
super(DisguiseManager.INSTANCE, projectileManager, damageManager, blockRestore, conditionManager, "Necromancer", cornerLocation,
|
||||
super(DisguiseManager.INSTANCE, projectileManager, damageManager, blockRestore, conditionManager, "Skeleton King", cornerLocation,
|
||||
"schematic/Golem.schematic");
|
||||
}
|
||||
|
||||
@ -34,11 +34,11 @@ public class NecromancerBoss extends WorldEvent
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this necromancer boss has been defeated
|
||||
* Check if this skeleton boss has been defeated
|
||||
*/
|
||||
private void checkDeath()
|
||||
{
|
||||
if (getCreatures().size() == 0)
|
||||
if (getBossesAlive() == 0)
|
||||
{
|
||||
setState(EventState.COMPLETE);
|
||||
Bukkit.broadcastMessage(F.main(getName(), "The demonic " + getName() + " has been slain!"));
|
||||
@ -50,15 +50,22 @@ public class NecromancerBoss extends WorldEvent
|
||||
{
|
||||
super.removeCreature(creature);
|
||||
|
||||
if (creature instanceof NecromancerCreature)
|
||||
if (creature instanceof SkeletonCreature)
|
||||
{
|
||||
checkDeath();
|
||||
}
|
||||
if (creature instanceof WraithCreature)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setState(EventState state)
|
||||
{
|
||||
super.setState(state);
|
||||
if (state == EventState.LIVE)
|
||||
{
|
||||
WraithDeathEvent event = new WraithDeathEvent((WraithCreature)creature);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
Bukkit.broadcastMessage("Calling Wraith Death");
|
||||
Bukkit.getScheduler().runTaskLater(getPlugin(), () ->
|
||||
{
|
||||
canMove = true;
|
||||
}, 20 * 3);
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,10 +79,25 @@ public class NecromancerBoss extends WorldEvent
|
||||
return minionCreature;
|
||||
}
|
||||
|
||||
private NecromancerCreature spawnNecromancer(Location location)
|
||||
private SkeletonCreature spawnNecromancer(Location location)
|
||||
{
|
||||
NecromancerCreature necromancerCreature = new NecromancerCreature(this, location, 2500);
|
||||
SkeletonCreature necromancerCreature = new SkeletonCreature(this, location, 2500);
|
||||
registerCreature(necromancerCreature);
|
||||
return necromancerCreature;
|
||||
}
|
||||
|
||||
private int getBossesAlive()
|
||||
{
|
||||
int alive = 0;
|
||||
|
||||
for (EventCreature creature : getCreatures())
|
||||
{
|
||||
if (creature instanceof SkeletonCreature)
|
||||
{
|
||||
alive++;
|
||||
}
|
||||
}
|
||||
|
||||
return alive;
|
||||
}
|
||||
}
|
@ -1,10 +1,11 @@
|
||||
package mineplex.minecraft.game.core.boss.necromancer;
|
||||
package mineplex.minecraft.game.core.boss.skeletonking;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Random;
|
||||
@ -19,42 +20,60 @@ import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.minecraft.game.core.boss.BossAbility;
|
||||
import mineplex.minecraft.game.core.boss.EventCreature;
|
||||
import mineplex.minecraft.game.core.boss.necromancer.abilities.NecromancerHellishFlood;
|
||||
import mineplex.minecraft.game.core.boss.necromancer.abilities.NecromancerPulse;
|
||||
import mineplex.minecraft.game.core.boss.necromancer.abilities.NecromancerSmite;
|
||||
import mineplex.minecraft.game.core.boss.necromancer.abilities.NecromancerStrike;
|
||||
import mineplex.minecraft.game.core.boss.necromancer.abilities.NecromancerWraithSummon;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.abilities.SkeletonArcherShield;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.abilities.SkeletonPassive;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.abilities.SkeletonPulse;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.abilities.SkeletonSmite;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.abilities.SkeletonStrike;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.abilities.SkeletonWraithSummon;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.minion.UndeadArcherCreature;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.minion.UndeadWarriorCreature;
|
||||
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Skeleton;
|
||||
import org.bukkit.entity.Skeleton.SkeletonType;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class NecromancerCreature extends EventCreature<Skeleton>
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
public class SkeletonCreature extends EventCreature<Skeleton>
|
||||
{
|
||||
private ArrayList<BossAbility> _currentAbilities = new ArrayList<BossAbility>();
|
||||
private ArrayList<BossAbility> _currentAbilities = Lists.newArrayList();
|
||||
private SkeletonPassive _passive;
|
||||
private int _lastAbility;
|
||||
private HashMap<Class, Long> _cooldowns = new HashMap<Class, Long>();
|
||||
private boolean _hasUsedWraiths;
|
||||
private List<Location> _movePoints;
|
||||
private HashMap<Class, Long> _cooldowns = new HashMap<>();
|
||||
private LinkedList<Double> _wraithTriggers = new LinkedList<>();
|
||||
private List<Location> _movePoints = Lists.newArrayList();
|
||||
private Location _movingTo;
|
||||
private boolean _moving;
|
||||
private long _lastMoved;
|
||||
private long _lastUsedPassive;
|
||||
public List<UndeadArcherCreature> Archers = Lists.newArrayList();
|
||||
public List<UndeadWarriorCreature> Warriors = Lists.newArrayList();
|
||||
|
||||
public NecromancerCreature(NecromancerBoss boss, Location location, double maxHealth)
|
||||
public SkeletonCreature(SkeletonBoss boss, Location location, double maxHealth)
|
||||
{
|
||||
super(boss, location, "Necromancer", true, maxHealth, Skeleton.class);
|
||||
super(boss, location, "Skeleton King", true, maxHealth, Skeleton.class);
|
||||
|
||||
spawnEntity();
|
||||
_passive = new SkeletonPassive(this);
|
||||
_wraithTriggers.add(1500D);
|
||||
_wraithTriggers.add(1000D);
|
||||
_wraithTriggers.add(500D);
|
||||
_wraithTriggers.add(100D);
|
||||
getEntity().getWorld().setThunderDuration(10000000);
|
||||
getEntity().getWorld().setThundering(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -69,7 +88,11 @@ public class NecromancerCreature extends EventCreature<Skeleton>
|
||||
@Override
|
||||
public void dieCustom()
|
||||
{
|
||||
HandlerList.unregisterAll(_passive);
|
||||
_passive = null;
|
||||
endAbility();
|
||||
getEntity().getWorld().setThunderDuration(0);
|
||||
getEntity().getWorld().setThundering(false);
|
||||
}
|
||||
|
||||
private void endAbility()
|
||||
@ -90,6 +113,15 @@ public class NecromancerCreature extends EventCreature<Skeleton>
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_passive != null && ((SkeletonBoss)getEvent()).canMove)
|
||||
{
|
||||
if (UtilTime.elapsed(_lastUsedPassive, _passive.getCooldown() * 20) || _passive.isProgressing())
|
||||
{
|
||||
_lastUsedPassive = System.currentTimeMillis();
|
||||
_passive.tick();
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<BossAbility> itel = _currentAbilities.iterator();
|
||||
boolean canDoNew = _currentAbilities.size() < 3;
|
||||
@ -131,19 +163,19 @@ public class NecromancerCreature extends EventCreature<Skeleton>
|
||||
|
||||
if (!dist.isEmpty())
|
||||
{
|
||||
{// Strike and Pulse
|
||||
ArrayList<Player> players = getPlayers(dist, UtilMath.r(10) == 0 ? 20 : 16);
|
||||
{// Pulse & Strike
|
||||
ArrayList<Player> players = getPlayers(dist, UtilMath.r(10) == 0 ? 25 : 20);
|
||||
ArrayList<Player> near = getPlayers(dist, 5);
|
||||
|
||||
if (!players.isEmpty())
|
||||
{
|
||||
if (!near.isEmpty() && near.size() >= 4 && new Random().nextDouble() <= .45)
|
||||
{
|
||||
weight.put(NecromancerPulse.class, 999);
|
||||
weight.put(SkeletonPulse.class, 999);
|
||||
}
|
||||
else
|
||||
{
|
||||
weight.put(NecromancerStrike.class, 6);
|
||||
weight.put(SkeletonStrike.class, 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -152,32 +184,43 @@ public class NecromancerCreature extends EventCreature<Skeleton>
|
||||
|
||||
if (!players.isEmpty())
|
||||
{
|
||||
weight.put(NecromancerSmite.class, 6);
|
||||
weight.put(SkeletonSmite.class, 6);
|
||||
}
|
||||
}
|
||||
if (getHealthPercent() < .7)
|
||||
{//Hellish Flood
|
||||
{//Archer Shield
|
||||
ArrayList<Player> players = getPlayers(dist, 20);
|
||||
double score = 0;
|
||||
for (Player player : players)
|
||||
{
|
||||
score += (18 - dist.get(player)) / 2;
|
||||
}
|
||||
if (players.size() >= 4 || (!players.isEmpty() && players.get(0).isOp()))
|
||||
if (players.size() >= 4)
|
||||
{
|
||||
score += 17;
|
||||
}
|
||||
if (score > 0)
|
||||
{
|
||||
weight.put(NecromancerHellishFlood.class, (int) Math.ceil(score));
|
||||
weight.put(SkeletonArcherShield.class, (int) Math.ceil(score));
|
||||
}
|
||||
}
|
||||
Bukkit.broadcastMessage(_hasUsedWraiths + "");
|
||||
if (getHealth() <= 90 && !_hasUsedWraiths)
|
||||
Double wraithUse = null;
|
||||
for (Double test : _wraithTriggers)
|
||||
{
|
||||
if (wraithUse == null)
|
||||
{
|
||||
if (getHealth() <= test)
|
||||
{
|
||||
Bukkit.broadcastMessage(test + "Verified");
|
||||
wraithUse = test;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (wraithUse != null)
|
||||
{// Wraith Summon
|
||||
_hasUsedWraiths = true;
|
||||
_wraithTriggers.remove(wraithUse);
|
||||
weight.clear();
|
||||
weight.put(NecromancerWraithSummon.class, 999);
|
||||
weight.put(SkeletonWraithSummon.class, 999);
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,7 +279,7 @@ public class NecromancerCreature extends EventCreature<Skeleton>
|
||||
{
|
||||
try
|
||||
{
|
||||
ability = entry.getKey().getConstructor(NecromancerCreature.class).newInstance(this);
|
||||
ability = entry.getKey().getConstructor(SkeletonCreature.class).newInstance(this);
|
||||
|
||||
if (ability.getTarget() == null || ability.hasFinished())
|
||||
{
|
||||
@ -284,6 +327,10 @@ public class NecromancerCreature extends EventCreature<Skeleton>
|
||||
canMove = false;
|
||||
}
|
||||
}
|
||||
if (!((SkeletonBoss)getEvent()).canMove)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_moving)
|
||||
{
|
||||
@ -291,7 +338,7 @@ public class NecromancerCreature extends EventCreature<Skeleton>
|
||||
{
|
||||
_movingTo = selectWalkTarget();
|
||||
}
|
||||
if (UtilMath.offset(getEntity().getLocation(), _movingTo) > 1.3)
|
||||
if (UtilMath.offset(getEntity().getLocation(), _movingTo) <= 1.3)
|
||||
{
|
||||
_lastMoved = System.currentTimeMillis();
|
||||
_movingTo = null;
|
||||
@ -301,6 +348,7 @@ public class NecromancerCreature extends EventCreature<Skeleton>
|
||||
UtilEnt.LookAt(getEntity(), _movingTo);
|
||||
Vector walk = UtilAlg.getTrajectory(getEntity().getLocation(), _movingTo);
|
||||
walk.multiply(walk.length());
|
||||
walk.multiply(.2);
|
||||
getEntity().setVelocity(walk);
|
||||
}
|
||||
else
|
||||
@ -318,7 +366,9 @@ public class NecromancerCreature extends EventCreature<Skeleton>
|
||||
{
|
||||
if (_movePoints.isEmpty())
|
||||
{
|
||||
generateWalkPoints(getEntity().getLocation());
|
||||
Location base = getSpawnLocation().clone();
|
||||
base.setY(getEntity().getLocation().getY());
|
||||
generateWalkPoints(base);
|
||||
}
|
||||
Location selected = _movePoints.get(new Random().nextInt(_movePoints.size()));
|
||||
_movePoints.remove(selected);
|
||||
@ -365,7 +415,7 @@ public class NecromancerCreature extends EventCreature<Skeleton>
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onNecromancerDamage(CustomDamageEvent event)
|
||||
public void onSkeletonDamage(CustomDamageEvent event)
|
||||
{
|
||||
if (event.GetDamageeEntity().getEntityId() == getEntity().getEntityId())
|
||||
{
|
||||
@ -389,4 +439,34 @@ public class NecromancerCreature extends EventCreature<Skeleton>
|
||||
event.SetCancelled("Boss Invulnerability");
|
||||
}
|
||||
}
|
||||
|
||||
@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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,186 @@
|
||||
package mineplex.minecraft.game.core.boss.skeletonking.abilities;
|
||||
|
||||
import mineplex.core.common.util.UtilAction;
|
||||
import mineplex.core.common.util.UtilAlg;
|
||||
import mineplex.core.common.util.UtilEnt;
|
||||
import mineplex.core.common.util.UtilParticle;
|
||||
import mineplex.core.common.util.UtilParticle.ParticleType;
|
||||
import mineplex.core.common.util.UtilParticle.ViewDist;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.minecraft.game.core.boss.BossAbility;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonCreature;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.minion.UndeadArcherCreature;
|
||||
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftSkeleton;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Skeleton;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.ProjectileHitEvent;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class SkeletonArcherShield extends BossAbility<SkeletonCreature, Skeleton>
|
||||
{
|
||||
private static long ATTACK_DURATION = 10000;
|
||||
private static long ARROW_DELAY = 100;
|
||||
private static long ARROW_WARMUP = 2000;
|
||||
private static double PULL_RANGE = 12;
|
||||
private long _start;
|
||||
private long _lastShoot;
|
||||
private boolean _teleported;
|
||||
|
||||
public SkeletonArcherShield(SkeletonCreature creature)
|
||||
{
|
||||
super(creature);
|
||||
_start = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCooldown()
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMove()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inProgress()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFinished()
|
||||
{
|
||||
return UtilTime.elapsed(_start, ATTACK_DURATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFinished()
|
||||
{
|
||||
_start = System.currentTimeMillis() - ATTACK_DURATION;
|
||||
for (UndeadArcherCreature creature : getBoss().Archers)
|
||||
{
|
||||
creature.getEntity().remove();
|
||||
}
|
||||
}
|
||||
|
||||
private void run(boolean initial)
|
||||
{
|
||||
for (int i = 0; i < getBoss().Archers.size(); i++)
|
||||
{
|
||||
Skeleton archer = getBoss().Archers.get(i).getEntity();
|
||||
UtilEnt.Vegetate(archer);
|
||||
((CraftSkeleton)archer).setVegetated(false);
|
||||
|
||||
double lead = i * ((2d * Math.PI)/getBoss().Archers.size());
|
||||
|
||||
double sizeMod = 2;
|
||||
|
||||
//Orbit
|
||||
double speed = 10d;
|
||||
double oX = -Math.sin(getEntity().getTicksLived()/speed + lead) * 2 * sizeMod;
|
||||
double oY = 0;
|
||||
double oZ = Math.cos(getEntity().getTicksLived()/speed + lead) * 2 * sizeMod;
|
||||
|
||||
if (initial)
|
||||
{
|
||||
archer.teleport(getEntity().getLocation().add(oX, oY, oZ));
|
||||
UtilEnt.Vegetate(archer);
|
||||
}
|
||||
else
|
||||
{
|
||||
Location to = getEntity().getLocation().add(oX, oY, oZ);
|
||||
UtilEnt.LookAt(archer, to);
|
||||
UtilAction.velocity(archer, UtilAlg.getTrajectory(archer.getLocation(), to), 0.4, false, 0, 0.1, 1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void shoot()
|
||||
{
|
||||
if (UtilTime.elapsed(_start, ARROW_WARMUP) && UtilTime.elapsed(_lastShoot, ARROW_DELAY))
|
||||
{
|
||||
_lastShoot = System.currentTimeMillis();
|
||||
for (UndeadArcherCreature archer : getBoss().Archers)
|
||||
{
|
||||
Location spawn = archer.getEntity().getEyeLocation().add(UtilAlg.getTrajectory(getEntity().getEyeLocation(), archer.getEntity().getEyeLocation()).normalize());
|
||||
Vector vector = UtilAlg.getTrajectory(getEntity().getEyeLocation(), spawn);
|
||||
Arrow arrow = archer.getEntity().getWorld().spawnArrow(spawn, vector, 0.6f, 12f);
|
||||
arrow.setMetadata("SHIELD_SHOT", new FixedMetadataValue(getBoss().getEvent().getPlugin(), true));
|
||||
arrow.setMetadata("BARBED_ARROW", new FixedMetadataValue(getBoss().getEvent().getPlugin(), 10));
|
||||
arrow.setShooter(archer.getEntity());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
if (!_teleported)
|
||||
{
|
||||
run(true);
|
||||
_teleported = true;
|
||||
for (Player near : UtilPlayer.getInRadius(getEntity().getLocation(), PULL_RANGE).keySet())
|
||||
{
|
||||
Vector velocity = UtilAlg.getTrajectory(near, getEntity());
|
||||
UtilAction.velocity(near, velocity, 2, false, 0, 0, 1, true);
|
||||
near.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 5 * 20, -2));
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
Vector random = new Vector(Math.random() * 4 - 2, Math.random() * 4 - 2, Math.random() * 4 - 2);
|
||||
|
||||
Location origin = getEntity().getLocation().add(0, 1.3, 0);
|
||||
origin.add(velocity.clone().multiply(10));
|
||||
origin.add(random);
|
||||
|
||||
Vector vel = UtilAlg.getTrajectory(origin, getEntity().getLocation().add(0, 1.3, 0));
|
||||
vel.multiply(7);
|
||||
|
||||
UtilParticle.PlayParticleToAll(ParticleType.MAGIC_CRIT, origin, (float)vel.getX(), (float)vel.getY(), (float)vel.getZ(), 1, 0, ViewDist.LONG);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
run(false);
|
||||
shoot();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onDamage(CustomDamageEvent event)
|
||||
{
|
||||
if (event.GetDamageeEntity().equals(getBoss().getEntity()))
|
||||
{
|
||||
if (!hasFinished())
|
||||
{
|
||||
event.SetCancelled("Wraiths Alive");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onArrowHit(ProjectileHitEvent event)
|
||||
{
|
||||
if (event.getEntity().hasMetadata("SHIELD_SHOT"))
|
||||
{
|
||||
Bukkit.getScheduler().runTaskLater(getBoss().getEvent().getPlugin(), () ->
|
||||
{
|
||||
event.getEntity().remove();
|
||||
}, 20L);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +1,22 @@
|
||||
package mineplex.minecraft.game.core.boss.necromancer.abilities;
|
||||
package mineplex.minecraft.game.core.boss.skeletonking.abilities;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
import mineplex.core.common.util.UtilParticle;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.core.common.util.UtilParticle.ParticleType;
|
||||
import mineplex.core.common.util.UtilParticle.ViewDist;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.minecraft.game.core.boss.BossAbility;
|
||||
import mineplex.minecraft.game.core.boss.necromancer.NecromancerBoss;
|
||||
import mineplex.minecraft.game.core.boss.necromancer.NecromancerCreature;
|
||||
import mineplex.minecraft.game.core.boss.necromancer.minion.MinionType;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonBoss;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonCreature;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.minion.MinionType;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Skeleton;
|
||||
|
||||
public class NecromancerHellishFlood extends BossAbility<NecromancerCreature, Skeleton>
|
||||
public class SkeletonHellishFlood extends BossAbility<SkeletonCreature, Skeleton>
|
||||
{
|
||||
private static final int WAVE_COUNT = 3;
|
||||
private static final int WAVE_SIZE = 5;
|
||||
@ -29,7 +28,7 @@ public class NecromancerHellishFlood extends BossAbility<NecromancerCreature, Sk
|
||||
private int _current;
|
||||
private int _ticks;
|
||||
|
||||
public NecromancerHellishFlood(NecromancerCreature creature)
|
||||
public SkeletonHellishFlood(SkeletonCreature creature)
|
||||
{
|
||||
super(creature);
|
||||
|
||||
@ -96,7 +95,6 @@ public class NecromancerHellishFlood extends BossAbility<NecromancerCreature, Sk
|
||||
_ticks++;
|
||||
if (UtilTime.elapsed(_lastSpawned, WAVE_DELAY))
|
||||
{
|
||||
Bukkit.broadcastMessage("Current: " + _current + ", Size: " + WAVE_COUNT);
|
||||
if (_current <= WAVE_COUNT)
|
||||
{
|
||||
for (MinionType type : _waves.get("Wave " + _current))
|
||||
@ -104,16 +102,14 @@ public class NecromancerHellishFlood extends BossAbility<NecromancerCreature, Sk
|
||||
Location toSpawn = getLocation().clone();
|
||||
toSpawn.add(UtilMath.random(3, 6), 0, UtilMath.random(3, 6));
|
||||
|
||||
((NecromancerBoss)getBoss().getEvent()).spawnMinion(type, toSpawn);
|
||||
((SkeletonBoss)getBoss().getEvent()).spawnMinion(type, toSpawn);
|
||||
|
||||
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, toSpawn, null, 0, 2, ViewDist.MAX);
|
||||
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, toSpawn, null, 0, 2, ViewDist.MAX);
|
||||
}
|
||||
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, getEntity().getLocation(), null, 0, 2, ViewDist.MAX);
|
||||
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, getEntity().getLocation(), null, 0, 2, ViewDist.MAX);
|
||||
Bukkit.broadcastMessage(_waves.size() + " - Initial");
|
||||
_waves.remove("Wave " + _current);
|
||||
Bukkit.broadcastMessage(_waves.size() + " - After");
|
||||
_current++;
|
||||
_lastSpawned = System.currentTimeMillis();
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
package mineplex.minecraft.game.core.boss.skeletonking.abilities;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
import mineplex.core.common.util.UtilParticle;
|
||||
import mineplex.core.common.util.UtilParticle.ParticleType;
|
||||
import mineplex.core.common.util.UtilParticle.ViewDist;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.minecraft.game.core.boss.BossPassive;
|
||||
import mineplex.minecraft.game.core.boss.EventCreatureDeathEvent;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonBoss;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonCreature;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.minion.MinionType;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.minion.UndeadArcherCreature;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.minion.UndeadWarriorCreature;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Skeleton;
|
||||
import org.bukkit.event.EventHandler;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
public class SkeletonPassive extends BossPassive<SkeletonCreature, Skeleton>
|
||||
{
|
||||
private static final int MAX_ARCHERS = 10;
|
||||
private static final int MAX_WARRIORS = 8;
|
||||
private static final long SPAWN_RATE = 1000;
|
||||
private List<Location> _queuedArchers = Lists.newArrayList();
|
||||
private List<Location> _queuedWarriors = Lists.newArrayList();
|
||||
private long _lastASpawned;
|
||||
private long _lastWSpawned;
|
||||
|
||||
public SkeletonPassive(SkeletonCreature creature)
|
||||
{
|
||||
super(creature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCooldown()
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProgressing()
|
||||
{
|
||||
return !_queuedArchers.isEmpty() || !_queuedWarriors.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
if (getBoss().Archers.size() < MAX_ARCHERS && _queuedArchers.isEmpty())
|
||||
{
|
||||
for (int i = 0; i < (MAX_ARCHERS - getBoss().Archers.size()); i++)
|
||||
{
|
||||
Location spawn = getLocation().clone();
|
||||
spawn.add(UtilMath.random(3, 6), 0, UtilMath.random(3, 6));
|
||||
_queuedArchers.add(spawn);
|
||||
}
|
||||
}
|
||||
if (getBoss().Warriors.size() < MAX_WARRIORS && _queuedWarriors.isEmpty())
|
||||
{
|
||||
for (int i = 0; i < (MAX_WARRIORS - getBoss().Warriors.size()); i++)
|
||||
{
|
||||
Location spawn = getLocation().clone();
|
||||
spawn.add(UtilMath.random(3, 6), 0, UtilMath.random(3, 6));
|
||||
_queuedWarriors.add(spawn);
|
||||
}
|
||||
}
|
||||
|
||||
for (Location animate : _queuedArchers)
|
||||
{
|
||||
UtilParticle.PlayParticleToAll(ParticleType.BLOCK_DUST.getParticle(Material.DIRT, 0),
|
||||
animate.clone().add(0, 0.2, 0), null, 0, 4, ViewDist.NORMAL);
|
||||
}
|
||||
for (Location animate : _queuedWarriors)
|
||||
{
|
||||
UtilParticle.PlayParticleToAll(ParticleType.BLOCK_DUST.getParticle(Material.DIRT, 0),
|
||||
animate.clone().add(0, 0.2, 0), null, 0, 4, ViewDist.NORMAL);
|
||||
}
|
||||
|
||||
if (!_queuedArchers.isEmpty() && UtilTime.elapsed(_lastASpawned, SPAWN_RATE))
|
||||
{
|
||||
_lastASpawned = System.currentTimeMillis();
|
||||
Location spawn = _queuedArchers.remove(0);
|
||||
getBoss().Archers.add((UndeadArcherCreature) ((SkeletonBoss)getBoss().getEvent()).spawnMinion(MinionType.ARCHER, spawn));
|
||||
|
||||
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, spawn, null, 0, 2, ViewDist.MAX);
|
||||
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, spawn, null, 0, 2, ViewDist.MAX);
|
||||
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, getEntity().getLocation(), null, 0, 2, ViewDist.MAX);
|
||||
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, getEntity().getLocation(), null, 0, 2, ViewDist.MAX);
|
||||
}
|
||||
if (!_queuedWarriors.isEmpty() && UtilTime.elapsed(_lastWSpawned, SPAWN_RATE))
|
||||
{
|
||||
_lastWSpawned = System.currentTimeMillis();
|
||||
Location spawn = _queuedWarriors.remove(0);
|
||||
getBoss().Warriors.add((UndeadWarriorCreature) ((SkeletonBoss)getBoss().getEvent()).spawnMinion(MinionType.WARRIOR, spawn));
|
||||
|
||||
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, spawn, null, 0, 2, ViewDist.MAX);
|
||||
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, spawn, null, 0, 2, ViewDist.MAX);
|
||||
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, getEntity().getLocation(), null, 0, 2, ViewDist.MAX);
|
||||
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, getEntity().getLocation(), null, 0, 2, ViewDist.MAX);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onArcherDeath(EventCreatureDeathEvent event)
|
||||
{
|
||||
if (event.getCreature() instanceof UndeadArcherCreature)
|
||||
{
|
||||
getBoss().Archers.remove(event.getCreature());
|
||||
}
|
||||
if (event.getCreature() instanceof UndeadWarriorCreature)
|
||||
{
|
||||
getBoss().Warriors.remove(event.getCreature());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package mineplex.minecraft.game.core.boss.necromancer.abilities;
|
||||
package mineplex.minecraft.game.core.boss.skeletonking.abilities;
|
||||
|
||||
import mineplex.core.common.util.UtilAction;
|
||||
import mineplex.core.common.util.UtilAlg;
|
||||
@ -9,7 +9,7 @@ import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.core.recharge.Recharge;
|
||||
import mineplex.minecraft.game.core.boss.BossAbility;
|
||||
import mineplex.minecraft.game.core.boss.necromancer.NecromancerCreature;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonCreature;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
@ -17,14 +17,15 @@ import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Skeleton;
|
||||
|
||||
public class NecromancerPulse extends BossAbility<NecromancerCreature, Skeleton>
|
||||
public class SkeletonPulse extends BossAbility<SkeletonCreature, Skeleton>
|
||||
{
|
||||
private static final long TOTAL_ATTACK_DURATION = 3000;
|
||||
private static final long TOTAL_ATTACK_DURATION = 8000;
|
||||
private static final long TOTAL_ATTACK_PROGRESS = 3000;
|
||||
private long _start, _lastIncrement;
|
||||
private int _radius;
|
||||
private Location _center;
|
||||
|
||||
public NecromancerPulse(NecromancerCreature creature)
|
||||
public SkeletonPulse(SkeletonCreature creature)
|
||||
{
|
||||
super(creature);
|
||||
_start = System.currentTimeMillis();
|
||||
@ -35,7 +36,7 @@ public class NecromancerPulse extends BossAbility<NecromancerCreature, Skeleton>
|
||||
|
||||
private int getRadius()
|
||||
{
|
||||
return Math.min(6, _radius);
|
||||
return Math.min(8, _radius);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -47,13 +48,13 @@ public class NecromancerPulse extends BossAbility<NecromancerCreature, Skeleton>
|
||||
@Override
|
||||
public boolean canMove()
|
||||
{
|
||||
return false;
|
||||
return UtilTime.elapsed(_start, TOTAL_ATTACK_PROGRESS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inProgress()
|
||||
{
|
||||
return true;
|
||||
return UtilTime.elapsed(_start, TOTAL_ATTACK_PROGRESS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -82,7 +83,7 @@ public class NecromancerPulse extends BossAbility<NecromancerCreature, Skeleton>
|
||||
double x = getRadius() * Math.cos(token);
|
||||
double z = getRadius() * Math.sin(token);
|
||||
|
||||
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, _center.clone().add(x, 0.3, z), null, 0, 1, ViewDist.MAX);
|
||||
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, _center.clone().add(x, 1.5, z), null, 0, 1, ViewDist.MAX);
|
||||
}
|
||||
|
||||
for (Player player : UtilPlayer.getInRadius(getEntity().getLocation(), getRadius()).keySet())
|
||||
@ -101,7 +102,7 @@ public class NecromancerPulse extends BossAbility<NecromancerCreature, Skeleton>
|
||||
}
|
||||
|
||||
player.playSound(player.getLocation(), Sound.AMBIENCE_THUNDER, 1f, 1f);
|
||||
UtilAction.velocity(player, UtilAlg.getTrajectory2d(getEntity(), player), .2, false, 0.6, 0, 1.4, true);
|
||||
UtilAction.velocity(player, UtilAlg.getTrajectory2d(getEntity(), player), 2, false, 0.6, 0, 1.4, true);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package mineplex.minecraft.game.core.boss.necromancer.abilities;
|
||||
package mineplex.minecraft.game.core.boss.skeletonking.abilities;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@ -8,21 +8,21 @@ import mineplex.core.common.util.UtilParticle.ViewDist;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.minecraft.game.core.boss.BossAbility;
|
||||
import mineplex.minecraft.game.core.boss.necromancer.NecromancerCreature;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonCreature;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Skeleton;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
|
||||
public class NecromancerSmite extends BossAbility<NecromancerCreature, Skeleton>
|
||||
public class SkeletonSmite extends BossAbility<SkeletonCreature, Skeleton>
|
||||
{
|
||||
private static final long TOTAL_ATTACK_DURATION = 8000;
|
||||
private long _start;
|
||||
private int _ticks;
|
||||
private boolean _shot;
|
||||
|
||||
public NecromancerSmite(NecromancerCreature creature)
|
||||
public SkeletonSmite(SkeletonCreature creature)
|
||||
{
|
||||
super(creature);
|
||||
_start = System.currentTimeMillis();
|
@ -1,4 +1,4 @@
|
||||
package mineplex.minecraft.game.core.boss.necromancer.abilities;
|
||||
package mineplex.minecraft.game.core.boss.skeletonking.abilities;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
@ -13,7 +13,7 @@ import mineplex.core.common.util.UtilParticle.ViewDist;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.minecraft.game.core.boss.BossAbility;
|
||||
import mineplex.minecraft.game.core.boss.necromancer.NecromancerCreature;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonCreature;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
@ -23,27 +23,28 @@ import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
public class NecromancerStrike extends BossAbility<NecromancerCreature, Skeleton>
|
||||
public class SkeletonStrike extends BossAbility<SkeletonCreature, Skeleton>
|
||||
{
|
||||
private static final double MAX_RANGE = 20;
|
||||
private static final Integer MAX_TARGETS = 3;
|
||||
private static final double MAX_RANGE = 25;
|
||||
private static final Integer MAX_TARGETS = 1;
|
||||
private boolean _shot;
|
||||
|
||||
public NecromancerStrike(NecromancerCreature creature)
|
||||
public SkeletonStrike(SkeletonCreature creature)
|
||||
{
|
||||
super(creature);
|
||||
_shot = false;
|
||||
}
|
||||
|
||||
private int getPosition(Player toAdd, LinkedList<Player> ordered, HashMap<Player, Double> distances)
|
||||
private int getPosition(Player toAdd, LinkedList<Player> ordered)
|
||||
{
|
||||
int position = ordered.size();
|
||||
int index = 0;
|
||||
for (Player player : ordered)
|
||||
{
|
||||
if (distances.get(player) >= distances.get(toAdd))
|
||||
if (player.getHealth() < toAdd.getHealth())
|
||||
{
|
||||
position = index;
|
||||
return position;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
@ -72,7 +73,7 @@ public class NecromancerStrike extends BossAbility<NecromancerCreature, Skeleton
|
||||
}
|
||||
else
|
||||
{
|
||||
selections.add(getPosition(nearby, selections, near), nearby);
|
||||
selections.add(getPosition(nearby, selections), nearby);
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,7 +102,7 @@ public class NecromancerStrike extends BossAbility<NecromancerCreature, Skeleton
|
||||
canHit = false;
|
||||
break;
|
||||
}
|
||||
if (UtilMath.offset(newTarget, target.getLocation()) <= 0.7)
|
||||
if (UtilMath.offset(newTarget, target.getLocation()) <= 0.9)
|
||||
{
|
||||
canHit = true;
|
||||
break;
|
||||
@ -117,14 +118,14 @@ public class NecromancerStrike extends BossAbility<NecromancerCreature, Skeleton
|
||||
|
||||
if (canHit)
|
||||
{
|
||||
getBoss().getEvent().getDamageManager().NewDamageEvent(target, getEntity(), null, DamageCause.CUSTOM, 10 * getBoss().getDifficulty(), true, true, false, getEntity().getName(), "Mystical Energy");
|
||||
getBoss().getEvent().getDamageManager().NewDamageEvent(target, getEntity(), null, DamageCause.CUSTOM, 12 * getBoss().getDifficulty(), true, true, false, getEntity().getName(), "Mystical Energy");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCooldown()
|
||||
{
|
||||
return 0;
|
||||
return 15;
|
||||
}
|
||||
|
||||
@Override
|
@ -1,20 +1,24 @@
|
||||
package mineplex.minecraft.game.core.boss.necromancer.abilities;
|
||||
package mineplex.minecraft.game.core.boss.skeletonking.abilities;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import mineplex.core.common.util.C;
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.UtilParticle;
|
||||
import mineplex.core.common.util.UtilParticle.ParticleType;
|
||||
import mineplex.core.common.util.UtilParticle.ViewDist;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.minecraft.game.core.boss.BossAbility;
|
||||
import mineplex.minecraft.game.core.boss.necromancer.NecromancerBoss;
|
||||
import mineplex.minecraft.game.core.boss.necromancer.NecromancerCreature;
|
||||
import mineplex.minecraft.game.core.boss.necromancer.minion.MinionType;
|
||||
import mineplex.minecraft.game.core.boss.necromancer.minion.WraithCreature;
|
||||
import mineplex.minecraft.game.core.boss.EventCreatureDeathEvent;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonBoss;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonCreature;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.minion.MinionType;
|
||||
import mineplex.minecraft.game.core.boss.skeletonking.minion.WraithCreature;
|
||||
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -23,27 +27,42 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class NecromancerWraithSummon extends BossAbility<NecromancerCreature, Skeleton>
|
||||
public class SkeletonWraithSummon extends BossAbility<SkeletonCreature, Skeleton>
|
||||
{
|
||||
private static final int WRAITH_AMOUNT = 4;
|
||||
private static final double DISTANCE_FROM_NECROMANCER = 4;
|
||||
private static final double DISTANCE_FROM_KING = 4;
|
||||
private static final double FINAL_SKELETON_HEALTH = 100;
|
||||
private static final double FINAL_WRAITH_MULTIPLIER = 2;
|
||||
private final int WRAITH_AMOUNT_THIS_USE;
|
||||
|
||||
private ConcurrentHashMap<WraithCreature, String> _wraiths = new ConcurrentHashMap<>();
|
||||
private Location[] _spawns;
|
||||
private int _ticks;
|
||||
|
||||
public NecromancerWraithSummon(NecromancerCreature creature)
|
||||
public SkeletonWraithSummon(SkeletonCreature creature)
|
||||
{
|
||||
super(creature);
|
||||
|
||||
_spawns = new Location[]
|
||||
{
|
||||
getEntity().getLocation().add(DISTANCE_FROM_NECROMANCER, 0, DISTANCE_FROM_NECROMANCER),
|
||||
getEntity().getLocation().add(DISTANCE_FROM_NECROMANCER * -1, 0, DISTANCE_FROM_NECROMANCER),
|
||||
getEntity().getLocation().add(DISTANCE_FROM_NECROMANCER, 0, DISTANCE_FROM_NECROMANCER * -1),
|
||||
getEntity().getLocation().add(DISTANCE_FROM_NECROMANCER * -1, 0, DISTANCE_FROM_NECROMANCER * -1)
|
||||
getEntity().getLocation().add(DISTANCE_FROM_KING, 0, DISTANCE_FROM_KING),
|
||||
getEntity().getLocation().add(DISTANCE_FROM_KING * -1, 0, DISTANCE_FROM_KING),
|
||||
getEntity().getLocation().add(DISTANCE_FROM_KING, 0, DISTANCE_FROM_KING * -1),
|
||||
getEntity().getLocation().add(DISTANCE_FROM_KING * -1, 0, DISTANCE_FROM_KING * -1),
|
||||
getEntity().getLocation().add(DISTANCE_FROM_KING / 2, 0, DISTANCE_FROM_KING / 2),
|
||||
getEntity().getLocation().add((DISTANCE_FROM_KING / 2) * -1, 0, DISTANCE_FROM_KING / 2),
|
||||
getEntity().getLocation().add(DISTANCE_FROM_KING / 2, 0, (DISTANCE_FROM_KING / 2) * -1),
|
||||
getEntity().getLocation().add((DISTANCE_FROM_KING / 2) * -1, 0, (DISTANCE_FROM_KING / 2) * -1)
|
||||
};
|
||||
Bukkit.broadcastMessage("Instantiated Wraith");
|
||||
|
||||
if (creature.getHealth() <= FINAL_SKELETON_HEALTH)
|
||||
{
|
||||
WRAITH_AMOUNT_THIS_USE = (int)(WRAITH_AMOUNT * FINAL_WRAITH_MULTIPLIER);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRAITH_AMOUNT_THIS_USE = WRAITH_AMOUNT;
|
||||
}
|
||||
}
|
||||
|
||||
private String getNumberString(Integer number)
|
||||
@ -76,14 +95,14 @@ public class NecromancerWraithSummon extends BossAbility<NecromancerCreature, Sk
|
||||
|
||||
private void spawnWraith(Location loc, int number)
|
||||
{
|
||||
WraithCreature wraith = (WraithCreature)((NecromancerBoss)getBoss().getEvent()).spawnMinion(MinionType.WRAITH, loc);
|
||||
WraithCreature wraith = (WraithCreature)((SkeletonBoss)getBoss().getEvent()).spawnMinion(MinionType.WRAITH, loc);
|
||||
_wraiths.put(wraith, getNumberString(number));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCooldown()
|
||||
{
|
||||
return 9999;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -122,7 +141,7 @@ public class NecromancerWraithSummon extends BossAbility<NecromancerCreature, Sk
|
||||
{
|
||||
if (WRAITH_AMOUNT > 0)
|
||||
{
|
||||
for (int i = 0; i < WRAITH_AMOUNT; i++)
|
||||
for (int i = 0; i < WRAITH_AMOUNT_THIS_USE; i++)
|
||||
{
|
||||
int spawnIndex = i;
|
||||
if (spawnIndex >= _spawns.length)
|
||||
@ -143,7 +162,7 @@ public class NecromancerWraithSummon extends BossAbility<NecromancerCreature, Sk
|
||||
continue;
|
||||
}
|
||||
|
||||
player.sendMessage(F.main(getBoss().getEvent().getName(), "You must slay all " + WRAITH_AMOUNT + " wraiths before continuing to fight the Necromancer!"));
|
||||
player.sendMessage(F.main(getBoss().getEvent().getName(), "You must slay all " + WRAITH_AMOUNT_THIS_USE + " wraiths before continuing to fight the " + getBoss().getEvent().getName() + "!"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -174,17 +193,31 @@ public class NecromancerWraithSummon extends BossAbility<NecromancerCreature, Sk
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onWraithDie(WraithDeathEvent event)
|
||||
public void onWraithDie(EventCreatureDeathEvent event)
|
||||
{
|
||||
String number = _wraiths.remove(event.getWraith());
|
||||
if (number != null)
|
||||
if (event.getCreature() instanceof WraithCreature)
|
||||
{
|
||||
Bukkit.broadcastMessage(F.main(getBoss().getEvent().getName(), "The " + number + " wraith has been slain!"));
|
||||
String number = _wraiths.remove(event.getCreature());
|
||||
if (number != null)
|
||||
{
|
||||
double remainPercent = new BigDecimal(_wraiths.size()).divide(new BigDecimal(WRAITH_AMOUNT_THIS_USE)).doubleValue();
|
||||
ChatColor remainColor = ChatColor.GREEN;
|
||||
if (remainPercent < .66)
|
||||
{
|
||||
remainColor = ChatColor.YELLOW;
|
||||
}
|
||||
if (remainPercent < .33)
|
||||
{
|
||||
remainColor = ChatColor.RED;
|
||||
}
|
||||
Bukkit.broadcastMessage(F.main(getBoss().getEvent().getName(), "A wraith has been slain!" + " (" + remainColor + _wraiths.size() + "/" + WRAITH_AMOUNT_THIS_USE + C.cGray + ") wraiths remaining!"));
|
||||
System.out.println(F.main(getBoss().getEvent().getName(), "The " + number + " wraith has been slain!"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onNecromancerDamage(CustomDamageEvent event)
|
||||
public void onDamage(CustomDamageEvent event)
|
||||
{
|
||||
if (event.GetDamageeEntity().equals(getBoss().getEntity()))
|
||||
{
|
@ -1,4 +1,4 @@
|
||||
package mineplex.minecraft.game.core.boss.necromancer.minion;
|
||||
package mineplex.minecraft.game.core.boss.skeletonking.minion;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
@ -1,7 +1,4 @@
|
||||
package mineplex.minecraft.game.core.boss.necromancer.minion;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
package mineplex.minecraft.game.core.boss.skeletonking.minion;
|
||||
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
@ -21,21 +18,21 @@ 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 UndeadArcherCreature extends EventCreature<Skeleton>
|
||||
{
|
||||
private static final int BARBED_LEVEL = 1;
|
||||
private static final int LIFETIME = 40;
|
||||
|
||||
private HashSet<Projectile> _arrows = new HashSet<Projectile>();
|
||||
private static final int LIFETIME = -1;
|
||||
|
||||
public UndeadArcherCreature(WorldEvent event, Location spawnLocation)
|
||||
{
|
||||
super(event, spawnLocation, "Undead Archer", true, 100, Skeleton.class);
|
||||
super(event, spawnLocation, "Undead Archer", true, 25, Skeleton.class);
|
||||
|
||||
spawnEntity();
|
||||
}
|
||||
@ -114,7 +111,7 @@ public class UndeadArcherCreature extends EventCreature<Skeleton>
|
||||
return;
|
||||
}
|
||||
|
||||
_arrows.add((Projectile) event.getProjectile());
|
||||
event.getProjectile().setMetadata("BARBED_ARROW", new FixedMetadataValue(getEvent().getPlugin(), 2));
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
@ -139,6 +136,11 @@ public class UndeadArcherCreature extends EventCreature<Skeleton>
|
||||
return;
|
||||
}
|
||||
|
||||
if (!projectile.hasMetadata("BARBED_ARROW"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (damagee == null)
|
||||
{
|
||||
return;
|
||||
@ -149,6 +151,11 @@ public class UndeadArcherCreature extends EventCreature<Skeleton>
|
||||
return;
|
||||
}
|
||||
|
||||
if (!getEntity().equals(damager))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Level
|
||||
if (BARBED_LEVEL == 0)
|
||||
{
|
||||
@ -163,7 +170,7 @@ public class UndeadArcherCreature extends EventCreature<Skeleton>
|
||||
}
|
||||
|
||||
// Damage
|
||||
event.AddMod(damager.getName(), "Barbed Arrows", 0, false);
|
||||
event.AddMod(damager.getName(), "Barbed Arrows", projectile.getMetadata("BARBED_ARROW").get(0).asDouble(), false);
|
||||
|
||||
// Condition
|
||||
getEvent().getCondition().Factory().Slow("Barbed Arrows", damagee, damager, (projectile.getVelocity().length() / 3) * (2 + BARBED_LEVEL), 0, false, true, true, true);
|
||||
@ -182,14 +189,46 @@ public class UndeadArcherCreature extends EventCreature<Skeleton>
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
for (Iterator<Projectile> arrowIterator = _arrows.iterator(); arrowIterator.hasNext();)
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onTarget(EntityTargetLivingEntityEvent event)
|
||||
{
|
||||
if (getEntity().equals(event.getEntity()))
|
||||
{
|
||||
Projectile arrow = arrowIterator.next();
|
||||
|
||||
if (arrow.isDead() || !arrow.isValid())
|
||||
if (!(event.getTarget() instanceof Player))
|
||||
{
|
||||
arrowIterator.remove();
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package mineplex.minecraft.game.core.boss.necromancer.minion;
|
||||
package mineplex.minecraft.game.core.boss.skeletonking.minion;
|
||||
|
||||
import mineplex.core.common.util.UtilAction;
|
||||
import mineplex.core.common.util.UtilAlg;
|
||||
@ -7,12 +7,18 @@ import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.minecraft.game.core.boss.EventCreature;
|
||||
import mineplex.minecraft.game.core.boss.WorldEvent;
|
||||
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
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.EntityTargetLivingEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
@ -20,11 +26,11 @@ import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
public class UndeadWarriorCreature extends EventCreature<Zombie>
|
||||
{
|
||||
private static final int LIFETIME = 40;
|
||||
private static final int LIFETIME = -1;
|
||||
|
||||
public UndeadWarriorCreature(WorldEvent event, Location spawnLocation)
|
||||
{
|
||||
super(event, spawnLocation, "Undead Warrior", true, 100, Zombie.class);
|
||||
super(event, spawnLocation, "Undead Warrior", true, 30, Zombie.class);
|
||||
spawnEntity();
|
||||
}
|
||||
|
||||
@ -107,4 +113,76 @@ public class UndeadWarriorCreature extends EventCreature<Zombie>
|
||||
//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 attack(CustomDamageEvent event)
|
||||
{
|
||||
if (event.IsCancelled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LivingEntity damagee = event.GetDamageeEntity();
|
||||
LivingEntity damager = event.GetDamagerEntity(false);
|
||||
|
||||
if (damagee == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (damager == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (getEntity().equals(damager))
|
||||
{
|
||||
if (damagee instanceof Player)
|
||||
{
|
||||
((Player)damagee).setFoodLevel(((Player)damagee).getFoodLevel() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package mineplex.minecraft.game.core.boss.necromancer.minion;
|
||||
package mineplex.minecraft.game.core.boss.skeletonking.minion;
|
||||
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
import mineplex.core.common.util.UtilParticle;
|
||||
@ -16,9 +16,12 @@ import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
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;
|
||||
@ -99,8 +102,10 @@ public class WraithCreature extends EventCreature<Zombie>
|
||||
return;
|
||||
}
|
||||
|
||||
// Damage
|
||||
event.AddMult(damager.getName(), "Mystical Darkness", 2, false);
|
||||
if (getEntity().equals(damager))
|
||||
{
|
||||
event.AddMult(damager.getName(), "Mystical Darkness", 2, false);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@ -137,4 +142,46 @@ public class WraithCreature extends EventCreature<Zombie>
|
||||
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, zombie.getLocation(), 0, 0, 0, 0, 5, ViewDist.MAX);
|
||||
zombie.getWorld().playSound(zombie.getLocation(), Sound.ENDERMAN_TELEPORT, 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user