Merge branch 'feature/clans-season-3' into develop

This commit is contained in:
cnr 2017-06-16 22:26:36 -05:00
commit c4d5ed4cbd
195 changed files with 18117 additions and 756 deletions

View File

@ -0,0 +1,54 @@
package mineplex.core.common;
import java.util.Objects;
/**
* Represents an operation that accepts two input arguments and returns no
* result. This is the three-arity specialization of {@link Consumer}.
* Unlike most other functional interfaces, {@code TriConsumer} is expected
* to operate via side-effects.
*
* <p>This is a <a href="package-summary.html">functional interface</a>
* whose functional method is {@link #accept(Object, Object, Object)}.
*
* @param <T> the type of the first argument to the operation
* @param <U> the type of the second argument to the operation
* @param <V> the type of the third argument to the operation
*
* @see Consumer
*/
@FunctionalInterface
public interface TriConsumer<T, U, V>
{
/**
* Performs this operation on the given arguments.
*
* @param t the first input argument
* @param u the second input argument
* @param v the third input argument
*/
void accept(T t, U u, V v);
/**
* Returns a composed {@code TriConsumer} that performs, in sequence, this
* operation followed by the {@code after} operation. If performing either
* operation throws an exception, it is relayed to the caller of the
* composed operation. If performing this operation throws an exception,
* the {@code after} operation will not be performed.
*
* @param after the operation to perform after this operation
* @return a composed {@code TriConsumer} that performs in sequence this
* operation followed by the {@code after} operation
* @throws NullPointerException if {@code after} is null
*/
default TriConsumer<T, U, V> andThen(TriConsumer<? super T, ? super U, ? super V> after)
{
Objects.requireNonNull(after);
return (f, s, t) -> {
accept(f, s, t);
after.accept(f, s, t);
};
}
}

View File

@ -1032,7 +1032,12 @@ public class UtilEnt
return null; return null;
} }
return entity.getMetadata(key).get(0); return entity.getMetadata(key).get(0).value();
}
public static void removeMetadata(Entity entity, String key)
{
entity.removeMetadata(key, UtilServer.getPlugin());
} }
public static void SetItemInHand(LivingEntity entity, ItemStack item) public static void SetItemInHand(LivingEntity entity, ItemStack item)

View File

@ -1158,6 +1158,16 @@ public class UtilItem
return i; return i;
} }
public static boolean isUnbreakable(ItemStack i)
{
if (i == null)
{
return false;
}
return i.getItemMeta().spigot().isUnbreakable();
}
/** /**
* *

View File

@ -54,6 +54,23 @@ public class UtilMath
return a.subtract(b).length(); return a.subtract(b).length();
} }
public static double offset2dSquared(Entity a, Entity b)
{
return offset2dSquared(a.getLocation().toVector(), b.getLocation().toVector());
}
public static double offset2dSquared(Location a, Location b)
{
return offset2dSquared(a.toVector(), b.toVector());
}
public static double offset2dSquared(Vector a, Vector b)
{
a.setY(0);
b.setY(0);
return a.subtract(b).lengthSquared();
}
public static double offset(Entity a, Entity b) public static double offset(Entity a, Entity b)
{ {
return offset(a.getLocation().toVector(), b.getLocation().toVector()); return offset(a.getLocation().toVector(), b.getLocation().toVector());
@ -283,4 +300,36 @@ public class UtilMath
{ {
return n - ((int) ((int) n)); return n - ((int) ((int) n));
} }
public static int getMax(int... ints)
{
if (ints.length < 1)
{
return -1;
}
int max = ints[0];
for (int i = 1; i < ints.length; i++)
{
max = Math.max(max, ints[i]);
}
return max;
}
public static int getMin(int... ints)
{
if (ints.length < 1)
{
return -1;
}
int min = ints[0];
for (int i = 1; i < ints.length; i++)
{
min = Math.min(min, ints[i]);
}
return min;
}
} }

View File

@ -595,8 +595,13 @@ public class UtilPlayer
return nearbyMap; return nearbyMap;
} }
public static Player getClosest(Location loc, Collection<Player> ignore) public static Player getClosest(Location loc, Collection<Player> ignore)
{
return getClosest(loc, -1, ignore);
}
public static Player getClosest(Location loc, double maxDist, Collection<Player> ignore)
{ {
Player best = null; Player best = null;
double bestDist = 0; double bestDist = 0;
@ -613,6 +618,11 @@ public class UtilPlayer
continue; continue;
double dist = UtilMath.offset(cur.getLocation(), loc); double dist = UtilMath.offset(cur.getLocation(), loc);
if (maxDist > 0 && dist > maxDist)
{
continue;
}
if (best == null || dist < bestDist) if (best == null || dist < bestDist)
{ {
@ -623,8 +633,13 @@ public class UtilPlayer
return best; return best;
} }
public static Player getClosest(Location loc, Entity... ignore) public static Player getClosest(Location loc, Entity... ignore)
{
return getClosest(loc, -1, ignore);
}
public static Player getClosest(Location loc, double maxDist, Entity... ignore)
{ {
Player best = null; Player best = null;
double bestDist = 0; double bestDist = 0;
@ -654,7 +669,12 @@ public class UtilPlayer
continue; continue;
} }
double dist = UtilMath.offsetSquared(cur.getLocation(), loc); double dist = UtilMath.offset(cur.getLocation(), loc);
if (maxDist > 0 && dist > maxDist)
{
continue;
}
if (best == null || dist < bestDist) if (best == null || dist < bestDist)
{ {

View File

@ -176,7 +176,7 @@ public class CoreClientManager extends MiniPlugin
} }
/** /**
* Get the databse account id for a player. Requires the player is online * Get the database account id for a player. Requires the player is online
* *
* @param player * @param player
* @return * @return

View File

@ -64,7 +64,7 @@ public class TestRank extends CommandBase<CoreClientManager>
UtilPlayer.message(caller, F.main(Plugin.getName(), ChatColor.RED + "" + ChatColor.BOLD + "Invalid rank!")); UtilPlayer.message(caller, F.main(Plugin.getName(), ChatColor.RED + "" + ChatColor.BOLD + "Invalid rank!"));
return; return;
} }
if (Plugin.Get(caller).GetRank(true) == Rank.SNR_MODERATOR) if (!Plugin.Get(caller).GetRank(true).has(Rank.JNR_DEV))
{ {
if (tempRank.has(Rank.TWITCH)) if (tempRank.has(Rank.TWITCH))
{ {

View File

@ -1000,10 +1000,10 @@ public class ItemStackFactory extends MiniPlugin
ItemMeta meta = stack.getItemMeta(); ItemMeta meta = stack.getItemMeta();
if (meta == null) if (meta == null)
return 0; return empty;
if (meta.getLore() == null) if (meta.getLore() == null)
return 0; return empty;
for (String cur : meta.getLore()) for (String cur : meta.getLore())
if (cur.contains(var)) if (cur.contains(var))
@ -1021,7 +1021,7 @@ public class ItemStackFactory extends MiniPlugin
} }
return 0; return empty;
} }
public void SetLoreVar(ItemStack stack, String var, String value) public void SetLoreVar(ItemStack stack, String var, String value)

View File

@ -1,7 +1,9 @@
package mineplex.game.clans; package mineplex.game.clans;
import mineplex.core.aprilfools.AprilFoolsManager; import static mineplex.core.Managers.require;
import net.minecraft.server.v1_8_R3.MinecraftServer;
import java.io.File;
import java.io.IOException;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@ -11,7 +13,6 @@ import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.spigotmc.SpigotConfig; import org.spigotmc.SpigotConfig;
import mineplex.core.common.Constants;
import mineplex.core.CustomTagFix; import mineplex.core.CustomTagFix;
import mineplex.core.FoodDupeFix; import mineplex.core.FoodDupeFix;
import mineplex.core.TimingsFix; import mineplex.core.TimingsFix;
@ -20,12 +21,14 @@ import mineplex.core.achievement.AchievementManager;
import mineplex.core.antihack.AntiHack; import mineplex.core.antihack.AntiHack;
import mineplex.core.antihack.guardians.AntiHackGuardian; import mineplex.core.antihack.guardians.AntiHackGuardian;
import mineplex.core.antihack.guardians.GuardianManager; import mineplex.core.antihack.guardians.GuardianManager;
import mineplex.core.aprilfools.AprilFoolsManager;
import mineplex.core.blockrestore.BlockRestore; import mineplex.core.blockrestore.BlockRestore;
import mineplex.core.chat.Chat; import mineplex.core.chat.Chat;
import mineplex.core.chatsnap.SnapshotManager; import mineplex.core.chatsnap.SnapshotManager;
import mineplex.core.chatsnap.SnapshotPlugin; import mineplex.core.chatsnap.SnapshotPlugin;
import mineplex.core.chatsnap.SnapshotRepository; import mineplex.core.chatsnap.SnapshotRepository;
import mineplex.core.command.CommandCenter; import mineplex.core.command.CommandCenter;
import mineplex.core.common.Constants;
import mineplex.core.common.MinecraftVersion; import mineplex.core.common.MinecraftVersion;
import mineplex.core.common.Pair; import mineplex.core.common.Pair;
import mineplex.core.common.events.ServerShutdownEvent; import mineplex.core.common.events.ServerShutdownEvent;
@ -74,12 +77,13 @@ import mineplex.game.clans.shop.mining.MiningShop;
import mineplex.game.clans.shop.pvp.PvpShop; import mineplex.game.clans.shop.pvp.PvpShop;
import mineplex.game.clans.spawn.travel.TravelShop; import mineplex.game.clans.spawn.travel.TravelShop;
import mineplex.game.clans.world.WorldManager; import mineplex.game.clans.world.WorldManager;
import net.minecraft.server.v1_8_R3.MinecraftServer;
import static mineplex.core.Managers.require;
public class Clans extends JavaPlugin public class Clans extends JavaPlugin
{ {
public static final String MAP = "Season 2"; public static final String MAP = "Season 3";
public static boolean HARDCORE = false;
// Modules // Modules
private CoreClientManager _clientManager; private CoreClientManager _clientManager;
@ -89,6 +93,14 @@ public class Clans extends JavaPlugin
@Override @Override
public void onEnable() public void onEnable()
{ {
try
{
HARDCORE = new File(new File(".").getCanonicalPath() + File.separator + "Hardcore.dat").exists();
}
catch (IOException e)
{
e.printStackTrace();
}
Bukkit.setSpawnRadius(0); Bukkit.setSpawnRadius(0);
// Configs // Configs

View File

@ -1,33 +1,17 @@
package mineplex.game.clans; package mineplex.game.clans;
import com.google.common.collect.Sets;
import mineplex.core.MiniPlugin;
import mineplex.core.common.util.UtilItem;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import java.util.Set; import mineplex.core.MiniPlugin;
import mineplex.core.common.util.UtilItem;
import mineplex.core.itemstack.ItemStackFactory;
public class Farming extends MiniPlugin public class Farming extends MiniPlugin
{ {
private static final Set<Material> PLANTABLE = Sets.newHashSet(
Material.WHEAT,
Material.SUGAR_CANE_BLOCK,
Material.PUMPKIN_STEM,
Material.MELON_STEM,
Material.COCOA,
Material.CARROT,
Material.POTATO
);
public Farming(JavaPlugin plugin) public Farming(JavaPlugin plugin)
{ {
super("Farming", plugin); super("Farming", plugin);
@ -50,27 +34,4 @@ public class Farming extends MiniPlugin
if (Math.random() > 0.999) if (Math.random() > 0.999)
event.getBlock().getWorld().dropItemNaturally(dropLocation, ItemStackFactory.Instance.CreateStack(Material.GOLDEN_APPLE)); event.getBlock().getWorld().dropItemNaturally(dropLocation, ItemStackFactory.Instance.CreateStack(Material.GOLDEN_APPLE));
} }
}
@EventHandler (ignoreCancelled = true)
public void BlockPlace(BlockPlaceEvent event)
{
if (!PLANTABLE.contains(event.getBlock().getType()))
return;
double blockY = event.getBlock().getLocation().getY();
double seaLevel = event.getBlock().getWorld().getSeaLevel();
if (blockY < seaLevel - 12)
{
UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot plant " +
F.item(ItemStackFactory.Instance.GetName(event.getPlayer().getItemInHand(), true)) + " this deep underground."));
event.setCancelled(true);
}
else if (blockY > seaLevel + 24)
{
UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot plant " +
F.item(ItemStackFactory.Instance.GetName(event.getPlayer().getItemInHand(), true)) + " at this altitude."));
event.setCancelled(true);
}
}
}

View File

@ -11,7 +11,6 @@ import java.util.UUID;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import mineplex.core.common.util.C; import mineplex.core.common.util.C;
@ -208,11 +207,18 @@ public class ClanInfo
} }
public int getAlliesMax() public int getAlliesMax()
{
return getAlliesMaxWithMemberCountOf(_memberMap.size());
}
public int getAlliesMaxWithMemberCountOf(int memberCount)
{ {
if (ssAdmin()) if (ssAdmin())
{
return 1000; return 1000;
}
return Math.max(2, 9 - _memberMap.size());
return Math.max(2, 6 - memberCount);
} }
public BedStatus getBedStatus() public BedStatus getBedStatus()

View File

@ -372,15 +372,11 @@ public class ClansAdmin
} }
else else
{ {
Clans.getClanDataAccess().war(clan, clanAgainst, value, new Callback<ClanWarData>() Clans.getClanDataAccess().war(clan, clanAgainst, value, data ->
{ {
@Override UtilPlayer.message(caller, F.main("Clans Admin", "Updated war points against " + F.elem(data.getClanB())));
public void run(ClanWarData data) Clans.messageClan(clan, F.main("Clans", "Your war points with " + F.elem(clanAgainst.getName()) + " have been edited by " + F.elem(caller.getName()) + "!"));
{ Clans.messageClan(clanAgainst, F.main("Clans", "Your war points with " + F.elem(clan.getName()) + " have been edited by " + F.elem(caller.getName()) + "!"));
UtilPlayer.message(caller, F.main("Clans Admin", "Updated war points against " + F.elem(data.getClanB())));
Clans.messageClan(clan, F.main("Clans", "Your war points with " + F.elem(clanAgainst.getName()) + " have been edited by " + F.elem(caller.getName()) + "!"));
Clans.messageClan(clanAgainst, F.main("Clans", "Your war points with " + F.elem(clan.getName()) + " have been edited by " + F.elem(caller.getName()) + "!"));
}
}); });
} }
} }
@ -401,15 +397,11 @@ public class ClansAdmin
} }
else else
{ {
Clans.getClanDataAccess().war(clan, clanAgainst, value, new Callback<ClanWarData>() Clans.getClanDataAccess().war(clan, clanAgainst, value, data ->
{ {
@Override UtilPlayer.message(caller, F.main("Clans Admin", "Updated war points against " + F.elem(data.getClanB())));
public void run(ClanWarData data) Clans.messageClan(clan, F.main("Clans", "Your war points with " + F.elem(clanAgainst.getName()) + " have been edited by " + F.elem(caller.getName()) + "!"));
{ Clans.messageClan(clanAgainst, F.main("Clans", "Your war points with " + F.elem(clan.getName()) + " have been edited by " + F.elem(caller.getName()) + "!"));
UtilPlayer.message(caller, F.main("Clans Admin", "Updated war points against " + F.elem(data.getClanB())));
Clans.messageClan(clan, F.main("Clans", "Your war points with " + F.elem(clanAgainst.getName()) + " have been edited by " + F.elem(caller.getName()) + "!"));
Clans.messageClan(clanAgainst, F.main("Clans", "Your war points with " + F.elem(clan.getName()) + " have been edited by " + F.elem(caller.getName()) + "!"));
}
}); });
} }
} }

View File

@ -78,6 +78,8 @@ public class ClansBlocks
denyUsePlace.add(390); //Pot denyUsePlace.add(390); //Pot
denyUsePlace.add(404); //Comparator denyUsePlace.add(404); //Comparator
denyUsePlace.add(407); //TNT Cart denyUsePlace.add(407); //TNT Cart
denyUsePlace.add(287); //String
denyUsePlace.add(397); //Skulls
} }
if (id == 65) if (id == 65)

View File

@ -9,6 +9,7 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.Managers;
import mineplex.core.MiniPlugin; import mineplex.core.MiniPlugin;
import mineplex.core.common.util.C; import mineplex.core.common.util.C;
import mineplex.core.common.util.F; import mineplex.core.common.util.F;
@ -20,6 +21,8 @@ import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent; import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.clans.ClansUtility.ClanRelation; import mineplex.game.clans.clans.ClansUtility.ClanRelation;
import mineplex.game.clans.clans.event.PlayerEnterTerritoryEvent; import mineplex.game.clans.clans.event.PlayerEnterTerritoryEvent;
import mineplex.game.clans.clans.nether.NetherManager;
import mineplex.game.clans.clans.worldevent.WorldEventManager;
import mineplex.game.clans.core.repository.ClanTerritory; import mineplex.game.clans.core.repository.ClanTerritory;
public class ClansDisplay extends MiniPlugin public class ClansDisplay extends MiniPlugin
@ -56,7 +59,7 @@ public class ClansDisplay extends MiniPlugin
client.setTerritory(UtilWorld.chunkToStr(player.getLocation().getChunk())); client.setTerritory(UtilWorld.chunkToStr(player.getLocation().getChunk()));
// AutoClaim // AutoClaim
if (client.isAutoClaim()) _clansManager.getClanAdmin().claim(player); if (client.isAutoClaim() && !(Managers.get(NetherManager.class).isInNether(player) || Managers.get(WorldEventManager.class).getRaidManager().isInRaid(player.getLocation()))) _clansManager.getClanAdmin().claim(player);
// Map // Map
String owner = "Wilderness"; String owner = "Wilderness";
@ -65,7 +68,7 @@ public class ClansDisplay extends MiniPlugin
boolean safe = _clansManager.getClanUtility().isSafe(player); boolean safe = _clansManager.getClanUtility().isSafe(player);
PlayerEnterTerritoryEvent event = new PlayerEnterTerritoryEvent(player, client.getOwner(), owner, (owner.equals("Wilderness") && !_clansManager.getNetherManager().isInNether(player)) ? false : _clansManager.getClanUtility().getClaim(player.getLocation()).isSafe(player.getLocation()), true); PlayerEnterTerritoryEvent event = new PlayerEnterTerritoryEvent(player, client.getOwner(), owner, safe, true);
UtilServer.getServer().getPluginManager().callEvent(event); UtilServer.getServer().getPluginManager().callEvent(event);
@ -127,6 +130,11 @@ public class ClansDisplay extends MiniPlugin
} }
} }
if (_clansManager.getWorldEvent().getRaidManager().isInRaid(player.getLocation()))
{
ownerString = C.cDRed + "Raid World";
}
// if (_clansManager.getNetherManager().isInNether(player)) // if (_clansManager.getNetherManager().isInNether(player))
// { // {
// _clansManager.message(player, "You are not allowed to claim territory in " + F.clansNether("The Nether") + "."); // _clansManager.message(player, "You are not allowed to claim territory in " + F.clansNether("The Nether") + ".");

View File

@ -31,6 +31,7 @@ import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.server.ServerListPingEvent;
import org.bukkit.event.vehicle.VehicleEnterEvent; import org.bukkit.event.vehicle.VehicleEnterEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
@ -85,11 +86,13 @@ import mineplex.core.task.TaskManager;
import mineplex.core.teleport.Teleport; import mineplex.core.teleport.Teleport;
import mineplex.core.updater.UpdateType; import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent; import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.Clans;
import mineplex.game.clans.clans.ClanTips.TipType; import mineplex.game.clans.clans.ClanTips.TipType;
import mineplex.game.clans.clans.ClansUtility.ClanRelation; import mineplex.game.clans.clans.ClansUtility.ClanRelation;
import mineplex.game.clans.clans.amplifiers.AmplifierManager; import mineplex.game.clans.clans.amplifiers.AmplifierManager;
import mineplex.game.clans.clans.ban.ClansBanManager; import mineplex.game.clans.clans.ban.ClansBanManager;
import mineplex.game.clans.clans.banners.BannerManager; import mineplex.game.clans.clans.banners.BannerManager;
import mineplex.game.clans.clans.boxes.BoxManager;
import mineplex.game.clans.clans.commands.ClanManagementCommand; import mineplex.game.clans.clans.commands.ClanManagementCommand;
import mineplex.game.clans.clans.commands.ClansAllyChatCommand; import mineplex.game.clans.clans.commands.ClansAllyChatCommand;
import mineplex.game.clans.clans.commands.ClansChatCommand; import mineplex.game.clans.clans.commands.ClansChatCommand;
@ -104,6 +107,7 @@ import mineplex.game.clans.clans.gui.ClanShop;
import mineplex.game.clans.clans.invsee.InvseeManager; import mineplex.game.clans.clans.invsee.InvseeManager;
import mineplex.game.clans.clans.loot.LootManager; import mineplex.game.clans.clans.loot.LootManager;
import mineplex.game.clans.clans.map.ItemMapManager; import mineplex.game.clans.clans.map.ItemMapManager;
import mineplex.game.clans.clans.mounts.MountManager;
import mineplex.game.clans.clans.nameblacklist.ClansBlacklist; import mineplex.game.clans.clans.nameblacklist.ClansBlacklist;
import mineplex.game.clans.clans.nether.NetherManager; import mineplex.game.clans.clans.nether.NetherManager;
import mineplex.game.clans.clans.observer.ObserverManager; import mineplex.game.clans.clans.observer.ObserverManager;
@ -433,10 +437,10 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
new Location(Spawn.getSpawnWorld(), -25, 200, 390), new Location(Spawn.getSpawnWorld(), -25, 200, 390),
// East Spawn // East Spawn
new Location(Spawn.getSpawnWorld(), 34, 200, -393), new Location(Spawn.getSpawnWorld(), 34, 206, -393),
new Location(Spawn.getSpawnWorld(), 8, 200, -365), new Location(Spawn.getSpawnWorld(), 8, 206, -365),
new Location(Spawn.getSpawnWorld(), -25, 200, -393), new Location(Spawn.getSpawnWorld(), -25, 206, -393),
new Location(Spawn.getSpawnWorld(), 8, 200, -424) new Location(Spawn.getSpawnWorld(), 8, 206, -424)
); );
List<Location> welcomeHolograms = Arrays.asList( List<Location> welcomeHolograms = Arrays.asList(
@ -444,10 +448,10 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
new Location(Spawn.getSpawnWorld(), 8, 200, 399), new Location(Spawn.getSpawnWorld(), 8, 200, 399),
new Location(Spawn.getSpawnWorld(), 0, 200, 390), new Location(Spawn.getSpawnWorld(), 0, 200, 390),
new Location(Spawn.getSpawnWorld(), 8, 200, 381), new Location(Spawn.getSpawnWorld(), 8, 200, 381),
new Location(Spawn.getSpawnWorld(), 8, 200, -384), new Location(Spawn.getSpawnWorld(), 8, 206, -384),
new Location(Spawn.getSpawnWorld(), 0, 200, -393), new Location(Spawn.getSpawnWorld(), 0, 206, -393),
new Location(Spawn.getSpawnWorld(), 8, 200, -402), new Location(Spawn.getSpawnWorld(), 8, 206, -402),
new Location(Spawn.getSpawnWorld(), 17, 200, -393) new Location(Spawn.getSpawnWorld(), 17, 206, -393)
); );
for (Location location : jumpOffHolograms) for (Location location : jumpOffHolograms)
@ -472,6 +476,10 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
_netherManager = new NetherManager(this); _netherManager = new NetherManager(this);
_amplifierManager = new AmplifierManager(plugin); _amplifierManager = new AmplifierManager(plugin);
new MountManager(plugin, clientManager, donationManager);
new BoxManager(plugin);
_restartManager = new RestartManager(plugin); _restartManager = new RestartManager(plugin);
} }
@ -650,6 +658,19 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
public long lastPower = System.currentTimeMillis(); public long lastPower = System.currentTimeMillis();
@EventHandler
public void displayHardcoreMode(ServerListPingEvent event)
{
if (Clans.HARDCORE)
{
event.setMotd("Hardcore");
}
else
{
event.setMotd("Casual");
}
}
@EventHandler @EventHandler
public void savePlayerActiveBuild(PlayerQuitEvent event) public void savePlayerActiveBuild(PlayerQuitEvent event)
{ {
@ -912,7 +933,7 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
recipients.clear(); recipients.clear();
} }
@EventHandler @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void disableObsidian(BlockBreakEvent event) public void disableObsidian(BlockBreakEvent event)
{ {
if(event.getBlock().getType().equals(Material.OBSIDIAN)) if(event.getBlock().getType().equals(Material.OBSIDIAN))
@ -1220,6 +1241,7 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
_safeLog.onDisable(); _safeLog.onDisable();
_restartManager.onDisable(); _restartManager.onDisable();
_observerManager.onDisable(); _observerManager.onDisable();
Managers.get(MountManager.class).onDisable();
} }
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.HIGHEST)
@ -1387,29 +1409,6 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
} }
} }
@EventHandler
public void damageHorse(EntityDamageEvent event)
{
if (event.getEntity() instanceof Horse)
{
if (event.getEntity().getPassenger() != null && event.getEntity().getPassenger() instanceof Player)
{
event.getEntity().getPassenger().eject();
Recharge.Instance.use((Player) event.getEntity().getPassenger(), "Ride Horse", 2 * 20L, false, false);
}
event.getEntity().eject();
}
else if(event.getEntity() instanceof Player)
{
if(event.getEntity().getVehicle() != null && event.getEntity().getVehicle() instanceof Horse)
{
Recharge.Instance.use((Player) event.getEntity(), "Ride Horse", 2 * 20L, false, false);
event.getEntity().getVehicle().eject();
}
}
}
public Pair<ClanInfo, Long> leftRecently(UUID uniqueId, long time) public Pair<ClanInfo, Long> leftRecently(UUID uniqueId, long time)
{ {
if (_clanMemberLeftMap.containsKey(uniqueId) && (System.currentTimeMillis() - _clanMemberLeftMap.get(uniqueId).getRight()) <= time) if (_clanMemberLeftMap.containsKey(uniqueId) && (System.currentTimeMillis() - _clanMemberLeftMap.get(uniqueId).getRight()) <= time)
@ -1465,4 +1464,4 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
{ {
return _incognitoManager; return _incognitoManager;
} }
} }

View File

@ -1221,6 +1221,12 @@ public class ClansUtility
UtilPlayer.message(caller, F.main("Clans", "You cannot invite yourself.")); UtilPlayer.message(caller, F.main("Clans", "You cannot invite yourself."));
return; return;
} }
if (clan.getAllies() > clan.getAlliesMaxWithMemberCountOf(clan.getSize() + 1))
{
UtilPlayer.message(caller, F.main("Clans", "You cannot invite more members until you remove some allies."));
return;
}
// Inform // Inform
clan.inform(F.name(caller.getName()) + " invited " + F.name(target.getName()) + " to join your Clan.", caller.getName()); clan.inform(F.name(caller.getName()) + " invited " + F.name(target.getName()) + " to join your Clan.", caller.getName());

View File

@ -266,7 +266,7 @@ public class ClansBanManager extends MiniPlugin
player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 999999, -10)); player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 999999, -10));
for (Player alert : UtilServer.GetPlayers()) for (Player alert : UtilServer.GetPlayers())
{ {
if (_clientManager.Get(staff).GetRank().has(null, Rank.ADMIN, new Rank[] {Rank.CMOD, Rank.CMA}, false)) if (_clientManager.Get(alert).GetRank().has(null, Rank.ADMIN, new Rank[] {Rank.CMOD, Rank.CMA}, false))
{ {
UtilPlayer.message(alert, F.main(getName(), F.elem(player.getName()) + " has been frozen by " + F.elem(staff.getName()) + "!")); UtilPlayer.message(alert, F.main(getName(), F.elem(player.getName()) + " has been frozen by " + F.elem(staff.getName()) + "!"));
} }
@ -287,7 +287,7 @@ public class ClansBanManager extends MiniPlugin
player.removePotionEffect(PotionEffectType.JUMP); player.removePotionEffect(PotionEffectType.JUMP);
for (Player alert : UtilServer.GetPlayers()) for (Player alert : UtilServer.GetPlayers())
{ {
if (_clientManager.Get(staff).GetRank().has(null, Rank.ADMIN, new Rank[] {Rank.CMOD, Rank.CMA}, false)) if (_clientManager.Get(alert).GetRank().has(null, Rank.ADMIN, new Rank[] {Rank.CMOD, Rank.CMA}, false))
{ {
UtilPlayer.message(alert, F.main(getName(), F.elem(player.getName()) + " has been unfrozen by " + F.elem(staff.getName()) + "!")); UtilPlayer.message(alert, F.main(getName(), F.elem(player.getName()) + " has been unfrozen by " + F.elem(staff.getName()) + "!"));
continue; continue;

View File

@ -10,6 +10,7 @@ import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPhysicsEvent; import org.bukkit.event.block.BlockPhysicsEvent;
import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockPlaceEvent;
@ -170,7 +171,7 @@ public class BannerManager extends MiniPlugin
} }
} }
@EventHandler @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBreak(BlockBreakEvent event) public void onBreak(BlockBreakEvent event)
{ {
if (event.getBlock().getType() == Material.STANDING_BANNER || event.getBlock().getType() == Material.WALL_BANNER) if (event.getBlock().getType() == Material.STANDING_BANNER || event.getBlock().getType() == Material.WALL_BANNER)

View File

@ -0,0 +1,222 @@
package mineplex.game.clans.clans.boxes;
import java.util.function.Consumer;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.inventory.CraftItemEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.inventory.PrepareItemCraftEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.Managers;
import mineplex.core.MiniPlugin;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.C;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.game.clans.clans.boxes.extra.BuilderBoxInventory;
import mineplex.game.clans.clans.boxes.extra.DyeBoxSpinner;
public class BoxManager extends MiniPlugin
{
private BuilderBoxInventory _builderBox;
public BoxManager(JavaPlugin plugin)
{
super("Box Manager", plugin);
final BoxShop shop = new BoxShop(this);
_builderBox = new BuilderBoxInventory();
addCommand(new CommandBase<BoxManager>(this, Rank.ALL, "boxes", "box")
{
@Override
public void Execute(Player caller, String[] args)
{
shop.attemptShopOpen(caller);
}
});
}
@EventHandler(priority=EventPriority.HIGHEST)
public void onCraftWithDye(PrepareItemCraftEvent event)
{
if (event.getInventory().getResult() == null)
{
return;
}
if (event.getInventory().getResult().getType() == Material.LAPIS_BLOCK)
{
for (ItemStack item : event.getInventory().getMatrix())
{
if (item == null)
{
continue;
}
if (item.hasItemMeta() && item.getItemMeta().hasDisplayName() && item.getItemMeta().getDisplayName().equals(C.cGold + "Dye"))
{
event.getInventory().setResult(null);
return;
}
}
return;
}
if (event.getInventory().getResult().getType() == Material.INK_SACK)
{
event.getInventory().setResult(null);
return;
}
for (ItemStack item : event.getInventory().getMatrix())
{
if (item == null)
{
continue;
}
if (item.getType() != Material.INK_SACK)
{
continue;
}
if (!item.hasItemMeta() || !item.getItemMeta().hasDisplayName() || !item.getItemMeta().getDisplayName().equals(C.cGold + "Dye"))
{
event.getInventory().setResult(null);
}
}
}
@EventHandler(priority=EventPriority.HIGHEST)
public void onCraftWithDye(CraftItemEvent event)
{
if (event.getInventory().getResult() == null)
{
return;
}
if (event.getInventory().getResult().getType() == Material.LAPIS_BLOCK)
{
for (ItemStack item : event.getInventory().getMatrix())
{
if (item == null)
{
continue;
}
if (item.hasItemMeta() && item.getItemMeta().hasDisplayName() && item.getItemMeta().getDisplayName().equals(C.cGold + "Dye"))
{
event.setCancelled(true);
return;
}
}
return;
}
if (event.getInventory().getResult().getType() == Material.INK_SACK)
{
event.setCancelled(true);
return;
}
for (ItemStack item : event.getInventory().getMatrix())
{
if (item == null)
{
continue;
}
if (item.getType() != Material.INK_SACK)
{
continue;
}
if (!item.hasItemMeta() || !item.getItemMeta().hasDisplayName() || !item.getItemMeta().getDisplayName().equals(C.cGold + "Dye"))
{
event.setCancelled(true);
}
}
}
@EventHandler(priority=EventPriority.HIGHEST)
public void onPlaceDyeInAnvil(InventoryClickEvent event)
{
if (!(event.getWhoClicked() instanceof Player))
{
return;
}
if (!event.getInventory().getType().equals(InventoryType.ANVIL))
{
return;
}
if (!(event.getCursor() != null && event.getCursor().hasItemMeta() && event.getCursor().getItemMeta().hasDisplayName() && event.getCursor().getItemMeta().getDisplayName().equals(C.cGold + "Dye")) && !(event.getCurrentItem() != null && event.getCurrentItem().hasItemMeta() && event.getCurrentItem().getItemMeta().hasDisplayName() && event.getCurrentItem().getItemMeta().getDisplayName().equals(C.cGold + "Dye")))
{
return;
}
event.setCancelled(true);
}
@EventHandler
public void onInteract(PlayerInteractEvent event)
{
if (event.getItem() == null || !event.getItem().hasItemMeta() || !event.getItem().getItemMeta().hasDisplayName())
{
return;
}
if (event.getItem().getItemMeta().getDisplayName().equals(C.cGold + "Dye"))
{
event.setCancelled(true);
}
}
public static enum BoxType
{
BUILDER_BOX("Clans Builder Box", C.cGold + "Builder's Box", Material.GLOWSTONE, Managers.get(BoxManager.class)._builderBox::open),
@SuppressWarnings("deprecation")
DYE_BOX("Clans Dye Box", C.cGreen + "Dye Box", Material.INK_SACK, DyeColor.RED.getDyeData(), DyeBoxSpinner::createSpinner),
;
private String _itemName, _displayName;
private ItemBuilder _displayBuilder;
private Consumer<Player> _itemGenerator;
private BoxType(String itemName, String displayName, Material displayMaterial, Consumer<Player> itemGenerator)
{
_itemName = itemName;
_displayName = displayName;
_displayBuilder = new ItemBuilder(displayMaterial).setTitle(displayName).addLore(C.cRed);
_itemGenerator = itemGenerator;
}
private BoxType(String itemName, String displayName, Material displayMaterial, short data, Consumer<Player> itemGenerator)
{
_itemName = itemName;
_displayName = displayName;
_displayBuilder = new ItemBuilder(displayMaterial).setData(data).setTitle(displayName).addLore(C.cRed);
_itemGenerator = itemGenerator;
}
public String getItemName()
{
return _itemName;
}
public String getDisplayName()
{
return _displayName;
}
public ItemStack getDisplayItem(int owned)
{
ItemBuilder newBuilder = new ItemBuilder(_displayBuilder.build());
if (owned > 0)
{
newBuilder.setGlow(true);
}
return newBuilder.addLore(C.cGreenB + "Owned: " + C.cWhite + owned).build();
}
public void onUse(Player player)
{
_itemGenerator.accept(player);
}
}
}

View File

@ -0,0 +1,49 @@
package mineplex.game.clans.clans.boxes;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import mineplex.core.recharge.Recharge;
import mineplex.core.shop.item.IButton;
import mineplex.core.shop.page.ShopPageBase;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.boxes.BoxManager.BoxType;
public class BoxOverviewPage extends ShopPageBase<BoxManager, BoxShop>
{
public BoxOverviewPage(BoxManager plugin, BoxShop shop, String name, Player player)
{
super(plugin, shop, ClansManager.getInstance().getClientManager(), ClansManager.getInstance().getDonationManager(), name, player, 9);
buildPage();
}
@Override
protected void buildPage()
{
int[] slots = {3, 5};
for (int i = 0; i < BoxType.values().length && i < slots.length; i++)
{
BoxType type = BoxType.values()[i];
int slot = slots[i];
final int owns = ClansManager.getInstance().getInventoryManager().Get(getPlayer()).getItemCount(type.getItemName());
IButton button = (player, clickType) ->
{
if (owns < 1)
{
playDenySound(player);
}
else
{
player.closeInventory();
player.playSound(player.getLocation(), Sound.CHEST_OPEN, 1f, 1f);
if (Recharge.Instance.use(player, "Clans Box Click", 1000, false, false))
{
type.onUse(player);
}
}
};
addButton(slot, type.getDisplayItem(owns), button);
}
}
}

View File

@ -0,0 +1,21 @@
package mineplex.game.clans.clans.boxes;
import org.bukkit.entity.Player;
import mineplex.core.shop.ShopBase;
import mineplex.core.shop.page.ShopPageBase;
import mineplex.game.clans.clans.ClansManager;
public class BoxShop extends ShopBase<BoxManager>
{
public BoxShop(BoxManager plugin)
{
super(plugin, ClansManager.getInstance().getClientManager(), ClansManager.getInstance().getDonationManager(), "Your Boxes");
}
@Override
protected ShopPageBase<BoxManager, ? extends ShopBase<BoxManager>> buildPagesFor(Player player)
{
return new BoxOverviewPage(getPlugin(), this, "Your Boxes", player);
}
}

View File

@ -0,0 +1,171 @@
package mineplex.game.clans.clans.boxes.extra;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.bukkit.Bukkit;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.Pair;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.boxes.BoxManager.BoxType;
public class BuilderBoxInventory implements Listener
{
private Map<Pair<Material, Byte>, ItemStack> _replace = new HashMap<>();
public BuilderBoxInventory()
{
_replace.put(Pair.create(Material.STONE, (byte)0), new ItemStack(Material.STAINED_CLAY));
_replace.put(Pair.create(Material.GLASS, (byte)0), new ItemStack(Material.STAINED_GLASS));
_replace.put(Pair.create(Material.THIN_GLASS, (byte)0), new ItemStack(Material.STAINED_GLASS_PANE));
_replace.put(Pair.create(Material.WOOL, (byte)0), new ItemStack(Material.WOOL));
_replace.put(Pair.create(Material.CARPET, (byte)0), new ItemStack(Material.CARPET));
_replace.put(Pair.create(Material.RED_ROSE, (byte)0), new ItemStack(Material.RED_ROSE));
_replace.put(Pair.create(Material.RED_ROSE, (byte)1), new ItemStack(Material.RED_ROSE));
_replace.put(Pair.create(Material.RED_ROSE, (byte)2), new ItemStack(Material.RED_ROSE));
_replace.put(Pair.create(Material.RED_ROSE, (byte)3), new ItemStack(Material.RED_ROSE));
_replace.put(Pair.create(Material.RED_ROSE, (byte)4), new ItemStack(Material.RED_ROSE));
_replace.put(Pair.create(Material.RED_ROSE, (byte)5), new ItemStack(Material.RED_ROSE));
_replace.put(Pair.create(Material.RED_ROSE, (byte)6), new ItemStack(Material.RED_ROSE));
_replace.put(Pair.create(Material.RED_ROSE, (byte)7), new ItemStack(Material.RED_ROSE));
_replace.put(Pair.create(Material.RED_ROSE, (byte)8), new ItemStack(Material.RED_ROSE));
_replace.put(Pair.create(Material.COBBLE_WALL, (byte)0), new ItemStack(Material.COBBLE_WALL));
_replace.put(Pair.create(Material.JACK_O_LANTERN, (byte)0), new ItemStack(Material.GLOWSTONE));
_replace.put(Pair.create(Material.SMOOTH_BRICK, (byte)0), new ItemStack(Material.SMOOTH_BRICK));
UtilServer.RegisterEvents(this);
}
@SuppressWarnings("deprecation")
private Pair<ItemStack, Boolean> convert(ItemStack old)
{
if (old == null)
{
return Pair.create(old, false);
}
Pair<Material, Byte> pair = Pair.create(old.getType(), old.getData().getData());
if (!_replace.containsKey(pair))
{
return Pair.create(old, false);
}
ItemBuilder after = new ItemBuilder(_replace.get(pair));
if (after.getType() == Material.RED_ROSE)
{
after.setData((short)UtilMath.r(9));
}
else if (after.getType() == Material.COBBLE_WALL)
{
after.setData((short)1);
}
else if (after.getType() == Material.GLOWSTONE)
{
after.setData((short)0);
}
else if (after.getType() == Material.SMOOTH_BRICK)
{
after.setData(UtilMath.randomElement(new Short[] {1, 3}).shortValue());
}
else
{
after.setData(UtilMath.randomElement(DyeColor.values()).getWoolData());
}
after.setAmount(old.getAmount());
return Pair.create(after.build(), true);
}
@SuppressWarnings("deprecation")
public void open(Player player)
{
Inventory newInv = Bukkit.createInventory(player, 27, "Builder's Box");
ItemStack border = new ItemBuilder(Material.STAINED_GLASS_PANE).setData((short)DyeColor.GRAY.getWoolData()).setTitle(C.cRed + " ").build();
ItemStack button = new ItemBuilder(Material.STAINED_GLASS_PANE).setData((short)DyeColor.LIME.getWoolData()).setTitle(C.cGreenB + "Convert").build();
for (int i = 0; i < 27; i++)
{
if (i == 22)
{
newInv.setItem(i, button);
continue;
}
if (i < 9 || i > 17)
{
newInv.setItem(i, border);
}
}
player.openInventory(newInv);
}
@EventHandler
public void onClose(InventoryCloseEvent event)
{
InventoryView view = event.getView();
if (view.getTopInventory() != null)
{
Inventory top = view.getTopInventory();
if (top.getTitle().equals("Builder's Box"))
{
List<ItemStack> items = new ArrayList<>();
for (int i = 9; i < 18; i++)
{
items.add(top.getItem(i));
}
if (items != null && !items.isEmpty());
{
int totalChanged = 0;
for (Pair<ItemStack, Boolean> pair : items.stream().map(this::convert).collect(Collectors.toList()))
{
if (pair.getLeft() == null)
{
continue;
}
if (pair.getRight())
{
totalChanged++;
}
event.getPlayer().getInventory().addItem(pair.getLeft());
}
if (totalChanged > 0)
{
ClansManager.getInstance().getInventoryManager().addItemToInventory((Player)event.getPlayer(), BoxType.BUILDER_BOX.getItemName(), -1);
UtilPlayer.message(event.getPlayer(), F.main("Builder's Box", "You have redeemed your box contents!"));
}
}
}
}
}
@EventHandler
public void onClick(InventoryClickEvent event)
{
if (event.getClickedInventory() != null && event.getClickedInventory().getTitle().equals("Builder's Box"))
{
if (event.getSlot() < 9 || event.getSlot() > 17)
{
event.setCancelled(true);
}
if (event.getSlot() == 22)
{
event.getWhoClicked().closeInventory();
}
}
}
}

View File

@ -0,0 +1,172 @@
package mineplex.game.clans.clans.boxes.extra;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.bukkit.Bukkit;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
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.boxes.BoxManager.BoxType;
public class DyeBoxSpinner implements Listener
{
private Player _player;
private Inventory _inv;
private int _step;
private List<ItemStack> _items;
private boolean _givenRewards = false;
private DyeBoxSpinner(Player player)
{
_player = player;
_inv = Bukkit.createInventory(player, 27, "Dye Box");
_step = 0;
_items = new ArrayList<>();
buildGUI();
generateRewards();
player.openInventory(_inv);
Bukkit.getPluginManager().registerEvents(this, UtilServer.getPlugin());
}
/**
* Upper and lower bounds are inclusive
*/
private int getRandom(int max, int min)
{
return UtilMath.r(max - min + 1) + min;
}
@SuppressWarnings("deprecation")
private void buildGUI()
{
ItemStack border = new ItemBuilder(Material.STAINED_GLASS_PANE).setData((short)DyeColor.GRAY.getWoolData()).setTitle(C.cRed + " ").build();
ItemStack fill = new ItemBuilder(Material.STAINED_GLASS_PANE).setData((short)DyeColor.BLACK.getWoolData()).setTitle(C.cRed + " ").build();
for (int i = 0; i < 27; i++)
{
if (i < 9 || i > 17)
{
_inv.setItem(i, border);
}
else
{
_inv.setItem(i, fill);
}
}
}
@SuppressWarnings("deprecation")
private void generateRewards()
{
List<DyeColor> commonColors = Arrays.asList(DyeColor.values()).stream().filter(c -> c != DyeColor.BLACK && c != DyeColor.WHITE).collect(Collectors.toList());
List<DyeColor> rareColors = Arrays.asList(DyeColor.WHITE, DyeColor.BLACK);
for (int i = 1; i <= getRandom(9, 5); i++)
{
DyeColor color = null;
if (Math.random() <= 0.05)
{
color = UtilMath.randomElement(rareColors);
}
else
{
color = UtilMath.randomElement(commonColors);
}
_items.add(new ItemBuilder(Material.INK_SACK).setData(color.getDyeData()).setTitle(C.cGold + "Dye").build());
}
}
private void giveRewards()
{
if (_givenRewards)
{
return;
}
_givenRewards = true;
_player.closeInventory();
_items.forEach(_player.getInventory()::addItem);
UtilPlayer.message(_player, F.main("Dye Box", "You have redeemed your box contents!"));
}
@SuppressWarnings("deprecation")
private void progress()
{
if (_step == 0)
{
_step++;
return;
}
if (_step < 10)
{
int slot = 18 - _step;
if (Math.max(18, slot) - Math.min(18, slot) <= _items.size())
{
_inv.setItem(slot, new ItemBuilder(Material.STAINED_GLASS_PANE).setData((short)DyeColor.LIME.getWoolData()).setTitle(C.cRed + " ").build());
}
_step++;
return;
}
if (_step == 10)
{
int slot = 17;
for (int i = 0; i < _items.size(); i++)
{
_inv.setItem(slot, _items.get(i));
slot--;
}
_step++;
return;
}
}
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (event.getType() == UpdateType.FASTEST)
{
if (_player.getOpenInventory() == null || _player.getOpenInventory().getTopInventory() == null || !_player.getOpenInventory().getTopInventory().getName().equals("Dye Box"))
{
HandlerList.unregisterAll(this);
giveRewards();
}
}
if (event.getType() == UpdateType.SEC)
{
progress();
}
}
@EventHandler
public void onClick(InventoryClickEvent event)
{
if (event.getWhoClicked().getEntityId() == _player.getEntityId())
{
event.setCancelled(true);
}
}
public static void createSpinner(Player player)
{
ClansManager.getInstance().getInventoryManager().addItemToInventory(player, BoxType.DYE_BOX.getItemName(), -1);
new DyeBoxSpinner(player);
}
}

View File

@ -2,10 +2,13 @@ package mineplex.game.clans.clans.commands;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import mineplex.core.Managers;
import mineplex.core.command.CommandBase; import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank; import mineplex.core.common.Rank;
import mineplex.core.common.util.F; import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilPlayer;
import mineplex.core.punish.Punish;
import mineplex.core.punish.PunishClient;
import mineplex.game.clans.clans.ClanInfo; import mineplex.game.clans.clans.ClanInfo;
import mineplex.game.clans.clans.ClansManager; import mineplex.game.clans.clans.ClansManager;
@ -39,7 +42,16 @@ public class ClansAllyChatCommand extends CommandBase<ClansManager>
{ {
ClanInfo clan = Plugin.getClanUtility().getClanByPlayer(caller); ClanInfo clan = Plugin.getClanUtility().getClanByPlayer(caller);
if (clan == null) UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); if (clan == null) UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan."));
else Plugin.chatAlly(clan, caller, F.combine(args, 0, null, false)); else
{
PunishClient punishClient = Managers.get(Punish.class).GetClient(caller.getName());
if (punishClient != null && punishClient.IsMuted())
{
UtilPlayer.message(caller, F.main("Clans", "You cannot do this while muted!"));
return;
}
Plugin.chatAlly(clan, caller, F.combine(args, 0, null, false));
}
} }
} }
} }

View File

@ -2,10 +2,13 @@ package mineplex.game.clans.clans.commands;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import mineplex.core.Managers;
import mineplex.core.command.CommandBase; import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank; import mineplex.core.common.Rank;
import mineplex.core.common.util.F; import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilPlayer;
import mineplex.core.punish.Punish;
import mineplex.core.punish.PunishClient;
import mineplex.game.clans.clans.ClanInfo; import mineplex.game.clans.clans.ClanInfo;
import mineplex.game.clans.clans.ClansManager; import mineplex.game.clans.clans.ClansManager;
@ -41,7 +44,15 @@ public class ClansChatCommand extends CommandBase<ClansManager>
if (clan == null) if (clan == null)
UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan."));
else else
{
PunishClient punishClient = Managers.get(Punish.class).GetClient(caller.getName());
if (punishClient != null && punishClient.IsMuted())
{
UtilPlayer.message(caller, F.main("Clans", "You cannot do this while muted!"));
return;
}
Plugin.chatClan(clan, caller, F.combine(args, 0, null, false)); Plugin.chatClan(clan, caller, F.combine(args, 0, null, false));
}
} }
} }
} }

View File

@ -549,6 +549,12 @@ public class ClansCommand extends CommandBase<ClansManager>
UtilPlayer.message(caller, F.main("Clans", "The clan " + F.elem("Clan " + clan.getName()) + " is full and cannot be joined!")); UtilPlayer.message(caller, F.main("Clans", "The clan " + F.elem("Clan " + clan.getName()) + " is full and cannot be joined!"));
return; return;
} }
if (clan.getAllies() > clan.getAlliesMaxWithMemberCountOf(clan.getSize() + 1))
{
UtilPlayer.message(caller, F.main("Clans", "You cannot join " + F.elem("Clan " + clan.getName()) + " until they remove some allies!"));
return;
}
ClanJoinEvent event = new ClanJoinEvent(clan, caller); ClanJoinEvent event = new ClanJoinEvent(clan, caller);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);

View File

@ -7,8 +7,8 @@ public enum ClanIcon
JOIN(Material.PRISMARINE, (byte) 1), JOIN(Material.PRISMARINE, (byte) 1),
LEAVE(Material.PRISMARINE, (byte) 2), LEAVE(Material.PRISMARINE, (byte) 2),
TERRITORY(Material.PRISMARINE, (byte) 0), TERRITORY(Material.PRISMARINE, (byte) 0),
MEMBER(Material.SAND, (byte) 1), MEMBER(Material.WATER_BUCKET, (byte) 0),
COMMANDS(Material.RED_SANDSTONE, (byte) 0), COMMANDS(Material.LAVA_BUCKET, (byte) 0),
ENERGY(Material.SEA_LANTERN, (byte) 0), ENERGY(Material.SEA_LANTERN, (byte) 0),
CASTLE(Material.RECORD_9, (byte) 0), CASTLE(Material.RECORD_9, (byte) 0),
WAR(Material.RECORD_11, (byte) 0), WAR(Material.RECORD_11, (byte) 0),

View File

@ -9,6 +9,7 @@ import org.bukkit.event.inventory.ClickType;
import mineplex.core.common.util.C; import mineplex.core.common.util.C;
import mineplex.core.common.util.F; import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilWorld; import mineplex.core.common.util.UtilWorld;
import mineplex.game.clans.clans.ClanInfo; import mineplex.game.clans.clans.ClanInfo;
import mineplex.game.clans.clans.ClanRole; import mineplex.game.clans.clans.ClanRole;
@ -27,12 +28,18 @@ public class ClanTerritoryButton extends ClanButton
{ {
if (UtilServer.CallEvent(new ClansButtonClickEvent(player, ClansButtonClickEvent.ButtonType.Territory)).isCancelled()) if (UtilServer.CallEvent(new ClansButtonClickEvent(player, ClansButtonClickEvent.ButtonType.Territory)).isCancelled())
return; return;
// if (_clansManager.getNetherManager().isInNether(player)) if (_clansManager.getNetherManager().isInNether(player))
// { {
// _clansManager.message(player, "You are not allowed to do anything with Territory while in " + F.clansNether("The Nether") + "."); UtilPlayer.message(player, F.main(_clansManager.getNetherManager().getName(), "You cannot manage your clan's territory while in " + F.clansNether("The Nether") + "!"));
// player.closeInventory(); player.closeInventory();
// return; return;
// } }
if (_clansManager.getWorldEvent().getRaidManager().isInRaid(player.getLocation()))
{
UtilPlayer.message(player, F.main(_clansManager.getWorldEvent().getRaidManager().getName(), "You cannot manage your clan's territory while in a raid!"));
player.closeInventory();
return;
}
if (clickType == ClickType.LEFT) if (clickType == ClickType.LEFT)
{ {

View File

@ -361,4 +361,4 @@ public class ClanMainPage extends ClanPageBase
addButton(slot, item, new ClanMemeberButton(getShop(), getPlugin(), getPlayer(), guiInfo, guiRole, this, clansPlayer.getPlayerName())); addButton(slot, item, new ClanMemeberButton(getShop(), getPlugin(), getPlayer(), guiInfo, guiRole, this, clansPlayer.getPlayerName()));
} }
} }

View File

@ -4,6 +4,7 @@ import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import mineplex.game.clans.clans.mounts.Mount.MountType;
import mineplex.game.clans.economy.GoldManager; import mineplex.game.clans.economy.GoldManager;
import mineplex.game.clans.items.GearManager; import mineplex.game.clans.items.GearManager;
import mineplex.core.common.weight.WeightSet; import mineplex.core.common.weight.WeightSet;
@ -87,8 +88,9 @@ public class LootManager
private void populateRare() private void populateRare()
{ {
// Gear // Gear
_rareSet.add(90, new GearLoot(_gearManager)); _rareSet.add(70, new GearLoot(_gearManager));
_rareSet.add(10, new GoldTokenLoot(50000, 100000)); _rareSet.add(10, new GoldTokenLoot(50000, 100000));
_rareSet.add(20, new MountLoot(1, 3, MountType.values()));
} }
public void dropCommon(Location location) public void dropCommon(Location location)

View File

@ -0,0 +1,45 @@
package mineplex.game.clans.clans.loot;
import org.bukkit.Color;
import org.bukkit.FireworkEffect.Type;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.UtilFirework;
import mineplex.core.common.util.UtilMath;
import mineplex.game.clans.clans.mounts.Mount.MountType;
import mineplex.game.clans.clans.mounts.MountClaimToken;
public class MountLoot implements ILoot
{
private int _minStars, _maxStars;
private MountType[] _types;
public MountLoot(int minStars, int maxStars, MountType... types)
{
_minStars = Math.max(minStars, 1);
_maxStars = Math.min(maxStars, 3);
if (types.length == 0)
{
_types = MountType.values();
}
else
{
_types = types;
}
}
@Override
public void dropLoot(Location location)
{
MountClaimToken token = new MountClaimToken(UtilMath.rRange(_minStars, _maxStars), UtilMath.rRange(_minStars, _maxStars), UtilMath.rRange(_minStars, _maxStars), UtilMath.randomElement(_types));
UtilFirework.playFirework(location.clone().add(0, 3, 0), Type.BALL, Color.SILVER, true, false);
location.getWorld().dropItemNaturally(location.clone().add(0, 3, 0), token.toItem());
}
@Override
public ItemStack getItemStack()
{
return new MountClaimToken(UtilMath.rRange(_minStars, _maxStars), UtilMath.rRange(_minStars, _maxStars), UtilMath.rRange(_minStars, _maxStars), UtilMath.randomElement(_types)).toItem();
}
}

View File

@ -1,20 +1,6 @@
package mineplex.game.clans.clans.map; package mineplex.game.clans.clans.map;
import java.awt.Color; import java.awt.Color;
import java.util.List;
import mineplex.core.common.util.UtilTime;
import mineplex.core.recharge.Recharge;
import mineplex.game.clans.clans.ClanInfo;
import mineplex.game.clans.clans.ClansUtility;
import mineplex.game.clans.clans.worldevent.WorldEventManager;
import mineplex.game.clans.tutorial.TutorialManager;
import mineplex.game.clans.tutorial.TutorialRegion;
import mineplex.game.clans.tutorial.TutorialType;
import mineplex.game.clans.tutorial.map.TutorialMapManager;
import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial;
import mineplex.minecraft.game.core.boss.EventState;
import mineplex.minecraft.game.core.boss.WorldEvent;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@ -26,6 +12,14 @@ import org.bukkit.map.MapPalette;
import org.bukkit.map.MapRenderer; import org.bukkit.map.MapRenderer;
import org.bukkit.map.MapView; import org.bukkit.map.MapView;
import mineplex.core.common.util.UtilTime;
import mineplex.game.clans.clans.ClanInfo;
import mineplex.game.clans.clans.ClansUtility;
import mineplex.game.clans.clans.worldevent.WorldEventManager;
import mineplex.game.clans.clans.worldevent.api.EventState;
import mineplex.game.clans.clans.worldevent.api.WorldEvent;
import mineplex.game.clans.tutorial.TutorialManager;
public class ItemMapRenderer extends MapRenderer public class ItemMapRenderer extends MapRenderer
{ {
private ItemMapManager _manager; private ItemMapManager _manager;

View File

@ -0,0 +1,370 @@
package mineplex.game.clans.clans.mounts;
import java.util.function.Consumer;
import org.bukkit.ChatColor;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftHorse;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Horse.Color;
import org.bukkit.entity.Horse.Style;
import org.bukkit.entity.Horse.Variant;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.TriConsumer;
import mineplex.core.common.util.C;
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.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.disguise.disguises.DisguiseBase;
import mineplex.core.disguise.disguises.DisguiseCow;
import mineplex.core.disguise.disguises.DisguiseSheep;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.game.clans.clans.ClansManager;
import net.minecraft.server.v1_8_R3.GenericAttributes;
public class Mount
{
private static final long HIT_REGEN_COOLDOWN = 30000;
private Player _owner;
private CraftHorse _entity;
private SkinType _skin;
private final int _strength;
private long _lastHit;
private int _hits;
public Mount(Player owner, CraftHorse entity, SkinType skin, int strength)
{
_owner = owner;
_entity = entity;
_skin = skin;
_strength = strength;
_lastHit = System.currentTimeMillis();
_hits = 0;
}
public Player getOwner()
{
return _owner;
}
public CraftHorse getEntity()
{
return _entity;
}
public void update()
{
if (_skin != null)
{
_skin.onUpdate(_entity);
}
if (UtilTime.elapsed(_lastHit, HIT_REGEN_COOLDOWN) && _hits > 0)
{
_hits--;
_lastHit = System.currentTimeMillis();
}
}
public void despawn(boolean forced)
{
UtilServer.CallEvent(new MountDespawnEvent(this, forced));
_entity.getInventory().setSaddle(null);
_entity.getInventory().setArmor(null);
for (ItemStack item : _entity.getInventory().getContents())
{
if (item == null || item.getType() == Material.AIR)
{
continue;
}
_entity.getWorld().dropItem(_entity.getLocation(), item);
}
_entity.remove();
}
public void handleHit()
{
_hits++;
if (_hits == _strength)
{
despawn(true);
}
}
public static enum SkinType
{
INFERNAL_HORROR(1, "Clans Infernal Horror Mount Skin", C.cRed + "Infernal Horror", Material.BONE, Color.BLACK, Variant.SKELETON_HORSE, Style.BLACK_DOTS, horse -> {}, horse ->
{
UtilParticle.PlayParticleToAll(ParticleType.FLAME, horse.getLocation().add(0, 1, 0),
0.25f, 0.25f, 0.25f, 0, 2,ViewDist.NORMAL);
}, MountType.HORSE),
GLACIAL_STEED(2, "Clans Glacial Steed Mount Skin", C.cGray + "Glacial Steed", Material.SNOW_BALL, Color.WHITE, Variant.HORSE, Style.WHITE, horse -> {}, horse ->
{
UtilParticle.PlayParticleToAll(ParticleType.SNOW_SHOVEL, horse.getLocation().add(0, 1, 0),
0.25f, 0.25f, 0.25f, 0.1f, 4, ViewDist.NORMAL);
}, MountType.HORSE),
ZOMBIE_HORSE(3, "Clans Zombie Horse Mount Skin", C.cDGray + "Zombie Horse", Material.ROTTEN_FLESH, Color.BLACK, Variant.UNDEAD_HORSE, Style.BLACK_DOTS, horse -> {}, horse ->
{
UtilParticle.PlayParticleToAll(ParticleType.FOOTSTEP, horse.getLocation(),
null, 0, 1, ViewDist.NORMAL);
}, MountType.HORSE),
@SuppressWarnings("deprecation")
RAINBOW_SHEEP(4, "Clans Rainbow Sheep Mount Skin", C.cGreen + "Rainbow " + C.cAqua + "Sheep", new ItemBuilder(Material.WOOL).setData(DyeColor.RED.getWoolData()).build(),Color.WHITE, Variant.HORSE, Style.NONE, horse ->
{
DisguiseSheep disguise = new DisguiseSheep(horse);
disguise.setName(horse.getCustomName());
ClansManager.getInstance().getDisguiseManager().disguise(disguise);
}, horse ->
{
DisguiseBase base = ClansManager.getInstance().getDisguiseManager().getActiveDisguise(horse);
if (base == null || !(base instanceof DisguiseSheep))
{
return;
}
DisguiseSheep sheep = (DisguiseSheep)base;
if (horse.getTicksLived() % 4 == 0) sheep.setColor(DyeColor.RED);
else if (horse.getTicksLived() % 4 == 1) sheep.setColor(DyeColor.YELLOW);
else if (horse.getTicksLived() % 4 == 2) sheep.setColor(DyeColor.GREEN);
else if (horse.getTicksLived() % 4 == 3) sheep.setColor(DyeColor.BLUE);
}, MountType.HORSE),
ROYAL_STEED(5, "Clans Royal Steed Mount Skin", C.cGold + "Royal Steed", Material.DIAMOND_BARDING, Color.WHITE, Variant.HORSE, Style.WHITE, horse ->
{
horse.getInventory().setArmor(new ItemBuilder(Material.DIAMOND_BARDING).setTitle(C.cGoldB + "Royal Armor").build());
}, horse ->
{
UtilParticle.PlayParticleToAll(ParticleType.BLOCK_DUST.getParticle(Material.GOLD_BLOCK, 0), horse.getLocation().add(0, 1, 0),
0.25f, 0.25f, 0.25f, 0, 3, ViewDist.NORMAL);
}, MountType.HORSE),
ROYAL_GUARD_STEED(6, "Clans Royal Guard Steed Mount Skin", C.cGray + "Royal Guard's Steed", Material.GOLD_BARDING, Color.BLACK, Variant.HORSE, Style.NONE, horse ->
{
horse.getInventory().setArmor(new ItemBuilder(Material.GOLD_BARDING).setTitle(C.cGoldB + "Guardian Armor").build());
}, horse ->
{
UtilParticle.PlayParticleToAll(ParticleType.BLOCK_DUST.getParticle(Material.IRON_BLOCK, 0), horse.getLocation().add(0, 1, 0),
0.25f, 0.25f, 0.25f, 0, 3, ViewDist.NORMAL);
}, MountType.HORSE),
KNIGHT_STEED(7, "Clans Knight Steed Mount Skin", C.cDRed + "Knight's Steed", Material.IRON_BARDING, Color.GRAY, Variant.HORSE, Style.NONE, horse ->
{
horse.getInventory().setArmor(new ItemBuilder(Material.IRON_BARDING).setTitle(C.cGoldB + "Knightly Armor").build());
}, horse ->
{
UtilParticle.PlayParticleToAll(ParticleType.ICON_CRACK.getParticle(Material.APPLE, 0), horse.getLocation().add(0, 1, 0),
0.25f, 0.25f, 0.25f, 0, 3, ViewDist.NORMAL);
}, MountType.HORSE),
COW(8, "Clans Cow Mount Skin", C.cWhite + "Cow", Material.MILK_BUCKET, Color.WHITE, Variant.HORSE, Style.NONE, horse ->
{
DisguiseCow disguise = new DisguiseCow(horse);
disguise.setName(horse.getCustomName());
ClansManager.getInstance().getDisguiseManager().disguise(disguise);
}, horse -> {}, MountType.HORSE),
SHEEP(9, "Clans Sheep Mount Skin", C.cWhite + "Sheep", Material.WOOL, Color.WHITE, Variant.HORSE, Style.NONE, horse ->
{
DisguiseSheep disguise = new DisguiseSheep(horse);
disguise.setName(horse.getCustomName());
ClansManager.getInstance().getDisguiseManager().disguise(disguise);
}, horse -> {}, MountType.HORSE),
TRUSTY_MULE(10, "Clans Trusty Mule Mount Skin", C.cBlue + "Trusty Mule", Material.APPLE, Color.BROWN, Variant.MULE, Style.NONE, horse -> {}, horse -> {}, MountType.DONKEY)
;
private final int _id;
private final String _packageName;
private final String _displayName;
private final ItemStack _baseDisplayItem;
private final Color _color;
private final Variant _variant;
private final Style _style;
private final Consumer<CraftHorse> _onSpawn, _onUpdate;
private final MountType[] _possibleTypes;
private SkinType(int id, String packageName, String displayName, Material displayType, Color color, Variant variant, Style style, Consumer<CraftHorse> onSpawn, Consumer<CraftHorse> onUpdate, MountType... possibleTypes)
{
this(id, packageName, displayName, new ItemStack(displayType), color, variant, style, onSpawn, onUpdate, possibleTypes);
}
private SkinType(int id, String packageName, String displayName, ItemStack baseDisplayItem, Color color, Variant variant, Style style, Consumer<CraftHorse> onSpawn, Consumer<CraftHorse> onUpdate, MountType... possibleTypes)
{
_id = id;
_packageName = packageName;
_displayName = displayName;
_baseDisplayItem = baseDisplayItem;
_color = color;
_variant = variant;
_style = style;
_onSpawn = onSpawn;
_onUpdate = onUpdate;
_possibleTypes = possibleTypes;
}
public int getId()
{
return _id;
}
public String getPackageName()
{
return _packageName;
}
public String getDisplayName()
{
return _displayName;
}
public ItemStack getBaseDisplay()
{
return _baseDisplayItem;
}
public Color getColor()
{
return _color;
}
public Variant getVariant()
{
return _variant;
}
public Style getStyle()
{
return _style;
}
public void onSpawn(CraftHorse horse)
{
_onSpawn.accept(horse);
}
public void onUpdate(CraftHorse horse)
{
_onUpdate.accept(horse);
}
public MountType[] getPossibleTypes()
{
return _possibleTypes;
}
public static SkinType getFromId(int id)
{
for (SkinType type : SkinType.values())
{
if (type.getId() == id)
{
return type;
}
}
return null;
}
}
public static enum MountType
{
HORSE(1, C.cWhite + "Horse", Material.IRON_BARDING, (owner, skin, stats) ->
{
CraftHorse horse = (CraftHorse) owner.getWorld().spawnEntity(owner.getLocation(), EntityType.HORSE);
horse.setAdult();
horse.setAgeLock(true);
horse.setBreed(false);
horse.setCustomNameVisible(true);
horse.setCustomName(owner.getName() + "'s " + (skin == null ? "Horse" : ChatColor.stripColor(skin.getDisplayName())));
if (skin != null)
{
horse.setVariant(skin.getVariant());
horse.setColor(skin.getColor());
horse.setStyle(skin.getStyle());
skin.onSpawn(horse);
}
horse.setTamed(true);
horse.getInventory().setSaddle(new ItemStack(Material.SADDLE));
horse.setOwner(owner);
horse.setJumpStrength(MountManager.getJump(stats.JumpStars));
horse.getHandle().getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(MountManager.getSpeed(stats.SpeedStars));
//horse.setPassenger(owner);
Mount mount = new Mount(owner, horse, skin, MountManager.getStrength(stats.StrengthStars));
UtilServer.CallEvent(new MountSpawnEvent(mount));
}),
DONKEY(2, C.cWhite + "Donkey", Material.GOLD_BARDING, (owner, skin, stats) ->
{
CraftHorse horse = (CraftHorse) owner.getWorld().spawnEntity(owner.getLocation(), EntityType.HORSE);
horse.setAdult();
horse.setAgeLock(true);
horse.setBreed(false);
horse.setCustomNameVisible(true);
horse.setCustomName(owner.getName() + "'s " + (skin == null ? "Donkey" : ChatColor.stripColor(skin.getDisplayName())));
if (skin != null)
{
horse.setVariant(skin.getVariant());
skin.onSpawn(horse);
}
else
{
horse.setVariant(Variant.DONKEY);
}
horse.setTamed(true);
horse.getInventory().setSaddle(new ItemStack(Material.SADDLE));
horse.setOwner(owner);
horse.setJumpStrength(MountManager.getJump(stats.JumpStars));
horse.getHandle().getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(MountManager.getSpeed(stats.SpeedStars));
horse.setCarryingChest(true);
//horse.setPassenger(owner);
Mount mount = new Mount(owner, horse, skin, MountManager.getStrength(stats.StrengthStars));
UtilServer.CallEvent(new MountSpawnEvent(mount));
})
;
private final int _id;
private final String _displayName;
private final Material _displayType;
private final TriConsumer<Player, SkinType, MountStatToken> _spawnHandler;
private MountType(int id, String displayName, Material displayType, TriConsumer<Player, SkinType, MountStatToken> spawnHandler)
{
_id = id;
_displayName = displayName;
_displayType = displayType;
_spawnHandler = spawnHandler;
}
public int getId()
{
return _id;
}
public String getDisplayName()
{
return _displayName;
}
public Material getDisplayType()
{
return _displayType;
}
public void spawn(Player owner, SkinType skinType, MountStatToken statToken)
{
_spawnHandler.accept(owner, skinType, statToken);
}
public static MountType getFromId(int id)
{
for (MountType type : MountType.values())
{
if (type.getId() == id)
{
return type;
}
}
return null;
}
}
}

View File

@ -0,0 +1,103 @@
package mineplex.game.clans.clans.mounts;
import org.bukkit.ChatColor;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.C;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.game.clans.clans.mounts.Mount.MountType;
public class MountClaimToken
{
private final String STAR = "";
public final int JumpStars;
public final int SpeedStars;
public final int StrengthStars;
public final MountType Type;
public MountClaimToken(int jumpStars, int speedStars, int strengthStars, MountType type)
{
JumpStars = jumpStars;
SpeedStars = speedStars;
StrengthStars = strengthStars;
Type = type;
}
public ItemStack toItem()
{
ItemBuilder builder = new ItemBuilder(Type.getDisplayType());
builder.setTitle(Type.getDisplayName() + " Mount Token");
String strength = C.cYellow;
for (int i = 0; i < StrengthStars; i++)
{
strength += STAR;
}
builder.addLore(C.cPurple + "Strength: " + strength);
String speed = C.cYellow;
for (int i = 0; i < SpeedStars; i++)
{
speed += STAR;
}
builder.addLore(C.cPurple + "Speed: " + speed);
String jump = C.cYellow;
for (int i = 0; i < JumpStars; i++)
{
jump += STAR;
}
builder.addLore(C.cPurple + "Jump: " + jump);
builder.addLore(C.cRed);
builder.addLore(C.cDGreen + "Right-Click While Holding to Consume");
return builder.build();
}
public static MountClaimToken fromItem(ItemStack item)
{
if (!item.hasItemMeta() || !item.getItemMeta().hasLore())
{
return null;
}
MountType type = null;
for (MountType check : MountType.values())
{
if (check.getDisplayType() == item.getType())
{
type = check;
break;
}
}
if (type == null)
{
return null;
}
int strength = -1;
int speed = -1;
int jump = -1;
for (String lore : item.getItemMeta().getLore())
{
if (ChatColor.stripColor(lore).startsWith("Strength: "))
{
strength = ChatColor.stripColor(lore).replace("Strength: ", "").length();
}
if (ChatColor.stripColor(lore).startsWith("Speed: "))
{
speed = ChatColor.stripColor(lore).replace("Speed: ", "").length();
}
if (ChatColor.stripColor(lore).startsWith("Jump: "))
{
jump = ChatColor.stripColor(lore).replace("Jump: ", "").length();
}
}
if (strength <= 0 || speed <= 0 || jump <= 0)
{
return null;
}
return new MountClaimToken(strength, speed, jump, type);
}
}

View File

@ -0,0 +1,41 @@
package mineplex.game.clans.clans.mounts;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* Event called before a mount despawns
*/
public class MountDespawnEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private final Mount _mount;
private final boolean _forced;
public MountDespawnEvent(Mount mount, boolean forced)
{
_mount = mount;
_forced = forced;
}
public Mount getMount()
{
return _mount;
}
public boolean isForced()
{
return _forced;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
}

View File

@ -0,0 +1,528 @@
package mineplex.game.clans.clans.mounts;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.WeakHashMap;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftHorse;
import org.bukkit.entity.Horse;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.inventory.HorseInventory;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.MiniDbClientPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Pair;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilEvent;
import mineplex.core.common.util.UtilEvent.ActionType;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.donation.DonationManager;
import mineplex.core.recharge.Recharge;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.mounts.Mount.MountType;
import mineplex.game.clans.clans.mounts.Mount.SkinType;
import mineplex.game.clans.clans.mounts.gui.MountShop;
import mineplex.game.clans.spawn.Spawn;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import mineplex.serverdata.Utility;
public class MountManager extends MiniDbClientPlugin<MountOwnerData>
{
private static final double[] JUMP_STARS = {0.8, 1, 1.2};
private static final double[] SPEED_STARS = {0.2, 0.27, 0.33};
private static final int[] STRENGTH_STARS = {1, 2, 3};
private static final long SUMMON_WARMUP = 5000;
private static final long FORCED_COOLDOWN = 120 * 1000;
private static final long MAX_TIME_DISMOUNTED = 30000;
private static final int MAX_PER_TYPE = 3;
private final MountRepository _repository;
private final DonationManager _donationManager;
private final Map<CraftHorse, Mount> _spawnedMounts = new HashMap<>();
private final Map<Player, Pair<Long, MountToken>> _summoning = new WeakHashMap<>();
public MountManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager)
{
super("Clans Mount Manager", plugin, clientManager);
_repository = new MountRepository(plugin, this);
_donationManager = donationManager;
final MountShop shop = new MountShop(this);
addCommand(new CommandBase<MountManager>(this, Rank.ALL, "mounts", "mount")
{
@Override
public void Execute(Player caller, String[] args)
{
shop.attemptShopOpen(caller);
}
});
addCommand(new CommandBase<MountManager>(this, Rank.ADMIN, "givemount")
{
@Override
public void Execute(Player caller, String[] args)
{
if (args.length < 4)
{
UtilPlayer.message(caller, F.main(getName(), "Usage: /" + _aliasUsed + " <SPEED> <JUMP> <STRENGTH> <TYPE>"));
return;
}
Integer speed = 0;
Integer jump = 0;
Integer strength = 0;
MountType type = null;
try
{
speed = Integer.parseInt(args[0]);
}
catch (Exception e)
{
UtilPlayer.message(caller, F.main(getName(), "Invalid speed!"));
return;
}
try
{
jump = Integer.parseInt(args[1]);
}
catch (Exception e)
{
UtilPlayer.message(caller, F.main(getName(), "Invalid jump!"));
return;
}
try
{
strength = Integer.parseInt(args[2]);
}
catch (Exception e)
{
UtilPlayer.message(caller, F.main(getName(), "Invalid strength!"));
return;
}
try
{
type = MountType.valueOf(args[3]);
}
catch (Exception e)
{
UtilPlayer.message(caller, F.main(getName(), "Invalid type!"));
return;
}
caller.getInventory().addItem(new MountClaimToken(jump, speed, strength, type).toItem());
}
});
}
public DonationManager getDonationManager()
{
return _donationManager;
}
public MountRepository getRepository()
{
return _repository;
}
@Override
public void disable()
{
_summoning.clear();
_spawnedMounts.keySet().forEach(CraftHorse::remove);
_spawnedMounts.clear();
}
public boolean summonMount(Player player, MountToken token)
{
if (_summoning.containsKey(player))
{
UtilPlayer.message(player, F.main(getName(), "You are already summoning a mount!"));
return false;
}
if (Spawn.getInstance().isSafe(player.getLocation()))
{
UtilPlayer.message(player, F.main(getName(), "You cannot summon a mount in safezones!"));
return false;
}
if (ClansManager.getInstance().getNetherManager().isInNether(player))
{
UtilPlayer.message(player, F.main(getName(), "You cannot summon a mount in the Nether!"));
return false;
}
if (ClansManager.getInstance().getWorldEvent().getRaidManager().isInRaid(player.getLocation()))
{
UtilPlayer.message(player, F.main(getName(), "You cannot summon a mount inside a raid!"));
return false;
}
if (!Recharge.Instance.usable(player, "Mount Spawn Delay"))
{
UtilPlayer.message(player, F.main(getName(), "You cannot summon a mount so soon after your last one was forcibly despawned!"));
return false;
}
_spawnedMounts.values().stream().filter(mount -> mount.getOwner().getEntityId() == player.getEntityId()).findFirst().ifPresent(mount -> mount.despawn(false));
_summoning.put(player, Pair.create(System.currentTimeMillis(), token));
UtilPlayer.message(player, F.main(getName(), "You are now summoning your mount! Please remain still for 5 seconds!"));
return true;
}
public void giveMount(Player player, MountType type)
{
Pair<MountToken, MountStatToken> tokens = Get(player).grantMount(type);
_repository.saveMount(ClientManager.getAccountId(player), tokens.getLeft(), tokens.getRight());
}
public void giveMount(Player player, MountClaimToken token)
{
Pair<MountToken, MountStatToken> tokens = Get(player).grantMount(token.Type, token.SpeedStars, token.JumpStars, token.StrengthStars);
_repository.saveMount(ClientManager.getAccountId(player), tokens.getLeft(), tokens.getRight());
}
public void removeMountToken(Player player, MountToken token, Runnable after)
{
getRepository().deleteMount(token, id ->
{
Get(player).removeMount(id.intValue());
Pair<Long, MountToken> summonPair = _summoning.get(player);
if (summonPair != null)
{
if (summonPair.getRight().Id == id)
{
UtilEnt.addFlag(player, "REMOVED_MOUNT_TOKEN");
}
}
after.run();
});
}
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (event.getType() == UpdateType.TICK)
{
Iterator<Entry<CraftHorse, Mount>> mountIterator = _spawnedMounts.entrySet().iterator();
while (mountIterator.hasNext())
{
Entry<CraftHorse, Mount> entry = mountIterator.next();
if (entry.getKey().isDead() || !entry.getKey().isValid())
{
mountIterator.remove();
entry.getValue().despawn(false);
continue;
}
if (entry.getValue().getOwner().isDead() || !entry.getValue().getOwner().isValid() || !entry.getValue().getOwner().isOnline())
{
mountIterator.remove();
entry.getValue().despawn(false);
continue;
}
if (Spawn.getInstance().isSafe(entry.getKey().getLocation()))
{
mountIterator.remove();
entry.getValue().despawn(false);
continue;
}
if (ClansManager.getInstance().getNetherManager().isInNether(entry.getKey().getLocation()))
{
mountIterator.remove();
entry.getValue().despawn(false);
continue;
}
if (ClansManager.getInstance().getWorldEvent().getRaidManager().isInRaid(entry.getKey().getLocation()))
{
mountIterator.remove();
entry.getValue().despawn(false);
continue;
}
if (entry.getKey().getPassenger() == null)
{
if (UtilEnt.GetMetadata(entry.getKey(), "DISMOUNT_TIME") != null)
{
Long dismount = (Long) UtilEnt.GetMetadata(entry.getKey(), "DISMOUNT_TIME");
if (UtilTime.elapsed(dismount.longValue(), MAX_TIME_DISMOUNTED))
{
mountIterator.remove();
entry.getValue().despawn(false);
continue;
}
}
else
{
UtilEnt.SetMetadata(entry.getKey(), "DISMOUNT_TIME", System.currentTimeMillis());
}
}
else
{
UtilEnt.removeMetadata(entry.getKey(), "DISMOUNT_TIME");
}
entry.getValue().update();
}
Iterator<Entry<Player, Pair<Long, MountToken>>> summoningIterator = _summoning.entrySet().iterator();
while (summoningIterator.hasNext())
{
Entry<Player, Pair<Long, MountToken>> entry = summoningIterator.next();
if (UtilEnt.hasFlag(entry.getKey(), "REMOVED_MOUNT_TOKEN"))
{
summoningIterator.remove();
UtilEnt.removeFlag(entry.getKey(), "REMOVED_MOUNT_TOKEN");
continue;
}
if (UtilTime.elapsed(entry.getValue().getLeft(), SUMMON_WARMUP))
{
summoningIterator.remove();
if (entry.getKey().isDead() || !entry.getKey().isValid() || !entry.getKey().isOnline())
{
continue;
}
if (Spawn.getInstance().isSafe(entry.getKey().getLocation()))
{
continue;
}
if (ClansManager.getInstance().getNetherManager().isInNether(entry.getKey().getLocation()))
{
continue;
}
if (ClansManager.getInstance().getWorldEvent().getRaidManager().isInRaid(entry.getKey().getLocation()))
{
continue;
}
entry.getValue().getRight().Type.spawn(entry.getKey(), entry.getValue().getRight().Skin, Get(entry.getKey()).getStatToken(entry.getValue().getRight()));
continue;
}
if (UtilEnt.hasFlag(entry.getKey(), "MOVED_WHILE_SUMMONING_MOUNT"))
{
summoningIterator.remove();
UtilEnt.removeFlag(entry.getKey(), "MOVED_WHILE_SUMMONING_MOUNT");
UtilPlayer.message(entry.getKey(), F.main(getName(), "You have stopped summoning your mount as you have moved!"));
continue;
}
}
}
}
@EventHandler
public void onMove(PlayerMoveEvent event)
{
if (_summoning.containsKey(event.getPlayer()) && !UtilEnt.hasFlag(event.getPlayer(), "MOVED_WHILE_SUMMONING_MOUNT"))
{
Block from = event.getFrom().getBlock();
Block to = event.getTo().getBlock();
if (from.getX() == to.getX() && from.getY() == to.getY() && from.getZ() == to.getZ())
{
return;
}
UtilEnt.addFlag(event.getPlayer(), "MOVED_WHILE_SUMMONING_MOUNT");
}
}
@EventHandler
public void onSummon(MountSpawnEvent event)
{
_spawnedMounts.put(event.getMount().getEntity(), event.getMount());
UtilPlayer.message(event.getMount().getOwner(), F.main(getName(), "Your mount has spawned!"));
}
@EventHandler
public void onDespawn(MountDespawnEvent event)
{
_spawnedMounts.remove(event.getMount().getEntity());
event.getMount().getEntity().eject();
event.getMount().getEntity().remove();
UtilPlayer.message(event.getMount().getOwner(), F.main(getName(), "Your mount has despawned!"));
if (event.isForced())
{
Recharge.Instance.use(event.getMount().getOwner(), "Mount Spawn Delay", FORCED_COOLDOWN, false, false);
}
}
@EventHandler
public void onUseToken(PlayerInteractEvent event)
{
if (!UtilEvent.isAction(event, ActionType.R))
{
return;
}
if (event.getItem() == null)
{
return;
}
MountClaimToken token = MountClaimToken.fromItem(event.getItem());
if (token == null)
{
return;
}
event.setCancelled(true);
if (Get(event.getPlayer()).getAmountOwned(token.Type) >= MAX_PER_TYPE)
{
UtilPlayer.message(event.getPlayer(), F.main(getName(), "You have reached the maximum amount of that type of mount!"));
return;
}
giveMount(event.getPlayer(), token);
UtilPlayer.message(event.getPlayer(), F.main(getName(), "You have redeemed your mount!"));
event.getPlayer().getInventory().setItemInHand(null);
}
@EventHandler(priority = EventPriority.LOWEST)
public void handleHorseHits(CustomDamageEvent event)
{
if (event.GetDamageeEntity() == null || !(event.GetDamageeEntity() instanceof Horse))
{
return;
}
Mount mount = _spawnedMounts.get(event.GetDamageeEntity());
if (mount == null)
{
return;
}
if (event.GetDamagerPlayer(true) != null && event.GetDamagerPlayer(true).getEntityId() == mount.getOwner().getEntityId())
{
event.SetCancelled("Damaging own mount");
mount.despawn(false);
return;
}
event.setDamagee(mount.getOwner());
if (event.GetCause() != DamageCause.FALL)
{
mount.handleHit();
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void handleRiderHits(CustomDamageEvent event)
{
if (event.GetDamageePlayer() == null || event.GetDamageePlayer().getVehicle() == null || !(event.GetDamageePlayer().getVehicle() instanceof Horse))
{
return;
}
if (event.GetDamagerPlayer(true) != null && event.GetDamagerPlayer(true).getEntityId() == event.GetDamageePlayer().getEntityId())
{
return;
}
Mount mount = _spawnedMounts.get(event.GetDamageePlayer().getVehicle());
if (mount == null)
{
return;
}
if (event.GetCause() != DamageCause.FALL)
{
mount.handleHit();
}
}
@EventHandler
public void onEditHorseInventory(InventoryClickEvent event)
{
if (!(event.getClickedInventory() instanceof HorseInventory))
{
return;
}
if (!_spawnedMounts.containsKey(event.getClickedInventory().getHolder()))
{
return;
}
if (event.getSlot() == 0 || event.getSlot() == 1)
{
event.setCancelled(true);
}
}
@EventHandler
public void mountInteract(PlayerInteractEntityEvent event)
{
if (!(event.getRightClicked() instanceof Horse))
{
return;
}
Mount mount = _spawnedMounts.get(event.getRightClicked());
if (mount == null)
{
return;
}
if (mount.getOwner().getEntityId() == event.getPlayer().getEntityId())
{
return;
}
UtilPlayer.message(event.getPlayer(), F.main(getName(), "This is not your Mount!"));
event.setCancelled(true);
}
@Override
public String getQuery(int accountId, String uuid, String name)
{
return "SELECT am.id, am.mountTypeId, am.mountSkinId, ms.statToken FROM accountClansMounts AS am INNER JOIN clansMountStats AS ms ON ms.mountId = am.id WHERE am.accountId=" + accountId + ";";
}
@Override
public void processLoginResultSet(String playerName, UUID uuid, int accountId, ResultSet resultSet) throws SQLException
{
MountOwnerData data = new MountOwnerData();
while (resultSet.next())
{
MountToken token = new MountToken();
token.Id = resultSet.getInt("id");
token.Type = MountType.getFromId(resultSet.getInt("mountTypeId"));
token.Skin = SkinType.getFromId(resultSet.getInt("mountSkinId"));
MountStatToken statToken = Utility.deserialize(resultSet.getString("statToken"), MountStatToken.class);
data.acceptLoad(token, statToken);
}
Set(uuid, data);
}
@Override
protected MountOwnerData addPlayer(UUID uuid)
{
return new MountOwnerData();
}
public static double getSpeed(int stars)
{
stars = Math.min(Math.max(1, stars), 3);
return SPEED_STARS[stars - 1];
}
public static double getJump(int stars)
{
stars = Math.min(Math.max(1, stars), 3);
return JUMP_STARS[stars - 1];
}
public static int getStrength(int stars)
{
stars = Math.min(Math.max(1, stars), 3);
return STRENGTH_STARS[stars - 1];
}
}

View File

@ -0,0 +1,80 @@
package mineplex.game.clans.clans.mounts;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import mineplex.core.common.Pair;
import mineplex.core.common.util.UtilMath;
import mineplex.game.clans.clans.mounts.Mount.MountType;
public class MountOwnerData
{
private Map<MountToken, MountStatToken> _mounts = new LinkedHashMap<>();
public List<Pair<MountToken, MountStatToken>> getOwnedMounts(boolean onlyInitialized)
{
return _mounts.entrySet().stream().filter(entry -> onlyInitialized ? entry.getKey().Id != -1 : true).map(entry -> Pair.create(entry.getKey(), entry.getValue())).collect(Collectors.toList());
}
public List<Pair<MountToken, MountStatToken>> getOwnedMounts(boolean onlyInitialized, MountType type)
{
return _mounts.entrySet().stream().filter(entry -> (onlyInitialized ? entry.getKey().Id != -1 : true) && type == entry.getKey().Type).map(entry -> Pair.create(entry.getKey(), entry.getValue())).collect(Collectors.toList());
}
public MountStatToken getStatToken(MountToken mountToken)
{
return _mounts.get(mountToken);
}
public boolean ownsMount(MountType type)
{
return getAmountOwned(type) > 0;
}
public long getAmountOwned(MountType type)
{
return _mounts.keySet().stream().filter(token -> token.Type == type).count();
}
public void acceptLoad(MountToken token, MountStatToken statToken)
{
_mounts.put(token, statToken);
}
public Pair<MountToken, MountStatToken> grantMount(MountType type, int speed, int jump, int strength)
{
MountToken token = new MountToken();
token.Type = type;
MountStatToken statToken = new MountStatToken();
statToken.JumpStars = jump;
statToken.SpeedStars = speed;
statToken.StrengthStars = strength;
_mounts.put(token, statToken);
return Pair.create(token, statToken);
}
public Pair<MountToken, MountStatToken> grantMount(MountType type)
{
int speed = UtilMath.rRange(1, 3);
int jump = UtilMath.rRange(1, 3);
int strength = UtilMath.rRange(1, 3);
return grantMount(type, speed, jump, strength);
}
public Integer[] removeMounts(MountType type)
{
Integer[] array = _mounts.keySet().stream().filter(token->token.Type == type).map(token->token.Id).toArray(size->new Integer[size]);
_mounts.keySet().removeIf(token->token.Type == type);
return array;
}
public void removeMount(int id)
{
_mounts.keySet().removeIf(token->token.Id == id);
}
}

View File

@ -0,0 +1,180 @@
package mineplex.game.clans.clans.mounts;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.function.Consumer;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.common.Pair;
import mineplex.serverdata.Utility;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnVarChar;
/**
* Database repository class for mounts
*/
public class MountRepository extends RepositoryBase
{
private static final String CREATE_MOUNTS_TABLE = "CREATE TABLE IF NOT EXISTS accountClansMounts (id INT NOT NULL AUTO_INCREMENT,"
+ "accountId INT NOT NULL,"
+ "mountTypeId INT NOT NULL,"
+ "mountSkinId INT NOT NULL,"
+ "INDEX typeIndex (mountTypeId),"
+ "INDEX skinIndex (mountSkinId),"
+ "PRIMARY KEY (id));";
private static final String CREATE_MOUNT_STATS_TABLE = "CREATE TABLE IF NOT EXISTS clansMountStats (mountId INT NOT NULL,"
+ "statToken VARCHAR(20) NOT NULL,"
+ "PRIMARY KEY (mountId));";
private static final String INSERT_MOUNT = "INSERT INTO accountClansMounts (accountId, mountTypeId, mountSkinId) VALUES (?, ?, ?);";
private static final String SAVE_MOUNT = "UPDATE accountClansMounts SET mountSkinId=? WHERE id=?;";
private static final String SAVE_MOUNT_STATS = "INSERT INTO clansMountStats (mountId, statToken) VALUES (?, ?) ON DUPLICATE KEY UPDATE statToken=VALUES(statToken);";
private static final String DELETE_MOUNT = "DELETE FROM accountClansMounts WHERE id=?;";
private static final String DELETE_MOUNT_STATS = "DELETE FROM clansMountStats WHERE mountId=?;";
private MountManager _mountManager;
public MountRepository(JavaPlugin plugin, MountManager mountManager)
{
super(DBPool.getAccount());
_mountManager = mountManager;
}
/**
* Saves a mount into the database
* @param accountId The owner's account id
* @param token The mount token to save
* @param statToken The stat token to save
*/
public void saveMount(final int accountId, final MountToken token, final MountStatToken statToken)
{
_mountManager.runAsync(() ->
{
try (Connection connection = getConnection();)
{
if (token.Id == -1)
{
executeInsert(connection, INSERT_MOUNT, idResult ->
{
if (idResult.next())
{
token.Id = idResult.getInt(1);
}
}, null, new ColumnInt("accountId", accountId), new ColumnInt("mountTypeId", token.Type.getId()), new ColumnInt("mountSkinId", token.Skin == null ? -1 : token.Skin.getId()));
}
else
{
executeUpdate(connection, SAVE_MOUNT, null, new ColumnInt("mountSkinId", token.Skin == null ? -1 : token.Skin.getId()), new ColumnInt("id", token.Id));
}
if (token.Id == -1)
{
return;
}
executeUpdate(connection, SAVE_MOUNT_STATS, null, new ColumnInt("mountId", token.Id), new ColumnVarChar("statToken", 20, Utility.serialize(statToken)));
}
catch (SQLException e)
{
e.printStackTrace();
}
});
}
/**
* Saves a list of mounts into the database
* @param accountId The owner's account id
* @param tokens The list of token pairs to save
*/
public void saveMounts(final int accountId, final List<Pair<MountToken, MountStatToken>> tokens)
{
_mountManager.runAsync(() ->
{
try (Connection connection = getConnection())
{
for (Pair<MountToken, MountStatToken> tokenPair : tokens)
{
MountToken token = tokenPair.getLeft();
MountStatToken statToken = tokenPair.getRight();
if (token.Id == -1)
{
executeInsert(connection, INSERT_MOUNT, idResult ->
{
if (idResult.next())
{
token.Id = idResult.getInt(1);
}
}, null, new ColumnInt("accountId", accountId), new ColumnInt("mountTypeId", token.Type.getId()), new ColumnInt("mountSkinId", token.Skin == null ? -1 : token.Skin.getId()));
}
else
{
executeUpdate(connection, SAVE_MOUNT, null, new ColumnInt("mountSkinId", token.Skin == null ? -1 : token.Skin.getId()), new ColumnInt("id", token.Id));
}
if (token.Id == -1)
{
continue;
}
executeUpdate(connection, SAVE_MOUNT_STATS, null, new ColumnInt("mountId", token.Id), new ColumnVarChar("statToken", 100, Utility.serialize(statToken)));
}
}
catch (SQLException e)
{
e.printStackTrace();
}
});
}
/**
* Deletes a mount from the database
* @param token The mount to delete
*/
public void deleteMount(final MountToken token, final Consumer<Integer> after)
{
if (token.Id == -1)
{
return;
}
_mountManager.runAsync(() ->
{
executeUpdate(DELETE_MOUNT, new ColumnInt("id", token.Id));
executeUpdate(DELETE_MOUNT_STATS, new ColumnInt("mountId", token.Id));
if (after != null)
{
_mountManager.runSync(() ->
{
after.accept(token.Id);
});
}
});
}
/**
* Deletes an array from the database
* @param ids The mount ids to delete
*/
public void deleteMounts(final int[] ids, final Runnable after)
{
if (ids.length <= 0)
{
return;
}
_mountManager.runAsync(() ->
{
String idList = ids[0] + "";
for (int i = 1; i < ids.length; i++)
{
idList += ("," + ids[i]);
}
executeUpdate(DELETE_MOUNT.replace("id=?;", "id IN (" + idList + ");"));
executeUpdate(DELETE_MOUNT_STATS.replace("mountId=?;", "mountId IN (" + idList + ");"));
if (after != null)
{
_mountManager.runSync(after);
}
});
}
}

View File

@ -0,0 +1,34 @@
package mineplex.game.clans.clans.mounts;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* Event called after a mount spawns
*/
public class MountSpawnEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private final Mount _mount;
public MountSpawnEvent(Mount mount)
{
_mount = mount;
}
public Mount getMount()
{
return _mount;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
}

View File

@ -0,0 +1,8 @@
package mineplex.game.clans.clans.mounts;
public class MountStatToken
{
public int JumpStars = 1;
public int SpeedStars = 1;
public int StrengthStars = 1;
}

View File

@ -0,0 +1,11 @@
package mineplex.game.clans.clans.mounts;
import mineplex.game.clans.clans.mounts.Mount.MountType;
import mineplex.game.clans.clans.mounts.Mount.SkinType;
public class MountToken
{
public int Id = -1;
public MountType Type = null;
public SkinType Skin = null;
}

View File

@ -0,0 +1,166 @@
package mineplex.game.clans.clans.mounts.gui;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.Pair;
import mineplex.core.common.util.C;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.shop.confirmation.ConfirmationCallback;
import mineplex.core.shop.confirmation.ConfirmationPage;
import mineplex.core.shop.confirmation.ConfirmationProcessor;
import mineplex.core.shop.item.IButton;
import mineplex.core.shop.page.ShopPageBase;
import mineplex.game.clans.clans.mounts.Mount.MountType;
import mineplex.game.clans.clans.mounts.MountManager;
import mineplex.game.clans.clans.mounts.MountStatToken;
import mineplex.game.clans.clans.mounts.MountToken;
public class MountOverviewPage extends ShopPageBase<MountManager, MountShop>
{
private final String STAR = "";
public MountOverviewPage(MountManager plugin, MountShop shop, String name, Player player)
{
super(plugin, shop, plugin.getClientManager(), plugin.getDonationManager(), name, player, 27);
buildPage();
}
private ItemStack toItem(MountToken mountToken, MountStatToken statToken, boolean overview)
{
ItemBuilder builder = new ItemBuilder(mountToken.Type.getDisplayType());
builder.setTitle(mountToken.Type.getDisplayName() + " Mount");
builder.addLore(C.cPurple + "Skin: " + (mountToken.Skin == null ? C.cYellow + "Default" : mountToken.Skin.getDisplayName()));
String strength = C.cYellow;
for (int i = 0; i < statToken.StrengthStars; i++)
{
strength += STAR;
}
builder.addLore(C.cPurple + "Strength: " + strength);
String speed = C.cYellow;
for (int i = 0; i < statToken.SpeedStars; i++)
{
speed += STAR;
}
builder.addLore(C.cPurple + "Speed: " + speed);
String jump = C.cYellow;
for (int i = 0; i < statToken.JumpStars; i++)
{
jump += STAR;
}
builder.addLore(C.cPurple + "Jump: " + jump);
if (overview)
{
builder.addLore(C.cRed);
builder.addLore(C.cDGreen + "Left-Click to Summon");
builder.addLore(C.cDGreen + "Right-Click to Manage Skin");
builder.addLore(C.cDRed + "Shift Right-Click to Destroy");
}
return builder.build();
}
@Override
protected void buildPage()
{
int[] horseSlots = {10, 11, 12};
List<Pair<MountToken, MountStatToken>> horses = getPlugin().Get(getPlayer()).getOwnedMounts(true, MountType.HORSE);
int[] donkeySlots = {14, 15, 16};
List<Pair<MountToken, MountStatToken>> donkeys = getPlugin().Get(getPlayer()).getOwnedMounts(true, MountType.DONKEY);
for (int i = 0; i < horseSlots.length; i++)
{
int slot = horseSlots[i];
ItemStack item = new ItemBuilder(Material.INK_SACK).setData((short)8).setTitle(C.cRed).build();
IButton button = null;
if (horses.size() > i)
{
Pair<MountToken, MountStatToken> tokens = horses.get(i);
item = toItem(tokens.getLeft(), tokens.getRight(), true);
button = (player, clickType) ->
{
if (clickType == ClickType.LEFT)
{
if (!getPlugin().summonMount(player, tokens.getLeft()))
{
playDenySound(player);
}
}
else if (clickType == ClickType.RIGHT)
{
getShop().openPageForPlayer(player, new MountSkinPage(this, player, tokens.getLeft()));
}
else if (clickType == ClickType.SHIFT_RIGHT)
{
getShop().openPageForPlayer(player, new ConfirmationPage<MountManager, MountShop>(player, MountOverviewPage.this, new ConfirmationProcessor()
{
@Override
public void init(Inventory inventory) {}
@Override
public void process(ConfirmationCallback callback)
{
getPlugin().removeMountToken(player, tokens.getLeft(), () ->
{
MountOverviewPage.this.refresh();
callback.resolve("Mount successfully deleted!");
});
}
}, toItem(tokens.getLeft(), tokens.getRight(), false)));
}
};
}
addButton(slot, item, button);
}
for (int i = 0; i < donkeySlots.length; i++)
{
int slot = donkeySlots[i];
ItemStack item = new ItemBuilder(Material.INK_SACK).setData((short)8).setTitle(C.cRed).build();
IButton button = null;
if (donkeys.size() > i)
{
Pair<MountToken, MountStatToken> tokens = donkeys.get(i);
item = toItem(tokens.getLeft(), tokens.getRight(), true);
button = (player, clickType) ->
{
if (clickType == ClickType.LEFT)
{
if (!getPlugin().summonMount(player, tokens.getLeft()))
{
playDenySound(player);
}
}
else if (clickType == ClickType.RIGHT)
{
getShop().openPageForPlayer(player, new MountSkinPage(this, player, tokens.getLeft()));
}
else if (clickType == ClickType.SHIFT_RIGHT)
{
getShop().openPageForPlayer(player, new ConfirmationPage<MountManager, MountShop>(player, new MountOverviewPage(getPlugin(), getShop(), getName(), getPlayer()), new ConfirmationProcessor()
{
@Override
public void init(Inventory inventory) {}
@Override
public void process(ConfirmationCallback callback)
{
getPlugin().removeMountToken(player, tokens.getLeft(), () ->
{
MountOverviewPage.this.refresh();
callback.resolve("Mount successfully deleted!");
});
}
}, toItem(tokens.getLeft(), tokens.getRight(), false)));
}
};
}
addButton(slot, item, button);
}
}
}

View File

@ -0,0 +1,21 @@
package mineplex.game.clans.clans.mounts.gui;
import org.bukkit.entity.Player;
import mineplex.core.shop.ShopBase;
import mineplex.core.shop.page.ShopPageBase;
import mineplex.game.clans.clans.mounts.MountManager;
public class MountShop extends ShopBase<MountManager>
{
public MountShop(MountManager plugin)
{
super(plugin, plugin.getClientManager(), plugin.getDonationManager(), "Manage Mounts");
}
@Override
protected ShopPageBase<MountManager, ? extends ShopBase<MountManager>> buildPagesFor(Player player)
{
return new MountOverviewPage(getPlugin(), this, "Manage Mounts", player);
}
}

View File

@ -0,0 +1,142 @@
package mineplex.game.clans.clans.mounts.gui;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.Rank;
import mineplex.core.common.util.C;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.shop.page.ShopPageBase;
import mineplex.game.clans.clans.mounts.Mount.SkinType;
import mineplex.game.clans.clans.mounts.MountManager;
import mineplex.game.clans.clans.mounts.MountToken;
public class MountSkinPage extends ShopPageBase<MountManager, MountShop>
{
private MountOverviewPage _overview;
private MountToken _token;
public MountSkinPage(MountOverviewPage overview, Player player, MountToken token)
{
super(overview.getPlugin(), overview.getShop(), overview.getClientManager(), overview.getDonationManager(), "Skin Management", player, 54);
_overview = overview;
_token = token;
buildPage();
}
private List<SkinType> getAllowed()
{
List<SkinType> allowed = new LinkedList<>();
for (SkinType type : SkinType.values())
{
if (Arrays.asList(type.getPossibleTypes()).contains(_token.Type))
{
allowed.add(type);
}
}
return allowed;
}
private boolean hasUnlocked(Player player, SkinType type)
{
if (getClientManager().Get(player).GetRank().has(Rank.ADMIN))
{
return true;
}
return getDonationManager().Get(player).ownsUnknownSalesPackage(type.getPackageName());
}
private boolean hasUnlocked(SkinType type)
{
return hasUnlocked(getPlayer(), type);
}
private ItemStack buildResetItem()
{
ItemBuilder builder = new ItemBuilder(Material.WATER_BUCKET);
builder.setTitle(C.cYellow + "Default Skin");
if (_token.Skin == null)
{
builder.setLore(C.cRed, C.cGreenB + "SELECTED");
}
return builder.build();
}
private ItemStack buildSkinItem(SkinType type)
{
ItemBuilder builder = new ItemBuilder(type.getBaseDisplay());
builder.setTitle(type.getDisplayName());
builder.setLore(C.cRed);
if (_token.Skin == type)
{
builder.addLore(C.cGreenB + "SELECTED");
}
else if (hasUnlocked(type))
{
builder.addLore(C.cGreenB + "UNLOCKED");
}
else
{
builder.addLore(C.cGray + "Available at http://www.mineplex.com/shop");
builder.addLore(C.cRedB + "LOCKED");
}
return builder.build();
}
@Override
protected void buildPage()
{
addButton(0, new ItemBuilder(Material.BED).setTitle(C.cGreen + "Back").build(), (player, clickType) ->
{
_overview.refresh();
getShop().openPageForPlayer(player, _overview);
});
addButton(13, buildResetItem(), (player, clickType) ->
{
if (_token.Skin == null)
{
playDenySound(player);
}
else
{
playAcceptSound(player);
_token.Skin = null;
getPlugin().getRepository().saveMount(getClientManager().Get(player).getAccountId(), _token, getPlugin().Get(player).getStatToken(_token));
refresh();
}
});
int[] skinSlots = {20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42};
List<SkinType> allowed = getAllowed();
for (int i = 0; i < skinSlots.length && i < allowed.size(); i++)
{
SkinType type = allowed.get(i);
addButton(skinSlots[i], buildSkinItem(type), (player, clickType) ->
{
if (hasUnlocked(player, type) && _token.Skin != type)
{
playAcceptSound(player);
_token.Skin = type;
getPlugin().getRepository().saveMount(getClientManager().Get(player).getAccountId(), _token, getPlugin().Get(player).getStatToken(_token));
refresh();
}
else
{
playDenySound(player);
}
});
}
}
}

View File

@ -1,5 +1,6 @@
package mineplex.game.clans.clans.nether; package mineplex.game.clans.clans.nether;
import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -19,6 +20,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action; import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.EntityPortalEvent; import org.bukkit.event.entity.EntityPortalEvent;
import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerDropItemEvent;
@ -52,11 +54,8 @@ import mineplex.game.clans.clans.nether.command.ForceTeleportCommand;
import mineplex.game.clans.clans.nether.command.PortalCommand; import mineplex.game.clans.clans.nether.command.PortalCommand;
import mineplex.game.clans.clans.nether.data.ClaimData; import mineplex.game.clans.clans.nether.data.ClaimData;
import mineplex.game.clans.clans.nether.miniboss.NetherMinibossManager; import mineplex.game.clans.clans.nether.miniboss.NetherMinibossManager;
import mineplex.game.clans.clans.worldevent.boss.BossDeathEvent;
import mineplex.game.clans.spawn.Spawn; import mineplex.game.clans.spawn.Spawn;
import mineplex.minecraft.game.core.boss.EventCreatureDeathEvent;
import mineplex.minecraft.game.core.boss.broodmother.SpiderCreature;
import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature;
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonCreature;
/** /**
* Manager for all nether features * Manager for all nether features
@ -75,9 +74,9 @@ public class NetherManager extends MiniPlugin
private PortalRepository _repo; private PortalRepository _repo;
private NetherMinibossManager _miniboss; private NetherMinibossManager _miniboss;
private World _netherWorld; private World _netherWorld;
private List<NetherPortal> _portals = Lists.newArrayList(); private List<NetherPortal> _portals = new ArrayList<>();
public List<BossNetherPortal> BossPortals = Lists.newArrayList(); public List<BossNetherPortal> BossPortals = new ArrayList<>();
private List<NetherPortal> _returnPortals = Lists.newArrayList(); private List<NetherPortal> _returnPortals = new ArrayList<>();
public Map<Player, Long> InNether = new HashMap<>(); public Map<Player, Long> InNether = new HashMap<>();
public Map<Player, Location> OverworldOrigins = new HashMap<>(); public Map<Player, Location> OverworldOrigins = new HashMap<>();
public Map<Player, ClaimData> Claiming = new HashMap<>(); public Map<Player, ClaimData> Claiming = new HashMap<>();
@ -151,7 +150,17 @@ public class NetherManager extends MiniPlugin
*/ */
public boolean isInNether(Player player) public boolean isInNether(Player player)
{ {
return player.getWorld().equals(_netherWorld); return isInNether(player.getLocation());
}
/**
* Checks if a location is in the nether
* @param location The location to check
* @return Whether the player is in the nether
*/
public boolean isInNether(Location location)
{
return location.getWorld().equals(_netherWorld);
} }
/** /**
@ -298,6 +307,7 @@ public class NetherManager extends MiniPlugin
} }
BossNetherPortal portal = new BossNetherPortal(bossSpawn.clone().add(-2, 5, 0), bossSpawn.clone().add(2, 0, 0), false); BossNetherPortal portal = new BossNetherPortal(bossSpawn.clone().add(-2, 5, 0), bossSpawn.clone().add(2, 0, 0), false);
portal.open(PORTAL_OPEN_DURATION); portal.open(PORTAL_OPEN_DURATION);
BossPortals.add(portal);
for (NetherPortal returnPortal : _returnPortals) for (NetherPortal returnPortal : _returnPortals)
{ {
returnPortal.open(-1); returnPortal.open(-1);
@ -493,13 +503,19 @@ public class NetherManager extends MiniPlugin
@EventHandler @EventHandler
public void onTpHome(ClansCommandExecutedEvent event) public void onTpHome(ClansCommandExecutedEvent event)
{ {
if (!isInNether(event.getPlayer()))
{
return;
}
if (event.getCommand().equalsIgnoreCase("tphome") || event.getCommand().equalsIgnoreCase("stuck")) if (event.getCommand().equalsIgnoreCase("tphome") || event.getCommand().equalsIgnoreCase("stuck"))
{ {
if (isInNether(event.getPlayer())) event.setCancelled(true);
{ UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot teleport while in " + F.clansNether("The Nether") + "!"));
event.setCancelled(true); }
UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot teleport while in " + F.clansNether("The Nether") + "!")); if (event.getCommand().equalsIgnoreCase("claim") || event.getCommand().equalsIgnoreCase("unclaim") || event.getCommand().equalsIgnoreCase("unclaimall") || event.getCommand().equalsIgnoreCase("homeset"))
} {
event.setCancelled(true);
UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot manage your clan's territory while in " + F.clansNether("The Nether") + "!"));
} }
} }
@ -555,11 +571,17 @@ public class NetherManager extends MiniPlugin
} }
@EventHandler @EventHandler
public void onBossDeath(EventCreatureDeathEvent event) public void onBossDeath(BossDeathEvent event)
{ {
if (event.getCreature() instanceof GolemCreature || event.getCreature() instanceof SkeletonCreature || event.getCreature() instanceof SpiderCreature) spawnBossPortal(event.getEvent().getCenterLocation().clone());
}
@EventHandler
public void onBlockDamage(EntityExplodeEvent event)
{
if (isInNether(event.getLocation()))
{ {
spawnBossPortal(event.getCreature().getEvent().getCenterLocation().clone().subtract(0, 1, 0)); event.setYield(0f);
} }
} }
} }

View File

@ -1,11 +1,6 @@
package mineplex.game.clans.clans.nether.miniboss; package mineplex.game.clans.clans.nether.miniboss;
import java.util.HashMap; import java.util.Map;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilEnt;
import mineplex.game.clans.clans.ClansManager;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Sound; import org.bukkit.Sound;
@ -18,6 +13,11 @@ import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilEnt;
import mineplex.game.clans.clans.ClansManager;
/** /**
* Manager class for managing boss fireballs * Manager class for managing boss fireballs
*/ */
@ -48,7 +48,7 @@ public class MinibossFireball implements Listener
return; return;
} }
HashMap<LivingEntity, Double> hitMap = UtilEnt.getInRadius(proj.getLocation(), FIREBALL_EXPLOSION_RANGE); Map<LivingEntity, Double> hitMap = UtilEnt.getInRadius(proj.getLocation(), FIREBALL_EXPLOSION_RANGE);
for (LivingEntity cur : hitMap.keySet()) for (LivingEntity cur : hitMap.keySet())
{ {
double range = hitMap.get(cur); double range = hitMap.get(cur);

View File

@ -1,8 +1,8 @@
package mineplex.game.clans.clans.nether.miniboss; package mineplex.game.clans.clans.nether.miniboss;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@ -29,7 +29,7 @@ public class NetherMinibossManager implements Listener
{ {
private static final long MINIBOSS_SPAWN_RATE = 10000; private static final long MINIBOSS_SPAWN_RATE = 10000;
private NetherManager _manager; private NetherManager _manager;
private HashMap<Location, NetherMinibossType> _spawns = new HashMap<>(); private Map<Location, NetherMinibossType> _spawns = new HashMap<>();
private long _lastSpawned; private long _lastSpawned;
private boolean _allowSpawn = false; private boolean _allowSpawn = false;
private boolean _allowSpawnEvent = false; private boolean _allowSpawnEvent = false;
@ -49,16 +49,13 @@ public class NetherMinibossManager implements Listener
sort.add(new Location(manager.getNetherWorld(), 43, 134, 22)); sort.add(new Location(manager.getNetherWorld(), 43, 134, 22));
sort.add(new Location(manager.getNetherWorld(), 102, 141, -31)); sort.add(new Location(manager.getNetherWorld(), 102, 141, -31));
sort.add(new Location(manager.getNetherWorld(), 151, 136, 34)); sort.add(new Location(manager.getNetherWorld(), 151, 136, 34));
sort.sort(new Comparator<Location>() sort.sort((o1, o2) ->
{ {
public int compare(Location o1, Location o2) if (UtilMath.offset2d(o1, manager.getNetherWorld().getSpawnLocation()) < UtilMath.offset(o2, manager.getNetherWorld().getSpawnLocation()))
{ {
if (UtilMath.offset2d(o1, manager.getNetherWorld().getSpawnLocation()) < UtilMath.offset(o2, manager.getNetherWorld().getSpawnLocation())) return -1;
{
return -1;
}
return 1;
} }
return 1;
}); });
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {

View File

@ -17,12 +17,12 @@ public enum NetherMinibossType
ARCHER("Undead Archer", 25D, EntityType.SKELETON, ArcherMiniboss.class) ARCHER("Undead Archer", 25D, EntityType.SKELETON, ArcherMiniboss.class)
; ;
private Class<? extends NetherMiniBoss> _code; private Class<? extends NetherMiniBoss<?>> _code;
private String _name; private String _name;
private Double _maxHealth; private Double _maxHealth;
private EntityType _type; private EntityType _type;
private NetherMinibossType(String name, Double maxHealth, EntityType type, Class<? extends NetherMiniBoss> code) private NetherMinibossType(String name, Double maxHealth, EntityType type, Class<? extends NetherMiniBoss<?>> code)
{ {
_name = name; _name = name;
_maxHealth = maxHealth; _maxHealth = maxHealth;
@ -35,7 +35,7 @@ public enum NetherMinibossType
* @param spawn The location to spawn the boss in * @param spawn The location to spawn the boss in
* @return The instance of the miniboss * @return The instance of the miniboss
*/ */
public NetherMiniBoss getNewInstance(Location spawn) public NetherMiniBoss<?> getNewInstance(Location spawn)
{ {
try try
{ {

View File

@ -2,13 +2,6 @@ package mineplex.game.clans.clans.nether.miniboss.bosses;
import java.util.Random; import java.util.Random;
import mineplex.core.common.util.UtilMath;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.amplifiers.AmplifierManager;
import mineplex.game.clans.clans.nether.miniboss.NetherMiniBoss;
import mineplex.game.clans.items.runes.RuneManager.RuneAttribute;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Arrow; import org.bukkit.entity.Arrow;
@ -28,6 +21,13 @@ import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import mineplex.core.common.util.UtilMath;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.amplifiers.AmplifierManager;
import mineplex.game.clans.clans.nether.miniboss.NetherMiniBoss;
import mineplex.game.clans.items.runes.RuneManager.RuneAttribute;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
/** /**
* Class for running an individual Archer miniboss * Class for running an individual Archer miniboss
*/ */
@ -35,7 +35,10 @@ public class ArcherMiniboss extends NetherMiniBoss<Skeleton>
{ {
private static final int BARBED_LEVEL = 1; private static final int BARBED_LEVEL = 1;
private static final double RUNE_DROP_CHANCE = .02; private static final double RUNE_DROP_CHANCE = .02;
private static final int MAX_DIAMOND_DROPS = 5; private static final int MAX_VALUABLE_DROPS = 5;
private static final Material[] VALUABLE_DROP_TYPES = new Material[] {Material.DIAMOND, Material.GOLD_INGOT, Material.IRON_INGOT, Material.LEATHER};
private static final Material[] SET_DROP_TYPES = new Material[] {Material.DIAMOND_HELMET, Material.DIAMOND_CHESTPLATE, Material.DIAMOND_LEGGINGS, Material.DIAMOND_BOOTS, Material.GOLD_HELMET, Material.GOLD_CHESTPLATE, Material.GOLD_LEGGINGS, Material.GOLD_BOOTS, Material.IRON_HELMET, Material.IRON_CHESTPLATE, Material.IRON_LEGGINGS, Material.IRON_BOOTS, Material.CHAINMAIL_HELMET, Material.CHAINMAIL_CHESTPLATE, Material.CHAINMAIL_LEGGINGS, Material.CHAINMAIL_BOOTS, Material.LEATHER_HELMET, Material.LEATHER_CHESTPLATE, Material.LEATHER_LEGGINGS, Material.LEATHER_BOOTS};
private static final double SET_DROP_CHANCE = .02;
public ArcherMiniboss(String displayName, Double maxHealth, Location spawn, EntityType type) public ArcherMiniboss(String displayName, Double maxHealth, Location spawn, EntityType type)
{ {
@ -63,7 +66,7 @@ public class ArcherMiniboss extends NetherMiniBoss<Skeleton>
@Override @Override
public void customDeath(Location deathLocation) public void customDeath(Location deathLocation)
{ {
deathLocation.getWorld().dropItemNaturally(deathLocation, new ItemStack(Material.DIAMOND, UtilMath.r(MAX_DIAMOND_DROPS) + 1)); deathLocation.getWorld().dropItemNaturally(deathLocation, new ItemStack(VALUABLE_DROP_TYPES[UtilMath.r(VALUABLE_DROP_TYPES.length)], UtilMath.r(MAX_VALUABLE_DROPS) + 1));
double runeDropChance = RUNE_DROP_CHANCE; double runeDropChance = RUNE_DROP_CHANCE;
if (ClansManager.getInstance().getAmplifierManager().hasActiveAmplifier()) if (ClansManager.getInstance().getAmplifierManager().hasActiveAmplifier())
{ {
@ -74,6 +77,10 @@ public class ArcherMiniboss extends NetherMiniBoss<Skeleton>
RuneAttribute runeType = RuneAttribute.values()[UtilMath.r(RuneAttribute.values().length)]; RuneAttribute runeType = RuneAttribute.values()[UtilMath.r(RuneAttribute.values().length)];
deathLocation.getWorld().dropItemNaturally(deathLocation, ClansManager.getInstance().getGearManager().getRuneManager().getRune(runeType)); deathLocation.getWorld().dropItemNaturally(deathLocation, ClansManager.getInstance().getGearManager().getRuneManager().getRune(runeType));
} }
if (new Random().nextDouble() <= SET_DROP_CHANCE)
{
deathLocation.getWorld().dropItemNaturally(deathLocation, new ItemStack(SET_DROP_TYPES[UtilMath.r(SET_DROP_TYPES.length)], 1));
}
} }
@EventHandler @EventHandler

View File

@ -2,16 +2,6 @@ package mineplex.game.clans.clans.nether.miniboss.bosses;
import java.util.Random; import java.util.Random;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.amplifiers.AmplifierManager;
import mineplex.game.clans.clans.nether.miniboss.MinibossFireball;
import mineplex.game.clans.clans.nether.miniboss.NetherMiniBoss;
import mineplex.game.clans.items.runes.RuneManager.RuneAttribute;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -23,6 +13,16 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.ProjectileLaunchEvent; import org.bukkit.event.entity.ProjectileLaunchEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.amplifiers.AmplifierManager;
import mineplex.game.clans.clans.nether.miniboss.MinibossFireball;
import mineplex.game.clans.clans.nether.miniboss.NetherMiniBoss;
import mineplex.game.clans.items.runes.RuneManager.RuneAttribute;
/** /**
* Class for running an individual Ghast miniboss * Class for running an individual Ghast miniboss
*/ */
@ -32,8 +32,11 @@ public class GhastMiniboss extends NetherMiniBoss<Ghast>
private static final long FIREBALL_LAUNCH_RATE = 500; private static final long FIREBALL_LAUNCH_RATE = 500;
private static final int FIREBALLS_PER_USE = 5; private static final int FIREBALLS_PER_USE = 5;
private static final double RUNE_DROP_CHANCE = .02; private static final double RUNE_DROP_CHANCE = .02;
private static final int MAX_DIAMOND_DROPS = 5; private static final int MAX_VALUABLE_DROPS = 5;
private static final Material[] VALUABLE_DROP_TYPES = new Material[] {Material.DIAMOND, Material.GOLD_INGOT, Material.IRON_INGOT, Material.LEATHER};
private static final double MAX_TARGET_RANGE = 25; private static final double MAX_TARGET_RANGE = 25;
private static final Material[] SET_DROP_TYPES = new Material[] {Material.DIAMOND_HELMET, Material.DIAMOND_CHESTPLATE, Material.DIAMOND_LEGGINGS, Material.DIAMOND_BOOTS, Material.GOLD_HELMET, Material.GOLD_CHESTPLATE, Material.GOLD_LEGGINGS, Material.GOLD_BOOTS, Material.IRON_HELMET, Material.IRON_CHESTPLATE, Material.IRON_LEGGINGS, Material.IRON_BOOTS, Material.CHAINMAIL_HELMET, Material.CHAINMAIL_CHESTPLATE, Material.CHAINMAIL_LEGGINGS, Material.CHAINMAIL_BOOTS, Material.LEATHER_HELMET, Material.LEATHER_CHESTPLATE, Material.LEATHER_LEGGINGS, Material.LEATHER_BOOTS};
private static final double SET_DROP_CHANCE = .02;
private long _lastFireballUse; private long _lastFireballUse;
private int _fireballsRemaining; private int _fireballsRemaining;
@ -72,7 +75,7 @@ public class GhastMiniboss extends NetherMiniBoss<Ghast>
@Override @Override
public void customDeath(Location deathLocation) public void customDeath(Location deathLocation)
{ {
deathLocation.getWorld().dropItemNaturally(deathLocation, new ItemStack(Material.DIAMOND, UtilMath.r(MAX_DIAMOND_DROPS) + 1)); deathLocation.getWorld().dropItemNaturally(deathLocation, new ItemStack(VALUABLE_DROP_TYPES[UtilMath.r(VALUABLE_DROP_TYPES.length)], UtilMath.r(MAX_VALUABLE_DROPS) + 1));
double runeDropChance = RUNE_DROP_CHANCE; double runeDropChance = RUNE_DROP_CHANCE;
if (ClansManager.getInstance().getAmplifierManager().hasActiveAmplifier()) if (ClansManager.getInstance().getAmplifierManager().hasActiveAmplifier())
{ {
@ -83,6 +86,10 @@ public class GhastMiniboss extends NetherMiniBoss<Ghast>
RuneAttribute runeType = RuneAttribute.values()[UtilMath.r(RuneAttribute.values().length)]; RuneAttribute runeType = RuneAttribute.values()[UtilMath.r(RuneAttribute.values().length)];
deathLocation.getWorld().dropItemNaturally(deathLocation, ClansManager.getInstance().getGearManager().getRuneManager().getRune(runeType)); deathLocation.getWorld().dropItemNaturally(deathLocation, ClansManager.getInstance().getGearManager().getRuneManager().getRune(runeType));
} }
if (new Random().nextDouble() <= SET_DROP_CHANCE)
{
deathLocation.getWorld().dropItemNaturally(deathLocation, new ItemStack(SET_DROP_TYPES[UtilMath.r(SET_DROP_TYPES.length)], 1));
}
} }
@Override @Override

View File

@ -2,15 +2,6 @@ package mineplex.game.clans.clans.nether.miniboss.bosses;
import java.util.Random; import java.util.Random;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilMath;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.amplifiers.AmplifierManager;
import mineplex.game.clans.clans.nether.miniboss.NetherMiniBoss;
import mineplex.game.clans.items.runes.RuneManager.RuneAttribute;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Sound; import org.bukkit.Sound;
@ -27,13 +18,25 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilMath;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.amplifiers.AmplifierManager;
import mineplex.game.clans.clans.nether.miniboss.NetherMiniBoss;
import mineplex.game.clans.items.runes.RuneManager.RuneAttribute;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
/** /**
* Class for running an individual Warrior miniboss * Class for running an individual Warrior miniboss
*/ */
public class WarriorMiniboss extends NetherMiniBoss<Zombie> public class WarriorMiniboss extends NetherMiniBoss<Zombie>
{ {
private static final double RUNE_DROP_CHANCE = .02; private static final double RUNE_DROP_CHANCE = .02;
private static final int MAX_DIAMOND_DROPS = 5; private static final int MAX_VALUABLE_DROPS = 5;
private static final Material[] VALUABLE_DROP_TYPES = new Material[] {Material.DIAMOND, Material.GOLD_INGOT, Material.IRON_INGOT, Material.LEATHER};
private static final Material[] SET_DROP_TYPES = new Material[] {Material.DIAMOND_HELMET, Material.DIAMOND_CHESTPLATE, Material.DIAMOND_LEGGINGS, Material.DIAMOND_BOOTS, Material.GOLD_HELMET, Material.GOLD_CHESTPLATE, Material.GOLD_LEGGINGS, Material.GOLD_BOOTS, Material.IRON_HELMET, Material.IRON_CHESTPLATE, Material.IRON_LEGGINGS, Material.IRON_BOOTS, Material.CHAINMAIL_HELMET, Material.CHAINMAIL_CHESTPLATE, Material.CHAINMAIL_LEGGINGS, Material.CHAINMAIL_BOOTS, Material.LEATHER_HELMET, Material.LEATHER_CHESTPLATE, Material.LEATHER_LEGGINGS, Material.LEATHER_BOOTS};
private static final double SET_DROP_CHANCE = .02;
private static final double LEAP_CHANCE = .9; private static final double LEAP_CHANCE = .9;
private static final double LEAP_MIN_DIST = 3; private static final double LEAP_MIN_DIST = 3;
private static final double LEAP_MAX_DIST = 16; private static final double LEAP_MAX_DIST = 16;
@ -66,7 +69,7 @@ public class WarriorMiniboss extends NetherMiniBoss<Zombie>
@Override @Override
public void customDeath(Location deathLocation) public void customDeath(Location deathLocation)
{ {
deathLocation.getWorld().dropItemNaturally(deathLocation, new ItemStack(Material.DIAMOND, UtilMath.r(MAX_DIAMOND_DROPS) + 1)); deathLocation.getWorld().dropItemNaturally(deathLocation, new ItemStack(VALUABLE_DROP_TYPES[UtilMath.r(VALUABLE_DROP_TYPES.length)], UtilMath.r(MAX_VALUABLE_DROPS) + 1));
double runeDropChance = RUNE_DROP_CHANCE; double runeDropChance = RUNE_DROP_CHANCE;
if (ClansManager.getInstance().getAmplifierManager().hasActiveAmplifier()) if (ClansManager.getInstance().getAmplifierManager().hasActiveAmplifier())
{ {
@ -77,6 +80,10 @@ public class WarriorMiniboss extends NetherMiniBoss<Zombie>
RuneAttribute runeType = RuneAttribute.values()[UtilMath.r(RuneAttribute.values().length)]; RuneAttribute runeType = RuneAttribute.values()[UtilMath.r(RuneAttribute.values().length)];
deathLocation.getWorld().dropItemNaturally(deathLocation, ClansManager.getInstance().getGearManager().getRuneManager().getRune(runeType)); deathLocation.getWorld().dropItemNaturally(deathLocation, ClansManager.getInstance().getGearManager().getRuneManager().getRune(runeType));
} }
if (new Random().nextDouble() <= SET_DROP_CHANCE)
{
deathLocation.getWorld().dropItemNaturally(deathLocation, new ItemStack(SET_DROP_TYPES[UtilMath.r(SET_DROP_TYPES.length)], 1));
}
} }
@Override @Override

View File

@ -24,7 +24,7 @@ public class ClansRegions extends MiniPlugin
public final static int SHOP_RADIUS = 6; // Radius of shop claim area (measured in chunks) public final static int SHOP_RADIUS = 6; // Radius of shop claim area (measured in chunks)
public final static int FIELDS_RADIUS = 7; // Radius of fields claim area (measured in chunks) public final static int FIELDS_RADIUS = 7; // Radius of fields claim area (measured in chunks)
public final static int BORDERLANDS_RADIUS = 85; // Radius of borderlands claim area (measured in chunks) public final static int BORDERLANDS_RADIUS = 85; // Radius of borderlands claim area (measured in chunks)
public static final int BORDER_RADIUS = 1250; public static final int BORDER_RADIUS = 1280;
private ClansManager _manager; private ClansManager _manager;
private World _world; private World _world;

View File

@ -13,6 +13,7 @@ import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilText; import mineplex.core.common.util.UtilText;
import mineplex.core.thereallyoldscoreboardapiweshouldremove.PlayerScoreboard; import mineplex.core.thereallyoldscoreboardapiweshouldremove.PlayerScoreboard;
import mineplex.core.thereallyoldscoreboardapiweshouldremove.ScoreboardManager; import mineplex.core.thereallyoldscoreboardapiweshouldremove.ScoreboardManager;
import mineplex.game.clans.Clans;
import mineplex.game.clans.clans.ClanInfo; import mineplex.game.clans.clans.ClanInfo;
import mineplex.game.clans.clans.ClansManager; import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.ClansUtility.ClanRelation; import mineplex.game.clans.clans.ClansUtility.ClanRelation;
@ -112,17 +113,19 @@ public class ClansPlayerScoreboard extends PlayerScoreboard
team.setPrefix(relation.getColor(false).toString()); team.setPrefix(relation.getColor(false).toString());
} }
if (Clans.HARDCORE)
Objective domObjective;
if ((domObjective = scoreboard.getObjective(DisplaySlot.BELOW_NAME)) == null)
{ {
domObjective = scoreboard.registerNewObjective("war", "dummy"); Objective domObjective;
domObjective.setDisplayName("War Points"); if ((domObjective = scoreboard.getObjective(DisplaySlot.BELOW_NAME)) == null)
domObjective.setDisplaySlot(DisplaySlot.BELOW_NAME); {
} domObjective = scoreboard.registerNewObjective("war", "dummy");
domObjective.setDisplayName("War Points");
domObjective.setDisplaySlot(DisplaySlot.BELOW_NAME);
}
if (clanInfo != null) if (clanInfo != null)
domObjective.getScore(otherPlayer.getName()).setScore(ownScore); domObjective.getScore(otherPlayer.getName()).setScore(ownScore);
}
team.addPlayer(otherPlayer); team.addPlayer(otherPlayer);
} }

View File

@ -58,6 +58,11 @@ public class ScoreboardElementPlayer implements ScoreboardElement
} }
} }
if (_clansManager.getWorldEvent().getRaidManager().isInRaid(player.getLocation()))
{
regionString = C.cDRed + "Raid World";
}
output.add(regionString); output.add(regionString);
return output; return output;

View File

@ -10,8 +10,10 @@ import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime; import mineplex.core.common.util.UtilTime;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.updater.UpdateType; import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent; import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.Clans;
import mineplex.game.clans.clans.ClansManager; import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.siege.command.GiveWeaponCommand; import mineplex.game.clans.clans.siege.command.GiveWeaponCommand;
import mineplex.game.clans.clans.siege.outpost.OutpostManager; import mineplex.game.clans.clans.siege.outpost.OutpostManager;
@ -213,10 +215,24 @@ public class SiegeManager extends MiniPlugin
@EventHandler @EventHandler
public void onBlockPlace(BlockPlaceEvent event) public void onBlockPlace(BlockPlaceEvent event)
{ {
if (!Clans.HARDCORE)
{
return;
}
if (event.getItemInHand().isSimilar(Cannon.CANNON_ITEM)) if (event.getItemInHand().isSimilar(Cannon.CANNON_ITEM))
{ {
event.setCancelled(true); event.setCancelled(true);
int health = ItemStackFactory.Instance.GetLoreVar(event.getPlayer().getItemInHand(), "Health", 0);
if (health != 0)
{
if (trySpawnCannon(event.getPlayer(), event.getBlock().getLocation()))
{
event.getPlayer().setItemInHand(UtilInv.decrement(event.getPlayer().getItemInHand()));
}
return;
}
if (trySpawnCannon(event.getPlayer(), event.getBlock().getLocation())) if (trySpawnCannon(event.getPlayer(), event.getBlock().getLocation()))
{ {
event.getPlayer().setItemInHand(UtilInv.decrement(event.getPlayer().getItemInHand())); event.getPlayer().setItemInHand(UtilInv.decrement(event.getPlayer().getItemInHand()));
@ -236,6 +252,46 @@ public class SiegeManager extends MiniPlugin
// } // }
} }
public boolean trySpawnCannon(Player player, Location location, int health)
{
if (_clansManager.getNetherManager().isInNether(player))
{
_clansManager.message(player, "You are not allowed to place this in " + F.clansNether("The Nether") + ".");
return false;
}
if (_clansManager.getWorldEvent().getRaidManager().isInRaid(player.getLocation()))
{
_clansManager.message(player, "You are not allowed to place this in a raid.");
return false;
}
if (!_clansManager.isInClan(player))
{
UtilPlayer.message(player, F.main("Clans", "You must be in a Clan to place a Cannon."));
return false;
}
if (_clansManager.hasTimer(player))
{
UtilPlayer.message(player, F.main("Clans", "You cannot place a Cannon whilst protected from pvp."));
return false;
}
ClanTerritory claim = _clansManager.getClanUtility().getClaim(location);
if (claim != null && !claim.Owner.equals(_clansManager.getClan(player).getName()))
{
UtilPlayer.message(player, F.main("Clans", "You must place a Cannon in the Wilderness or your own Territory."));
return false;
}
spawnCannon(player, location).setHealth(health);
return true;
}
public boolean trySpawnCannon(Player player, Location location) public boolean trySpawnCannon(Player player, Location location)
{ {
if (_clansManager.getNetherManager().isInNether(player)) if (_clansManager.getNetherManager().isInNether(player))
@ -244,6 +300,12 @@ public class SiegeManager extends MiniPlugin
return false; return false;
} }
if (_clansManager.getWorldEvent().getRaidManager().isInRaid(player.getLocation()))
{
_clansManager.message(player, "You are not allowed to place this in a raid.");
return false;
}
if (!_clansManager.isInClan(player)) if (!_clansManager.isInClan(player))
{ {

View File

@ -8,6 +8,7 @@ import java.util.List;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.entity.FallingBlock; import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@ -63,11 +64,13 @@ import net.minecraft.server.v1_8_R3.AxisAlignedBB;
public class Outpost implements Listener public class Outpost implements Listener
{ {
protected static final long MAX_LIFETIME = 30 * 60 * 1000; // 30 minutes protected static final long MAX_LIFETIME = 45 * 60 * 1000; // 30 minutes
public static final ItemStack OUTPOST_ITEM = new ItemBuilder(Material.BEACON, 1).setRawTitle(C.Reset + C.cBlue + "Outpost").build(); public static final ItemStack OUTPOST_ITEM = new ItemBuilder(Material.BEACON, 1).setRawTitle(C.Reset + C.cBlue + "Outpost").build();
public static final long PREP_TIME = 2 * 60 * 1000; public static final long PREP_TIME = 2 * 60 * 1000;
private static final int MAX_HEALTH = 100;
private OutpostManager _outpostManager; private OutpostManager _outpostManager;
private final int _uniqueId; private final int _uniqueId;
@ -103,10 +106,18 @@ public class Outpost implements Listener
private Hologram _lifetimeLeft; private Hologram _lifetimeLeft;
private int _health;
private long _lastDamage;
private long _lastRegen;
public Outpost(OutpostManager outpostManager, OutpostToken token) public Outpost(OutpostManager outpostManager, OutpostToken token)
{ {
_outpostManager = outpostManager; _outpostManager = outpostManager;
_health = MAX_HEALTH;
_uniqueId = token.UniqueId; _uniqueId = token.UniqueId;
_ownerClan = token.OwnerClan; _ownerClan = token.OwnerClan;
@ -137,7 +148,36 @@ public class Outpost implements Listener
return; return;
if (clickType == ClickType.LEFT || clickType == ClickType.SHIFT_LEFT) if (clickType == ClickType.LEFT || clickType == ClickType.SHIFT_LEFT)
kill(); {
if (_outpostManager.getClansManager().hasTimer(player))
{
UtilPlayer.message(player, F.main("Clans", "You cannot destroy an Outpost whilst protected from PvP."));
return;
}
if (!UtilTime.elapsed(_lastDamage, 5000))
{
return;
}
if (_health <= 2)
{
UtilPlayer.message(player, F.main("Clans", "You have destroyed " + F.elem(_ownerClan.getName()) + "'s Outpost!"));
_core.getBlock().setType(Material.AIR);
_ownerClan.inform("Your Outpost has been destroyed!", null);
UtilTextMiddle.display("Siege", "Your Outpost has been destroyed", 20, 100, 20, _ownerClan.getOnlinePlayersArray());
if (getState() == OutpostState.AWAITING)
cleanup();
else
kill();
return;
}
_lastDamage = System.currentTimeMillis();
_health -= 2;
}
} }
}); });
@ -149,7 +189,7 @@ public class Outpost implements Listener
_preHologram2.start(); _preHologram2.start();
} }
_blocks = _type.createBuildQueue(_origin, _ownerClan.Clans); _blocks = _type.createBuildQueue(_origin, _ownerClan.Clans, _ownerClan);
_state = token.OutpostState; _state = token.OutpostState;
@ -165,6 +205,8 @@ public class Outpost implements Listener
{ {
_outpostManager = outpostManager; _outpostManager = outpostManager;
_health = MAX_HEALTH;
_uniqueId = outpostManager.getSiegeManager().randomId(); _uniqueId = outpostManager.getSiegeManager().randomId();
_ownerClan = clan; _ownerClan = clan;
@ -210,7 +252,36 @@ public class Outpost implements Listener
return; return;
if (clickType == ClickType.LEFT || clickType == ClickType.SHIFT_LEFT) if (clickType == ClickType.LEFT || clickType == ClickType.SHIFT_LEFT)
kill(); {
if (_outpostManager.getClansManager().hasTimer(player))
{
UtilPlayer.message(player, F.main("Clans", "You cannot destroy an Outpost whilst protected from PvP."));
return;
}
if (!UtilTime.elapsed(_lastDamage, 5000))
{
return;
}
if (_health <= 2)
{
UtilPlayer.message(player, F.main("Clans", "You have destroyed " + F.elem(_ownerClan.getName()) + "'s Outpost!"));
_core.getBlock().setType(Material.AIR);
_ownerClan.inform("Your Outpost has been destroyed!", null);
UtilTextMiddle.display("Siege", "Your Outpost has been destroyed", 20, 100, 20, _ownerClan.getOnlinePlayersArray());
if (getState() == OutpostState.AWAITING)
cleanup();
else
kill();
return;
}
_lastDamage = System.currentTimeMillis();
_health -= 2;
}
} }
}); });
} }
@ -280,6 +351,20 @@ public class Outpost implements Listener
return; return;
} }
for (Block block : UtilBlock.getBlocksInRadius(event.getClickedBlock().getLocation(), 5))
{
if (block.getType() == Material.WATER || block.getType() == Material.STATIONARY_WATER)
{
UtilPlayer.message(event.getPlayer(), F.main("Clans", "You cannot activate an Outpost that close to water!"));
return;
}
if (block.getType() == Material.LAVA || block.getType() == Material.STATIONARY_LAVA)
{
UtilPlayer.message(event.getPlayer(), F.main("Clans", "You cannot activate an Outpost that close to lava!"));
return;
}
}
_origin.getBlock().setType(Material.AIR); _origin.getBlock().setType(Material.AIR);
beginConstruction(); beginConstruction();
} }
@ -291,26 +376,35 @@ public class Outpost implements Listener
{ {
if (event.getBlock().getLocation().equals(_core) && getState() == OutpostState.LIVE) if (event.getBlock().getLocation().equals(_core) && getState() == OutpostState.LIVE)
{ {
event.setCancelled(true);
if(_outpostManager.getClansManager().hasTimer(event.getPlayer())) if (_outpostManager.getClansManager().hasTimer(event.getPlayer()))
{ {
UtilPlayer.message(event.getPlayer(), F.main("Clans", "You cannot destroy an Outpost whilst protected from PvP.")); UtilPlayer.message(event.getPlayer(), F.main("Clans", "You cannot destroy an Outpost whilst protected from PvP."));
event.setCancelled(true);
return; return;
} }
UtilPlayer.message(event.getPlayer(), F.main("Clans", "You have destroyed " + F.elem(_ownerClan.getName()) + "'s Outpost!")); if (!UtilTime.elapsed(_lastDamage, 5000))
{
return;
}
if (_health <= 2)
{
UtilPlayer.message(event.getPlayer(), F.main("Clans", "You have destroyed " + F.elem(_ownerClan.getName()) + "'s Outpost!"));
_core.getBlock().setType(Material.AIR);
_ownerClan.inform("Your Outpost has been destroyed!", null);
UtilTextMiddle.display("Siege", "Your Outpost has been destroyed", 20, 100, 20, _ownerClan.getOnlinePlayersArray());
if (getState() == OutpostState.AWAITING)
cleanup();
else
kill();
return;
}
_core.getBlock().setType(Material.AIR); _lastDamage = System.currentTimeMillis();
_health -= 2;
_ownerClan.inform("Your Outpost has been destroyed!", null);
UtilTextMiddle.display("Siege", "Your Outpost has been destroyed", 20, 100, 20, _ownerClan.getOnlinePlayersArray());
if (getState() == OutpostState.AWAITING)
cleanup();
else
kill();
event.setCancelled(true);
} }
} }
@ -329,20 +423,35 @@ public class Outpost implements Listener
if (event.getBlock().getLocation().equals(_core) && getState() == OutpostState.LIVE) if (event.getBlock().getLocation().equals(_core) && getState() == OutpostState.LIVE)
{ {
UtilPlayer.message(event.getPlayer(), F.main("Clans", "You have destroyed " + F.elem(_ownerClan.getName()) + "'s Outpost!"));
_core.getBlock().setType(Material.AIR);
_ownerClan.inform("Your Outpost has been destroyed!", null);
UtilTextMiddle.display("Siege", "Your Outpost has been destroyed", 20, 100, 20, _ownerClan.getOnlinePlayersArray());
if (getState() == OutpostState.AWAITING)
cleanup();
else
kill();
event.setCancelled(true); event.setCancelled(true);
return; if (_outpostManager.getClansManager().hasTimer(event.getPlayer()))
{
UtilPlayer.message(event.getPlayer(), F.main("Clans", "You cannot destroy an Outpost whilst protected from PvP."));
return;
}
if (!UtilTime.elapsed(_lastDamage, 5000))
{
return;
}
if (_health <= 2)
{
UtilPlayer.message(event.getPlayer(), F.main("Clans", "You have destroyed " + F.elem(_ownerClan.getName()) + "'s Outpost!"));
_core.getBlock().setType(Material.AIR);
_ownerClan.inform("Your Outpost has been destroyed!", null);
UtilTextMiddle.display("Siege", "Your Outpost has been destroyed", 20, 100, 20, _ownerClan.getOnlinePlayersArray());
if (getState() == OutpostState.AWAITING)
cleanup();
else
kill();
return;
}
_lastDamage = System.currentTimeMillis();
_health -= 2;
} }
if (UtilAlg.inBoundingBox(event.getBlock().getLocation(), _startCorner.clone().subtract(.5, 0, .5), _endCorner)) if (UtilAlg.inBoundingBox(event.getBlock().getLocation(), _startCorner.clone().subtract(.5, 0, .5), _endCorner))
@ -410,7 +519,9 @@ public class Outpost implements Listener
} }
if (_lifetimeLeft != null) if (_lifetimeLeft != null)
_lifetimeLeft.setText("Despawning in " + F.time(UtilTime.MakeStr(MAX_LIFETIME - (System.currentTimeMillis() - _timeSpawned)))); {
_lifetimeLeft.setText("Health: " + _health, "Despawning in " + F.time(UtilTime.MakeStr(MAX_LIFETIME - (System.currentTimeMillis() - _timeSpawned))));
}
if (_state == OutpostState.CONSTRUCTING) if (_state == OutpostState.CONSTRUCTING)
{ {
@ -467,6 +578,11 @@ public class Outpost implements Listener
{ {
kill(); kill();
} }
if (_health < MAX_HEALTH && UtilTime.elapsed(_lastDamage, 15000) && UtilTime.elapsed(_lastRegen, 1000))
{
_lastRegen = System.currentTimeMillis();
_health++;
}
} }
} }
@ -498,12 +614,13 @@ public class Outpost implements Listener
_lifetimeLeft.start(); _lifetimeLeft.start();
_state = OutpostState.CONSTRUCTING; _state = OutpostState.CONSTRUCTING;
_blocks = new LinkedHashMap<>(_buildQueue = _type.createBuildQueue(_origin, _ownerClan.Clans)); _blocks = new LinkedHashMap<>(_buildQueue = _type.createBuildQueue(_origin, _ownerClan.Clans, _ownerClan));
_ownerClan.inform("Siege", "Your Outpost is now being constructed.", null); _ownerClan.inform("Siege", "Your Outpost is now being constructed.", null);
//Inform nearby Clans //Inform nearby Clans
for (int chunkX = -3; chunkX < 3; chunkX++) for (int chunkX = -3; chunkX < 3; chunkX++)
{
for (int chunkZ = -3; chunkZ < 3; chunkZ++) for (int chunkZ = -3; chunkZ < 3; chunkZ++)
{ {
ClanTerritory territory = _ownerClan.Clans.getClanUtility().getClaim(_origin.getWorld().getChunkAt(_origin.getChunk().getX() + chunkX, _origin.getChunk().getZ() + chunkZ)); ClanTerritory territory = _ownerClan.Clans.getClanUtility().getClaim(_origin.getWorld().getChunkAt(_origin.getChunk().getX() + chunkX, _origin.getChunk().getZ() + chunkZ));
@ -516,6 +633,7 @@ public class Outpost implements Listener
UtilTextMiddle.display("Siege", "A Siege has been declared on your Clan!", 20, 100, 20, clan.getOnlinePlayersArray()); UtilTextMiddle.display("Siege", "A Siege has been declared on your Clan!", 20, 100, 20, clan.getOnlinePlayersArray());
} }
} }
}
} }
public void kill() public void kill()

View File

@ -24,6 +24,7 @@ import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilPlayer;
import mineplex.core.updater.UpdateType; import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent; import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.Clans;
import mineplex.game.clans.clans.ClanInfo; import mineplex.game.clans.clans.ClanInfo;
import mineplex.game.clans.clans.ClansManager; import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.event.PlayerClaimTerritoryEvent; import mineplex.game.clans.clans.event.PlayerClaimTerritoryEvent;
@ -61,6 +62,10 @@ public class OutpostManager extends MiniPlugin
@EventHandler(priority = EventPriority.LOWEST) @EventHandler(priority = EventPriority.LOWEST)
public void onPlaceBlock(BlockPlaceEvent event) public void onPlaceBlock(BlockPlaceEvent event)
{ {
if (!Clans.HARDCORE)
{
return;
}
if (event.getItemInHand().isSimilar(Outpost.OUTPOST_ITEM)) if (event.getItemInHand().isSimilar(Outpost.OUTPOST_ITEM))
if (!spawnOutpost(event.getPlayer(), event.getBlock().getLocation(), OutpostType.MK_III)) if (!spawnOutpost(event.getPlayer(), event.getBlock().getLocation(), OutpostType.MK_III))
event.setCancelled(true); event.setCancelled(true);
@ -75,13 +80,20 @@ public class OutpostManager extends MiniPlugin
return false; return false;
} }
if (_clansManager.getWorldEvent().getRaidManager().isInRaid(player.getLocation()))
{
_clansManager.message(player, "You are not allowed to place this in a raid.");
return false;
}
if (!_clansManager.isInClan(player)) if (!_clansManager.isInClan(player))
{ {
UtilPlayer.message(player, F.main("Clans", "You must be in a Clan to place an Outpost.")); UtilPlayer.message(player, F.main("Clans", "You must be in a Clan to place an Outpost."));
return false; return false;
} }
if(_clansManager.hasTimer(player)) if (_clansManager.hasTimer(player))
{ {
UtilPlayer.message(player, F.main("Clans", "You can't place an Outpost whilst protected from PvP.")); UtilPlayer.message(player, F.main("Clans", "You can't place an Outpost whilst protected from PvP."));
return false; return false;
@ -123,6 +135,7 @@ public class OutpostManager extends MiniPlugin
} }
for (int x = -2; x < 2; x++) for (int x = -2; x < 2; x++)
{
for (int z = -2; z < 2; z++) for (int z = -2; z < 2; z++)
{ {
Chunk chunk = location.getWorld().getChunkAt(location.getChunk().getX() + x, location.getChunk().getZ() + z); Chunk chunk = location.getWorld().getChunkAt(location.getChunk().getX() + x, location.getChunk().getZ() + z);
@ -138,10 +151,12 @@ public class OutpostManager extends MiniPlugin
} }
} }
} }
}
boolean gut = false; boolean gut = false;
for (int x = -6; x < 6; x++) for (int x = -6; x < 6; x++)
{
for (int z = -6; z < 6; z++) for (int z = -6; z < 6; z++)
{ {
Chunk chunk = location.getWorld().getChunkAt(location.getChunk().getX() + x, location.getChunk().getZ() + z); Chunk chunk = location.getWorld().getChunkAt(location.getChunk().getX() + x, location.getChunk().getZ() + z);
@ -159,6 +174,7 @@ public class OutpostManager extends MiniPlugin
} }
} }
} }
}
/* das ist schlecht */ /* das ist schlecht */
if (!gut) if (!gut)
@ -168,7 +184,9 @@ public class OutpostManager extends MiniPlugin
} }
for (int x = -type._size; x < type._size; x++) for (int x = -type._size; x < type._size; x++)
{
for (int y = -1; y < type._ySize; y++) for (int y = -1; y < type._ySize; y++)
{
for (int z = -type._size; z < type._size; z++) for (int z = -type._size; z < type._size; z++)
{ {
Location loc = location.clone().add(x, y, z); Location loc = location.clone().add(x, y, z);
@ -179,6 +197,8 @@ public class OutpostManager extends MiniPlugin
return false; return false;
} }
} }
}
}
_outposts.put(clan.getName(), new Outpost(this, clan, location, type)); _outposts.put(clan.getName(), new Outpost(this, clan, location, type));
_idToOutpost.put(Integer.valueOf(_outposts.get(clan.getName()).getUniqueId()), _outposts.get(clan.getName())); _idToOutpost.put(Integer.valueOf(_outposts.get(clan.getName()).getUniqueId()), _outposts.get(clan.getName()));

View File

@ -1,27 +1,30 @@
package mineplex.game.clans.clans.siege.outpost; package mineplex.game.clans.clans.siege.outpost;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Objects;
import org.bukkit.DyeColor;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.banner.Pattern;
import mineplex.core.common.block.schematic.Schematic; import mineplex.core.common.block.schematic.Schematic;
import mineplex.core.common.block.schematic.UtilSchematic; import mineplex.core.common.block.schematic.UtilSchematic;
import mineplex.core.common.util.UtilWorld; import mineplex.core.common.util.UtilWorld;
import mineplex.game.clans.clans.ClanInfo;
import mineplex.game.clans.clans.ClansManager; import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.banners.BannerManager;
import mineplex.game.clans.clans.banners.BannerPattern;
import mineplex.game.clans.clans.banners.ClanBanner;
import mineplex.game.clans.clans.siege.outpost.build.OutpostBlock; import mineplex.game.clans.clans.siege.outpost.build.OutpostBlock;
import mineplex.game.clans.clans.siege.outpost.build.OutpostBlockBanner; import mineplex.game.clans.clans.siege.outpost.build.OutpostBlockBanner;
import net.minecraft.server.v1_8_R3.NBTTagCompound;
public enum OutpostType public enum OutpostType
{ {
MK_I(1, 3, 6) { MK_I(1, 3, 6) {
public LinkedHashMap<String, OutpostBlock> createBuildQueue(Location location, ClansManager clans) public LinkedHashMap<String, OutpostBlock> createBuildQueue(Location location, ClansManager clans, ClanInfo owner)
{ {
LinkedHashMap<String, OutpostBlock> build = new LinkedHashMap<>(); LinkedHashMap<String, OutpostBlock> build = new LinkedHashMap<>();
@ -232,7 +235,7 @@ public enum OutpostType
} }
}, },
MK_II(2, 5, 25) { MK_II(2, 5, 25) {
public LinkedHashMap<String, OutpostBlock> createBuildQueue(Location location, ClansManager clans) public LinkedHashMap<String, OutpostBlock> createBuildQueue(Location location, ClansManager clans, ClanInfo owner)
{ {
try try
{ {
@ -292,7 +295,7 @@ public enum OutpostType
} }
}, },
MK_III(3, 5, 25) { MK_III(3, 5, 25) {
public LinkedHashMap<String, OutpostBlock> createBuildQueue(Location location, ClansManager clans) public LinkedHashMap<String, OutpostBlock> createBuildQueue(Location location, ClansManager clans, ClanInfo owner)
{ {
try try
{ {
@ -300,6 +303,8 @@ public enum OutpostType
File file = new File("schematic" + File.separator + "outpost_mk_III.schematic"); File file = new File("schematic" + File.separator + "outpost_mk_III.schematic");
Schematic schematic = UtilSchematic.loadSchematic(file); Schematic schematic = UtilSchematic.loadSchematic(file);
BannerManager bm = clans.getBannerManager();
ClanBanner cb = bm.LoadedBanners.get(owner.getName());
for (int y = 0; y < schematic.getHeight(); y++) for (int y = 0; y < schematic.getHeight(); y++)
{ {
@ -319,10 +324,16 @@ public enum OutpostType
if (Material.getMaterial(schematic.getBlock(x, y, z)).name().contains("BANNER")) if (Material.getMaterial(schematic.getBlock(x, y, z)).name().contains("BANNER"))
{ {
build.put(UtilWorld.locToStr(loc), new OutpostBlockBanner(build, loc, schematic.getBlock(x, y, z), schematic.getData(x, y, z), DyeColor.RED)); if (cb == null)
{
continue;
}
build.put(UtilWorld.locToStr(loc), new OutpostBlockBanner(build, loc, schematic.getBlock(x, y, z), schematic.getData(x, y, z), cb.getBaseColor(), cb.getPatterns().stream().map(BannerPattern::getBukkitPattern).filter(Objects::nonNull).toArray(size -> new Pattern[size])));
} }
else else
{
build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, schematic.getBlock(x, y, z), schematic.getData(x, y, z))); build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, schematic.getBlock(x, y, z), schematic.getData(x, y, z)));
}
} }
} }
} }
@ -374,7 +385,7 @@ public enum OutpostType
return _id; return _id;
} }
public abstract LinkedHashMap<String, OutpostBlock> createBuildQueue(Location location, ClansManager clans); public abstract LinkedHashMap<String, OutpostBlock> createBuildQueue(Location location, ClansManager clans, ClanInfo owner);
public abstract Location getCoreLocation(Location location); public abstract Location getCoreLocation(Location location);

View File

@ -1,8 +1,5 @@
package mineplex.game.clans.clans.siege.repository.tokens; package mineplex.game.clans.clans.siege.repository.tokens;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Location; import org.bukkit.Location;
import mineplex.game.clans.clans.ClanInfo; import mineplex.game.clans.clans.ClanInfo;
@ -15,6 +12,5 @@ public class SiegeWeaponToken
public Location Location; public Location Location;
public int Health; public int Health;
public int Yaw; public int Yaw;
public long LastFired; public long LastFired;
}
}

View File

@ -1,7 +1,7 @@
package mineplex.game.clans.clans.siege.weapon.projectile; package mineplex.game.clans.clans.siege.weapon.projectile;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -110,7 +110,7 @@ public class Crater
} }
}, 1L); }, 1L);
HashMap<LivingEntity, Double> hitMap = UtilEnt.getInRadius(_origin, 3.5); Map<LivingEntity, Double> hitMap = UtilEnt.getInRadius(_origin, 3.5);
for (LivingEntity hit : hitMap.keySet()) for (LivingEntity hit : hitMap.keySet())
{ {
ClansManager.getInstance().getDamageManager().NewDamageEvent(hit, _cause, null, DamageCause.ENTITY_EXPLOSION, 7 / hitMap.get(hit), true, true, false, _cause.getName(), "Siege Cannon"); ClansManager.getInstance().getDamageManager().NewDamageEvent(hit, _cause, null, DamageCause.ENTITY_EXPLOSION, 7 / hitMap.get(hit), true, true, false, _cause.getName(), "Siege Cannon");

View File

@ -3,20 +3,13 @@ package mineplex.game.clans.clans.siege.weapon.projectile;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed; import org.bukkit.entity.TNTPrimed;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityChangeBlockEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock; import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilItem;
import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilServer;
import mineplex.core.updater.UpdateType; import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent; import mineplex.core.updater.event.UpdateEvent;

View File

@ -18,6 +18,7 @@ import mineplex.core.thereallyoldscoreboardapiweshouldremove.ScoreboardManager;
import mineplex.core.thereallyoldscoreboardapiweshouldremove.elements.ScoreboardElement; import mineplex.core.thereallyoldscoreboardapiweshouldremove.elements.ScoreboardElement;
import mineplex.core.updater.UpdateType; import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent; import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.Clans;
import mineplex.game.clans.clans.ClanInfo; import mineplex.game.clans.clans.ClanInfo;
import mineplex.game.clans.clans.ClanTips.TipType; import mineplex.game.clans.clans.ClanTips.TipType;
import mineplex.game.clans.clans.ClansManager; import mineplex.game.clans.clans.ClansManager;
@ -107,6 +108,10 @@ public class WarManager extends MiniPlugin implements ScoreboardElement
@EventHandler @EventHandler
public void handleDeath(final ClansPlayerDeathEvent event) public void handleDeath(final ClansPlayerDeathEvent event)
{ {
if (!Clans.HARDCORE)
{
return;
}
ClanInfo deathClan = event.getPlayer().getClan(); ClanInfo deathClan = event.getPlayer().getClan();
if (deathClan == null) if (deathClan == null)

View File

@ -7,6 +7,7 @@ import mineplex.core.common.Rank;
import mineplex.core.common.util.F; import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime; import mineplex.core.common.util.UtilTime;
import mineplex.game.clans.Clans;
import mineplex.game.clans.clans.ClanInfo; import mineplex.game.clans.clans.ClanInfo;
import mineplex.game.clans.clans.ClansManager; import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.core.war.ClanWarData; import mineplex.game.clans.core.war.ClanWarData;
@ -22,6 +23,11 @@ public class WarPointsCommand extends CommandBase<WarManager>
@Override @Override
public void Execute(Player caller, String[] args) public void Execute(Player caller, String[] args)
{ {
if (!Clans.HARDCORE)
{
UtilPlayer.message(caller, F.main("Clans", "This is not a hardcore server!"));
return;
}
ClansManager clansManager = Plugin.getClansManager(); ClansManager clansManager = Plugin.getClansManager();
ClanInfo clan = clansManager.getClan(caller); ClanInfo clan = clansManager.getClan(caller);

View File

@ -72,7 +72,7 @@ public class WarPointEvasion extends MiniPlugin
{ {
Chunk chunk = event.getClaimedChunk(); Chunk chunk = event.getClaimedChunk();
if(_chunkCooldown.containsKey(chunk)) if (_chunkCooldown.containsKey(chunk))
{ {
event.setCancelled(true); event.setCancelled(true);
event.getClaimer().sendMessage(F.main("Clans", "You cannot claim this chunk for another " + UtilTime.convertString(COOLDOWN_TIME - (System.currentTimeMillis() - _chunkCooldown.get(chunk)), 1, UtilTime.TimeUnit.MINUTES))); event.getClaimer().sendMessage(F.main("Clans", "You cannot claim this chunk for another " + UtilTime.convertString(COOLDOWN_TIME - (System.currentTimeMillis() - _chunkCooldown.get(chunk)), 1, UtilTime.TimeUnit.MINUTES)));

View File

@ -5,11 +5,19 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.plugin.java.JavaPlugin;
import com.google.common.collect.Lists;
import mineplex.core.MiniPlugin; import mineplex.core.MiniPlugin;
import mineplex.core.blockrestore.BlockRestore; import mineplex.core.blockrestore.BlockRestore;
import mineplex.core.blood.Blood;
import mineplex.core.common.util.C; import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilWorld;
import mineplex.core.disguise.DisguiseManager; import mineplex.core.disguise.DisguiseManager;
import mineplex.core.thereallyoldscoreboardapiweshouldremove.ScoreboardManager; import mineplex.core.thereallyoldscoreboardapiweshouldremove.ScoreboardManager;
import mineplex.core.thereallyoldscoreboardapiweshouldremove.elements.ScoreboardElement; import mineplex.core.thereallyoldscoreboardapiweshouldremove.elements.ScoreboardElement;
@ -18,33 +26,23 @@ import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.clans.ClansManager; import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.loot.LootManager; import mineplex.game.clans.clans.loot.LootManager;
import mineplex.game.clans.clans.regions.ClansRegions; import mineplex.game.clans.clans.regions.ClansRegions;
import mineplex.game.clans.clans.worldevent.api.EventState;
import mineplex.game.clans.clans.worldevent.api.WorldEvent;
import mineplex.game.clans.clans.worldevent.boss.BossArenaLocationFinder;
import mineplex.game.clans.clans.worldevent.command.WorldEventCommand; import mineplex.game.clans.clans.worldevent.command.WorldEventCommand;
import mineplex.game.clans.clans.worldevent.raid.RaidManager;
import mineplex.minecraft.game.classcombat.Skill.SkillFactory; import mineplex.minecraft.game.classcombat.Skill.SkillFactory;
import mineplex.minecraft.game.classcombat.Skill.event.SkillTriggerEvent; 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.broodmother.SpiderCreature;
import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature;
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonCreature;
import mineplex.minecraft.game.core.damage.DamageManager; import mineplex.minecraft.game.core.damage.DamageManager;
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 com.google.common.collect.Lists;
public class WorldEventManager extends MiniPlugin implements ScoreboardElement public class WorldEventManager extends MiniPlugin implements ScoreboardElement
{ {
private static final double ARENA_RADIUS = 40;
private final List<WorldEvent> _runningEvents; private final List<WorldEvent> _runningEvents;
private Random _random; private Random _random;
private ClansManager _clansManager; private ClansManager _clansManager;
private EventTerrainFinder _terrainFinder; private EventTerrainFinder _terrainFinder;
private BossArenaLocationFinder _bossFinder;
private DamageManager _damageManager; private DamageManager _damageManager;
private LootManager _lootManager; private LootManager _lootManager;
private BlockRestore _blockRestore; private BlockRestore _blockRestore;
@ -53,20 +51,27 @@ public class WorldEventManager extends MiniPlugin implements ScoreboardElement
private long _nextEventStart; private long _nextEventStart;
private RaidManager _raidManager;
public WorldEventManager(JavaPlugin plugin, ClansManager clansManager, DamageManager damageManager, LootManager lootManager, BlockRestore blockRestore, ClansRegions clansRegions, SkillFactory skillFactory) public WorldEventManager(JavaPlugin plugin, ClansManager clansManager, DamageManager damageManager, LootManager lootManager, BlockRestore blockRestore, ClansRegions clansRegions, SkillFactory skillFactory)
{ {
super("World Event", plugin); super("World Event", plugin);
_random = new Random(); _random = new Random();
_terrainFinder = new EventTerrainFinder(clansManager); _terrainFinder = new EventTerrainFinder(clansManager);
_bossFinder = new BossArenaLocationFinder(UtilWorld.getWorld("world"));
_clansManager = clansManager; _clansManager = clansManager;
_damageManager = damageManager; _damageManager = damageManager;
_lootManager = lootManager; _lootManager = lootManager;
_blockRestore = blockRestore; _blockRestore = blockRestore;
_runningEvents = new LinkedList<WorldEvent>(); _runningEvents = new LinkedList<>();
_skillFactory = skillFactory; _skillFactory = skillFactory;
new Blood(plugin);
_raidManager = new RaidManager(plugin);
updateNextEventTime(); updateNextEventTime();
} }
@ -75,24 +80,22 @@ public class WorldEventManager extends MiniPlugin implements ScoreboardElement
addCommand(new WorldEventCommand(this)); addCommand(new WorldEventCommand(this));
} }
// PS: This never gets called
@Override @Override
public void disable() public void disable()
{ {
for (WorldEvent event : _runningEvents) for (WorldEvent event : _runningEvents)
{ {
event.cancel(); event.stop(true);
} }
_runningEvents.clear();
_raidManager.onDisable();
} }
public boolean isInEvent(Location location) public boolean isInEvent(Location location)
{ {
for (WorldEvent event : _runningEvents) for (WorldEvent event : _runningEvents)
{ {
if (UtilMath.offset2d(location, event.getCenterLocation()) <= ARENA_RADIUS) event.isInBounds(location, true);
{
return true;
}
} }
return false; return false;
@ -103,28 +106,9 @@ public class WorldEventManager extends MiniPlugin implements ScoreboardElement
{ {
if (event.GetSkillName().equalsIgnoreCase("Ice Prison")) if (event.GetSkillName().equalsIgnoreCase("Ice Prison"))
{ {
for (WorldEvent e : _runningEvents) if (isInEvent(event.GetPlayer().getLocation()))
{ {
if (isInEvent(event.GetPlayer().getLocation())) event.SetCancelled(true);
{
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);
} }
} }
} }
@ -137,26 +121,7 @@ public class WorldEventManager extends MiniPlugin implements ScoreboardElement
return; return;
} }
boolean removed = false; boolean removed = _runningEvents.removeIf(e -> e.getState() == EventState.STOPPED);
Iterator<WorldEvent> iterator = _runningEvents.iterator();
while (iterator.hasNext())
{
WorldEvent worldEvent = iterator.next();
if (worldEvent.getState() == EventState.COMPLETE || worldEvent.getState() == EventState.CANCELLED)
{
HandlerList.unregisterAll(worldEvent);
iterator.remove();
// If the event was cancelled, cleanup was already done.
if (worldEvent.getState() == EventState.COMPLETE)
{
worldEvent.cleanup();
}
removed = true;
}
}
if (removed && _runningEvents.size() == 0) if (removed && _runningEvents.size() == 0)
{ {
@ -191,19 +156,25 @@ public class WorldEventManager extends MiniPlugin implements ScoreboardElement
private WorldEventType tryStartEvent() private WorldEventType tryStartEvent()
{ {
WorldEventType[] types = WorldEventType.values(); WorldEventType[] types = WorldEventType.values();
WorldEventType type = types[_random.nextInt(types.length)]; if (types.length == 0)
Location location = _terrainFinder.findAreaInBorderlands(false);
if (location != null)
{ {
initializeEvent(type.createInstance(this, location, _skillFactory)); return null;
return type;
} }
else else
{ {
// Try again in 5 minutes WorldEventType type = types[_random.nextInt(types.length)];
_nextEventStart = System.currentTimeMillis() + (5 * 60 * 1000); //Location location = _terrainFinder.findAreaInBorderlands(false);
//if (location != null)
{
initializeEvent(type.createInstance(this));
return type;
}
//else
//{
// Try again in 5 minutes
//_nextEventStart = System.currentTimeMillis() + (5 * 60 * 1000);
//}
} }
return null;
} }
private void initializeEvent(WorldEvent event) private void initializeEvent(WorldEvent event)
@ -213,30 +184,33 @@ public class WorldEventManager extends MiniPlugin implements ScoreboardElement
throw new RuntimeException("WorldEvent may not be null"); throw new RuntimeException("WorldEvent may not be null");
} }
event.loadMap();
event.start(); event.start();
getPlugin().getServer().getPluginManager().registerEvents(event, getPlugin());
_runningEvents.add(event); _runningEvents.add(event);
} }
public WorldEvent startEventFromName(Location location, String name) public WorldEvent startEventFromName(String name)
{ {
WorldEventType eventType = WorldEventType.valueOf(name); WorldEventType eventType = WorldEventType.valueOf(name);
if (eventType != null) if (eventType != null)
{ {
WorldEvent event = eventType.createInstance(this, location, _skillFactory); WorldEvent event = eventType.createInstance(this);
if (event == null)
{
return null;
}
initializeEvent(event); initializeEvent(event);
return event; return event;
} }
return null; return null;
} }
public WorldEvent startEventFromType(WorldEventType eventType) public WorldEvent startEventFromType(WorldEventType eventType)
{ {
if (eventType != null) if (eventType != null)
{ {
Location location = _terrainFinder.findAreaInBorderlands(true); //Location location = _terrainFinder.findAreaInBorderlands(true);
WorldEvent event = eventType.createInstance(this, location, _skillFactory); WorldEvent event = eventType.createInstance(this);
if (event != null) if (event != null)
{ {
initializeEvent(event); initializeEvent(event);
@ -253,8 +227,7 @@ public class WorldEventManager extends MiniPlugin implements ScoreboardElement
while (iterator.hasNext()) while (iterator.hasNext())
{ {
WorldEvent event = iterator.next(); WorldEvent event = iterator.next();
if (event.getState() != EventState.COMPLETE) event.cancel(); event.stop(true);
HandlerList.unregisterAll(event);
iterator.remove(); iterator.remove();
} }
@ -281,6 +254,16 @@ public class WorldEventManager extends MiniPlugin implements ScoreboardElement
return _terrainFinder; return _terrainFinder;
} }
public BossArenaLocationFinder getBossArenaLocationFinder()
{
return _bossFinder;
}
public RaidManager getRaidManager()
{
return _raidManager;
}
private void updateNextEventTime() private void updateNextEventTime()
{ {
// 45 Minutes + (0 - 15 Minutes) // 45 Minutes + (0 - 15 Minutes)
@ -341,4 +324,4 @@ public class WorldEventManager extends MiniPlugin implements ScoreboardElement
{ {
return getClans().getDisguiseManager(); return getClans().getDisguiseManager();
} }
} }

View File

@ -1,73 +1,45 @@
package mineplex.game.clans.clans.worldevent; package mineplex.game.clans.clans.worldevent;
import java.lang.reflect.Constructor; import mineplex.game.clans.clans.worldevent.api.WorldEvent;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemBoss;
import org.bukkit.Location; import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonBoss;
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.skeletonking.SkeletonBoss;
public enum WorldEventType public enum WorldEventType
{ {
//SLIME_KING("Slime King", SlimeBoss.class, 30), //SLIME_KING("Slime King", SlimeBoss.class, 30),
//KING_OF_THE_HILL("King of The Hill", KingHill.class, 30), //KING_OF_THE_HILL("King of The Hill", KingHill.class, 30),
//UNDEAD_CAMP("Undead Camp", UndeadCamp.class, 30), //UNDEAD_CAMP("Undead Camp", UndeadCamp.class, 30),
IRON_WIZARD("Iron Wizard",GolemBoss.class, 30), //IRON_WIZARD("Iron Wizard", GolemBoss.class, 30),
//BROOD_MOTHER("Brood Mother", SpiderBoss.class, 30), //BROOD_MOTHER("Brood Mother", SpiderBoss.class, 30),
SKELETON_KING("Skeleton King", SkeletonBoss.class, 30); //SKELETON_KING("Skeleton King", SkeletonBoss.class, 30)
IRON_WIZARD("Iron Wizard", GolemBoss.class, (man) ->
{
return new GolemBoss(man);
}),
SKELETON_KING("Skeleton King", SkeletonBoss.class, (man) ->
{
return new SkeletonBoss(man);
})
;
private String _name; private String _name;
private Class<? extends WorldEvent> _clazz; private Class<? extends WorldEvent> _clazz;
private int _areaNeeded; private EventCreator _creator;
WorldEventType(String name, Class<? extends WorldEvent> clazz, int areaNeeded) WorldEventType(String name, Class<? extends WorldEvent> clazz, EventCreator creator)
{ {
_name = name; _name = name;
_clazz = clazz; _clazz = clazz;
_areaNeeded = areaNeeded; _creator = creator;
} }
public int getAreaNeeded() public WorldEvent createInstance(WorldEventManager eventManager)
{
return _areaNeeded;
}
public WorldEvent createInstance(WorldEventManager eventManager, Location centerLocation, SkillFactory skillFactory)
{ {
WorldEvent worldEvent = null; WorldEvent worldEvent = null;
try if (_creator != null)
{ {
for (Constructor<?> con : _clazz.getConstructors()) worldEvent = _creator.createEvent(eventManager);
{
Class<?>[] classes = con.getParameterTypes();
if (classes[0] == WorldEventManager.class)
{
if (classes.length == 3)
{
worldEvent = (WorldEvent) con.newInstance(eventManager, centerLocation, skillFactory);
}
else
{
worldEvent = (WorldEvent) con.newInstance(eventManager, centerLocation);
}
}
else if (classes.length == 4)
{
worldEvent = (WorldEvent) con.newInstance(eventManager.getDamage(), eventManager.getBlockRestore(), eventManager.getClans().getCondition(), centerLocation);
}
else
{
worldEvent = (WorldEvent) con.newInstance(eventManager.getDisguiseManager(), eventManager.getDamage(), eventManager.getBlockRestore(), eventManager.getClans().getCondition(), eventManager.getClans().getProjectile(), centerLocation);
}
}
}
catch (Exception e)
{
e.printStackTrace();
} }
return worldEvent; return worldEvent;
@ -75,6 +47,11 @@ public enum WorldEventType
public String getName() public String getName()
{ {
return this._name; return _name;
} }
}
private static interface EventCreator
{
WorldEvent createEvent(WorldEventManager manager);
}
}

View File

@ -0,0 +1,109 @@
package mineplex.game.clans.clans.worldevent.api;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
public abstract class BossAbility<T extends EventCreature<Y>, Y extends LivingEntity> implements Listener
{
private T _creature;
private Map<UUID, Long> _damaged = new HashMap<>();
public BossAbility(T creature)
{
_creature = creature;
}
public abstract boolean canMove();
public abstract boolean inProgress();
public abstract boolean hasFinished();
public abstract void setFinished();
public abstract void tick();
public boolean canDamage(Entity player)
{
if (_damaged.containsKey(player.getUniqueId()))
{
if (!UtilTime.elapsed(_damaged.get(player.getUniqueId()), 400))
{
return false;
}
}
_damaged.put(player.getUniqueId(), System.currentTimeMillis());
return true;
}
public int getCooldown()
{
return 3;
}
public Y getEntity()
{
return getBoss().getEntity();
}
public T getBoss()
{
return _creature;
}
public Location getLocation()
{
return getEntity().getLocation();
}
public Player getTarget()
{
return getTarget(30);
}
public Player getTarget(double minDistance, double maxDistance)
{
Player target = null;
double dist = 0;
for (Player player : UtilPlayer.getNearby(getLocation(), maxDistance, true))
{
if (!player.hasLineOfSight(getEntity()))
{
continue;
}
double d = player.getLocation().distance(getLocation());
if (d < minDistance)
{
continue;
}
if (target == null || dist > d)
{
target = player;
dist = d;
}
}
return target;
}
public Player getTarget(double maxDistance)
{
return getTarget(0, maxDistance);
}
}

View File

@ -0,0 +1,50 @@
package mineplex.game.clans.clans.worldevent.api;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Listener;
import mineplex.core.common.util.UtilServer;
public abstract class BossPassive<T extends EventCreature<Y>, Y extends LivingEntity> implements Listener
{
private T _creature;
private final int _cooldown;
public BossPassive(T creature)
{
this(creature, 30);
}
public BossPassive(T creature, int cooldown)
{
_creature = creature;
_cooldown = cooldown;
Bukkit.getPluginManager().registerEvents(this, UtilServer.getPlugin());
}
public abstract boolean isProgressing();
public abstract void tick();
public int getCooldown()
{
return _cooldown;
}
public Y getEntity()
{
return getBoss().getEntity();
}
public T getBoss()
{
return _creature;
}
public Location getLocation()
{
return getEntity().getLocation();
}
}

View File

@ -0,0 +1,44 @@
package mineplex.game.clans.clans.worldevent.api;
import org.bukkit.Location;
import mineplex.core.common.util.UtilMath;
public class EventArena
{
private final Location _centerLocation;
private final double _radius;
private final double _radiusSquared;
public EventArena(Location center, double radius)
{
_centerLocation = center;
_radius = radius;
_radiusSquared = Math.pow(radius, 2);
}
public Location getCenterLocation()
{
return _centerLocation;
}
public double getRadius()
{
return _radius;
}
public double getRadiusSquared()
{
return _radiusSquared;
}
public boolean isInArena(Location checkLocation, boolean flat)
{
if (flat)
{
return UtilMath.offset2dSquared(checkLocation, _centerLocation) <= _radiusSquared;
}
return UtilMath.offsetSquared(checkLocation, _centerLocation) <= _radiusSquared;
}
}

View File

@ -0,0 +1,412 @@
package mineplex.game.clans.clans.worldevent.api;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityCombustEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.world.ChunkUnloadEvent;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilTime;
import mineplex.core.disguise.disguises.DisguiseBase;
import mineplex.core.disguise.disguises.DisguiseInsentient;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.condition.Condition.ConditionType;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
public abstract class EventCreature<T extends LivingEntity> implements Listener
{
protected static final boolean DEBUG_MODE = true;
private static final long TELEPORT_HOME_WARMUP = 5000;
private static final long HEALTH_REGEN_COOLDOWN = 1500;
private static final long SAFE_TO_HEALTH_REGEN_COOLDOWN = 15000;
private static final double HEALTH_PER_REGEN = 1.5;
private WorldEvent _event;
// Spawn Data
private T _entity;
private Class<? extends T> _entityClass;
private Location _spawnLocation, _lastLocation;
// Creature Data
private String _name;
private String _displayName;
private boolean _useName;
private double _health;
private double _maxHealth;
private boolean _showHealthName;
private long _teleportHome;
private double _walkRange;
private boolean _healthRegen;
// Fight Data
private long _lastDamaged;
private UUID _lastDamager;
private long _lastRegen;
public EventCreature(WorldEvent event, Location spawnLocation, String name, boolean useName, double health, double walkRange, boolean healthRegen, Class<T> entityClass)
{
_event = event;
_entityClass = entityClass;
_spawnLocation = spawnLocation;
_name = name;
_displayName = name;
_useName = useName;
_health = health;
_maxHealth = health;
_showHealthName = true;
_teleportHome = -1L;
_walkRange = walkRange;
_healthRegen = healthRegen;
}
public double getDifficulty()
{
return getEvent().getDifficulty();
}
protected void spawnEntity()
{
Location spawnLocation = _entity == null ? _spawnLocation : _entity.getLocation();
T entity = _spawnLocation.getWorld().spawn(spawnLocation, getEntityClass());
setEntity(entity);
updateEntityHealth();
entity.setRemoveWhenFarAway(false);
spawnCustom();
updateName();
}
protected abstract void spawnCustom();
protected void updateEntityHealth()
{
_entity.setMaxHealth(500d);
_entity.setHealth(500d);
}
protected void updateName()
{
String name = _displayName;
if (_showHealthName)
{
String healthString = (int) _health + "/" + (int) _maxHealth;
double per =_health / _maxHealth;
if (per > 0.5) healthString = C.cGreen + healthString;
if (per > 0.2) healthString = C.cYellow + healthString;
else healthString = C.cRed + healthString;
name += " " + C.cWhite + "(" + healthString + C.cWhite + ")";
}
DisguiseBase disguise = getEvent().getDisguiseManager().getActiveDisguise(getEntity());
if (disguise != null && disguise instanceof DisguiseInsentient)
{
((DisguiseInsentient) disguise).setName(name);
((DisguiseInsentient) disguise).setCustomNameVisible(_useName);
}
_entity.setCustomName(name);
_entity.setCustomNameVisible(_useName);
}
public void remove()
{
remove(true);
}
public void remove(boolean removeFromEvent)
{
if (_entity != null)
{
if (getHealth() > 0)
{
_entity.remove();
}
else
{
_entity.setHealth(0);
_entity.setCustomName("");
_entity.setCustomNameVisible(false);
}
}
if (removeFromEvent)
{
_event.removeCreature(this);
}
}
protected final void die()
{
dieCustom();
remove();
}
public abstract void dieCustom();
public WorldEvent getEvent()
{
return _event;
}
public void setEvent(WorldEvent event)
{
_event = event;
}
public T getEntity()
{
return _entity;
}
public void setEntity(T entity)
{
if (_entity != null) _entity.remove();
_entity = entity;
}
public Class<? extends T> getEntityClass()
{
return _entityClass;
}
public void setEntityClass(Class<? extends T> clazz)
{
_entityClass = clazz;
}
public double getHealthPercent()
{
return getHealth() / getMaxHealth();
}
public Location getSpawnLocation()
{
return _spawnLocation;
}
public Location getLastKnownLocation()
{
return _lastLocation;
}
public void setSpawnLocation(Location spawnLocation)
{
_spawnLocation = spawnLocation;
}
public String getDisplayName()
{
return _displayName;
}
public String getName()
{
return _name;
}
public void setName(String name)
{
_displayName = name == null ? _name : name;
updateName();
}
public boolean isUseName()
{
return _useName;
}
public void setUseName(boolean useName)
{
_useName = useName;
updateName();
}
public void applyDamage(double damage)
{
setHealth(getHealth() - damage);
}
public void applyRegen(double regen)
{
setHealth(getHealth() + regen);
}
public double getHealth()
{
return _health;
}
public void setHealth(double health)
{
_health = Math.min(health, getMaxHealth());
if (_health <= 0)
{
die();
}
else
{
updateName();
}
}
public double getMaxHealth()
{
return _maxHealth;
}
public void setMaxHealth(double maxHealth)
{
_maxHealth = maxHealth;
}
public void setShowHealthName(boolean showHealthName)
{
_showHealthName = showHealthName;
updateName();
}
/**
* Event listeners
*/
@EventHandler
public void onChunkUnload(ChunkUnloadEvent event)
{
if (_entity != null && _entity.getLocation().getChunk().equals(event.getChunk()))
{
event.setCancelled(true);
}
}
@EventHandler
public void update(UpdateEvent event)
{
if (event.getType() != UpdateType.FAST)
{
return;
}
if (_entity == null || _entity.isDead() || !_entity.isValid())
{
if (DEBUG_MODE)
{
System.out.println("Respawning " + getName() + " because it is null or dead");
}
spawnEntity();
}
if (_healthRegen && getHealth() < getMaxHealth() && UtilTime.elapsed(_lastDamaged, SAFE_TO_HEALTH_REGEN_COOLDOWN) && UtilTime.elapsed(_lastRegen, HEALTH_REGEN_COOLDOWN))
{
_lastRegen = System.currentTimeMillis();
applyRegen(HEALTH_PER_REGEN);
}
if (_walkRange != -1 && UtilMath.offset2d(_entity.getLocation(), _spawnLocation) > _walkRange)
{
if (_teleportHome != -1 && System.currentTimeMillis() >= _teleportHome)
{
_entity.teleport(_spawnLocation);
_teleportHome = -1;
}
else
{
_entity.setVelocity(UtilAlg.getTrajectory(_entity.getLocation(), _spawnLocation).normalize().multiply(2));
if (_teleportHome == -1)
{
_teleportHome = System.currentTimeMillis() + TELEPORT_HOME_WARMUP;
}
}
}
else
{
if (_teleportHome != -1)
{
_teleportHome = -1;
}
}
_lastLocation = _entity.getLocation();
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onDamage(CustomDamageEvent event)
{
if (_entity == null)
{
return;
}
if (!event.GetDamageeEntity().equals(_entity))
{
return;
}
updateEntityHealth();
applyDamage(event.GetDamage());
updateName();
_lastDamaged = System.currentTimeMillis();
_event.updateLastActive();
}
@EventHandler
public void damageType(CustomDamageEvent event)
{
if (_entity == null)
{
return;
}
if (!event.GetDamageeEntity().equals(_entity))
{
return;
}
DamageCause cause = event.GetCause();
if (cause == DamageCause.FALL && !getEvent().getCondition().HasCondition(_entity, ConditionType.FALLING, null))
{
event.SetCancelled("Cancel");
}
if (cause == DamageCause.DROWNING || cause == DamageCause.SUFFOCATION)
{
event.SetCancelled("Cancel");
}
}
@EventHandler
public void cancelCombust(EntityCombustEvent event)
{
if (_entity == null)
{
return;
}
if (!event.getEntity().equals(_entity))
{
return;
}
event.setCancelled(true);
}
}

View File

@ -0,0 +1,31 @@
package mineplex.game.clans.clans.worldevent.api;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class EventCreatureDeathEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private final EventCreature<?> _creature;
public EventCreatureDeathEvent(EventCreature<?> creature)
{
_creature = creature;
}
public EventCreature<?> getCreature()
{
return _creature;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
}

View File

@ -0,0 +1,9 @@
package mineplex.game.clans.clans.worldevent.api;
public enum EventState
{
LOADING,
LIVE,
STOPPED,
REMOVED
}

View File

@ -0,0 +1,337 @@
package mineplex.game.clans.clans.worldevent.api;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
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 mineplex.core.blockrestore.BlockRestore;
import mineplex.core.blockrestore.BlockRestoreMap;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
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.UtilWorld;
import mineplex.core.disguise.DisguiseManager;
import mineplex.core.projectile.ProjectileManager;
import mineplex.core.thereallyoldscoreboardapiweshouldremove.ScoreboardManager;
import mineplex.core.thereallyoldscoreboardapiweshouldremove.elements.ScoreboardElement;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.condition.ConditionManager;
import mineplex.minecraft.game.core.damage.DamageManager;
public abstract class WorldEvent implements Listener, ScoreboardElement
{
// 20 Minutes
private static final int ACTIVE_TIMEOUT = 1200000;
private static final int LOADING_TIMEOUT = 300000;
private DamageManager _damageManager;
private ConditionManager _conditionManager;
private DisguiseManager _disguiseManager;
private ProjectileManager _projectileManager;
private String _name;
private EventState _state;
private EventArena _arena;
private Random _random;
private long _timeStarted;
private long _lastActive;
private boolean _announceStart;
// Creatures
private List<EventCreature<?>> _creatures;
// Block Restore
private BlockRestoreMap _blockRestoreMap;
private double _difficulty = 1;
public WorldEvent(String name, Location centerLocation, double radius, boolean announceStart, DisguiseManager disguiseManager, ProjectileManager projectileManager, DamageManager damageManager, BlockRestore blockRestore, ConditionManager conditionManager)
{
_disguiseManager = disguiseManager;
_projectileManager = projectileManager;
_damageManager = damageManager;
_conditionManager = conditionManager;
_name = name;
_state = EventState.LOADING;
_arena = new EventArena(centerLocation, radius);
_random = new Random();
_announceStart = announceStart;
_creatures = new ArrayList<>();
_blockRestoreMap = blockRestore.createMap();
}
public String getName()
{
return _name;
}
public void setName(String name)
{
_name = name;
}
public EventArena getEventArena()
{
return _arena;
}
public EventState getState()
{
return _state;
}
protected void setState(EventState state)
{
_state = state;
}
public double getDifficulty()
{
return _difficulty;
}
public void setDifficulty(double difficulty)
{
_difficulty = difficulty;
}
public Location getCenterLocation()
{
return _arena.getCenterLocation();
}
public List<EventCreature<?>> getCreatures()
{
return _creatures;
}
public void registerCreature(EventCreature<?> creature)
{
UtilServer.RegisterEvents(creature);
_creatures.add(creature);
}
public void removeCreature(EventCreature<?> creature)
{
Bukkit.getPluginManager().callEvent(new EventCreatureDeathEvent(creature));
HandlerList.unregisterAll(creature);
_creatures.remove(creature);
}
public void clearCreatures()
{
for (EventCreature<?> creature : _creatures)
{
creature.remove(false);
HandlerList.unregisterAll(creature);
}
_creatures.clear();
}
public long getTimeRunning()
{
return System.currentTimeMillis() - _timeStarted;
}
public long getLastActive()
{
return _lastActive;
}
public void updateLastActive()
{
_lastActive = System.currentTimeMillis();
}
public boolean isInBounds(Location location, boolean flat)
{
return _arena.isInArena(location, flat);
}
protected Random getRandom()
{
return _random;
}
public DisguiseManager getDisguiseManager()
{
return _disguiseManager;
}
public ProjectileManager getProjectileManager()
{
return _projectileManager;
}
public DamageManager getDamageManager()
{
return _damageManager;
}
public ConditionManager getCondition()
{
return _conditionManager;
}
protected BlockRestoreMap getBlockRestoreMap()
{
return _blockRestoreMap;
}
public void setBlock(Block block, Material material)
{
setBlock(block, material, (byte) 0);
}
@SuppressWarnings("deprecation")
public void setBlock(Block block, Material material, byte data)
{
setBlock(block, material.getId(), data);
}
public void setBlock(Block block, int id, byte data)
{
_blockRestoreMap.set(block, id, data);
}
public void restoreBlocks()
{
_blockRestoreMap.restore();
}
public final void start()
{
_timeStarted = System.currentTimeMillis();
_lastActive = System.currentTimeMillis();
if (_announceStart)
{
announceStart();
}
setState(EventState.LIVE);
customStart();
UtilServer.RegisterEvents(this);
}
public void announceStart()
{
UtilTextMiddle.display(C.cGreen + getName(), UtilWorld.locToStrClean(getCenterLocation()), 10, 100, 40);
UtilServer.broadcast(F.main("Event", F.elem(getName()) + " has started at coordinates " + F.elem(UtilWorld.locToStrClean(getCenterLocation()))));
}
protected abstract void customStart();
protected abstract void customTick();
public final void cleanup(boolean onDisable)
{
clearCreatures();
restoreBlocks();
customCleanup(onDisable);
}
public abstract void customCleanup(boolean onDisable);
public final void stop()
{
stop(false);
}
public final void stop(boolean onDisable)
{
cleanup(onDisable);
if (onDisable)
{
setState(EventState.REMOVED);
}
else
{
setState(EventState.STOPPED);
}
customStop();
HandlerList.unregisterAll(this);
}
protected abstract void customStop();
public int getRandomRange(int min, int max)
{
return min + _random.nextInt(UtilMath.clamp(max - min, min, max));
}
public void announceMessage(String message)
{
UtilServer.broadcast(F.main("Event", F.elem(getName()) + ": " + message));
}
public void sendMessage(Player player, String message)
{
UtilPlayer.message(player, F.main("Event", F.elem(getName()) + ": " + message));
}
@EventHandler
public void tick(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
customTick();
}
@EventHandler
public void endInactive(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
{
return;
}
long diff = System.currentTimeMillis() - getLastActive();
if (diff > ACTIVE_TIMEOUT)
{
stop();
}
}
@EventHandler
public void prepareTimeout(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
{
return;
}
if (getState() != EventState.LOADING)
{
return;
}
// Event was preparing for more than 5 minutes
if (getTimeRunning() > LOADING_TIMEOUT)
{
stop();
}
}
@Override
public List<String> getLines(ScoreboardManager manager, Player player, List<String> out)
{
return null;
}
}

View File

@ -0,0 +1,66 @@
package mineplex.game.clans.clans.worldevent.boss;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.util.Vector;
import mineplex.core.common.Pair;
public class BossArenaLocationFinder
{
private World _world;
public BossArenaLocationFinder(World world)
{
_world = world;
}
public Location getIronWizardCenter()
{
return new Location(_world, 1057, 63, -77);
}
public Pair<List<Vector>, List<Vector>> getIronWizardPads()
{
List<Vector> in = new ArrayList<>();
List<Vector> out = new ArrayList<>();
in.add(new Vector(1006, 62, -77));
in.add(new Vector(1057, 62, -26));
in.add(new Vector(1108, 62, -77));
in.add(new Vector(1057, 62, -128));
out.add(new Vector(1035, 63, -77));
out.add(new Vector(1057, 63, -99));
out.add(new Vector(1079, 63, -77));
out.add(new Vector(1057, 63, -55));
return Pair.create(in, out);
}
public Location getSkeletonKingCenter()
{
return new Location(_world, -1043, 58, 159);
}
public Pair<List<Vector>, List<Vector>> getSkeletonKingPads()
{
List<Vector> in = new ArrayList<>();
List<Vector> out = new ArrayList<>();
in.add(new Vector(-1094, 57, 159));
in.add(new Vector(-1043, 57, 210));
in.add(new Vector(-992, 57, 159));
in.add(new Vector(-1043, 57, 108));
out.add(new Vector(-1021, 58, 159));
out.add(new Vector(-1043, 58, 137));
out.add(new Vector(-1065, 58, 159));
out.add(new Vector(-1043, 58, 181));
return Pair.create(in, out);
}
}

View File

@ -0,0 +1,39 @@
package mineplex.game.clans.clans.worldevent.boss;
import org.bukkit.Location;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class BossDeathEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private final BossWorldEvent<?> _event;
private final Location _deathLocation;
public BossDeathEvent(BossWorldEvent<?> event, Location location)
{
_event = event;
_deathLocation = location;
}
public BossWorldEvent<?> getEvent()
{
return _event;
}
public Location getDeathLocation()
{
return _deathLocation;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
}

View File

@ -0,0 +1,114 @@
package mineplex.game.clans.clans.worldevent.boss;
import java.util.List;
import java.util.stream.Collectors;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.util.Vector;
import mineplex.core.blockrestore.BlockRestore;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.disguise.DisguiseManager;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.projectile.ProjectileManager;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.worldevent.api.EventCreature;
import mineplex.game.clans.clans.worldevent.api.EventCreatureDeathEvent;
import mineplex.game.clans.clans.worldevent.api.EventState;
import mineplex.game.clans.clans.worldevent.api.WorldEvent;
import mineplex.minecraft.game.classcombat.Skill.ISkill;
import mineplex.minecraft.game.classcombat.Skill.Assassin.Recall;
import mineplex.minecraft.game.core.condition.ConditionManager;
import mineplex.minecraft.game.core.damage.DamageManager;
public abstract class BossWorldEvent<T extends EventCreature<?>> extends WorldEvent
{
private static final double TELEPORT_PAD_RANGE = 1.5;
private static final long DELAY_TILL_DROP_REWARD = 40;
private T _boss;
private List<Location> _teleportFrom;
private List<Location> _teleportTo;
public BossWorldEvent(String name, Location centerLocation, double radius, List<Vector> teleportFrom, List<Vector> teleportTo, DisguiseManager disguiseManager, ProjectileManager projectileManager, DamageManager damageManager, BlockRestore blockRestore, ConditionManager conditionManager)
{
super(name, centerLocation, radius, true, disguiseManager, projectileManager, damageManager, blockRestore, conditionManager);
_teleportFrom = teleportFrom.stream().map(vec -> vec.toLocation(centerLocation.getWorld())).collect(Collectors.toList());
_teleportTo = teleportTo.stream().map(vec -> vec.toLocation(centerLocation.getWorld())).collect(Collectors.toList());
}
public abstract String getDeathMessage();
public T getBossCreature()
{
return _boss;
}
public void setBossCreature(T boss)
{
_boss = boss;
}
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.FAST)
{
return;
}
if (getState() != EventState.LIVE)
{
return;
}
if (_teleportFrom.isEmpty() || _teleportTo.isEmpty())
{
return;
}
for (Location from : _teleportFrom)
{
for (Player player : UtilPlayer.getInRadius(from, TELEPORT_PAD_RANGE).keySet())
{
player.teleport(UtilMath.randomElement(_teleportTo));
for (ISkill skill : ClansManager.getInstance().getClassManager().Get(player).GetSkills())
{
if (skill instanceof Recall)
{
((Recall)skill).Reset(player);
}
}
sendMessage(player, "You have teleported inside the arena!");
}
}
}
@EventHandler
public void onBossDeath(EventCreatureDeathEvent event)
{
if (_boss == null)
{
return;
}
if (event.getCreature().equals(_boss))
{
Location drop = event.getCreature().getLastKnownLocation();
UtilServer.CallEvent(new BossDeathEvent(this, drop));
ClansManager.getInstance().runSyncLater(() ->
{
ClansManager.getInstance().getLootManager().dropRare(drop);
drop.getWorld().dropItem(drop, new ItemBuilder(Material.IRON_INGOT).setTitle(C.cDRedB + "Old Silver Token").setLore(C.cRed + "This token pulses with an evil aura.").setGlow(true).build());
}, DELAY_TILL_DROP_REWARD);
Bukkit.broadcastMessage(getDeathMessage());
stop();
}
}
}

View File

@ -0,0 +1,46 @@
package mineplex.game.clans.clans.worldevent.boss.ironwizard;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import mineplex.core.common.util.F;
import mineplex.game.clans.clans.worldevent.WorldEventManager;
import mineplex.game.clans.clans.worldevent.boss.BossWorldEvent;
public class GolemBoss extends BossWorldEvent<GolemCreature>
{
public GolemBoss(WorldEventManager manager)
{
super("Iron Wizard", manager.getBossArenaLocationFinder().getIronWizardCenter(), 50, manager.getBossArenaLocationFinder().getIronWizardPads().getLeft(), manager.getBossArenaLocationFinder().getIronWizardPads().getRight(), manager.getDisguiseManager(), manager.getClans().getProjectile(), manager.getClans().getDamageManager(), manager.getBlockRestore(), manager.getClans().getCondition());
}
@Override
protected void customStart()
{
Bukkit.broadcastMessage(F.main(getName(), "The mighty " + getName() + " challenges you to face him!"));
spawnGolem(getCenterLocation());
}
@Override
public String getDeathMessage()
{
return F.main(getName(), "The mighty " + getName() + " has fallen!");
}
private GolemCreature spawnGolem(Location location)
{
GolemCreature golemCreature = new GolemCreature(this, location);
registerCreature(golemCreature);
setBossCreature(golemCreature);
return golemCreature;
}
@Override
protected void customTick() {}
@Override
public void customCleanup(boolean onDisable) {}
@Override
protected void customStop() {}
}

View File

@ -0,0 +1,599 @@
package mineplex.game.clans.clans.worldevent.boss.ironwizard;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.api.EventCreature;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemBlockHail;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemBlockShot;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemDeadlyTremor;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemEarthquake;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemExplodingAura;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemIronHook;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemMeleeAttack;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemRupture;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemSlam;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemSpike;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
public class GolemCreature extends EventCreature<IronGolem>
{
private int _lastAbility;
private long _lastWalked;
private Location _standing;
private long _spawnDelay = System.currentTimeMillis();
private long _reverseWalk;
private Map<Class<? extends BossAbility<GolemCreature, IronGolem>>, Class<?>[]> _preferredCombos = new HashMap<>();
private Class<? extends BossAbility<GolemCreature, IronGolem>> _lastAttack;
private boolean _usedFinalAttack;
private List<BossAbility<GolemCreature, IronGolem>> _currentAbilities = new ArrayList<>();
private double _canDeadlyTremor = 225;
private Vector _afkWalk = new Vector();
private long _lastSlam;
public GolemCreature(GolemBoss boss, Location location)
{
super(boss, location, "Iron Wizard", true, 3000, 30, true, IronGolem.class);
spawnEntity();
_preferredCombos.put(GolemEarthquake.class, new Class[]
{
GolemBlockHail.class, GolemRupture.class
});
_preferredCombos.put(GolemMeleeAttack.class, new Class[]
{
GolemEarthquake.class, GolemRupture.class
});
_preferredCombos.put(GolemDeadlyTremor.class, new Class[]
{
GolemMeleeAttack.class
});
_preferredCombos.put(GolemBlockShot.class, new Class[]
{
GolemEarthquake.class
});
_preferredCombos.put(GolemRupture.class, new Class[]
{
GolemBlockShot.class
});
_preferredCombos.put(GolemBlockHail.class, new Class[]
{
GolemDeadlyTremor.class
});
}
private boolean hasFurther(Map<Player, Double> distances, double range)
{
for (Player player : distances.keySet())
{
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR)
{
continue;
}
Double dist = distances.get(player);
if (dist >= range)
{
return true;
}
}
return false;
}
@Override
protected void spawnCustom()
{
UtilEnt.vegetate(getEntity());
_standing = getEntity().getLocation();
}
@SuppressWarnings("unchecked")
@EventHandler
public void abilityTick(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
if (!UtilTime.elapsed(_spawnDelay, 5000))
{
_standing = getEntity().getLocation();
return;
}
Iterator<BossAbility<GolemCreature, IronGolem>> itel = _currentAbilities.iterator();
boolean canDoNew = _currentAbilities.size() < 3;
while (itel.hasNext())
{
BossAbility<GolemCreature, IronGolem> ability = itel.next();
if (ability.hasFinished())
{
itel.remove();
ability.setFinished();
_lastAbility = 20;
HandlerList.unregisterAll(ability);
if (DEBUG_MODE)
{
System.out.print("Unregistered golem ability " + ability.getClass().getSimpleName());
}
}
else if (!ability.inProgress())
{
canDoNew = false;
}
}
if (_lastAbility-- <= 0 && canDoNew && UtilBlock.solid(getEntity().getLocation().getBlock().getRelative(BlockFace.DOWN)))
{
Map<Class<? extends BossAbility<GolemCreature, IronGolem>>, Integer> weight = new HashMap<>();
Map<Player, Double> dist = new HashMap<>();
for (Player player : UtilPlayer.getNearby(getEntity().getLocation(), 50, true))
{
if (player.hasLineOfSight(getEntity()))
{
dist.put(player, player.getLocation().distance(getEntity().getLocation()));
}
}
if (!dist.isEmpty())
{
double hp = getHealthPercent();
{ // Melee
List<Player> players = getPlayers(dist, UtilMath.r(10) == 0 ? 4 : 3);
if (!players.isEmpty())
{
if (players.size() >= 4)
{
weight.put(GolemEarthquake.class, 999);
}
else
{
weight.put(GolemMeleeAttack.class, 999);
}
}
}
if (hasFurther(dist, 15))
{ // Iron Hook
weight.put(GolemIronHook.class, 6); //6
}
if (hp < 0.7)
{ // Earthquake
List<Player> players = getPlayers(dist, 10);
double score = 0;
for (Player player : players)
{
score += (8 - dist.get(player)) / 2;
}
if (players.size() >= 3)
{
score += 7;
}
if (score > 0)
{
weight.put(GolemEarthquake.class, (int) Math.ceil(score));
}
}
{ // Wall explode
if (!getPlayers(dist, 20).isEmpty() && getPlayers(dist, 4).isEmpty())
{
weight.put(GolemSpike.class, 8);
}
}
{ // Block Shot
List<Player> players = getPlayers(dist, 30);
for (Player player : players)
{
if (dist.get(player) > 4)
{
weight.put(GolemBlockShot.class, 6);
break;
}
}
}
{ // Rupture
List<Player> players = getPlayers(dist, 30);
if (!players.isEmpty())
{
weight.put(GolemRupture.class, (int) Math.min(5, dist.get(players.get(0))));
}
}
{ // Slam
List<Player> players = getPlayers(dist, 30);
if (!players.isEmpty() && UtilTime.elapsed(_lastSlam, 20000))
{
weight.put(GolemSlam.class, 6);
}
}
if (_canDeadlyTremor <= 0) // Deadly Tremor
{
List<Player> players = getPlayers(dist, 80);
for (BossAbility<GolemCreature, IronGolem> ability : _currentAbilities)
{
if (ability instanceof GolemExplodingAura)
{
players.clear();
}
}
if (!players.isEmpty())
{
weight.put(GolemDeadlyTremor.class, (int) 30);
}
}
{// Block Hail
List<Player> players = getPlayers(dist, 30);
if (!players.isEmpty())
{
int we = _lastAttack == GolemEarthquake.class ? 20 : UtilMath.r(15) - 2;
if (we > 0)
{
weight.put(GolemBlockHail.class, we);
}
}
}
if (!_usedFinalAttack && getHealth() < 90)
{
_usedFinalAttack = true;
weight.clear();
weight.put(GolemExplodingAura.class, 999);
}
if (_lastAttack != null && _preferredCombos.containsKey(_lastAttack))
{
weight.remove(_lastAttack);
for (Class<?> c : _preferredCombos.get(_lastAttack))
{
if (weight.containsKey(c))
{
weight.put((Class<? extends BossAbility<GolemCreature, IronGolem>>)c, weight.get(c) * 4);
}
}
}
for (BossAbility<GolemCreature, IronGolem> ability : _currentAbilities)
{
weight.remove(ability.getClass());
}
BossAbility<GolemCreature, IronGolem> ability = null;
if (!weight.isEmpty())
{
int i = 0;
for (Integer entry : weight.values())
{
i += entry;
}
for (int a = 0; a < 10; a++)
{
int luckyNumber = UtilMath.r(i);
for (Entry<Class<? extends BossAbility<GolemCreature, IronGolem>>, Integer> entry : weight.entrySet())
{
luckyNumber -= entry.getValue();
if (luckyNumber <= 0)
{
try
{
ability = entry.getKey().getConstructor(GolemCreature.class).newInstance(this);
if (ability.getTarget() == null)
{
ability = null;
}
else
{
break;
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
break;
}
}
}
}
if (ability != null && ability.getTarget() != null)
{
_lastAttack = (Class<? extends BossAbility<GolemCreature, IronGolem>>) ability.getClass();
if (ability instanceof GolemDeadlyTremor)
{
_canDeadlyTremor = 225;
}
else if (ability instanceof GolemSlam)
{
_lastSlam = System.currentTimeMillis();
}
Bukkit.getPluginManager().registerEvents(ability, UtilServer.getPlugin());
if (DEBUG_MODE)
{
System.out.print("Golem boss is using " + ability.getClass().getSimpleName());
}
_currentAbilities.add(ability);
}
_lastAbility = 10;
}
_lastAttack = null;
}
boolean canMove = true;
for (BossAbility<GolemCreature, IronGolem> ability : _currentAbilities)
{
try
{
ability.tick();
}
catch (Exception e)
{
e.printStackTrace(); //Keeps the boss from getting stuck if one of the moves throws an error in progression
}
if (!ability.canMove())
{
canMove = false;
}
}
if (canMove)
{
Player target = null;
double dist = 0;
for (Player player : UtilPlayer.getNearby(getEntity().getLocation(), 50, true))
{
if (!player.hasLineOfSight(getEntity()))
{
continue;
}
double d = player.getLocation().distance(getEntity().getLocation());
if (d > 1.5 && (d < 7 || d > 15) && (target == null || (d < 50 && dist > d)))
{
target = player;
dist = d;
}
}
Vector vec = null;
boolean superWalk = false;
if (target != null)
{
vec = target.getLocation().subtract(getEntity().getLocation()).toVector();
vec.setY(getEntity().getLocation().getY());
double len = vec.length();
vec.setX(vec.getX() * (UtilMath.random.nextDouble() / 3D));
vec.setZ(vec.getZ() * (UtilMath.random.nextDouble() / 3D));
vec.multiply(len);
if (target != null && dist < 8)
{
vec.multiply(-1);
superWalk = true;
}
if (!UtilAlg.HasSight(getEntity().getLocation(),
getEntity().getLocation().add(vec.clone().normalize().multiply(2))))
{
_reverseWalk = System.currentTimeMillis();
}
if (!UtilTime.elapsed(_reverseWalk, 4000))
{
vec.multiply(-1);
}
}
else if (!UtilTime.elapsed(_lastWalked, 7000))
{
vec = _afkWalk;
}
else if (UtilTime.elapsed(_lastWalked, 12000))
{
_afkWalk = new Vector();
for (int i = 0; i < 10; i++)
{
Vector vector = new Vector(UtilMath.r(20) - 10, 0, UtilMath.r(20) - 10);
if (UtilAlg.HasSight(getEntity().getLocation(),
getEntity().getLocation().add(vector.clone().normalize().multiply(2))))
{
vec = _afkWalk = vector;
break;
}
}
_lastWalked = System.currentTimeMillis();
}
if (vec != null)
{
{
UtilEnt.CreatureMoveFast(getEntity(), getEntity().getLocation().add(vec),
(target != null ? 1.8F : 1.1F) + (superWalk ? 0.4F : 0));
}
}
_standing = getEntity().getLocation();
}
else
{
Location l = getEntity().getLocation();
_standing.setYaw(l.getYaw());
_standing.setPitch(l.getPitch());
_standing.setY(l.getY());
getEntity().teleport(_standing);
}
}
private List<Player> getPlayers(final Map<Player, Double> map, double maxDist)
{
List<Player> list = new ArrayList<Player>();
for (Player p : map.keySet())
{
if (map.get(p) <= maxDist)
{
list.add(p);
}
}
Collections.sort(list, (o1, o2) ->
{
return Double.compare(map.get(o2), map.get(o1));
});
return list;
}
@EventHandler
public void onGolemDamage(CustomDamageEvent event)
{
if (event.GetDamageeEntity().equals(getEntity()))
{
event.AddKnockback("Heavy Golem", 0.3);
}
}
@EventHandler
public void onRangedAttack(CustomDamageEvent event)
{
if (event.GetDamageeEntity().equals(getEntity()))
{
if (event.GetDamageePlayer() != null)
{
if (event.GetProjectile() != null && event.GetProjectile() instanceof Arrow)
{
if (new Random().nextDouble() <= .5)
{
event.SetCancelled("Iron Skin Reflection");
getEntity().getWorld().playSound(getEntity().getLocation(), Sound.ZOMBIE_METAL, 0.5f, 1.6f);
return;
}
}
double dist = event.GetDamageePlayer().getLocation().distance(getEntity().getLocation());
double maxRange = _usedFinalAttack ? 20 : 45;
double modifier = (maxRange - dist) / maxRange;
if (modifier > 0)
{
event.AddMod("Ranged Resistance", 1 - modifier);
}
else
{
event.SetCancelled("Range too far");
}
}
}
}
@Override
public void dieCustom()
{
endAbility();
}
private void endAbility()
{
for (BossAbility<GolemCreature, IronGolem> ability : _currentAbilities)
{
ability.setFinished();
HandlerList.unregisterAll(ability);
}
_currentAbilities.clear();
}
@Override
public void setHealth(double health)
{
_canDeadlyTremor -= getHealth() - health;
super.setHealth(health);
if (getHealth() <= 100 && !_usedFinalAttack)
{
endAbility();
}
}
}

View File

@ -0,0 +1,88 @@
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.IronGolem;
import mineplex.core.common.util.UtilEnt;
import net.minecraft.server.v1_8_R3.DataWatcher;
import net.minecraft.server.v1_8_R3.Entity;
import net.minecraft.server.v1_8_R3.Packet;
import net.minecraft.server.v1_8_R3.PacketPlayOutAttachEntity;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving;
public class BlockHailBlock
{
private int _block = UtilEnt.getNewEntityId();
private int _silverfish = UtilEnt.getNewEntityId();
private Location _location;
private Material _mat;
public BlockHailBlock(Location loc, Material mat)
{
_location = loc;
_mat = mat;
}
public PacketPlayOutEntityDestroy getDestroyPacket()
{
return new PacketPlayOutEntityDestroy(new int[]
{
_silverfish, _block
});
}
public Location getLocation()
{
return _location;
}
public Material getMaterial()
{
return _mat;
}
@SuppressWarnings("deprecation")
public Packet<?>[] getSpawnPackets(IronGolem entity)
{
Packet<?>[] packets = new Packet[3];
PacketPlayOutSpawnEntityLiving packet1 = new PacketPlayOutSpawnEntityLiving();
DataWatcher watcher = new DataWatcher(null);
watcher.a(0, (byte) 32, Entity.META_ENTITYDATA, (byte) 0);
watcher.a(1, 0, Entity.META_AIR, 0);
packet1.a = _silverfish;
packet1.b = EntityType.SILVERFISH.getTypeId();
packet1.c = (int) Math.floor(_location.getX() * 32);
packet1.d = (int) Math.floor(_location.getY() * 32);
packet1.e = (int) Math.floor(_location.getZ() * 32);
packet1.l = watcher;
packets[0] = packet1;
PacketPlayOutSpawnEntity packet2 = new PacketPlayOutSpawnEntity(((CraftEntity) entity).getHandle(), 70, _mat.getId());
packet2.a = _block;
packet2.b = (int) Math.floor(_location.getX() * 32);
packet2.c = (int) Math.floor(entity.getLocation().getY() * 32);
packet2.d = (int) Math.floor(_location.getZ() * 32);
packets[1] = packet2;
PacketPlayOutAttachEntity packet3 = new PacketPlayOutAttachEntity();
packet3.b = _block;
packet3.c = _silverfish;
packets[2] = packet3;
return packets;
}
}

View File

@ -0,0 +1,475 @@
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.bukkit.Effect;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem;
import org.bukkit.entity.Entity;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilShapes;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
import net.minecraft.server.v1_8_R3.EntityIronGolem;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.MovingObjectPosition;
import net.minecraft.server.v1_8_R3.Packet;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_8_R3.Vec3D;
public class GolemBlockHail extends BossAbility<GolemCreature, IronGolem>
{
private int _currentBlock;
private int _currentLevel;
private List<FallingBlock> _fallingBlocks = new ArrayList<>();
private Map<Integer, List<BlockHailBlock>> _floatingBlocks = new HashMap<>();
private Map<String, Integer> _blocks = new HashMap<>();
private int _levelToReach;
private boolean _spawned;
private List<Location> _spawnLocs = new ArrayList<>();
private Player _target;
private Location _center;
private int _ticks;
public GolemBlockHail(GolemCreature creature)
{
super(creature);
_center = getLocation();
if (creature.getHealthPercent() > 0.75)
{
_levelToReach = 1;
}
else if (creature.getHealthPercent() > 0.5)
{
_levelToReach = 2;
}
else
{
_levelToReach = 3;
}
_target = getTarget();
}
@Override
public Player getTarget()
{
Player target = null;
double dist = 0;
if (inProgress())
{
for (Player player : UtilPlayer.getNearby(_center, 40, true))
{
if (!player.hasLineOfSight(getEntity()))
{
continue;
}
if (target != null && _blocks.containsKey(player.getName()) && _blocks.get(player.getName()) > 8)
{
continue;
}
double d = player.getLocation().distance(_center);
if (target == null || dist > d)
{
target = player;
dist = d;
}
}
}
return target;
}
@Override
public boolean canMove()
{
return _spawned && _floatingBlocks.isEmpty();
}
@Override
public boolean hasFinished()
{
return _target == null || !_target.isValid() || ((_fallingBlocks.isEmpty() && _spawned) && _ticks >= 8 * 9)
|| _center.distance(_target.getLocation()) > 100;
}
@SuppressWarnings("deprecation")
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
Iterator<FallingBlock> fallingIterator = _fallingBlocks.iterator();
while (fallingIterator.hasNext())
{
FallingBlock cur = fallingIterator.next();
if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
fallingIterator.remove();
Block block = cur.getLocation().getBlock();
block.setTypeIdAndData(0, (byte) 0, true);
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
// Expire
if (cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
cur.remove();
continue;
}
cur.remove();
continue;
}
double distanceToEntity = 0.0D;
LivingEntity victim = null;
net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) cur).getHandle();
Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY,
nmsEntity.locZ + nmsEntity.motZ);
MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false);
vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
if (finalObjectPosition != null)
{
vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c);
}
for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities(((CraftEntity) cur).getHandle(),
((CraftEntity) cur).getHandle().getBoundingBox().a(((CraftEntity) cur).getHandle().motX,
((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2)))
{
Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity();
if (bukkitEntity instanceof LivingEntity)
{
LivingEntity ent = (LivingEntity) bukkitEntity;
// Avoid Self
if (ent.equals(getEntity()))
continue;
// Creative or Spec
if (ent instanceof Player)
if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent))
continue;
// float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f);
AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F);
MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1);
if (entityCollisionPosition != null)
{
double d1 = vec3d.distanceSquared(entityCollisionPosition.pos);
if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D))
{
victim = ent;
distanceToEntity = d1;
}
}
}
}
if (victim != null)
{
cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId());
{
getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) victim, getEntity(), null,
DamageCause.CONTACT, 10 * getBoss().getDifficulty(), true, true, false, "Iron Wizard Block Hail",
"Iron Wizard Block Hail");
}
if (victim instanceof Player)
{
getBoss().getEvent().getCondition().Factory().Slow("Iron Wizard Block Hail", (LivingEntity) victim,
getEntity(), 3, 2, false, false, false, false);
}
fallingIterator.remove();
cur.remove();
}
else if (finalObjectPosition != null)
{
Block block = cur.getWorld().getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c));
if (!UtilBlock.airFoliage(block) && !block.isLiquid())
{
nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX));
nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY));
nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ));
float f2 = MathHelper.sqrt(
nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ * nmsEntity.motZ);
nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D;
nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D;
nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D;
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
fallingIterator.remove();
cur.remove();
}
}
else
{
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0),
cur.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL,
UtilServer.getPlayers());
}
}
}
@Override
public void setFinished()
{
for (List<BlockHailBlock> floatingBlocks : _floatingBlocks.values())
{
for (BlockHailBlock falling : floatingBlocks)
{
PacketPlayOutEntityDestroy packet = falling.getDestroyPacket();
for (Player player : UtilServer.getPlayers())
{
UtilPlayer.sendPacket(player, packet);
}
}
}
for (FallingBlock block : _fallingBlocks)
{
block.remove();
}
}
@SuppressWarnings("deprecation")
@Override
public void tick()
{
if (inProgress())
{
for (Player player : UtilPlayer.getNearby(_center, 5, true))
{
Location loc = player.getLocation();
if (Math.abs(loc.getY() - (_center.getY() + 1)) <= 1)
{
loc.setY(_center.getY());
if (loc.distance(_center) < 2.8 + (_currentLevel * 0.75))
{
if (canDamage(player))
{
getBoss().getEvent().getDamageManager().NewDamageEvent(player, getEntity(), null,
DamageCause.CONTACT, 10 * getBoss().getDifficulty(), true, true, false,
"Iron Wizard Protection", "Iron Wizard Protection");
loc.getWorld().playEffect(player.getLocation(), Effect.STEP_SOUND, Material.OBSIDIAN.getId());
loc.getWorld().playEffect(player.getEyeLocation(), Effect.STEP_SOUND, Material.OBSIDIAN.getId());
}
}
}
}
}
if (!_spawned)
{
if (_currentBlock >= _spawnLocs.size())
{
if (_currentLevel + 1 <= _levelToReach)
{
_currentLevel++;
_currentBlock = 0;
_spawnLocs = UtilShapes.getDistancedCircle(_center.clone().add(0, 2.8 + (_currentLevel * 0.75), 0), 1.3,
1 + (_currentLevel * 1.3));
for (int i = UtilMath.r(_spawnLocs.size()); i > 0; i--)
{
_spawnLocs.add(_spawnLocs.remove(0));
}
}
}
if (_currentBlock < _spawnLocs.size())
{
if (_ticks % 2 == 0)
{
IronGolem entity = getEntity();
Location loc = _spawnLocs.get(_currentBlock++);
List<BlockHailBlock> floatingBlocks = new ArrayList<>();
if (_floatingBlocks.containsKey(_currentLevel))
{
floatingBlocks = _floatingBlocks.get(_currentLevel);
}
else
{
_floatingBlocks.put(_currentLevel, floatingBlocks);
}
if (loc.getBlock().getType() == Material.AIR && UtilAlg.HasSight(entity.getLocation(), loc))
{
BlockHailBlock floating = new BlockHailBlock(loc, Material.STONE);
UtilEnt.CreatureLook(entity, _target);
floatingBlocks.add(floating);
Packet<?>[] packets = floating.getSpawnPackets(entity);
for (Player player : UtilPlayer.getNearby(loc, 100))
{
UtilPlayer.sendPacket(player, packets);
}
entity.getWorld().playSound(entity.getLocation(), Sound.DIG_GRASS, 3, 0.9F);
}
if (_floatingBlocks.size() % 2 == 0)
{
Collections.reverse(floatingBlocks);
}
}
}
else
{
_spawned = true;
_ticks = -20;
}
}
else if (_ticks > 0 && _ticks % 2 == 0 && !_floatingBlocks.isEmpty())
{
IronGolem entity = getEntity();
if (_ticks % 16 == 0)
{
_target = getTarget();
if (_target == null)
return;
}
EntityIronGolem golem = ((CraftIronGolem) entity).getHandle();
golem.world.broadcastEntityEffect(golem, (byte) 4);
UtilEnt.CreatureLook(entity, _target);
BlockHailBlock floatingBlock = null;
for (int i = 1; i <= _currentLevel; i++)
{
if (_floatingBlocks.containsKey(i) && !_floatingBlocks.get(i).isEmpty())
{
floatingBlock = _floatingBlocks.get(i).remove(0);
if (_floatingBlocks.get(i).isEmpty())
{
_floatingBlocks.remove(i);
}
break;
}
}
PacketPlayOutEntityDestroy packet = floatingBlock.getDestroyPacket();
for (Player player : UtilServer.getPlayers())
{
UtilPlayer.sendPacket(player, packet);
}
Location loc = floatingBlock.getLocation();
FallingBlock b = loc.getWorld().spawnFallingBlock(loc, floatingBlock.getMaterial(), (byte) 0);
b.setDropItem(false);
Vector vec = UtilAlg.calculateVelocity(loc.toVector(),
_target.getLocation().toVector().add(new Vector(UtilMath.r(6 + (_currentLevel * 2)) - (2 + _currentLevel), 0,
UtilMath.r(6 + (_currentLevel * 2)) - (2 + _currentLevel))),
6);
b.setVelocity(vec);
_fallingBlocks.add(b);
entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 3, 0.9F);
_blocks.put(_target.getName(), _blocks.containsKey(_target.getName()) ? _blocks.get(_target.getName()) + 1 : 1);
}
List<Location> points = new ArrayList<>();
for (int i = _currentLevel; i <= _currentLevel; i++)
{
points.addAll(UtilShapes.getDistancedCircle(_center.clone().add(0, 3.3 + (i * 0.75), 0), 0.3, 1 + (i * 1.3)));
}
for (int i = 0; i < points.size(); i++)
{
if (_spawned || i < _ticks)
{
Location loc = points.get(i);
UtilParticle.PlayParticle(
ParticleType.BLOCK_DUST.getParticle(_spawned && i < _ticks ? Material.STONE : Material.DIRT, 0), loc, 0,
0, 0, 0, 0, UtilParticle.ViewDist.LONG, UtilServer.getPlayers());
}
}
_ticks++;
}
@Override
public boolean inProgress()
{
return !_spawned || !_floatingBlocks.isEmpty();
}
}

View File

@ -0,0 +1,442 @@
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem;
import org.bukkit.entity.Entity;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
import net.minecraft.server.v1_8_R3.EntityIronGolem;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.MovingObjectPosition;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityVelocity;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity;
import net.minecraft.server.v1_8_R3.Vec3D;
public class GolemBlockShot extends BossAbility<GolemCreature, IronGolem>
{
private Map<Integer, Location> _blockLoc = new HashMap<>();
private Map<Integer, Material> _blockType = new HashMap<>();
private List<FallingBlock> _current = new ArrayList<>();
private Map<Integer, Long> _preshoot = new HashMap<>();
private Player _target;
private Map<Integer, Player> _targetBlock = new HashMap<>();
private Map<UUID, Integer> _shotAt = new HashMap<>();
private int _thrown;
private int _tick;
private int _toThrow;
public GolemBlockShot(GolemCreature creature)
{
super(creature);
if (creature.getHealthPercent() > 0.75)
{
_toThrow = 3;
}
else if (creature.getHealthPercent() > 0.5)
{
_toThrow = 6;
}
else
{
_toThrow = 9;
}
_target = getTarget();
}
@Override
public boolean canMove()
{
return _current.isEmpty() && _thrown == _toThrow;
}
@Override
public Player getTarget()
{
Player target = null;
double dist = 0;
Location loc1 = getLocation();
Location loc2 = loc1.clone().add(loc1.getDirection().setY(0).normalize());
List<Player> players = UtilPlayer.getNearby(getLocation(), 40, true);
for (Player player : players)
{
if (_shotAt.containsKey(player.getUniqueId()) && _shotAt.get(player.getUniqueId()) >= 3)
{
continue;
}
double dist1 = player.getLocation().distance(loc1);
double dist2 = player.getLocation().distance(loc2);
double dist3 = dist1 - dist2;
if (dist3 < 0.6 || dist1 > 30 || (target != null && dist3 < dist))
{
continue;
}
if (!player.hasLineOfSight(getEntity()))
{
continue;
}
target = player;
dist = dist3;
}
return target;
}
@Override
public boolean hasFinished()
{
return _current.isEmpty() && _preshoot.isEmpty() && (_target == null || _thrown >= _toThrow);
}
@SuppressWarnings("deprecation")
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
Iterator<FallingBlock> fallingIterator = _current.iterator();
while (fallingIterator.hasNext())
{
FallingBlock cur = fallingIterator.next();
if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
fallingIterator.remove();
Block block = cur.getLocation().getBlock();
block.setTypeIdAndData(0, (byte) 0, true);
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
// Expire
if (cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
cur.remove();
continue;
}
cur.remove();
continue;
}
double distanceToEntity = 0.0D;
LivingEntity victim = null;
net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) cur).getHandle();
Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY,
nmsEntity.locZ + nmsEntity.motZ);
MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false);
vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
if (finalObjectPosition != null)
{
vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c);
}
for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities(((CraftEntity) cur).getHandle(),
((CraftEntity) cur).getHandle().getBoundingBox().a(((CraftEntity) cur).getHandle().motX,
((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2)))
{
Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity();
if (bukkitEntity instanceof LivingEntity)
{
LivingEntity ent = (LivingEntity) bukkitEntity;
// Avoid Self
if (ent.equals(getEntity()))
continue;
// Creative or Spec
if (ent instanceof Player)
if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent))
continue;
// float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f);
AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F);
MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1);
if (entityCollisionPosition != null)
{
double d1 = vec3d.distanceSquared(entityCollisionPosition.pos);
if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D))
{
victim = ent;
distanceToEntity = d1;
}
}
}
}
if (victim != null)
{
cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId());
getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) victim, getEntity(), null,
DamageCause.CONTACT, 10 * getBoss().getDifficulty(), true, true, false, "Iron Wizard Block Shot",
"Iron Wizard Block Shot");
cur.remove();
fallingIterator.remove();
Vector vec = UtilAlg.getTrajectory(getEntity(), victim);
vec.setY(0).normalize();
double strength = 1;
if (!(victim instanceof Player) || !((Player) victim).isBlocking())
{
strength = 1.3;
}
UtilAction.velocity(victim, vec, strength, true, 0, 0.2, 1, true);
}
else if (finalObjectPosition != null)
{
Block block = cur.getWorld().getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c));
if (!UtilBlock.airFoliage(block) && !block.isLiquid())
{
nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX));
nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY));
nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ));
float f2 = MathHelper.sqrt(
nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ * nmsEntity.motZ);
nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D;
nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D;
nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D;
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
cur.remove();
fallingIterator.remove();
}
}
else
{
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0),
cur.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL,
UtilServer.getPlayers());
}
}
}
@Override
public void setFinished()
{
for (FallingBlock falling : _current)
{
falling.remove();
}
int[] ids = new int[_preshoot.size()];
int a = 0;
for (int id : _preshoot.keySet())
{
ids[a++] = id;
}
PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ids);
for (Player player : Bukkit.getOnlinePlayers())
{
UtilPlayer.sendPacket(player, packet);
}
}
@SuppressWarnings("deprecation")
@Override
public void tick()
{
if (_target == null || _target.getLocation().distance(getLocation()) > 30 || !_target.hasLineOfSight(getEntity()))
{
_target = getTarget();
}
Entity entity = getEntity();
if (_tick++ % 16 == 0 && _target != null && _thrown < _toThrow)
{
_thrown++;
UtilEnt.CreatureLook(entity, _target);
EntityIronGolem golem = ((CraftIronGolem) entity).getHandle();
golem.world.broadcastEntityEffect(golem, (byte) 4);
entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 2, 1);
Location loc = entity.getLocation();
loc.setYaw(loc.getYaw() + (UtilMath.r(150) - 75));
loc.add(loc.getDirection().setY(0).normalize());
Block block = loc.getBlock();
if (block.getType() == Material.AIR)
{
block = block.getRelative(BlockFace.DOWN);
}
Material mat = block.getType();
if (!UtilBlock.solid(block))
{
mat = Material.STONE;
}
int id = UtilEnt.getNewEntityId();
_preshoot.put(id, System.currentTimeMillis());
_blockType.put(id, mat);
_blockLoc.put(id, loc.clone().add(0, 0.6, 0));
_targetBlock.put(id, _target);
PacketPlayOutSpawnEntity packet = new PacketPlayOutSpawnEntity(((CraftEntity) entity).getHandle(), 70, mat.getId());
packet.a = id;
packet.b = (int) Math.floor(loc.getX() * 32);
packet.c = (int) Math.floor(loc.getY() * 32);
packet.d = (int) Math.floor(loc.getZ() * 32);
packet.g = (int) ((0.45) * 8000);
PacketPlayOutEntityVelocity packet2 = new PacketPlayOutEntityVelocity(id, 0, 0.45D, 0);
for (Player player : UtilPlayer.getNearby(loc, 70))
{
UtilPlayer.sendPacket(player, packet, packet2);
}
_shotAt.put(_target.getUniqueId(),
(_shotAt.containsKey(_target.getUniqueId()) ? _shotAt.get(_target.getUniqueId()) : 0) + 1);
_target = getTarget();
}
else
{
Iterator<Entry<Integer, Long>> itel = _preshoot.entrySet().iterator();
while (itel.hasNext())
{
Entry<Integer, Long> entry = itel.next();
if (UtilTime.elapsed(entry.getValue(), 920))
{
itel.remove();
int id = entry.getKey();
PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(new int[]
{
id
});
for (Player player : Bukkit.getOnlinePlayers())
{
UtilPlayer.sendPacket(player, packet);
}
Location loc = _blockLoc.get(id);
FallingBlock falling = loc.getWorld().spawnFallingBlock(loc, _blockType.get(id), (byte) 0);
falling.setDropItem(false);
_current.add(falling);
Player target = _targetBlock.get(id);
UtilEnt.CreatureLook(entity, target);
EntityIronGolem golem = ((CraftIronGolem) entity).getHandle();
golem.world.broadcastEntityEffect(golem, (byte) 4);
entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 2, 1.2F);
entity.getWorld().playEffect(falling.getLocation(), Effect.STEP_SOUND, falling.getBlockId());
Location l = falling.getLocation();
l.setY(entity.getLocation().getY());
Location loc1 = target.getEyeLocation();
if (loc1.getY() - l.getY() > 1)
{
loc1.setY(l.getY() + 1);
}
int dist = (int) Math.ceil(loc1.toVector().setY(0).distance(l.toVector().setY(0)));
Vector vector = UtilAlg.calculateVelocity(l.toVector(), loc1.toVector(), dist / 13);
falling.setVelocity(vector);
}
}
}
if (_thrown >= 3 && !UtilPlayer.getNearby(getLocation(), 10, true).isEmpty())
{
_thrown = 99;
}
}
@Override
public boolean inProgress()
{
return _thrown < _toThrow || !_current.isEmpty();
}
}

View File

@ -0,0 +1,336 @@
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.bukkit.Effect;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.entity.Entity;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilShapes;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.MovingObjectPosition;
import net.minecraft.server.v1_8_R3.Vec3D;
public class GolemCaveIn extends BossAbility<GolemCreature, IronGolem>
{
private List<Block> _blocks = new ArrayList<>();
private List<FallingBlock> _fallingBlocks = new ArrayList<>();
private int _tick;
public GolemCaveIn(GolemCreature creature)
{
super(creature);
}
@Override
public boolean canMove()
{
return false;
}
@Override
public Player getTarget()
{
if (getTarget(4) == null)
{
return getTarget(40);
}
return null;
}
@Override
public boolean hasFinished()
{
return _tick > 60 && _fallingBlocks.isEmpty();
}
@SuppressWarnings("deprecation")
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
Iterator<FallingBlock> fallingIterator = _fallingBlocks.iterator();
while (fallingIterator.hasNext())
{
FallingBlock cur = fallingIterator.next();
if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
fallingIterator.remove();
Block block = cur.getLocation().getBlock();
block.setTypeIdAndData(0, (byte) 0, true);
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
// Expire
if (cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
cur.remove();
continue;
}
cur.remove();
continue;
}
double distanceToEntity = 0.0D;
LivingEntity victim = null;
net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) cur).getHandle();
Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY,
nmsEntity.locZ + nmsEntity.motZ);
MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false);
vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
if (finalObjectPosition != null)
{
vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c);
}
for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities(((CraftEntity) cur).getHandle(),
((CraftEntity) cur).getHandle().getBoundingBox().a(((CraftEntity) cur).getHandle().motX,
((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2)))
{
Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity();
if (bukkitEntity instanceof LivingEntity)
{
LivingEntity ent = (LivingEntity) bukkitEntity;
// Avoid Self
if (ent.equals(getEntity()))
continue;
// Creative or Spec
if (ent instanceof Player)
if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent))
continue;
// float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f);
AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F);
MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1);
if (entityCollisionPosition != null)
{
double d1 = vec3d.distanceSquared(entityCollisionPosition.pos);
if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D))
{
victim = ent;
distanceToEntity = d1;
}
}
}
}
if (victim != null)
{
cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId());
if (canDamage(victim))
{
getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) victim, getEntity(), null,
DamageCause.CONTACT, 10 * getBoss().getDifficulty(), true, true, false, "Iron Wizard Cave In",
"Iron Wizard Cave In");
}
cur.remove();
fallingIterator.remove();
}
else if (finalObjectPosition != null)
{
Block block = cur.getWorld().getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c));
if (!UtilBlock.airFoliage(block) && !block.isLiquid())
{
nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX));
nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY));
nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ));
float f2 = MathHelper.sqrt(
nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ * nmsEntity.motZ);
nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D;
nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D;
nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D;
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
cur.remove();
fallingIterator.remove();
}
}
else
{
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0),
cur.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL,
UtilServer.getPlayers());
}
}
}
@SuppressWarnings("deprecation")
@Override
public void setFinished()
{
for (FallingBlock block : _fallingBlocks)
{
block.remove();
}
for (Block block : _blocks)
{
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getTypeId());
block.setType(Material.AIR);
}
}
@SuppressWarnings("deprecation")
@Override
public void tick()
{
if (_tick++ == 0)
{
Location l = getLocation();
List<Location> blocks = UtilShapes.getSphereBlocks(l, 3, 3, true);
for (Location loc : blocks)
{
if (loc.getBlockY() >= l.getBlockY())
{
Block b = loc.getBlock();
if (b.getType() == Material.AIR)
{
_blocks.add(b);
loc.setY(l.getY() - 1);
b.setType(loc.getBlock().getType());
b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, loc.getBlock().getTypeId());
}
}
}
}
if (_tick % 5 == 0)
{
for (Player player : UtilPlayer.getNearby(getLocation(), 2.5, true))
{
player.teleport(player.getLocation().add(0, 4, 0));
UtilAction.velocity(player, new Vector(UtilMath.r(10) - 5, 3, UtilMath.r(10) - 5).normalize());
}
}
if (_tick < 200)
{
Location loc = getLocation();
loc.setY(loc.getY() + 4);
for (int i = 0; i < 30; i++)
{
loc.setY(loc.getY() + 1);
Block b = loc.getBlock();
if (UtilBlock.solid(b))
{
break;
}
}
if (!UtilBlock.solid(loc.getBlock()))
{
return;
}
List<Player> players = UtilPlayer.getNearby(getLocation(), 50, true);
for (int i = 0; i < players.size() * 2; i++)
{
int dist = UtilMath.r(10);
if (dist < 3)
{
dist = 2;
}
else if (dist < 5)
{
dist = 5;
}
else
{
dist = 10;
}
Location l = players.get(UtilMath.r(players.size())).getLocation().add(UtilMath.r(dist * 2) - dist, 0,
UtilMath.r(dist * 2) - dist);
l.setY(loc.getY());
Block b = l.getBlock();
l.subtract(0, 1, 0);
if (UtilBlock.solid(b))
{
if (l.getBlock().getType() == Material.AIR)
{
if (UtilAlg.HasSight(l, getLocation().add(0, 4, 0)))
{
FallingBlock block = b.getWorld().spawnFallingBlock(b.getLocation().add(0.5, -1, 0.5), b.getTypeId(),
b.getData());
block.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, block.getBlockId());
block.setDropItem(false);
_fallingBlocks.add(block);
}
}
}
}
}
}
@Override
public boolean inProgress()
{
return true;
}
}

View File

@ -0,0 +1,89 @@
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
import org.bukkit.Effect;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.recharge.Recharge;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
public class GolemDeadlyTremor extends BossAbility<GolemCreature, IronGolem>
{
private static final long ATTACK_DURATION = 10000;
private long _start;
public GolemDeadlyTremor(GolemCreature creature)
{
super(creature);
_start = System.currentTimeMillis();
}
@Override
public boolean canMove()
{
return false;
}
@Override
public boolean inProgress()
{
return true;
}
@Override
public boolean hasFinished()
{
return UtilTime.elapsed(_start, ATTACK_DURATION);
}
@Override
public void setFinished()
{
_start = System.currentTimeMillis() - ATTACK_DURATION;
}
@Override
public void tick()
{
for (Player player : UtilPlayer.getInRadius(getLocation(), 30).keySet())
{
player.playSound(player.getLocation(), Sound.MINECART_BASE, 0.2f, 0.2f);
if (UtilEnt.isGrounded(player))
{
getBoss().getEvent().getDamageManager().NewDamageEvent(player, getBoss().getEntity(), null, DamageCause.CUSTOM, (1 + 2 * Math.random()) * getBoss().getDifficulty(), false, false, false, getBoss().getEntity().getName(), "Deadly Tremor");
if (Recharge.Instance.use(player, "Deadly Tremor Hit", 400, false, false))
{
UtilAction.velocity(player, new Vector(Math.random() - 0.5, Math.random() * 0.2, Math.random() - 0.5),
Math.random() * 1 + 1, false, 0, 0.1 + Math.random() * 0.2, 2, true);
}
}
for (Block block : UtilBlock.getInRadius(player.getLocation(), 5).keySet())
{
if (Math.random() < 0.98)
continue;
if (!UtilBlock.solid(block))
continue;
if (!UtilBlock.airFoliage(block.getRelative(BlockFace.UP)))
continue;
player.playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType());
}
}
}
}

View File

@ -0,0 +1,168 @@
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Entity;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
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.UtilServer;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
public class GolemEarthquake extends BossAbility<GolemCreature, IronGolem>
{
private Location _center;
private float _range;
private int _tick;
private List<UUID> _damaged = new ArrayList<>();
private boolean _earthquake;
public GolemEarthquake(GolemCreature creature)
{
super(creature);
_center = getLocation();
}
@Override
public boolean canMove()
{
return !UtilEnt.isGrounded(getEntity()) && _tick > 1;
}
@Override
public Player getTarget()
{
return getTarget(7);
}
@Override
public boolean hasFinished()
{
return _range > 19;
}
@Override
public void setFinished()
{
}
@Override
public void tick()
{
Entity entity = getEntity();
if (_tick == 0)
{
entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 4, 0);
entity.setVelocity(new Vector(0, 1, 0));
}
else if (!_earthquake)
{
_earthquake = _tick > 10 && UtilEnt.isGrounded(entity);
}
if (_earthquake)
{
_range += 0.7;
for (float range = _range - 2; range <= _range; range++)
{
if (range <= 0)
{
continue;
}
for (int x = -1; x <= 1; x++)
{
for (int z = -1; z <= 1; z++)
{
if ((x != 0) == (z != 0))
{
continue;
}
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.DIRT, 0),
_center.clone().add(x * range, 0.1, z * range), (x != 0) ? 0 : (range / 2), 0.1F,
(z != 0) ? 0 : (range / 2), 0, (int) (range * 4), UtilParticle.ViewDist.NORMAL,
UtilServer.getPlayers());
}
}
}
_center.getWorld().playSound(_center, Sound.DIG_STONE, 2, 0.8F);
HashSet<Player> toDamage = new HashSet<Player>();
Location cornerA = _center.clone().add(-_range, -1, -_range);
Location cornerB = _center.clone().add(_range, 1, _range);
Location cornerA1 = _center.clone().add(-(_range - 1.5), -1, -(_range - 1.5));
Location cornerB1 = _center.clone().add(_range - 1.5, 1, _range - 1.5);
for (Player player : Bukkit.getOnlinePlayers())
{
Location pLoc = player.getLocation();
if (_damaged.contains(player.getUniqueId()))
{
continue;
}
if (!UtilAlg.inBoundingBox(pLoc, cornerA, cornerB))
{
continue;
}
if (UtilAlg.inBoundingBox(pLoc, cornerA1, cornerB1))
{
continue;
}
toDamage.add(player);
}
for (Player player : toDamage)
{
_damaged.add(player.getUniqueId());
getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) player, getEntity(), null,
DamageCause.CONTACT, 14 * getBoss().getDifficulty(), false, true, false, "Iron Wizard Earthquake",
"Iron Wizard Earthquake");
getBoss().getEvent().getCondition().Factory().Slow("Earthquake", (LivingEntity) player, getEntity(), 3, 1, false,
false, false, false);
// Velocity
UtilAction.velocity(player, UtilAlg.getTrajectory2d(getLocation().toVector(), player.getLocation().toVector()),
1.8, true, 0, 0.5, 0.5, true);
// Condition
getBoss().getEvent().getCondition().Factory().Falling("Earthquake", player, getEntity(), 10, false, true);
}
}
_tick++;
}
@Override
public boolean inProgress()
{
return !_earthquake;
}
}

View File

@ -0,0 +1,400 @@
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.bukkit.Effect;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
import net.minecraft.server.v1_8_R3.DataWatcher;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.MovingObjectPosition;
import net.minecraft.server.v1_8_R3.Packet;
import net.minecraft.server.v1_8_R3.PacketPlayOutAttachEntity;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving;
import net.minecraft.server.v1_8_R3.Vec3D;
public class GolemExplodingAura extends BossAbility<GolemCreature, IronGolem>
{
private Map<Integer, Integer> _blocks = new HashMap<>();
private Map<Integer, Location> _blocksLoc = new HashMap<>();
private List<FallingBlock> _fallingBlocks = new ArrayList<>();
private Map<Integer, Material> _blockMaterial = new HashMap<>();
private int _tick;
public GolemExplodingAura(GolemCreature creature)
{
super(creature);
}
@Override
public boolean canMove()
{
return false;
}
@Override
public boolean hasFinished()
{
return _tick > 20 * 30 && _blocks.isEmpty() && _fallingBlocks.isEmpty();
}
@Override
public void setFinished()
{
for (FallingBlock block : _fallingBlocks)
{
block.remove();
}
int[] ids = new int[_blocks.size() * 2];
int i = 0;
for (Entry<Integer, Integer> id : _blocks.entrySet())
{
ids[i] = id.getKey();
ids[i + 1] = id.getValue();
i += 2;
}
PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ids);
for (Player player : UtilServer.getPlayers())
{
UtilPlayer.sendPacket(player, packet);
}
}
@SuppressWarnings("deprecation")
@Override
public void tick()
{
if (_tick < 25 * 25 && getBoss().getHealth() > 30)
{
double angle = (2 * Math.PI) / UtilMath.random.nextDouble();
double x = 1.7 * Math.cos(angle);
double z = 1.7 * Math.sin(angle);
Location loc = getLocation().add(x, 1 + (UtilMath.random.nextDouble() * 1.6), z);
loc.getWorld().playEffect(loc, Effect.STEP_SOUND, Material.DIRT.getId());
for (Player player : UtilPlayer.getNearby(getLocation(), 3, true))
{
getBoss().getEvent().getDamageManager().NewDamageEvent(player, getEntity(), null, DamageCause.CONTACT,
6 * getBoss().getDifficulty(), true, true, false, "Iron Wizard Protection", "Iron Wizard Protection");
UtilAction.velocity(player, UtilAlg.getTrajectory(getEntity(), player), 1, true, 0.3, 0, 0.3, false);
}
}
if (_tick < 20 * 30)
{
int key = UtilEnt.getNewEntityId();
int value = UtilEnt.getNewEntityId();
Location loc = null;
for (int i = 0; i < 30; i++)
{
double angle = (2 * Math.PI) / UtilMath.random.nextDouble();
double x = 1.7 * Math.cos(angle);
double z = 1.7 * Math.sin(angle);
loc = getLocation().add(x, 1 + (UtilMath.random.nextDouble() * 1.6), z);
boolean found = false;
for (Location l : _blocksLoc.values())
{
if (l.distance(loc) < 0.3)
{
found = true;
break;
}
}
if (found)
{
loc = null;
}
else
{
break;
}
}
if (loc != null)
{
_blocks.put(key, value);
_blocksLoc.put(key, loc);
_blockMaterial.put(key, UtilMath.random.nextBoolean() ? Material.DIRT : Material.STONE);
Packet<?>[] packets = new Packet[3];
PacketPlayOutSpawnEntityLiving packet1 = new PacketPlayOutSpawnEntityLiving();
DataWatcher watcher = new DataWatcher(null);
watcher.a(0, (byte) 32, net.minecraft.server.v1_8_R3.Entity.META_ENTITYDATA, (byte) 0);
watcher.a(1, 0, net.minecraft.server.v1_8_R3.Entity.META_AIR, 0);
packet1.a = key;
packet1.b = EntityType.SILVERFISH.getTypeId();
packet1.c = (int) Math.floor(loc.getX() * 32);
packet1.d = (int) Math.floor((loc.getY() - 0.125) * 32);
packet1.e = (int) Math.floor(loc.getZ() * 32);
packet1.l = watcher;
packets[0] = packet1;
PacketPlayOutSpawnEntity packet2 = new PacketPlayOutSpawnEntity(((CraftEntity) getEntity()).getHandle(), 70,
_blockMaterial.get(key).getId());
packet2.a = value;
packet2.b = (int) Math.floor(loc.getX() * 32);
packet2.c = (int) Math.floor(loc.getY() * 32);
packet2.d = (int) Math.floor(loc.getZ() * 32);
packets[1] = packet2;
PacketPlayOutAttachEntity packet3 = new PacketPlayOutAttachEntity();
packet3.b = value;
packet3.c = key;
packets[2] = packet3;
for (Player player : UtilPlayer.getNearby(getLocation(), 70))
{
UtilPlayer.sendPacket(player, packets);
}
}
}
if (_tick % 25 == 0)
{
for (int i = 0; i < 3; i++)
getLocation().getWorld().playSound(getLocation(), Sound.DIG_GRASS, 3, 2);
for (int key : new ArrayList<Integer>(_blocksLoc.keySet()))
{
PacketPlayOutEntityDestroy destroyPacket = new PacketPlayOutEntityDestroy(new int[]
{
key, _blocks.remove(key)
});
for (Player player : UtilServer.getPlayers())
{
UtilPlayer.sendPacket(player, destroyPacket);
}
Location loc = _blocksLoc.remove(key);
FallingBlock falling = loc.getWorld().spawnFallingBlock(loc, _blockMaterial.remove(key), (byte) 0);
_fallingBlocks.add(falling);
Vector vec = UtilAlg.getTrajectory(getLocation().add(0, 1, 0), loc);
vec.setY(Math.max(0.05, vec.getY()));
falling.setVelocity(vec);
loc.getWorld().playEffect(loc, Effect.STEP_SOUND, Material.DIRT.getId());
}
}
_tick++;
}
@SuppressWarnings("deprecation")
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
Iterator<FallingBlock> fallingIterator = _fallingBlocks.iterator();
while (fallingIterator.hasNext())
{
FallingBlock cur = fallingIterator.next();
if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
fallingIterator.remove();
Block block = cur.getLocation().getBlock();
block.setTypeIdAndData(0, (byte) 0, true);
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
// Expire
if (cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
cur.remove();
continue;
}
cur.remove();
continue;
}
double distanceToEntity = 0.0D;
LivingEntity victim = null;
net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) cur).getHandle();
Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY,
nmsEntity.locZ + nmsEntity.motZ);
MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false);
vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
if (finalObjectPosition != null)
{
vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c);
}
for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities(((CraftEntity) cur).getHandle(),
((CraftEntity) cur).getHandle().getBoundingBox().a(((CraftEntity) cur).getHandle().motX,
((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2)))
{
Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity();
if (bukkitEntity instanceof LivingEntity)
{
LivingEntity ent = (LivingEntity) bukkitEntity;
// Avoid Self
if (ent.equals(getEntity()))
{
continue;
}
// Creative or Spec
if (ent instanceof Player)
{
if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent))
{
continue;
}
}
AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F);
MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1);
if (entityCollisionPosition != null)
{
double d1 = vec3d.distanceSquared(entityCollisionPosition.pos);
if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D))
{
victim = ent;
distanceToEntity = d1;
}
}
}
}
if (victim != null)
{
cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId());
{
getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) victim, getEntity(), null,
DamageCause.CONTACT, 6 * getBoss().getDifficulty(), true, true, false, "Blocky Iron Wizard Aura",
"Blocky Iron Wizard Aura");
}
fallingIterator.remove();
cur.remove();
Vector vec = UtilAlg.getTrajectory(getEntity(), victim);
vec.setY(0).normalize();
double strength = 1;
if (!(victim instanceof Player) || !((Player) victim).isBlocking())
{
strength = 1.3;
}
UtilAction.velocity(victim, vec, strength, true, 0, 0.2, 1, true);
}
else if (finalObjectPosition != null)
{
Block block = cur.getWorld().getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c));
if (!UtilBlock.airFoliage(block) && !block.isLiquid())
{
nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX));
nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY));
nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ));
float f2 = MathHelper.sqrt(
nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ * nmsEntity.motZ);
nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D;
nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D;
nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D;
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
fallingIterator.remove();
cur.remove();
}
}
else
{
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0),
cur.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL,
UtilServer.getPlayers());
}
}
}
@Override
public boolean inProgress()
{
return false;
}
}

View File

@ -0,0 +1,590 @@
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
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.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
import net.minecraft.server.v1_8_R3.DataWatcher;
import net.minecraft.server.v1_8_R3.EntityIronGolem;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.MovingObjectPosition;
import net.minecraft.server.v1_8_R3.Packet;
import net.minecraft.server.v1_8_R3.PacketPlayOutAttachEntity;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntity;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving;
import net.minecraft.server.v1_8_R3.Vec3D;
public class GolemExplosiveBlock extends BossAbility<GolemCreature, IronGolem>
{
private Map<Integer, Vector> _blocksLocation = new HashMap<>();
private Location _center;
private int _explosionsLeft;
private FallingBlock _fallingBlock;
private Map<Integer, Integer> _fallingBlocks = new HashMap<>();
private List<Item> _items = new ArrayList<>();
private int _strength;
private Player _target;
private int _tick;
public GolemExplosiveBlock(GolemCreature creature, int strength)
{
super(creature);
_strength = strength;
_center = getLocation().add(0, 3, 0);
_target = getTarget();
if (_target != null)
{
UtilEnt.CreatureLook(getEntity(), _target);
}
}
@Override
public boolean canMove()
{
return _fallingBlock != null;
}
private int clamp(int value)
{
if (value < -127)
{
return -127;
}
if (value > 127)
{
return 127;
}
return value;
}
@Override
public Player getTarget()
{
HashMap<Player, Double> locs = new HashMap<Player, Double>();
for (Player player : UtilServer.getPlayers())
{
double dist = player.getLocation().distance(_center);
if (dist < 30)
{
double score = (dist > 10 ? 30 - dist : 10);
for (Player p : UtilServer.getPlayers())
{
if (player.getLocation().distance(p.getLocation()) < 4)
{
score += 7;
}
}
if (player.hasLineOfSight(getEntity()))
{
score += 10;
}
locs.put(player, score);
}
}
Player lowest = null;
for (Entry<Player, Double> entry : locs.entrySet())
{
if (lowest == null || locs.get(lowest) > locs.get(entry.getKey()))
{
lowest = entry.getKey();
}
}
return lowest;
}
@Override
public boolean hasFinished()
{
return _target == null || (_fallingBlock != null && !_fallingBlock.isValid() && _explosionsLeft == 0);
}
@EventHandler
public void onDamage(CustomDamageEvent event)
{
if (event.GetDamageeEntity().equals(getEntity()))
{
if (_tick >= 40 + (40 * _strength) && _tick <= 50 + (40 * _strength))
{
event.SetCancelled("Iron Wizard charging bomb");
}
event.SetKnockback(false);
}
}
public void onExplode(final Location loc)
{
for (int i = 0; i < _strength * 2; i++)
{
if (i == 0)
{
onSubExplode(loc);
}
else
{
_explosionsLeft++;
Bukkit.getScheduler().scheduleSyncDelayedTask(UtilServer.getPlugin(), () ->
{
onSubExplode(loc);
_explosionsLeft--;
}, 2 * i);
}
}
}
public void onSubExplode(Location loc)
{
for (int i = 0; i < 2; i++)
{
Location l = loc.clone().add(UtilMath.r(_strength * 4) - (_strength * 2), UtilMath.r(_strength * 2),
UtilMath.r(_strength * 4) - (_strength * 2));
UtilParticle.PlayParticle(ParticleType.LARGE_EXPLODE, l, _strength * 3, 1, _strength * 3, 0, _strength * 4,
ViewDist.LONG, UtilServer.getPlayers());
}
}
@SuppressWarnings("deprecation")
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
if (_fallingBlock == null)
{
return;
}
if (_fallingBlock.isDead()
|| !_fallingBlock.isValid()
|| _fallingBlock.getTicksLived() > 400
|| !_fallingBlock.getWorld().isChunkLoaded(_fallingBlock.getLocation().getBlockX() >> 4,
_fallingBlock.getLocation().getBlockZ() >> 4))
{
Block block = _fallingBlock.getLocation().getBlock();
block.setTypeIdAndData(0, (byte) 0, true);
_fallingBlock.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, _fallingBlock.getBlockId());
// Expire
if (_fallingBlock.getTicksLived() > 400
|| !_fallingBlock.getWorld().isChunkLoaded(_fallingBlock.getLocation().getBlockX() >> 4,
_fallingBlock.getLocation().getBlockZ() >> 4))
{
_fallingBlock.remove();
return;
}
_fallingBlock.remove();
return;
}
double distanceToEntity = 0.0D;
LivingEntity victim = null;
net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) _fallingBlock).getHandle();
Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false);
vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
if (finalObjectPosition != null)
{
vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c);
}
for (Object entity : ((CraftWorld) _fallingBlock.getWorld()).getHandle().getEntities(
((CraftEntity) _fallingBlock).getHandle(),
((CraftEntity) _fallingBlock).getHandle().getBoundingBox().a(((CraftEntity) _fallingBlock).getHandle().motX,
((CraftEntity) _fallingBlock).getHandle().motY, ((CraftEntity) _fallingBlock).getHandle().motZ).grow(2,
2, 2)))
{
Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity();
if (bukkitEntity instanceof LivingEntity)
{
LivingEntity ent = (LivingEntity) bukkitEntity;
// Avoid Self
if (ent.equals(getEntity()))
{
continue;
}
// Creative or Spec
if (ent instanceof Player)
{
if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent))
{
continue;
}
}
// float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f);
AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F);
MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1);
if (entityCollisionPosition != null)
{
double d1 = vec3d.distanceSquared(entityCollisionPosition.pos);
if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D))
{
victim = ent;
distanceToEntity = d1;
}
}
}
}
if (victim != null)
{
onExplode(victim.getEyeLocation());
_fallingBlock.remove();
}
else if (finalObjectPosition != null)
{
Block block = _fallingBlock.getWorld()
.getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c));
if (!UtilBlock.airFoliage(block) && !block.isLiquid())
{
nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX));
nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY));
nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ));
float f2 = MathHelper.sqrt(nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ
* nmsEntity.motZ);
nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D;
nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D;
nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D;
onExplode(block.getLocation().add(0.5, 0.5, 0.5));
_fallingBlock.remove();
}
}
else
{
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0),
_fallingBlock.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL,
UtilServer.getPlayers());
}
}
@Override
public void setFinished()
{
int[] ids = new int[_fallingBlocks.size() * 2];
int index = 0;
for (Entry<Integer, Integer> entry : _fallingBlocks.entrySet())
{
ids[index] = entry.getKey();
ids[index + 1] = entry.getValue();
index += 2;
}
PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ids);
for (Player player : Bukkit.getOnlinePlayers())
{
UtilPlayer.sendPacket(player, packet);
}
for (Item item : _items)
{
item.remove();
}
if (_fallingBlock != null)
{
_fallingBlock.remove();
}
}
@SuppressWarnings("deprecation")
@Override
public void tick()
{
IronGolem entity = getEntity();
Iterator<Item> itel = _items.iterator();
while (itel.hasNext())
{
Item item = itel.next();
Vector vec = item.getVelocity();
Location loc = item.getLocation();
if (item.getTicksLived() > 100 || vec.getY() <= 0 || loc.distance(_center) > loc.add(vec).distance(_center)
|| UtilEnt.isGrounded(item))
{
itel.remove();
}
}
// This spawns a floating block
if (_tick >= 20 && _tick % 60 == 0 && _fallingBlocks.size() < _strength)
{
int id = UtilEnt.getNewEntityId();
int id2 = UtilEnt.getNewEntityId();
_fallingBlocks.put(id, id2);
_blocksLocation.put(id, _center.toVector());
Packet<?>[] packets = new Packet[3];
PacketPlayOutSpawnEntityLiving packet1 = new PacketPlayOutSpawnEntityLiving();
DataWatcher watcher = new DataWatcher(null);
watcher.a(0, (byte) 32, net.minecraft.server.v1_8_R3.Entity.META_ENTITYDATA, (byte) 0);
watcher.a(1, 0, net.minecraft.server.v1_8_R3.Entity.META_AIR, 0);
packet1.a = id;
packet1.b = EntityType.SILVERFISH.getTypeId();
packet1.c = (int) Math.floor(_center.getX() * 32);
packet1.d = (int) Math.floor((_center.getY() - 0.125) * 32);
packet1.e = (int) Math.floor(_center.getZ() * 32);
packet1.l = watcher;
packets[0] = packet1;
PacketPlayOutSpawnEntity packet2 = new PacketPlayOutSpawnEntity(((CraftEntity) entity).getHandle(), 70,
Material.DIRT.getId());
packet2.a = id2;
packet2.b = (int) Math.floor(_center.getX() * 32);
packet2.c = (int) Math.floor(_center.getY() * 32);
packet2.d = (int) Math.floor(_center.getZ() * 32);
packets[1] = packet2;
PacketPlayOutAttachEntity packet3 = new PacketPlayOutAttachEntity();
packet3.b = id2;
packet3.c = id;
packets[2] = packet3;
for (Player player : UtilServer.getPlayers())
{
if (player.getLocation().distance(_center) < 80)
{
UtilPlayer.sendPacket(player, packets);
}
}
}
// This spawns a item that flies above the golem's head and disappears
if (UtilMath.r(6) == 0 && _tick < 40 + (_strength * 40))
{
double angle = ((2 * Math.PI) / 30) * UtilMath.r(30);
double x = 5 * Math.cos(angle);
double z = 5 * Math.sin(angle);
Location loc = _center.clone().add(x, -3, z);
Material mat = null;
switch (UtilMath.r(3))
{
case 0:
mat = Material.DIRT;
break;
case 1:
mat = Material.STONE;
break;
case 2:
mat = Material.COBBLESTONE;
break;
default:
break;
}
Item item = loc.getWorld().dropItem(loc, new ItemBuilder(mat).setTitle(System.currentTimeMillis() + "").build());
item.setPickupDelay(999999);
Vector vec = UtilAlg.getTrajectory(_center, item.getLocation());
vec.normalize().multiply(5);
item.setVelocity(vec);
// TODO Fix velocity
_items.add(item);
}
// 10 being when items no longer fly in, 0 being when its shot.
int ticksTillFired = (60 + (40 * _strength)) - _tick;
if (ticksTillFired > 20)
{
int strength = (int) Math.floor(_tick / 20D);
int nine = 8 - strength;
if (_tick % nine == 0)
{
_center.getWorld().playSound(_center, Sound.DIG_GRASS, strength + 1, 1F);
}
}
else if (ticksTillFired < 0)
{
if (_tick % 3 == 0)
{
_center.getWorld().playSound(_fallingBlock.getLocation(), Sound.WOOD_CLICK, _strength + 1, 0.4F);
}
}
// The location the falling blocks need to stick by
Vector blockCenter = _center.toVector();
if (ticksTillFired >= 0 && ticksTillFired <= 20)
{
Vector vec = entity.getLocation().add(entity.getLocation().getDirection().setY(0).normalize().multiply(1.2))
.add(0, 1, 0).toVector();
blockCenter = UtilAlg.getTrajectory(_center.toVector(), blockCenter);
vec.multiply(ticksTillFired / 10D);
_center.getWorld().playSound(_center, Sound.DIG_SNOW, _strength + 1, 0);
}
else if (_fallingBlock != null)
{
blockCenter = _fallingBlock.getLocation().add(0, 0.5, 0).toVector();
}
// Move the fake floating blocks
for (Entry<Integer, Integer> entry : _fallingBlocks.entrySet())
{
int id = entry.getKey();
Vector vec = _blocksLocation.get(id);
int x = clamp((int) ((blockCenter.getX() - vec.getX()) * 32) + (UtilMath.r(8) - 4));
int y = clamp((int) ((blockCenter.getY() - vec.getY()) * 32) + (UtilMath.r(8) - 4));
int z = clamp((int) ((blockCenter.getZ() - vec.getZ()) * 32) + (UtilMath.r(8) - 4));
vec.add(new Vector(x, y, z));
PacketPlayOutEntity.PacketPlayOutRelEntityMove packet = new PacketPlayOutEntity.PacketPlayOutRelEntityMove();
packet.a = id;
packet.b = (byte) x;
packet.c = (byte) y;
packet.d = (byte) z;
for (Player player : UtilServer.getPlayers())
{
if (player.getLocation().distance(_center) < 70)
{
UtilPlayer.sendPacket(player, packet);
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0),
vec.toLocation(_center.getWorld()), 0.7F, 0.7F, 0.7F, 0, 11, ViewDist.NORMAL, player);
}
}
}
if (ticksTillFired == 0)
{
int id = _fallingBlocks.keySet().iterator().next();
PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(new int[]
{
id, _fallingBlocks.get(id)
});
for (Player player : Bukkit.getOnlinePlayers())
{
UtilPlayer.sendPacket(player, packet);
}
_fallingBlocks.remove(id);
_fallingBlock = _center.getWorld().spawnFallingBlock(_blocksLocation.get(id).toLocation(_center.getWorld()),
Material.STONE, (byte) 0);
Vector vec1 = _fallingBlock.getLocation().toVector();
Vector vec2 = _target.getLocation().toVector();
Vector vec = UtilAlg.calculateVelocity(vec1, vec2, (int) (vec1.distanceSquared(vec2) / 4));
_fallingBlock.setVelocity(vec);
EntityIronGolem golem = ((CraftIronGolem) entity).getHandle();
golem.world.broadcastEntityEffect(golem, (byte) 4);
}
_tick++;
}
@Override
public boolean inProgress()
{
return false;
}
}

View File

@ -0,0 +1,163 @@
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Sound;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.updater.UpdateType;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
public class GolemIronHook extends BossAbility<GolemCreature, IronGolem>
{
private static final Integer MAX_TARGETS = 3;
private boolean _shot, _complete;
private List<Item> _hooks = new ArrayList<>();
public GolemIronHook(GolemCreature creature)
{
super(creature);
_shot = false;
_complete = false;
}
private int getPosition(Player toAdd, List<Player> ordered, Map<Player, Double> distances)
{
int position = ordered.size();
int index = 0;
for (Player player : ordered)
{
if (distances.get(player) < distances.get(toAdd))
{
position = index;
}
index++;
}
return position;
}
private void shoot()
{
IronGolem wizard = getBoss().getEntity();
List<Player> selections = new LinkedList<>();
List<Player> targeted = new ArrayList<>();
Map<Player, Double> near = UtilPlayer.getInRadius(wizard.getLocation(), 40D);
for (Player nearby : near.keySet())
{
if (nearby.getGameMode() == GameMode.CREATIVE || nearby.getGameMode() == GameMode.SPECTATOR)
{
continue;
}
if (selections.isEmpty())
{
selections.add(nearby);
}
else
{
selections.add(getPosition(nearby, selections, near), nearby);
}
}
for (int i = 0; i < MAX_TARGETS; i++)
{
if (i < selections.size())
{
targeted.add(selections.get(i));
}
}
if (targeted.isEmpty())
{
_complete = true;
setFinished();
return;
}
for (Player target : targeted)
{
Item item = wizard.getWorld().dropItem(wizard.getEyeLocation().add(UtilAlg.getTrajectory(wizard, target)), ItemStackFactory.Instance.CreateStack(131));
UtilAction.velocity(item, UtilAlg.getTrajectory(wizard, target).normalize(),
2, false, 0, 0.2, 20, false);
getBoss().getEvent().getProjectileManager().AddThrow(item, getBoss().getEntity(), new IronHook(getBoss().getEvent()), -1, true, true, true, true,
Sound.FIRE_IGNITE, 1.4f, 0.8f, ParticleType.CRIT, UpdateType.TICK, 1f);
item.getWorld().playSound(item.getLocation(), Sound.IRONGOLEM_THROW, 2f, 0.8f);
_hooks.add(item);
}
}
@Override
public int getCooldown()
{
return 10;
}
@Override
public boolean canMove()
{
return true;
}
@Override
public boolean inProgress()
{
return false;
}
@Override
public boolean hasFinished()
{
return _complete;
}
@Override
public void setFinished()
{
for (Item hook : _hooks)
{
if (!hook.isDead() && hook.isValid())
{
getBoss().getEvent().getProjectileManager().deleteThrown(hook);
hook.remove();
}
}
_hooks.clear();
}
@Override
public void tick()
{
if (_shot)
{
return;
}
shoot();
_shot = true;
Bukkit.getScheduler().runTaskLater(UtilServer.getPlugin(), () ->
{
_complete = true;
setFinished();
}, 2 * 20);
}
}

View File

@ -0,0 +1,90 @@
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
import org.bukkit.Sound;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilPlayer;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
import net.minecraft.server.v1_8_R3.EntityIronGolem;
public class GolemMeleeAttack extends BossAbility<GolemCreature, IronGolem>
{
private boolean _attacked;
public GolemMeleeAttack(GolemCreature creature)
{
super(creature);
}
@Override
public boolean canMove()
{
return true;
}
@Override
public int getCooldown()
{
return 20;
}
@Override
public Player getTarget()
{
return getTarget(4);
}
@Override
public boolean hasFinished()
{
return _attacked;
}
@Override
public void setFinished() {}
@Override
public void tick()
{
_attacked = true;
for (Player target : UtilPlayer.getNearby(getLocation(), 4, true))
{
if (target.getVelocity().length() > 0.5)
{
continue;
}
UtilEnt.CreatureLook(getEntity(), target);
getBoss().getEvent().getDamageManager().NewDamageEvent(target, getEntity(), null, DamageCause.ENTITY_ATTACK,
10 * getBoss().getDifficulty(), false, true, false, "Iron Wizard Melee Attack", "Iron Wizard Melee Attack");
Vector vec = getLocation().getDirection();
vec.setY(0).normalize().setY(0.5).multiply(2.4);
UtilAction.velocity(target, vec);
getBoss().getEvent().getCondition().Factory().Falling("Iron Wizard Throw", target, getEntity(), 3, false, false);
target.getWorld().playSound(target.getLocation(), Sound.IRONGOLEM_THROW, 3, 0.9F);
EntityIronGolem golem = ((CraftIronGolem) getEntity()).getHandle();
golem.world.broadcastEntityEffect(golem, (byte) 4);
}
}
@Override
public boolean inProgress()
{
return _attacked;
}
}

View File

@ -0,0 +1,238 @@
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem;
import org.bukkit.entity.Damageable;
import org.bukkit.entity.Entity;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilPlayer;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
import net.minecraft.server.v1_8_R3.EntityIronGolem;
/**
* Rumble is where the golem picks a target then starts playing a animation for a second where its obviously preparing to use it.
* Copy this from Wizards
*/
public class GolemRumble extends BossAbility<GolemCreature, IronGolem>
{
private Location _loc;
private int _ticks;
private int _travelled;
private Vector _vec;
private int _width = 1;
private Location _target;
public GolemRumble(GolemCreature creature)
{
super(creature);
Player target = getTarget();
if (target != null)
{
_target = target.getLocation();
UtilEnt.CreatureLook(getEntity(), _target);
}
}
@Override
public boolean canMove()
{
return _ticks >= 20;
}
@Override
public boolean hasFinished()
{
return _travelled > 35;
}
@Override
public void setFinished() {}
@SuppressWarnings("deprecation")
@Override
public void tick()
{
if (_ticks++ < 14)
{
IronGolem entity = getEntity();
EntityIronGolem golem = ((CraftIronGolem) entity).getHandle();
golem.world.broadcastEntityEffect(golem, (byte) 4);
if (_ticks % 2 == 0)
{
entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 3, 2F);
}
}
else if (_ticks % 2 == 0)
{
int oldWidth = _width;
if ((_width <= 3 || _ticks % 4 == 0) && _width <= 6)
{
_width++;
}
Location newLoc;
boolean validBlock = false;
List<Block> current = new ArrayList<>();
if (_vec == null)
{
_vec = _target.subtract(getLocation()).toVector().setY(0).normalize();
_loc = getLocation().subtract(0, 1, 0).getBlock().getLocation().add(0, 0.99, 0);
newLoc = _loc;
current.add(_loc.getBlock());
validBlock = true;
}
else
{ // Move rumble
newLoc = _loc.clone().add(_vec);
// Check if the rumble needs to go up or drop a block or two
for (int y : new int[] {0, 1, -1})
{
for (int a = 1; a <= 2; a++)
{
Block b = newLoc.clone().add(_vec.clone().multiply(a)).getBlock().getRelative(0, y, 0);
if (UtilBlock.solid(b) && !UtilBlock.solid(b.getRelative(0, 1, 0)))
{
validBlock = true;
newLoc.add(0, y, 0);
break;
}
}
if (validBlock)
{
break;
}
}
for (int width = -_width; width <= _width; width++)
{
if (Math.abs(width) <= oldWidth)
{
Block b = _loc.clone().add(UtilAlg.getRight(_vec).multiply(width)).getBlock();
if (!current.contains(b))
{
current.add(b);
}
}
if (validBlock)
{
Block b = newLoc.clone().add(UtilAlg.getRight(_vec).multiply(width)).getBlock();
if (!current.contains(b))
{
current.add(b);
b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getTypeId());
}
}
}
}
UtilEnt.CreatureLook(getEntity(), _loc);
for (Entity entity : getEntity().getWorld().getEntities())
{
if (entity instanceof Damageable && !UtilPlayer.isSpectator(entity) && entity != getEntity())
{
Block b = entity.getLocation().getBlock();
boolean canDamage = false;
for (int y = -1; y <= 0; y++)
{
if (current.contains(b.getRelative(0, y, 0)))
{
canDamage = true;
break;
}
}
if (!canDamage)
{
continue;
}
if (canDamage(entity))
{
getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) entity, getEntity(), null,
DamageCause.CONTACT, 8 * getBoss().getDifficulty(), false, true, false, "Iron Wizard Rumble",
"Iron Wizard Rumble");
}
UtilAction.velocity(entity, _vec.clone(), 1.5, true, 0, 0.2, 1, true);
if (entity instanceof Player)
{
getBoss().getEvent().getCondition().Factory().Slow("Rumble", (LivingEntity) entity, getEntity(), 3, 1,
false, false, false, false);
}
}
}
if (_travelled++ > 35 || !validBlock)
{
_travelled = 100;
}
_loc = newLoc;
}
}
public Player getTarget()
{
Player target = null;
double dist = 0;
for (Player player : UtilPlayer.getNearby(getLocation(), 30, true))
{
if (!player.hasLineOfSight(getEntity()))
{
continue;
}
double d = player.getLocation().distance(getLocation());
if (d > 2 && (target == null || dist > d))
{
target = player;
dist = d;
}
}
return target;
}
@Override
public boolean inProgress()
{
return _ticks < 14;
}
}

View File

@ -0,0 +1,367 @@
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.inventory.InventoryPickupItemEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import mineplex.core.common.Pair;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
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.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
import net.minecraft.server.v1_8_R3.EntityIronGolem;
public class GolemRupture extends BossAbility<GolemCreature, IronGolem>
{
private List<Pair<Location, Location>> _ruptures = new ArrayList<>();
private Map<Location, Long> _ruptureTime = new HashMap<>();
private List<String> _targetted = new ArrayList<>();
private int _rupturesLeft;
private int _tick;
private List<Item> _items = new ArrayList<>();
private int _ticksFinished;
public GolemRupture(GolemCreature creature)
{
super(creature);
if (creature.getHealthPercent() > 0.75)
{
_rupturesLeft = 2;
}
else if (creature.getHealthPercent() > 0.5)
{
_rupturesLeft = 5;
}
else
{
_rupturesLeft = 10;
}
}
@Override
public boolean canMove()
{
return false;
}
@EventHandler
public void HopperPickup(InventoryPickupItemEvent event)
{
if (_items.contains(event.getItem()))
{
event.setCancelled(true);
}
}
@SuppressWarnings("deprecation")
@EventHandler
public void ItemDestroy(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
if (_items.isEmpty())
{
return;
}
Iterator<Item> itemIterator = _items.iterator();
while (itemIterator.hasNext())
{
Item item = itemIterator.next();
if (item.isDead() || !item.isValid())
{
item.remove();
itemIterator.remove();
}
else if (UtilEnt.isGrounded(item) || item.getTicksLived() > 60)
{
item.getWorld().playEffect(item.getLocation(), Effect.STEP_SOUND, item.getItemStack().getTypeId());
item.remove();
itemIterator.remove();
}
}
}
@Override
public boolean inProgress()
{
return false;
}
@Override
public boolean hasFinished()
{
return _rupturesLeft <= 0 && _ruptures.isEmpty() && --_ticksFinished <= 0;
}
@Override
public void setFinished()
{
for (Item item : _items)
{
item.remove();
}
}
@Override
public void tick()
{
Iterator<Pair<Location, Location>> itel = _ruptures.iterator();
while (itel.hasNext())
{
Pair<Location, Location> pair = itel.next();
if (pair.getLeft().distance(pair.getRight()) > 0)
{
Vector vec = pair.getRight().toVector().subtract(pair.getLeft().toVector());
if (vec.length() > 1)
{
vec = vec.normalize();
}
pair.getLeft().add(vec);
}
if (pair.getLeft().distance(pair.getRight()) < 0.1)
{
if (!_ruptureTime.containsKey(pair.getLeft()))
{
_ruptureTime.put(pair.getLeft(), System.currentTimeMillis());
}
else if (UtilTime.elapsed(_ruptureTime.get(pair.getLeft()), 150))
{
itel.remove();
explodeRupture(pair.getLeft());
}
}
}
if (_tick % 10 == 0 && _rupturesLeft > 0)
{
_rupturesLeft--;
Location loc = getLocation().add(UtilMath.random.nextFloat() - 0.5, 0, UtilMath.random.nextFloat() - 0.5);
loc.setY(loc.getBlockY());
for (int y = 0; y > -3; y--)
{
if (!UtilBlock.airFoliage(loc.getBlock().getRelative(0, y, 0)))
{
loc.setY(loc.getY() + y);
break;
}
}
Player player = getTarget();
if (player != null)
{
_targetted.add(player.getName());
Location target = player.getLocation();
target.setY(loc.getY());
_ruptures.add(Pair.create(loc, target));
UtilEnt.CreatureLook(getEntity(), player.getLocation());
EntityIronGolem golem = ((CraftIronGolem) getEntity()).getHandle();
golem.world.broadcastEntityEffect(golem, (byte) 4);
}
else
{
_rupturesLeft = 0;
}
}
for (Pair<Location, Location> pair : _ruptures)
{
pair.getLeft().getWorld().playSound(pair.getLeft(), Sound.DIG_GRAVEL, 2.5F, 0.9F);
{
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.DIRT, 0),
pair.getLeft().clone().add(0, 1.1, 0), 1F, 0, 1F, 0, 70, ViewDist.NORMAL, UtilServer.getPlayers());
}
}
_tick++;
}
@Override
public Player getTarget()
{
Player target = null;
double dist = 0;
for (Player player : UtilPlayer.getNearby(getLocation(), 30, true))
{
if (!player.hasLineOfSight(getEntity()))
{
continue;
}
if (_targetted.contains(player.getName()))
{
continue;
}
double d = player.getLocation().distance(getLocation());
if (d < 7)
{
continue;
}
boolean valid = true;
for (Pair<Location, Location> loc : _ruptures)
{
if (loc.getRight().distance(player.getLocation()) < 1.5)
{
valid = false;
break;
}
}
if (!valid)
{
continue;
}
if (target == null || dist > d)
{
target = player;
dist = d;
}
}
return target;
}
@SuppressWarnings("deprecation")
private void explodeRupture(Location loc)
{
loc.add(0, 1.1, 0);
loc.setX(loc.getBlockX() + 0.5);
loc.setZ(loc.getBlockZ() + 0.5);
// Fling
HashMap<LivingEntity, Double> targets = UtilEnt.getInRadius(loc, 3.5);
for (LivingEntity cur : targets.keySet())
{
// Velocity
UtilAction.velocity(cur,
UtilAlg.getTrajectory2d(loc.toVector().add(new Vector(0.5, 0, 0.5)), cur.getLocation().toVector()),
0.8 + 0.8 * targets.get(cur), true, 0, 0.4 + 1.0 * targets.get(cur), 1.4, true);
// Condition
getBoss().getEvent().getCondition().Factory().Falling("Rupture", cur, getEntity(), 10, false, true);
// Damage Event
getBoss().getEvent().getDamageManager().NewDamageEvent(cur, getEntity(), null, DamageCause.CUSTOM,
8 * getBoss().getDifficulty(), false, true, false, "Iron Wizard", "Rupture");
}
List<Block> blocks = new ArrayList<>();
for (int x = -3; x <= 3; x++)
{
for (int z = -3; z <= 3; z++)
{
for (int y = 0; y <= 1; y++)
{
for (int i = 0; i < 2; i++)
{
if (Math.sqrt(x * x + z * z + y * y) <= 3)
{
blocks.add(loc.clone().add(x, y, z).getBlock());
}
}
}
}
}
Collections.shuffle(blocks);
// Blocks
int done = 0;
Iterator<Block> itel = blocks.iterator();
while (done < 30 && itel.hasNext())
{
Block block = itel.next();
Vector vec = new Vector(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5).normalize();
if (!UtilBlock.airFoliage(block))
{
continue;
}
// Add Directional
vec.add(UtilAlg.getTrajectory(loc.getBlock().getLocation(), block.getLocation().add(0.5, 0, 0.5)));
// Add Up
vec.add(new Vector(0, 1.6, 0));
vec.normalize();
// Scale
vec.multiply(0.1 + 0.3 * Math.random() + 0.6);
// Block!
Item item = loc.getWorld().dropItem(block.getLocation().add(0.5, 0, 0.5), new ItemStack(Material.DIRT, 0));
item.setVelocity(vec);
item.setPickupDelay(50000);
_items.add(item);
// Effect
loc.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, Material.STONE.getId());
done++;
}
_ticksFinished = 20;
}
}

View File

@ -0,0 +1,271 @@
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.inventory.InventoryPickupItemEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
public class GolemSlam extends BossAbility<GolemCreature, IronGolem>
{
private List<Item> _items = new ArrayList<>();
private int _ticksFinished;
private int _stage;
private Vector _target;
private int _ticksJumped;
public GolemSlam(GolemCreature creature)
{
super(creature);
Player target = getTarget();
if (target != null)
{
_target = UtilAlg.calculateVelocity(getLocation().toVector(),
target.getLocation().toVector().setY(getLocation().getY()), 2, getEntity());
}
}
@Override
public boolean canMove()
{
return !UtilEnt.isGrounded(getEntity()) && _stage == 1;
}
@Override
public boolean hasFinished()
{
return _stage == 2 && --_ticksFinished <= 0;
}
@Override
public void setFinished()
{
for (Item item : _items)
{
item.remove();
}
}
@Override
public void tick()
{
Entity entity = getEntity();
if (_stage == 0)
{
UtilEnt.CreatureLook(getEntity(), getLocation().add(_target));
entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 4, 0);
entity.setVelocity(_target);
_stage++;
}
else if (_stage == 1)
{
_ticksJumped++;
if (_ticksJumped > 4 && getLocation().subtract(0, 0.2, 0).getBlock().getType() != Material.AIR)
{
explodeRupture(getLocation());
_stage = 2;
}
}
}
@EventHandler
public void HopperPickup(InventoryPickupItemEvent event)
{
if (_items.contains(event.getItem()))
{
event.setCancelled(true);
}
}
@SuppressWarnings("deprecation")
@EventHandler
public void ItemDestroy(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
if (_items.isEmpty())
{
return;
}
Iterator<Item> itemIterator = _items.iterator();
while (itemIterator.hasNext())
{
Item item = itemIterator.next();
if (item.isDead() || !item.isValid())
{
item.remove();
itemIterator.remove();
}
else if (UtilEnt.isGrounded(item) || item.getTicksLived() > 60)
{
item.getWorld().playEffect(item.getLocation(), Effect.STEP_SOUND, item.getItemStack().getTypeId());
item.remove();
itemIterator.remove();
}
}
}
@Override
public boolean inProgress()
{
return true;
}
@Override
public Player getTarget()
{
Player target = null;
double dist = 0;
for (Player player : UtilPlayer.getNearby(getLocation(), 30, true))
{
if (!player.hasLineOfSight(getEntity()))
{
continue;
}
double d = player.getLocation().distance(getLocation());
if (d < 10)
{
continue;
}
if (target == null || dist > d)
{
target = player;
dist = d;
}
}
return target;
}
@SuppressWarnings("deprecation")
private void explodeRupture(Location loc)
{
loc.add(0, 1.1, 0);
loc.setX(loc.getBlockX() + 0.5);
loc.setZ(loc.getBlockZ() + 0.5);
// Fling
Map<LivingEntity, Double> targets = UtilEnt.getInRadius(loc, 3.5);
for (LivingEntity cur : targets.keySet())
{
if (cur.equals(getEntity()))
{
continue;
}
// Velocity
UtilAction.velocity(cur,
UtilAlg.getTrajectory2d(loc.toVector().add(new Vector(0.5, 0, 0.5)), cur.getLocation().toVector()),
0.8 + 0.8 * targets.get(cur), true, 0, 0.4 + 1.0 * targets.get(cur), 1.4, true);
// Condition
getBoss().getEvent().getCondition().Factory().Falling("Rupture", cur, getEntity(), 10, false, true);
// Damage Event
getBoss().getEvent().getDamageManager().NewDamageEvent(cur, getEntity(), null, DamageCause.CUSTOM,
8 * getBoss().getDifficulty(), false, true, false, "Iron Wizard", "Rupture");
}
List<Block> blocks = new ArrayList<Block>();
for (int x = -3; x <= 3; x++)
{
for (int z = -3; z <= 3; z++)
{
for (int y = 0; y <= 1; y++)
{
for (int i = 0; i < 2; i++)
{
if (Math.sqrt(x * x + z * z + y * y) <= 3)
{
blocks.add(loc.clone().add(x, y, z).getBlock());
}
}
}
}
}
Collections.shuffle(blocks);
// Blocks
int done = 0;
Iterator<Block> itel = blocks.iterator();
while (done < 30 && itel.hasNext())
{
Block block = itel.next();
Vector vec = new Vector(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5).normalize();
if (!UtilBlock.airFoliage(block))
continue;
// Add Directional
vec.add(UtilAlg.getTrajectory(loc.getBlock().getLocation(), block.getLocation().add(0.5, 0, 0.5)));
// Add Up
vec.add(new Vector(0, 1.6, 0));
vec.normalize();
// Scale
vec.multiply(0.1 + 0.3 * Math.random() + 0.6);
// Block!
Item item = loc.getWorld().dropItem(block.getLocation().add(0.5, 0, 0.5), new ItemStack(Material.DIRT, 0));
item.setVelocity(vec);
item.setPickupDelay(50000);
_items.add(item);
// Effect
loc.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, Material.DIRT.getId());
done++;
}
_ticksFinished = 20;
}
}

View File

@ -0,0 +1,104 @@
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.bukkit.Sound;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
public class GolemSpike extends BossAbility<GolemCreature, IronGolem>
{
private static final int SPIKE_HEIGHT = 2;
private static final long ATTACK_DURATION = 1000 + (500 * SPIKE_HEIGHT * 2);
private static final long SPIKE_REMAIN = 1000;
private long _start;
private List<GroundSpike> _spikes;
public GolemSpike(GolemCreature creature)
{
super(creature);
_start = System.currentTimeMillis();
_spikes = new ArrayList<>();
}
@Override
public int getCooldown()
{
return 15;
}
@Override
public boolean canMove()
{
return true;
}
@Override
public boolean inProgress()
{
return true;
}
@Override
public boolean hasFinished()
{
return UtilTime.elapsed(_start, ATTACK_DURATION) && _spikes.isEmpty();
}
@Override
public void setFinished()
{
_start = System.currentTimeMillis() - ATTACK_DURATION;
for (GroundSpike spike : _spikes)
{
spike.finish();
}
_spikes.clear();
}
@Override
public void tick()
{
if (_spikes.isEmpty())
{
for (Player player : UtilPlayer.getInRadius(getLocation(), 20).keySet())
{
if (UtilEnt.isGrounded(player))
{
player.playSound(player.getLocation(), Sound.STEP_STONE, 0.2f, 0.2f);
getBoss().getEvent().getDamageManager().NewDamageEvent(player, getBoss().getEntity(), null, DamageCause.CUSTOM, 5 * getBoss().getDifficulty(), false, false, false, getBoss().getEntity().getName(), "Stone Spike");
player.teleport(player.getLocation().add(0, SPIKE_HEIGHT, 0));
UtilAction.velocity(player, player.getLocation().toVector().normalize().add(new Vector(0, 0.02, 0)).normalize());
_spikes.add(new GroundSpike(player.getLocation().getBlock(), player.getLocation().getBlock().getRelative(0, -1, 0).getType(), new Random().nextInt(SPIKE_HEIGHT) + 2, SPIKE_REMAIN));
}
}
}
else
{
List<GroundSpike> toRemove = new ArrayList<>();
for (GroundSpike spike : _spikes)
{
spike.tick();
if (spike.isFinished())
{
toRemove.add(spike);
}
}
for (GroundSpike remove : toRemove)
{
_spikes.remove(remove);
}
}
}
}

View File

@ -0,0 +1,419 @@
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.bukkit.Effect;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.entity.Entity;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilShapes;
import mineplex.core.common.util.UtilTime;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.MovingObjectPosition;
import net.minecraft.server.v1_8_R3.Vec3D;
public class GolemWallExplode extends BossAbility<GolemCreature, IronGolem>
{
private Map<BlockFace, List<Block>> _blockWalls = new HashMap<>();
private List<String> _dontTarget = new ArrayList<>();
private List<FallingBlock> _fallingBlocks = new ArrayList<>();
private int _maxTimes = UtilMath.r(2) + 1;
private int _tick;
private int _timesDone;
private Map<BlockFace, Long> _wallTimers = new HashMap<>();
public GolemWallExplode(GolemCreature creature)
{
super(creature);
}
@Override
public boolean canMove()
{
return true;
}
@Override
public int getCooldown()
{
return 20;
}
private float getMod(int div)
{
return UtilMath.random.nextFloat() / div;
}
@Override
public Player getTarget()
{
for (Player player : UtilPlayer.getNearby(getLocation(), 15, true))
{
if (_dontTarget.contains(player.getName()))
{
continue;
}
if (player.getLocation().distance(getLocation()) <= 4)
{
continue;
}
return player;
}
return null;
}
@Override
public boolean hasFinished()
{
return _wallTimers.isEmpty() && _fallingBlocks.isEmpty() && _timesDone >= _maxTimes;
}
@SuppressWarnings("deprecation")
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
Iterator<FallingBlock> fallingIterator = _fallingBlocks.iterator();
while (fallingIterator.hasNext())
{
FallingBlock cur = fallingIterator.next();
if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
fallingIterator.remove();
Block block = cur.getLocation().getBlock();
block.setTypeIdAndData(0, (byte) 0, true);
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
// Expire
if (cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
cur.remove();
continue;
}
cur.remove();
continue;
}
double distanceToEntity = 0.0D;
LivingEntity victim = null;
net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) cur).getHandle();
Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY,
nmsEntity.locZ + nmsEntity.motZ);
MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false);
vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
if (finalObjectPosition != null)
{
vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c);
}
for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities(((CraftEntity) cur).getHandle(),
((CraftEntity) cur).getHandle().getBoundingBox().a(((CraftEntity) cur).getHandle().motX,
((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2)))
{
Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity();
if (bukkitEntity instanceof LivingEntity)
{
LivingEntity ent = (LivingEntity) bukkitEntity;
// Avoid Self
if (ent.equals(getEntity()))
continue;
// Creative or Spec
if (ent instanceof Player)
if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent))
continue;
// float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f);
AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F);
MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1);
if (entityCollisionPosition != null)
{
double d1 = vec3d.distanceSquared(entityCollisionPosition.pos);
if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D))
{
victim = ent;
distanceToEntity = d1;
}
}
}
}
if (victim != null)
{
cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId());
if (canDamage(victim))
{
getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) victim, getEntity(), null,
DamageCause.CONTACT, 10 * getBoss().getDifficulty(), true, true, false, "Iron Wizard Wall Explosion",
"Iron Wizard Wall Explosion");
}
cur.remove();
fallingIterator.remove();
Vector vec = cur.getVelocity();
UtilAction.velocity(victim, vec, 1.5, true, 0, 0.2, 1, true);
}
else if (finalObjectPosition != null)
{
Block block = cur.getWorld().getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c));
if (!UtilBlock.airFoliage(block) && !block.isLiquid())
{
nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX));
nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY));
nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ));
float f2 = MathHelper.sqrt(
nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ * nmsEntity.motZ);
nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D;
nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D;
nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D;
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
cur.remove();
fallingIterator.remove();
}
}
else
{
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0),
cur.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL,
UtilServer.getPlayers());
}
}
}
@Override
public void setFinished()
{
for (FallingBlock block : _fallingBlocks)
{
block.remove();
}
for (List<Block> list : _blockWalls.values())
{
for (Block b : list)
{
b.setType(Material.AIR);
}
}
}
@SuppressWarnings("deprecation")
@Override
public void tick()
{
if (_tick++ % 30 == 0 && _timesDone < _maxTimes)
{
_dontTarget.clear();
_timesDone++;
for (int i = 0; i < 10; i++)
{
Player target = getTarget();
if (target == null)
{
if (_dontTarget.isEmpty())
{
_timesDone = _maxTimes;
}
}
else
{
_dontTarget.add(target.getName());
UtilEnt.CreatureLook(getEntity(), target);
BlockFace face = UtilShapes.getFacing(getLocation().getYaw());
if (_wallTimers.containsKey(face))
{
continue;
}
ArrayList<Block> blocks = new ArrayList<Block>();
Location loc = getLocation().getBlock().getLocation().add(0.5, 0, 0.5);
int mul = (face.getModX() != 0 && face.getModZ() != 0) ? 2 : 3;
loc.add(face.getModX() * mul, 0, face.getModZ() * mul);
Block b = loc.getBlock();
BlockFace sideFace = UtilShapes.getSideBlockFaces(face, true)[0];
boolean invalid = false;
for (int mult = -3; mult <= 3; mult++)
{
Block block = b;
if (Math.abs(mult) < 3)
{
block = block.getRelative(face);
}
block = block.getRelative(sideFace, mult);
if (Math.abs(mult) == 3 && face.getModX() != 0 && face.getModZ() != 0)
{
block = block.getRelative(UtilShapes.getSideBlockFaces(face, false)[mult < 0 ? 0 : 1]);
}
if (!UtilAlg.HasSight(getLocation(), block.getLocation()))
{
invalid = true;
break;
}
Block under = block.getRelative(0, -1, 0);
if (!UtilBlock.solid(under))
{
continue;
}
for (int y = 0; y <= 1; y++)
{
block = block.getRelative(0, y, 0);
if (block.getType() != Material.AIR)
{
invalid = true;
break;
}
blocks.add(block);
}
if (invalid)
{
break;
}
}
if (invalid)
{
continue;
}
for (Block block : blocks)
{
block.setType(block.getWorld().getBlockAt(block.getX(), b.getY() - 1, block.getZ()).getType());
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getTypeId());
}
_blockWalls.put(face, blocks);
_wallTimers.put(face, System.currentTimeMillis());
break;
}
}
}
Iterator<Entry<BlockFace, List<Block>>> itel = _blockWalls.entrySet().iterator();
boolean doExplode = false;
while (itel.hasNext())
{
Entry<BlockFace, List<Block>> entry = itel.next();
BlockFace face = entry.getKey();
if (UtilTime.elapsed(_wallTimers.get(face), 1000))
{
doExplode = true;
itel.remove();
_wallTimers.remove(face);
for (Block b : entry.getValue())
{
FallingBlock block = getEntity().getWorld().spawnFallingBlock(b.getLocation().add(0.5, 0, 0.5), b.getType(),
(byte) 0);
block.setDropItem(false);
int index = entry.getValue().indexOf(b);
BlockFace f = index == 8 || index == 9 ? BlockFace.SELF
: UtilShapes.getSideBlockFaces(face, true)[index > 6 ? 0 : 1];
block.setVelocity(new Vector((face.getModX() * 0.6) + (f.getModX() * (0.05 + getMod(10))), 0.2 + getMod(15),
(face.getModZ() * 0.6) + (f.getModZ() * (0.05 + getMod(10)))));
_fallingBlocks.add(block);
b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getTypeId());
b.setType(Material.AIR);
}
}
}
if (doExplode)
{
onUpdate(new UpdateEvent(UpdateType.TICK));
}
}
@Override
public boolean inProgress()
{
return false;
}
}

View File

@ -0,0 +1,122 @@
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
import java.util.LinkedList;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
public class GroundSpike
{
private Block _initial;
private Material _type;
private int _max, _height;
private long _lastTick, _remain;
private LinkedList<Block> _blocks;
private boolean _shrinking, _finished;
public GroundSpike(Block first, Material type, int maxHeight, long remainDuration)
{
_initial = first;
_type = type;
_height = 0;
_max = maxHeight;
_remain = remainDuration;
_lastTick = System.currentTimeMillis();
_blocks = new LinkedList<>();
_shrinking = false;
_finished = false;
}
@SuppressWarnings("deprecation")
private void raise()
{
if ((_height + 1) < _max)
{
_lastTick = System.currentTimeMillis();
Block b = _initial.getRelative(0, _height, 0);
for (Player player : UtilServer.getPlayers())
{
player.sendBlockChange(b.getLocation(), _type, (byte)0);
}
_blocks.add(b);
_height++;
}
else
{
if (UtilTime.elapsed(_lastTick, _remain))
{
_shrinking = true;
lower();
}
}
}
@SuppressWarnings("deprecation")
private void lower()
{
_height = Math.min(_blocks.size() - 1, _height);
if ((_height - 1) >= 0)
{
_lastTick = System.currentTimeMillis();
for (Player player : UtilServer.getPlayers())
{
player.sendBlockChange(_blocks.get(_height).getLocation(), Material.AIR, (byte)0);
}
_blocks.remove(_height);
_height--;
}
else
{
finish();
}
}
public boolean isFinished()
{
if (!_blocks.isEmpty())
{
return false;
}
return _finished;
}
@SuppressWarnings("deprecation")
public void finish()
{
_finished = true;
for (Block block : _blocks)
{
for (Player player : UtilServer.getPlayers())
{
player.sendBlockChange(block.getLocation(), Material.AIR, (byte)0);
}
}
_blocks.clear();
}
public void tick()
{
if (isFinished())
{
return;
}
if (!UtilTime.elapsed(_lastTick, 500))
{
return;
}
if (_shrinking)
{
lower();
}
else
{
raise();
}
}
}

View File

@ -0,0 +1,54 @@
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
import org.bukkit.block.Block;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.projectile.IThrown;
import mineplex.core.projectile.ProjectileUser;
import mineplex.game.clans.clans.worldevent.api.WorldEvent;
public class IronHook implements IThrown
{
private WorldEvent _host;
public IronHook(WorldEvent event)
{
_host = event;
}
@Override
public void Collide(LivingEntity target, Block block, ProjectileUser data)
{
data.getThrown().remove();
if (!(data.getThrower() instanceof IronGolem))
return;
IronGolem wizard = (IronGolem)data.getThrower();
if (target == null)
return;
UtilAction.velocity(target, UtilAlg.getTrajectory(target.getLocation(), wizard.getLocation()), 5, false, 0, 0.7, 1.2, true);
_host.getCondition().Factory().Falling("Iron Hook", target, wizard, 10, false, true);
_host.getDamageManager().NewDamageEvent(target, wizard, null, DamageCause.CUSTOM, 5, false, true, false, wizard.getName(), "Iron Hook");
}
@Override
public void Idle(ProjectileUser data)
{
data.getThrown().remove();
}
@Override
public void Expire(ProjectileUser data)
{
data.getThrown().remove();
}
}

View File

@ -0,0 +1,65 @@
package mineplex.game.clans.clans.worldevent.boss.skeletonking;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilServer;
import mineplex.game.clans.clans.worldevent.WorldEventManager;
import mineplex.game.clans.clans.worldevent.api.EventCreature;
import mineplex.game.clans.clans.worldevent.boss.BossWorldEvent;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.MinionType;
public class SkeletonBoss extends BossWorldEvent<SkeletonCreature>
{
protected boolean canMove = false;
public SkeletonBoss(WorldEventManager manager)
{
super("Skeleton King", manager.getBossArenaLocationFinder().getSkeletonKingCenter(), 50, manager.getBossArenaLocationFinder().getSkeletonKingPads().getLeft(), manager.getBossArenaLocationFinder().getSkeletonKingPads().getRight(), manager.getDisguiseManager(), manager.getClans().getProjectile(), manager.getClans().getDamageManager(), manager.getBlockRestore(), manager.getClans().getCondition());
}
@Override
protected void customStart()
{
Bukkit.broadcastMessage(F.main(getName(), "The evils of the world have manifested in the form of the " + getName() + "! Become the champion of Light and destroy him!"));
spawnSkeletonKing(getCenterLocation());
Bukkit.getScheduler().runTaskLater(UtilServer.getPlugin(), () ->
{
canMove = true;
}, 20 * 3);
}
public EventCreature<?> spawnMinion(MinionType type, Location location)
{
EventCreature<?> minionCreature = type.getNewInstance(this, location);
if (minionCreature != null)
{
registerCreature(minionCreature);
}
return minionCreature;
}
private SkeletonCreature spawnSkeletonKing(Location location)
{
SkeletonCreature kingCreature = new SkeletonCreature(this, location);
registerCreature(kingCreature);
setBossCreature(kingCreature);
return kingCreature;
}
@Override
public String getDeathMessage()
{
return F.main(getName(), "The demonic " + getName() + " has been slain!");
}
@Override
protected void customTick() {}
@Override
public void customCleanup(boolean onDisable) {}
@Override
protected void customStop() {}
}

View File

@ -0,0 +1,482 @@
package mineplex.game.clans.clans.worldevent.boss.skeletonking;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
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;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.api.EventCreature;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities.SkeletonArcherShield;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities.SkeletonPassive;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities.SkeletonPulse;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities.SkeletonSmite;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities.SkeletonStrike;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities.SkeletonWraithSummon;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.UndeadArcherCreature;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.UndeadWarriorCreature;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
public class SkeletonCreature extends EventCreature<Skeleton>
{
private List<BossAbility<SkeletonCreature, Skeleton>> _currentAbilities = new ArrayList<>();
private SkeletonPassive _passive;
private int _lastAbility;
private Map<Class<?>, Long> _cooldowns = new HashMap<>();
private LinkedList<Double> _wraithTriggers = new LinkedList<>();
private List<Location> _movePoints = new ArrayList<>();
private Location _movingTo;
private boolean _moving;
private long _lastMoved;
private long _lastUsedPassive;
public List<UndeadArcherCreature> Archers = new ArrayList<>();
public List<UndeadWarriorCreature> Warriors = new ArrayList<>();
public SkeletonCreature(SkeletonBoss boss, Location location)
{
super(boss, location, "Skeleton King", true, 2500, 30, true, 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
protected void spawnCustom()
{
UtilEnt.vegetate(getEntity());
getEntity().setSkeletonType(SkeletonType.WITHER);
getEntity().getEquipment().setItemInHand(new ItemStack(Material.RECORD_6)); //Meridian Scepter
getEntity().getEquipment().setItemInHandDropChance(0.f);
}
@Override
public void dieCustom()
{
HandlerList.unregisterAll(_passive);
_passive = null;
endAbility();
getEntity().getWorld().setThunderDuration(0);
getEntity().getWorld().setThundering(false);
}
private void endAbility()
{
for (BossAbility<SkeletonCreature, Skeleton> ability : _currentAbilities)
{
ability.setFinished();
HandlerList.unregisterAll(ability);
}
_currentAbilities.clear();
}
@EventHandler
public void onTick(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
if (_passive != null && ((SkeletonBoss)getEvent()).canMove)
{
if (UtilTime.elapsed(_lastUsedPassive, _passive.getCooldown() * 20) || _passive.isProgressing())
{
_lastUsedPassive = System.currentTimeMillis();
_passive.tick();
}
}
Iterator<BossAbility<SkeletonCreature, Skeleton>> itel = _currentAbilities.iterator();
boolean canDoNew = _currentAbilities.size() < 3;
while (itel.hasNext())
{
BossAbility<SkeletonCreature, Skeleton> ability = itel.next();
if (ability.hasFinished())
{
itel.remove();
ability.setFinished();
_lastAbility = 20;// _currentAbility.getCooldown();
HandlerList.unregisterAll(ability);
if (DEBUG_MODE)
{
System.out.print("Unregistered necromancer ability " + ability.getClass().getSimpleName());
}
_cooldowns.put(ability.getClass(), System.currentTimeMillis() + (ability.getCooldown() * 1000));
}
else if (ability.inProgress())
{
canDoNew = false;
_lastAbility = 20;// _currentAbility.getCooldown();
}
}
if (_lastAbility-- <= 0 && canDoNew && UtilBlock.solid(getEntity().getLocation().getBlock().getRelative(BlockFace.DOWN)))
{
Map<Class<? extends BossAbility<SkeletonCreature, Skeleton>>, Integer> weight = new HashMap<>();
Map<Player, Double> dist = new HashMap<>();
for (Player player : UtilPlayer.getNearby(getEntity().getLocation(), 50, true))
{
if (player.hasLineOfSight(getEntity()))
{
dist.put(player, player.getLocation().distance(getEntity().getLocation()));
}
}
if (!dist.isEmpty())
{
{// Pulse & Strike
List<Player> players = getPlayers(dist, UtilMath.r(10) == 0 ? 25 : 20);
List<Player> near = getPlayers(dist, 5);
if (!players.isEmpty())
{
if (!near.isEmpty() && near.size() >= 4 && new Random().nextDouble() <= .45)
{
weight.put(SkeletonPulse.class, 999);
}
else
{
weight.put(SkeletonStrike.class, 6);
}
}
}
{// Smite
List<Player> players = getPlayers(dist, 15);
if (!players.isEmpty())
{
weight.put(SkeletonSmite.class, 6);
}
}
{//Archer Shield
List<Player> players = getPlayers(dist, 20);
double score = 0;
for (Player player : players)
{
score += (18 - dist.get(player)) / 2;
}
if (players.size() >= 4)
{
score += 17;
}
if (score > 0)
{
weight.put(SkeletonArcherShield.class, (int) Math.ceil(score));
}
}
Double wraithUse = null;
for (Double test : _wraithTriggers)
{
if (wraithUse == null)
{
if (getHealth() <= test)
{
wraithUse = test;
break;
}
}
}
if (wraithUse != null)
{// Wraith Summon
_wraithTriggers.remove(wraithUse);
weight.clear();
weight.put(SkeletonWraithSummon.class, 999);
}
}
for (BossAbility<SkeletonCreature, Skeleton> ability : _currentAbilities)
{
weight.remove(ability.getClass());
}
for (Class<?> c : _cooldowns.keySet())
{
if (_cooldowns.get(c) > System.currentTimeMillis())
{
weight.remove(c);
}
}
if (_moving)
{
Iterator<Class<? extends BossAbility<SkeletonCreature, Skeleton>>> trying = weight.keySet().iterator();
while (trying.hasNext())
{
Class<? extends BossAbility<SkeletonCreature, Skeleton>> abilityClass = trying.next();
try
{
BossAbility<SkeletonCreature, Skeleton> ability = abilityClass.newInstance();
if (!ability.canMove())
{
trying.remove();
}
}
catch (Exception e) {}
}
}
BossAbility<SkeletonCreature, Skeleton> ability = null;
if (!weight.isEmpty())
{
int i = 0;
for (Integer entry : weight.values())
{
i += entry;
}
loop: for (int a = 0; a < 10; a++)
{
int luckyNumber = UtilMath.r(i);
for (Entry<Class<? extends BossAbility<SkeletonCreature, Skeleton>>, Integer> entry : weight.entrySet())
{
luckyNumber -= entry.getValue();
if (luckyNumber <= 0)
{
try
{
ability = entry.getKey().getConstructor(SkeletonCreature.class).newInstance(this);
if (ability.getTarget() == null || ability.hasFinished())
{
ability = null;
}
else
{
break loop;
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
break;
}
}
}
}
if (ability != null && ability.getTarget() != null)
{
Bukkit.getPluginManager().registerEvents(ability, UtilServer.getPlugin());
if (DEBUG_MODE)
{
System.out.print("Necromancer is using " + ability.getClass().getSimpleName());
}
_currentAbilities.add(ability);
}
_lastAbility = 10;
}
for (BossAbility<SkeletonCreature, Skeleton> ability : _currentAbilities)
{
try
{
ability.tick();
}
catch (Exception e)
{
e.printStackTrace();
}
}
boolean canMove = true;
for (BossAbility<SkeletonCreature, Skeleton> ability : _currentAbilities)
{
if (!ability.canMove())
{
canMove = false;
}
}
if (!((SkeletonBoss)getEvent()).canMove)
{
return;
}
if (_moving)
{
if (_movingTo == null)
{
_movingTo = selectWalkTarget();
}
if (UtilMath.offset(getEntity().getLocation(), _movingTo) <= 1.3)
{
_lastMoved = System.currentTimeMillis();
_movingTo = null;
_moving = false;
return;
}
UtilEnt.LookAt(getEntity(), _movingTo);
Vector walk = UtilAlg.getTrajectory(getEntity().getLocation(), _movingTo);
walk.multiply(walk.length());
walk.multiply(.2);
getEntity().setVelocity(walk);
}
else
{
if (!UtilTime.elapsed(_lastMoved, 7000) || !canMove)
{
return;
}
_movingTo = selectWalkTarget();
_moving = true;
}
}
private Location selectWalkTarget()
{
if (_movePoints.isEmpty())
{
Location base = getSpawnLocation().clone();
base.setY(getEntity().getLocation().getY());
generateWalkPoints(base);
}
Location selected = _movePoints.get(new Random().nextInt(_movePoints.size()));
_movePoints.remove(selected);
return selected;
}
private void generateWalkPoints(Location base)
{
_movePoints.add(base.clone().add(5 + UtilMath.random(1, 3), 0, 5 + UtilMath.random(1, 3)));
_movePoints.add(base.clone().add(-5 + UtilMath.random(1, 3), 0, 5 + UtilMath.random(1, 3)));
_movePoints.add(base.clone().add(5 + UtilMath.random(1, 3), 0, -5 + UtilMath.random(1, 3)));
_movePoints.add(base.clone().add(-5 + UtilMath.random(1, 3), 0, -5 + UtilMath.random(1, 3)));
}
private List<Player> getPlayers(Map<Player, Double> map, double maxDist)
{
return getPlayers(map, 0, maxDist);
}
private List<Player> getPlayers(final Map<Player, Double> map, double minDist, double maxDist)
{
List<Player> list = new ArrayList<>();
for (Player p : map.keySet())
{
if (map.get(p) >= minDist && map.get(p) <= maxDist)
{
list.add(p);
}
}
Collections.sort(list, (o1, o2) ->
{
return Double.compare(map.get(o2), map.get(o1));
});
return list;
}
@EventHandler
public void onSkeletonDamage(CustomDamageEvent event)
{
if (event.GetDamageeEntity().getEntityId() == getEntity().getEntityId())
{
event.SetKnockback(false);
}
}
@EventHandler
public void noFallDamage(CustomDamageEvent event)
{
if (getEntity() == null)
{
return;
}
if (event.GetDamageeEntity().getEntityId() != getEntity().getEntityId())
{
return;
}
DamageCause cause = event.GetCause();
if (cause == DamageCause.FALL)
{
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");
}
}
}
}

View File

@ -0,0 +1,187 @@
package mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities;
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;
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.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonCreature;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.UndeadArcherCreature;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
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(UtilServer.getPlugin(), true));
arrow.setMetadata("BARBED_ARROW", new FixedMetadataValue(UtilServer.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(UtilServer.getPlugin(), () ->
{
event.getEntity().remove();
}, 20L);
}
}
}

View File

@ -0,0 +1,119 @@
package mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import org.bukkit.Location;
import org.bukkit.entity.Skeleton;
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.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonBoss;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonCreature;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.MinionType;
public class SkeletonHellishFlood extends BossAbility<SkeletonCreature, Skeleton>
{
private static final int WAVE_COUNT = 3;
private static final int WAVE_SIZE = 5;
private static final MinionType[] POSSIBLE_MINIONS = new MinionType[] {MinionType.WARRIOR, MinionType.ARCHER};
private static final long WAVE_DELAY = 1000;
private Map<String, MinionType[]> _waves = new HashMap<>();
private long _lastSpawned;
private int _current;
private int _ticks;
public SkeletonHellishFlood(SkeletonCreature creature)
{
super(creature);
if (WAVE_COUNT > 0)
{
for (int i = 1; i <= WAVE_COUNT; i++)
{
createWave(i);
}
}
_lastSpawned = System.currentTimeMillis();
_current = 1;
}
private void createWave(int number)
{
int length = POSSIBLE_MINIONS.length;
if (length <= 0 || WAVE_SIZE <= 0)
{
return;
}
MinionType[] wave = new MinionType[WAVE_SIZE];
for (int i = 0; i < WAVE_SIZE; i++)
{
wave[i] = POSSIBLE_MINIONS[new Random().nextInt(length)];
}
_waves.put("Wave " + number, wave);
}
@Override
public int getCooldown()
{
return 30;
}
@Override
public boolean canMove()
{
return false;
}
@Override
public boolean inProgress()
{
return true;
}
@Override
public boolean hasFinished()
{
return _waves.isEmpty() && _ticks > ((WAVE_DELAY / 1000) * 20 * (WAVE_COUNT - 1));
}
@Override
public void setFinished()
{
_waves.clear();
_ticks = 60;
}
@Override
public void tick()
{
_ticks++;
if (UtilTime.elapsed(_lastSpawned, WAVE_DELAY))
{
if (_current <= WAVE_COUNT)
{
for (MinionType type : _waves.get("Wave " + _current))
{
Location toSpawn = getLocation().clone();
toSpawn.add(UtilMath.random(3, 6), 0, UtilMath.random(3, 6));
((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);
_waves.remove("Wave " + _current);
_current++;
_lastSpawned = System.currentTimeMillis();
}
}
}
}

View File

@ -0,0 +1,120 @@
package mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Skeleton;
import org.bukkit.event.EventHandler;
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.game.clans.clans.worldevent.api.BossPassive;
import mineplex.game.clans.clans.worldevent.api.EventCreatureDeathEvent;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonBoss;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonCreature;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.MinionType;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.UndeadArcherCreature;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.UndeadWarriorCreature;
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 = 5000;
private List<Location> _queuedArchers = new ArrayList<>();
private List<Location> _queuedWarriors = new ArrayList<>();
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());
}
}
}

Some files were not shown because too many files have changed in this diff Show More