diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/RGBData.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/RGBData.java index 912516d17..adbe9749c 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/RGBData.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/RGBData.java @@ -1,5 +1,7 @@ package mineplex.core.common.util; +import org.bukkit.util.Vector; + public class RGBData { private double _red; @@ -50,4 +52,19 @@ public class RGBData + "green=" + (int) (_green * 255) + ", " + "blue=" + (int) (_blue * 255) + "]"; } + + public Vector ToVector() + { + return new Vector(Math.max(0.001, _red), _green, _blue); + } + + public RGBData Darken() + { + return new RGBData(getFullRed() - 25, getFullGreen() - 25, getFullBlue() - 25); + } + + public RGBData Lighten() + { + return new RGBData(getFullRed() + 25, getFullGreen() + 25, getFullBlue() + 25); + } } diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java index ef41e9450..b2e7a6777 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java @@ -3,6 +3,7 @@ package mineplex.core.common.util; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; +import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.TreeSet; diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilCollections.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilCollections.java index f6f7543bc..dadb62564 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilCollections.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilCollections.java @@ -3,14 +3,14 @@ package mineplex.core.common.util; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.Random; import java.util.function.Consumer; import java.util.function.Function; -import org.bukkit.Location; -import org.bukkit.block.Block; - public class UtilCollections { + public static Random Random = new Random(); + @SafeVarargs public static NautArrayList newNautList(E... elements) { @@ -177,7 +177,7 @@ public class UtilCollections return Arrays.copyOf(array, size); } - public static Object[] ensureSize(Object[] array, int size) + public static T[] ensureSize(T[] array, int size) { if (array.length <= size) { @@ -186,4 +186,49 @@ public class UtilCollections return Arrays.copyOf(array, size); } + + public static byte random(byte[] array) + { + return array[Random.nextInt(array.length)]; + } + + public static short random(short[] array) + { + return array[Random.nextInt(array.length)]; + } + + public static char random(char[] array) + { + return array[Random.nextInt(array.length)]; + } + + public static boolean random(boolean[] array) + { + return array[Random.nextInt(array.length)]; + } + + public static int random(int[] array) + { + return array[Random.nextInt(array.length)]; + } + + public static long random(long[] array) + { + return array[Random.nextInt(array.length)]; + } + + public static double random(double[] array) + { + return array[Random.nextInt(array.length)]; + } + + public static float random(float[] array) + { + return array[Random.nextInt(array.length)]; + } + + public static T random(T[] array) + { + return array[Random.nextInt(array.length)]; + } } diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilTrig.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilTrig.java new file mode 100644 index 000000000..fd0f566e7 --- /dev/null +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilTrig.java @@ -0,0 +1,24 @@ +package mineplex.core.common.util; + +import java.util.LinkedList; +import java.util.List; + +import org.bukkit.util.Vector; + +public class UtilTrig +{ + public static List GetCirclePoints(Vector origin, int points, double radius) + { + List list = new LinkedList<>(); + + double slice = 2 * Math.PI / points; + + for (int point = 0; point < points; point++) + { + double angle = slice * point; + list.add(new Vector(origin.getX() + radius * Math.cos(angle), 0, origin.getZ() + radius * Math.sin(angle))); + } + + return list; + } +} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java index fdd9d2293..f9d8b511d 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java @@ -207,6 +207,8 @@ public class ClansManager extends MiniClientPluginimplements IRelati private NautHashMap _claimMap = new NautHashMap(); private NautHashMap _unclaimMap = new NautHashMap(); + private DamageManager _damageManager; + public String UserDataDir = UtilServer.getServer().getWorlds().get(0).getWorldFolder().getPath() + File.separator + ".." + File.separator + "CLANS_USER_DATA" + File.separator; public ClanTips ClanTips; @@ -240,9 +242,9 @@ public class ClansManager extends MiniClientPluginimplements IRelati Creature creature = new Creature(plugin); _npcManager = new NpcManager(plugin, creature); _condition = new SkillConditionManager(plugin); - DamageManager damageManager = new DamageManager(plugin, _combatManager, _npcManager, _disguiseManager, _condition); - damageManager.addCommand(new KillCommand(damageManager)); - _worldEvent = new WorldEventManager(plugin, this, damageManager, _lootManager, blockRestore, _clanRegions, null); + _damageManager = new DamageManager(plugin, _combatManager, _npcManager, _disguiseManager, _condition); + _damageManager.addCommand(new KillCommand(_damageManager)); + _worldEvent = new WorldEventManager(plugin, this, _damageManager, _lootManager, blockRestore, _clanRegions, null); TaskManager taskManager = new TaskManager(plugin, _clientManager, webServerAddress); @@ -286,16 +288,16 @@ public class ClansManager extends MiniClientPluginimplements IRelati new PotatoManager(plugin, this); new Weapon(plugin, energy); - new Gameplay(plugin, this, blockRestore, damageManager); + new Gameplay(plugin, this, blockRestore, _damageManager); _projectileManager = new ProjectileManager(plugin); - Fire fire = new Fire(plugin, _condition, damageManager); + Fire fire = new Fire(plugin, _condition, _damageManager); HashSet itemIgnore = new HashSet(); itemIgnore.add("Proximity Explosive"); itemIgnore.add("Proximity Zapper"); - ItemFactory itemFactory = new ItemFactory(plugin, blockRestore, _condition, damageManager, energy, fire, _projectileManager, webServerAddress, itemIgnore); - SkillFactory skillManager = new SkillFactory(plugin, damageManager, this, _combatManager, _condition, _projectileManager, _disguiseManager, blockRestore, fire, new Movement(plugin), teleport, energy, webServerAddress); + ItemFactory itemFactory = new ItemFactory(plugin, blockRestore, _condition, _damageManager, energy, fire, _projectileManager, webServerAddress, itemIgnore); + SkillFactory skillManager = new SkillFactory(plugin, _damageManager, this, _combatManager, _condition, _projectileManager, _disguiseManager, blockRestore, fire, new Movement(plugin), teleport, energy, webServerAddress); skillManager.RemoveSkill("Dwarf Toss", "Block Toss"); skillManager.removeSkill("Whirlwind Axe"); skillManager.removeSkill("Shield Smash"); @@ -1059,6 +1061,12 @@ public class ClansManager extends MiniClientPluginimplements IRelati public void onJoin(PlayerLoginEvent event) { Rank rank = _clientManager.Get(event.getPlayer()).GetRank(); + + if (_serverName.equals("GClans-1")) + { + return; + } + if (!event.getPlayer().isWhitelisted() && !rank.has(Rank.LEGEND)) { event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "Clans is currently in Legend+ only Alpha!"); @@ -1198,4 +1206,9 @@ public class ClansManager extends MiniClientPluginimplements IRelati { return player.getName().equals("NewGarbo"); } + + public DamageManager getDamageManager() + { + return _damageManager; + } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapManager.java index 1a6268a76..ad18709cb 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapManager.java @@ -438,6 +438,19 @@ public class ItemMapManager extends MiniPlugin event.getEntity().remove(); } } + + public void removeMap(Player player) + { + for (int slot = 0; slot < player.getInventory().getSize(); slot++) + { + ItemStack item = player.getInventory().getItem(slot); + + if (item != null && item.getType() == Material.MAP && item.getDurability() >= _mapId && item.getDurability() <= _mapId + 100) + { + player.getInventory().setItem(slot, null); + } + } + } public ClansUtility getClansUtility() { diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherManager.java index 38470f58a..2ba9aeb80 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherManager.java @@ -14,6 +14,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerPortalEvent; import org.bukkit.inventory.ItemStack; @@ -27,6 +28,8 @@ import mineplex.core.common.util.UtilAlg; import mineplex.core.common.util.UtilBlock; import mineplex.core.common.util.UtilCollections; import mineplex.core.common.util.UtilFile; +import mineplex.core.common.util.UtilItem; +import mineplex.core.common.util.UtilMath; import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilWorld; @@ -119,15 +122,24 @@ public class NetherManager extends MiniPlugin Player player = event.getPlayer(); ItemStack item = player.getItemInHand(); + if (player.getGameMode() == GameMode.CREATIVE) + { + return; + } + if (!block.getWorld().equals(_netherWorld)) { return; } - if (player.getGameMode() == GameMode.CREATIVE) - { - return; - } + _portals + .stream() + .filter(portal -> UtilAlg.getAverageBlockLocation(portal.getToBlocks()).distance(block.getLocation()) < 15) + .limit(1) + .forEach(portal -> { + UtilPlayer.message(player, F.main("Clans", "You are not allowed to break this block.")); + event.setCancelled(true); + }); if (!item.getType().equals(Material.GOLD_PICKAXE)) { @@ -144,9 +156,60 @@ public class NetherManager extends MiniPlugin } } + @EventHandler + public void placeBlock(BlockPlaceEvent event) + { + Block block = event.getBlock(); + Player player = event.getPlayer(); + ItemStack item = player.getItemInHand(); + + if (player.getGameMode() == GameMode.CREATIVE) + { + return; + } + + if (!block.getWorld().equals(_netherWorld)) + { + return; + } + + if (!UtilItem.isFromNether(item)) + { + UtilPlayer.message(player, F.main("Clans", "You can only place blocks here that come from " + F.clansNether("The Nether") + ".")); + event.setCancelled(true); + return; + } + + _portals + .stream() + .filter(portal -> UtilAlg.getAverageBlockLocation(portal.getToBlocks()).distance(block.getLocation()) < 15) + .limit(1) + .forEach(portal -> { + UtilPlayer.message(player, F.main("Clans", "You are not allowed to place blocks here.")); + event.setCancelled(true); + }); + + if (block.getType().equals(Material.OBSIDIAN) || block.getType().equals(Material.PORTAL)) + { + UtilPlayer.message(player, F.main("Clans", "You are not allowed to place blocks here.")); + event.setCancelled(true); + return; + } + } + @EventHandler public void update(UpdateEvent event) { + if (event.getType() == UpdateType.FAST) + { + UtilServer.getPlayersCollection() + .stream() + .filter(player -> player.getWorld().equals(_netherWorld)) + .forEach(player -> { + player.setCompassTarget(new Location(_netherWorld, -200.d + UtilMath.r(400), player.getLocation().getY(), -200.d + UtilMath.r(400))); + _clansManager.getItemMapManager().removeMap(player); + }); + } if (event.getType() == UpdateType.SLOW) { _portals.forEach(portal -> { diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/Portal.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/Portal.java index 9c14b384c..ad3cc1803 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/Portal.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/Portal.java @@ -18,6 +18,9 @@ public class Portal private List _toPortalBlocks; private List _toObsidianBlocks; + private List _fromBlocks; + private List _toBlocks; + private Location _toOut; public final boolean Success; @@ -74,6 +77,11 @@ public class Portal } } + _fromBlocks.addAll(_fromObsidianBlocks); + _fromBlocks.addAll(_fromPortalBlocks); + _toBlocks.addAll(_toObsidianBlocks); + _toBlocks.addAll(_toPortalBlocks); + Success = true; } @@ -102,6 +110,16 @@ public class Portal return _toObsidianBlocks; } + public List getFromBlocks() + { + return _fromBlocks; + } + + public List getToBlocks() + { + return _toBlocks; + } + private boolean isValidPortalBlock(Block block) { return block.getType() == Material.OBSIDIAN || block.getType() == Material.PORTAL; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/Outpost.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/Outpost.java index 99834cdf2..a3811e4bc 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/Outpost.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/Outpost.java @@ -48,6 +48,7 @@ import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilText; import mineplex.core.common.util.UtilTextMiddle; import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilTrig; import mineplex.core.hologram.Hologram; import mineplex.core.hologram.HologramInteraction; import mineplex.core.itemstack.ItemBuilder; @@ -169,9 +170,9 @@ public class Outpost implements Listener _state = token.OutpostState; - _circleStages = new LoopIterator(circleAround(new Vector(0., 0., 0.), 40, .6d)); + _circleStages = new LoopIterator(UtilTrig.GetCirclePoints(new Vector(0., 0., 0.), 40, .6d)); - List reverse = circleAround(new Vector(0., 0., 0.), 40, .6d); + List reverse = UtilTrig.GetCirclePoints(new Vector(0., 0., 0.), 40, .6d); Collections.reverse(reverse); _reverseCircleStages = new LoopIterator(reverse); @@ -221,9 +222,9 @@ public class Outpost implements Listener _outpostManager.getRepository().insertOutpost(toToken()); - _circleStages = new LoopIterator(circleAround(new Vector(0., 0., 0.), 40, .6d)); + _circleStages = new LoopIterator(UtilTrig.GetCirclePoints(new Vector(0., 0., 0.), 40, .6d)); - List reverse = circleAround(new Vector(0., 0., 0.), 40, .6d); + List reverse = UtilTrig.GetCirclePoints(new Vector(0., 0., 0.), 40, .6d); Collections.reverse(reverse); _reverseCircleStages = new LoopIterator(reverse); @@ -328,7 +329,6 @@ public class Outpost implements Listener if (!_ownerClan.equals(_ownerClan.Clans.getClanUtility().getClanByPlayer(event.getPlayer()))) { UtilPlayer.message(event.getPlayer(), F.main("Clans", "This is not yours to activate!")); - return; } if (event.getClickedBlock() != null && _origin.equals(event.getClickedBlock().getLocation())) @@ -590,21 +590,6 @@ public class Outpost implements Listener _nameHolograms.forEach(Hologram::start); } - private List circleAround(Vector origin, int points, double radius) - { - List list = new LinkedList<>(); - - double slice = 2 * Math.PI / points; - - for (int point = 0; point < points; point++) - { - double angle = slice * point; - list.add(new Vector(origin.getX() + radius * Math.cos(angle), 0, origin.getZ() + radius * Math.sin(angle))); - } - - return list; - } - public void kill() { _state = OutpostState.DESTRUCTING; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/Cannon.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/Cannon.java index 67beb670a..03327d6e0 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/Cannon.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/Cannon.java @@ -357,17 +357,17 @@ public class Cannon extends SiegeWeapon if (firepower == 1) { - hMult = 0.6; + hMult = 1.2; yAdd = 0.5; } else if (firepower == 2) { - hMult = 1; + hMult = 1.7; yAdd = 0.55; } else if (firepower >= 3) { - hMult = 1.5; + hMult = 2.35; yAdd = 0.6; } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/Gameplay.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/Gameplay.java index 693d0b2ff..e595c74e8 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/Gameplay.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/Gameplay.java @@ -237,7 +237,7 @@ public class Gameplay extends MiniPlugin HashSet remove = new HashSet(); for (Block cur : _bucketWater.keySet()) - if (UtilTime.elapsed(_bucketWater.get(cur), 2000)) remove.add(cur); + if (UtilTime.elapsed(_bucketWater.get(cur).longValue(), 2000)) remove.add(cur); for (Block cur : remove) _bucketWater.remove(cur); diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/GearManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/GearManager.java index 73242f881..63464da3c 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/GearManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/GearManager.java @@ -29,6 +29,8 @@ import mineplex.core.common.util.C; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilServer; +import mineplex.core.common.weight.Weight; +import mineplex.core.common.weight.WeightSet; import mineplex.core.donation.DonationManager; import mineplex.core.packethandler.IPacketHandler; import mineplex.core.packethandler.PacketHandler; @@ -56,9 +58,9 @@ import mineplex.game.clans.items.attributes.weapon.JaggedAttribute; import mineplex.game.clans.items.attributes.weapon.SharpAttribute; import mineplex.game.clans.items.commands.GearCommand; import mineplex.game.clans.items.economy.GoldToken; -import mineplex.core.common.weight.Weight; -import mineplex.core.common.weight.WeightSet; import mineplex.game.clans.items.legendaries.AlligatorsTooth; +import mineplex.game.clans.items.legendaries.ChitauriScepter; +import mineplex.game.clans.items.legendaries.EnergyCrossbow; import mineplex.game.clans.items.legendaries.GiantsBroadsword; import mineplex.game.clans.items.legendaries.HyperAxe; import mineplex.game.clans.items.legendaries.LegendaryItem; @@ -153,7 +155,7 @@ public class GearManager extends MiniPlugin implements IPacketHandler, Runnable // TODO: Initialize list of attributes and types // Initialize various LegendaryItem types - _legendaryWeights = new WeightSet>(AlligatorsTooth.class, WindBlade.class, GiantsBroadsword.class, HyperAxe.class, MagneticMaul.class); + _legendaryWeights = new WeightSet>(ChitauriScepter.class, EnergyCrossbow.class, AlligatorsTooth.class, WindBlade.class, GiantsBroadsword.class, HyperAxe.class, MagneticMaul.class); // TODO: Add rest of legendaries, find better way? // Register listeners diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/ChitauriScepter.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/ChitauriScepter.java new file mode 100644 index 000000000..1f1f0a29b --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/ChitauriScepter.java @@ -0,0 +1,213 @@ +package mineplex.game.clans.items.legendaries; + +import java.util.Random; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.LineFormat; +import mineplex.core.common.util.RGBData; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilCollections; +import mineplex.core.common.util.UtilColor; +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.UtilShapes; +import mineplex.core.common.util.UtilText; +import mineplex.core.recharge.Recharge; +import mineplex.game.clans.clans.ClansManager; + +public class ChitauriScepter extends LegendaryItem +{ + private long _lastFire = System.currentTimeMillis(); + private long _interactWait; + + private RGBData[] colors = { UtilColor.RgbLightBlue, UtilColor.RgbLightBlue.Lighten(), UtilColor.RgbLightBlue.Darken() }; + + public ChitauriScepter() + { + super("Chitauri Scepter", UtilText.splitLinesToArray(new String[] { + C.cWhite + "Legend says " + + " ", + "#" + C.cYellow + "Right-Click" + C.cWhite + " to use Scepter." + }, LineFormat.LORE), Material.RECORD_7); + } + + @Override + public void update(Player wielder) + { + if ((System.currentTimeMillis() - _lastBlock) < 98 && (System.currentTimeMillis() - _interactWait) >= 98) + { + if (Recharge.Instance.use(wielder, getDisplayName(), 4000, true, true)) + { + fire(wielder); + + _interactWait = System.currentTimeMillis(); + } + } + } + + private void fire(final Player player) + { + final Location missileLocation = player.getEyeLocation(); + final Location shotFrom = missileLocation.clone(); + final Vector direction = missileLocation.getDirection().normalize().multiply(0.3); + final int maxRange = 40; + final int maxDings = maxRange * 3; + final int damage = 6; + + new BukkitRunnable() + { + private int dingsDone; + private Location previousLocation = missileLocation; + + private void burst() + { + for (Entity cur : missileLocation.getWorld().getEntities()) + { + if (cur == player || !(cur instanceof LivingEntity) || (cur instanceof Player && UtilPlayer.isSpectator(cur))) + continue; + + LivingEntity entity = (LivingEntity) cur; + + Location eLoc = entity.getLocation(); + + // If they are less than 0.5 blocks away + if (eLoc.clone().add(0, missileLocation.getY() - eLoc.getY(), 0).distance(missileLocation) <= 0.7) + { + // If it is in their body height + if (Math.abs((eLoc.getY() + (entity.getEyeHeight() / 1.5)) - missileLocation.getY()) <= entity + .getEyeHeight() / 2) + { + if (entity != player && (!(entity instanceof Player))) + { + ClansManager.getInstance().getDamageManager().NewDamageEvent(entity, player, null, DamageCause.CUSTOM, damage, true, + true, false, getDisplayName(), getDisplayName()); + + UtilPlayer.message(entity, F.main("Clans", F.elem(entity.getName()) + " hit you with a " + getDisplayName() + C.mBody + ".")); + UtilPlayer.message(player, F.main("Clans", "You hit " + F.elem(player.getName()) + " with your " + getDisplayName() + C.mBody + ".")); + } + } + } + } + + playParticle(missileLocation, previousLocation); + + missileLocation.getWorld().playSound(missileLocation, Sound.BAT_TAKEOFF, 1.2F, 1); + cancel(); + } + + public void run() + { + if (dingsDone >= maxDings || !player.isOnline()) + { + burst(); + } + else + { + for (int i = 0; i < 2; i++) + { + Player closestPlayer = null; + double dist = 0; + + for (Player closest : UtilServer.getPlayers()) + { + if (!closest.getWorld().equals(missileLocation.getWorld())) + { + continue; + } + + Location loc = closest.getLocation(); + + if (closest != player) + { + double dist1 = loc.distance(shotFrom); + if (dist1 < maxRange + 10) + { + double dist2 = missileLocation.distance(loc); + if (closestPlayer == null || dist2 < dist) + { + double dist3 = missileLocation.clone().add(direction).distance(loc); + + if (dist3 < dist2) + { + closestPlayer = closest; + dist = dist2; + } + } + } + } + } + + if (closestPlayer != null) + { + Vector newDirection = closestPlayer.getLocation().add(0, 1, 0).toVector() + .subtract(missileLocation.toVector()); + + direction.add(newDirection.normalize().multiply(0.01)).normalize().multiply(0.3); + } + + missileLocation.add(direction); + + for (Entity cur : missileLocation.getWorld().getEntities()) + { + + if (cur == player || !(cur instanceof LivingEntity) + || (cur instanceof Player && UtilPlayer.isSpectator(cur))) + continue; + + LivingEntity ent = (LivingEntity) cur; + + Location eLoc = ent.getLocation(); + + // If they are less than 0.5 blocks away + if (eLoc.clone().add(0, missileLocation.getY() - eLoc.getY(), 0).distance(missileLocation) <= 0.7) + { + // If it is in their body height + if (Math.abs((eLoc.getY() + (ent.getEyeHeight() / 1.5)) - missileLocation.getY()) <= ent + .getEyeHeight() / 2) + { + burst(); + return; + } + } + } + + if (UtilBlock.solid(missileLocation.getBlock())) + { + burst(); + return; + } + + playParticle(missileLocation, previousLocation); + previousLocation = missileLocation.clone(); + + dingsDone++; + } + + missileLocation.getWorld().playSound(missileLocation, Sound.ORB_PICKUP, 0.7F, 0); + } + } + }.runTaskTimer(ClansManager.getInstance().getPlugin(), 0, 0); + } + + private void playParticle(Location start, Location end) + { + for (Location loc : UtilShapes.getLinesDistancedPoints(start, end, 0.06)) + { + UtilParticle.PlayParticleToAll(ParticleType.RED_DUST, loc, UtilCollections.random(colors).ToVector(), 1f, 0, ViewDist.LONG); + } + } +} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/EnergyCrossbow.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/EnergyCrossbow.java index e81701ff9..3b7f02f37 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/EnergyCrossbow.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/EnergyCrossbow.java @@ -1,30 +1,50 @@ package mineplex.game.clans.items.legendaries; +import java.util.HashMap; + +import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Sound; import org.bukkit.entity.Arrow; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.ProjectileHitEvent; import mineplex.core.common.util.C; -import mineplex.core.common.util.F; import mineplex.core.common.util.LineFormat; -import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.RGBData; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilCollections; +import mineplex.core.common.util.UtilColor; +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.UtilServer; +import mineplex.core.common.util.UtilShapes; import mineplex.core.common.util.UtilText; +import mineplex.core.recharge.Recharge; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; public class EnergyCrossbow extends LegendaryItem { - private static final long COOLDOWN = 30000; - private long _lastFire = System.currentTimeMillis(); private long _interactWait; public EnergyCrossbow() { super("Energy Crossbow", UtilText.splitLinesToArray(new String[] { - C.cWhite + "This deadly tooth was stolen from a nest of reptillian beasts long ago. " - + "Legends say that the holder is granted the underwater agility of an Alligator", - " ", - "#" + C.cYellow + "Right-Click" + C.cWhite + " to use" + C.cGreen + " Swim" - }, LineFormat.LORE), Material.RECORD_4); + C.cWhite + "Legend says " + + " ", + "#" + C.cYellow + "Right-Click" + C.cWhite + " to fire Crossbow." + }, LineFormat.LORE), Material.RECORD_6); } @Override @@ -32,22 +52,121 @@ public class EnergyCrossbow extends LegendaryItem { if ((System.currentTimeMillis() - _lastBlock) < 98 && (System.currentTimeMillis() - _interactWait) >= 98) { - if ((System.currentTimeMillis() - _lastFire) >= COOLDOWN) + if (Recharge.Instance.use(wielder, "Crossbow", 4000, true, true)) { fire(wielder); _interactWait = System.currentTimeMillis(); } - else - { - UtilPlayer.message(wielder, F.main("Clans", "Energy Crossbow is cooling down!")); - } } } - private void fire(Player wielder) + private void fire(final Player player) { - final Arrow arrow = wielder.shootArrow(); + UtilServer.registerEvents(new Listener() { + private Location _lastLoc; + + private Arrow _arrow; + private Player _player; + + private RGBData[] colors = { UtilColor.RgbLightBlue, UtilColor.RgbLightBlue.Lighten(), UtilColor.RgbLightBlue.Darken() }; + + { + _player = player; + + Arrow arrow = _player.shootArrow(); + + arrow.setShooter(_player); + + _arrow = arrow; + + _player.playSound(_arrow.getLocation(), Sound.BAT_TAKEOFF, 2.f, 2.f); + } + + @EventHandler + public void update(UpdateEvent event) + { + if (_arrow == null || _arrow.isDead()) + { + HandlerList.unregisterAll(this); + + return; + } + + if (_lastLoc != null) + { + Location lastLoc = _lastLoc.clone(); + + while (UtilMath.offset(lastLoc, _arrow.getLocation()) > 0.1) + { + lastLoc.add(UtilAlg.getTrajectory(lastLoc, _arrow.getLocation()).multiply(0.1)); + + UtilParticle.PlayParticleToAll(ParticleType.RED_DUST, lastLoc, UtilCollections.random(colors).ToVector(), 1f, 0, ViewDist.MAX); + } + } + + _lastLoc = _arrow.getLocation(); + } + + private void hit() + { + HandlerList.unregisterAll(this); + + for (Location point : UtilShapes.getSphereBlocks(_arrow.getLocation(), 1, 1, true)) + UtilParticle.PlayParticleToAll(ParticleType.RED_DUST, _arrow.getLocation().add(point), UtilCollections.random(colors).ToVector(), 1f, 0, ViewDist.MAX); + + HashMap targets = UtilEnt.getInRadius(_arrow.getLocation(), 3.d); + for (LivingEntity entity : targets.keySet()) + { + if (entity.equals(_arrow.getShooter())) + continue; + + ClansManager.getInstance().getDamageManager().NewDamageEvent(entity, _player, _arrow, + DamageCause.CUSTOM, 6, true, true, false, + _player.getName(), "Energy Crossbow"); + } + + _arrow.remove(); + _arrow = null; + } + + @EventHandler + public void projectileHit(ProjectileHitEvent event) + { + if (!event.getEntity().equals(_arrow)) + { + return; + } + + ClansManager.getInstance().runSyncLater(this::hit, 1); + } + + @EventHandler + public void entityHurt(EntityDamageByEntityEvent event) + { + if (!event.getDamager().equals(_arrow)) + { + return; + } + + if (event.getEntity().equals(_arrow.getShooter()) || !(event.getEntity() instanceof LivingEntity)) + { + _arrow.remove(); + _arrow = null; + + return; + } + + event.setCancelled(true); + + ClansManager.getInstance().getDamageManager().NewDamageEvent((LivingEntity) event.getEntity(), _player, _arrow, + DamageCause.CUSTOM, 1.5d, true, true, false, + _player.getName(), "Energy Crossbow"); + + hit(); + } + + }); _lastFire = System.currentTimeMillis(); } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/HyperAxe.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/HyperAxe.java index c9630b26c..a01774651 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/HyperAxe.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/HyperAxe.java @@ -12,7 +12,7 @@ import mineplex.minecraft.game.core.damage.CustomDamageEvent; public class HyperAxe extends LegendaryItem { - public static final long ATTACK_RATE_DURATION = 200; + public static final long ATTACK_RATE_DURATION = 1000 / 17; private static ValueDistribution amountGen = generateDistribution(0, 3); // [1, 4] speed amount private static ValueDistribution durationGen = generateDistribution(80, 320); // [4, 16] seconds speed duration @@ -20,11 +20,10 @@ public class HyperAxe extends LegendaryItem private int _speedDuration; private long _lastAttack; - public long timeSinceLastAttack() { return System.currentTimeMillis() - _lastAttack; } public HyperAxe() { - super("Hyper Axe", new String[]{ + super("Hyper Axe", new String[] { C.cWhite + "Of all the weapons known to man,", C.cWhite + "none is more prevalent than the", C.cWhite + "Hyper Axe. Infused with rabbit's", @@ -43,10 +42,9 @@ public class HyperAxe extends LegendaryItem @Override public void update(Player wielder) { - if (isHoldingRightClick() && canBuff()) + if (isHoldingRightClick() && canBuff(wielder)) { buffPlayer(wielder); - _lastAttack = System.currentTimeMillis(); } } @@ -56,9 +54,9 @@ public class HyperAxe extends LegendaryItem if (timeSinceLastAttack() >= ATTACK_RATE_DURATION) { event.SetIgnoreRate(true); -// log("Ignoring rate!"); - event.AddMod("Hyper Axe", 1); + event.AddMod("Hyper Axe", 9); + _lastAttack = System.currentTimeMillis(); } else { @@ -66,18 +64,22 @@ public class HyperAxe extends LegendaryItem } } + public long timeSinceLastAttack() + { + return System.currentTimeMillis() - _lastAttack; + } + private void buffPlayer(Player wielder) { - if (!Recharge.Instance.use(wielder, "Hyper Rush", 16000, true, true)) - return; + Recharge.Instance.use(wielder, "Hyper Rush", 16000, true, false); // Give player speed buff wielder.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, _speedDuration, _speedAmount)); log("Buffing"); } - private boolean canBuff() + private boolean canBuff(Player wielder) { - return true; // TODO: Implement cooldown? (None specified in docs, sounds OP) + return Recharge.Instance.usable(wielder, "Hyper Rush", true); } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/ui/GearPage.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/ui/GearPage.java index 536c94df1..e2d96b6ec 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/ui/GearPage.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/ui/GearPage.java @@ -4,6 +4,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import org.apache.commons.lang3.text.WordUtils; +import org.apache.commons.lang3.tuple.Triple; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; @@ -40,13 +42,13 @@ import mineplex.game.clans.items.attributes.weapon.HasteAttribute; import mineplex.game.clans.items.attributes.weapon.JaggedAttribute; import mineplex.game.clans.items.attributes.weapon.SharpAttribute; import mineplex.game.clans.items.legendaries.AlligatorsTooth; +import mineplex.game.clans.items.legendaries.ChitauriScepter; +import mineplex.game.clans.items.legendaries.EnergyCrossbow; import mineplex.game.clans.items.legendaries.GiantsBroadsword; import mineplex.game.clans.items.legendaries.HyperAxe; import mineplex.game.clans.items.legendaries.LegendaryItem; import mineplex.game.clans.items.legendaries.MagneticMaul; import mineplex.game.clans.items.legendaries.WindBlade; -import org.apache.commons.lang3.text.WordUtils; -import org.apache.commons.lang3.tuple.Triple; public class GearPage extends ShopPageBase { @@ -98,7 +100,7 @@ public class GearPage extends ShopPageBase } }; - _legendaryItems = Arrays.> asList(AlligatorsTooth.class, WindBlade.class, GiantsBroadsword.class, HyperAxe.class, MagneticMaul.class); + _legendaryItems = Arrays.> asList(ChitauriScepter.class, EnergyCrossbow.class, AlligatorsTooth.class, WindBlade.class, GiantsBroadsword.class, HyperAxe.class, MagneticMaul.class); _armorSuperPrefixes = Arrays.> asList(LavaAttribute.class); _armorPrefixes = Arrays.> asList(PaddedAttribute.class, ReinforcedAttribute.class, SlantedAttribute.class);