Merge branch 'feature/clans-season-3' into develop
This commit is contained in:
commit
c4d5ed4cbd
@ -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);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -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)
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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))
|
||||||
{
|
{
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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()
|
||||||
|
@ -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()) + "!"));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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") + ".");
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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());
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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),
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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)
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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];
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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);
|
||||||
|
@ -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++)
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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))
|
||||||
{
|
{
|
||||||
|
@ -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()
|
||||||
|
@ -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()));
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
|
@ -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");
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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)));
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package mineplex.game.clans.clans.worldevent.api;
|
||||||
|
|
||||||
|
public enum EventState
|
||||||
|
{
|
||||||
|
LOADING,
|
||||||
|
LIVE,
|
||||||
|
STOPPED,
|
||||||
|
REMOVED
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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() {}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -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() {}
|
||||||
|
}
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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
Loading…
Reference in New Issue
Block a user