diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
new file mode 100644
index 0000000..d697d17
--- /dev/null
+++ b/.github/workflows/maven.yml
@@ -0,0 +1,31 @@
+# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
+# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven
+
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+name: Java CI with Maven
+
+on:
+ push:
+ branches: [ "2.15.1-prerelease" ]
+ pull_request:
+ branches: [ "2.15.1-prerelease" ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+ - name: Set up JDK 17
+ uses: actions/setup-java@v4
+ with:
+ java-version: '17'
+ distribution: 'temurin'
+ cache: maven
+ - name: Build with Maven
+ run: mvn -B package --file pom.xml
diff --git a/README.md b/README.md
index 717e9d0..4203184 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,14 @@
-[](https://github.com/CozmycDev/JedCore/releases)
-[](https://github.com/CozmycDev/JedCore/releases)
-
+[](https://github.com/Hihelloy-main/JedCore/releases)
+[](https://github.com/Hihelloy-main/JedCore/releases)
+
# JedCore
-This is my fork of plushmonkey's fork of jedk1's JedCore addon for ProjectKorra.
-Download releases [here](https://github.com/CozmycDev/JedCore/releases).
+This is my fork of Cozymc's fork of plushmonkey's fork of jedk1's JedCore addon for ProjectKorra.
+Download releases [here](https://github.com/Hihelloy-main/JedCore/releases).
Join our [Discord](https://discord.gg/gh9MfDmwZm) to discuss the plugin, suggest changes, report bugs, etc.
+This fork attempts on adding Folia support.
+
## Changelog
### 2.14.4
diff --git a/pom.xml b/pom.xml
index 647a300..665826b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
com.jedk1
jedcore
- 2.15.0-PK1.11.1
+ 2.15.1-PRE-RELEASE-3-PK1.12.1
jar
JedCore
@@ -13,22 +13,48 @@
spigot-repo
https://hub.spigotmc.org/nexus/content/repositories/snapshots/
+
+ papermc
+ https://repo.papermc.io/repository/maven-public/
+
+
+ jitpack.io
+ https://jitpack.io
+
+
-
-
- org.spigotmc
- spigot-api
- 1.20.2-R0.1-SNAPSHOT
- provided
-
-
- com.projectkorra
- projectkorra
- 1.11.1
-
+
+ com.projectkorra
+ projectkorra
+ 1.12.1-PRE-RELEASE-1
+ provided
+
+
+
+ org.spigotmc
+ spigot-api
+ 1.20.2-R0.1-SNAPSHOT
+ provided
+
+
+
+ com.google.guava
+ guava
+ 33.5.0-jre
+
+
+ com.cjcrafter
+ foliascheduler
+ 0.7.2
+
+
+ org.jetbrains
+ annotations
+ 26.0.2-1
+
@@ -51,8 +77,8 @@
maven-compiler-plugin
3.8.0
- 9
- 9
+ 17
+ 17
@@ -63,6 +89,47 @@
${dir}
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.4.1
+
+
+ package
+ shade
+
+
+
+ com.google.guava
+ com.jedk1.jedcore.libs.googleguava
+
+
+ org.jetbrains.annotations
+ com.jedk1.jedcore.libs.jetbrains
+
+
+ com.cjcrafter.foliascheduler
+ com.jedk1.jedcore.libs.foliascheduler
+
+
+
+
+
+ *:*
+
+ META-INF/*.SF
+ META-INF/*.DSA
+ META-INF/*.RSA
+ META-INF/versions/**
+ META-INF/*.kotlin_module
+
+
+
+ false
+
+
+
+
diff --git a/src/com/jedk1/jedcore/JCManager.java b/src/com/jedk1/jedcore/JCManager.java
index 5fda987..2dfa835 100644
--- a/src/com/jedk1/jedcore/JCManager.java
+++ b/src/com/jedk1/jedcore/JCManager.java
@@ -1,27 +1,29 @@
package com.jedk1.jedcore;
+import com.jedk1.jedcore.ability.earthbending.EarthPillar;
+import com.jedk1.jedcore.ability.firebending.LightningBurst;
+import com.jedk1.jedcore.ability.waterbending.HealingWaters;
+import com.jedk1.jedcore.ability.waterbending.IcePassive;
+import com.jedk1.jedcore.ability.waterbending.IceWall;
+import com.jedk1.jedcore.util.RegenTempBlock;
import org.bukkit.Bukkit;
- import com.jedk1.jedcore.ability.firebending.LightningBurst;
- import com.jedk1.jedcore.ability.waterbending.HealingWaters;
- import com.jedk1.jedcore.ability.waterbending.IcePassive;
- import com.jedk1.jedcore.util.RegenTempBlock;
-
public class JCManager implements Runnable {
- public JedCore plugin;
-
- public JCManager(JedCore plugin) {
- this.plugin = plugin;
- }
-
- public void run() {
- LightningBurst.progressAll();
-
- HealingWaters.heal(Bukkit.getServer());
- IcePassive.handleSkating();
-// IceWall.progressAll();
-
- RegenTempBlock.manage();
- }
+ public JedCore plugin;
+
+ public JCManager(JedCore plugin) {
+ this.plugin = plugin;
+ }
+
+ public void run() {
+ LightningBurst.progressAll();
+
+ HealingWaters.heal(Bukkit.getServer());
+ //IcePassive.handleSkating();
+ IceWall.progressAll();
+ EarthPillar.progressAll();
+
+ RegenTempBlock.manage();
+ }
}
\ No newline at end of file
diff --git a/src/com/jedk1/jedcore/JCMethods.java b/src/com/jedk1/jedcore/JCMethods.java
index 27d4ddb..abc4d74 100644
--- a/src/com/jedk1/jedcore/JCMethods.java
+++ b/src/com/jedk1/jedcore/JCMethods.java
@@ -1,356 +1,358 @@
package com.jedk1.jedcore;
-import java.util.*;
-
-import com.jedk1.jedcore.util.*;
+import com.jedk1.jedcore.command.Commands;
+import com.jedk1.jedcore.configuration.JedCoreConfig;
+import com.jedk1.jedcore.util.FireTick;
+import com.jedk1.jedcore.util.LightManagerUtil;
+import com.jedk1.jedcore.util.RegenTempBlock;
+import com.projectkorra.projectkorra.GeneralMethods;
+import com.projectkorra.projectkorra.ProjectKorra;
+import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.ElementalAbility;
+import com.projectkorra.projectkorra.ability.WaterAbility;
+import com.projectkorra.projectkorra.ability.util.ComboManager;
import com.projectkorra.projectkorra.region.RegionProtection;
-import org.bukkit.*;
+import com.projectkorra.projectkorra.util.TempBlock;
+import org.bukkit.Effect;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.Levelled;
-import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
-import com.jedk1.jedcore.configuration.JedCoreConfig;
-import com.jedk1.jedcore.scoreboard.BendingBoard;
-import com.projectkorra.projectkorra.GeneralMethods;
-import com.projectkorra.projectkorra.ProjectKorra;
-import com.projectkorra.projectkorra.ability.CoreAbility;
-import com.projectkorra.projectkorra.ability.util.ComboManager;
-import com.projectkorra.projectkorra.util.TempBlock;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
public class JCMethods {
- private static final ArrayList SMALL_PLANTS = new ArrayList(){{
- addAll(Arrays.asList(Material.GRASS_BLOCK, Material.FERN, Material.POPPY, Material.DANDELION, Material.OAK_SAPLING,
- Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING,
- Material.DARK_OAK_SAPLING, Material.ALLIUM, Material.ORANGE_TULIP, Material.PINK_TULIP, Material.RED_TULIP,
- Material.WHITE_TULIP, Material.ROSE_BUSH, Material.BLUE_ORCHID, Material.LILAC, Material.OXEYE_DAISY,
- Material.AZURE_BLUET, Material.PEONY, Material.SUNFLOWER, Material.LARGE_FERN, Material.RED_MUSHROOM,
- Material.BROWN_MUSHROOM, Material.PUMPKIN_STEM, Material.MELON_STEM, Material.WHEAT, Material.TALL_GRASS,
- Material.BEETROOTS, Material.CARROTS, Material.POTATOES, Material.CRIMSON_FUNGUS, Material.WARPED_FUNGUS,
- Material.BAMBOO, Material.BAMBOO_SAPLING));
- int serverVersion = GeneralMethods.getMCVersion();
- if (serverVersion >= 1170) {
- add(Material.getMaterial("AZALEA"));
- add(Material.getMaterial("FLOWERING_AZALEA"));
- add(Material.getMaterial("FLOWERING_AZALEA_LEAVES"));
- add(Material.getMaterial("AZALEA_LEAVES"));
- add(Material.getMaterial("BIG_DRIPLEAF"));
- add(Material.getMaterial("BIG_DRIPLEAF_STEM"));
- add(Material.getMaterial("SMALL_DRIPLEAF"));
- add(Material.getMaterial("HANGING_ROOTS"));
- add(Material.getMaterial("GLOW_LICHEN"));
- add(Material.getMaterial("CAVE_VINES"));
- add(Material.getMaterial("CAVE_VINES_PLANT"));
- }
- }};
-
- private static List worlds = new ArrayList<>();
- private static List combos = new ArrayList<>();
-
- public static List getDisabledWorlds() {
- return JCMethods.worlds;
- }
-
- public static void registerDisabledWorlds() {
- worlds.clear();
- List registeredworlds = ProjectKorra.plugin.getConfig().getStringList("Properties.DisabledWorlds");
- if (!registeredworlds.isEmpty()) {
- worlds.addAll(registeredworlds);
- }
- }
-
- public static boolean isDisabledWorld(World world) {
- return getDisabledWorlds().contains(world.getName());
- }
-
- public static List getCombos() {
- return JCMethods.combos;
- }
-
- public static void registerCombos() {
- combos.clear();
- combos.addAll(ComboManager.getComboAbilities().keySet());
- }
-
- /**
- * Gets the points of a line between two points.
- * @param startLoc
- * @param endLoc
- * @param points
- * @return locations
- */
- public static List getLinePoints(Location startLoc, Location endLoc, int points){
- List locations = new ArrayList();
- Location diff = endLoc.subtract(startLoc);
- double diffX = diff.getX() / points;
- double diffY = diff.getY() / points;
- double diffZ = diff.getZ() / points;
- Location loc = startLoc;
- for(int i = 0; i < points; i++){
- loc.add(new Location(startLoc.getWorld(), diffX, diffY, diffZ));
- locations.add(loc.clone());
- }
- return locations;
- }
-
- public static List getCirclePoints(Location location, int points, double size) {
- return getCirclePoints(location, points, size, 0);
- }
-
- /**
- * Gets points in a circle.
- * @param location
- * @param points
- * @param size
- * @return
- */
- public static List getCirclePoints(Location location, int points, double size, double startangle){
- List locations = new ArrayList();
- for(int i = 0; i < 360; i += 360/points){
- double angle = (i * Math.PI / 180);
- double x = size * Math.cos(angle + startangle);
- double z = size * Math.sin(angle + startangle);
- Location loc = location.clone();
- loc.add(x, 0, z);
- locations.add(loc);
- }
- return locations;
- }
-
- /**
- * Gets points in a vertical circle.
- * @param location
- * @param points
- * @param size
- * @param yawOffset
- * @return
- */
- public static List getVerticalCirclePoints(Location location, int points, double size, float yawOffset) {
- List locations = new ArrayList<>();
- Location fakeLoc = location.clone();
- fakeLoc.setPitch(0);
- fakeLoc.setYaw(yawOffset);
- Vector direction = fakeLoc.getDirection();
-
- for(double j = -180; j <= 180; j += points){
- Location tempLoc = fakeLoc.clone();
- Vector newDir = direction.clone().multiply(size * Math.cos(Math.toRadians(j)));
- tempLoc.add(newDir);
- tempLoc.setY(tempLoc.getY() + size + (size * Math.sin(Math.toRadians(j))));
- locations.add(tempLoc.clone());
- }
- return locations;
- }
-
- /**
- * Remove an item from a players inventory.
- * @param player
- * @param material
- * @param amount
- * @return
- */
- public static boolean removeItemFromInventory(Player player, Material material, int amount) {
- for (ItemStack item : player.getInventory().getContents()) {
- if (item != null && item.getType() == material) {
- if (item.getAmount() == amount) {
- Map remaining = player.getInventory().removeItem(item);
-
- if (!remaining.isEmpty()) {
- ItemStack offhand = player.getInventory().getItemInOffHand();
-
- // Spigot seems to not handle offhand correctly with removeItem, so try to manually remove it.
- if (offhand != null && offhand.getType() == material && offhand.getAmount() == amount) {
- player.getInventory().setItemInOffHand(null);
- }
- }
- } else if (item.getAmount() > amount) {
- item.setAmount(item.getAmount() - amount);
- }
-
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Gets points in a spiral shape.
- * @param location
- * @param points
- * @param spiralCount
- * @param startAngle
- * @param startSize
- * @param finalSize
- * @param noClip
- * @return
- */
- public static List getSpiralPoints(Location location, int points, int spiralCount, int startAngle, double startSize, double finalSize, boolean noClip){
- return getSpiralPoints(location, points, spiralCount, 0.0D, startAngle, startSize, finalSize, noClip);
- }
-
- /**
- * Gets points in a vertical spiral shape, could be used for a tornado.
- * @param location
- * @param points
- * @param spiralCount
- * @param height
- * @param startAngle
- * @param startSize
- * @param finalSize
- * @param noClip
- * @return
- */
- public static List getSpiralPoints(Location location, int points, int spiralCount, double height, int startAngle, double startSize, double finalSize, boolean noClip){
- List locations = new ArrayList();
-
- points = points/spiralCount;
- double sizeIncr = ((finalSize - startSize) / points)/spiralCount;
- double hightIncr = (height/points)/spiralCount;
- double size = startSize;
- for(int i = 0; i < spiralCount; i++){
- for(int j = 0; j < 360; j += 360/points){
- hightIncr = hightIncr + ((height/points)/spiralCount);
- size = size + sizeIncr;
- double angle = (j * Math.PI / 180);
- double x = size * Math.cos(angle + startAngle);
- double z = size * Math.sin(angle + startAngle);
- Location loc = location.clone();
- loc.add(x, hightIncr, z);
- if(!noClip && ElementalAbility.isAir(loc.getBlock().getType()))
- locations.add(loc);
- else if(noClip)
- locations.add(loc);
- }
- }
-
- return locations;
- }
-
- public static void extinguishBlocks(Player player, String ability, int range, int radius, boolean fire, boolean lava){
- for (Block block : GeneralMethods.getBlocksAroundPoint(player.getTargetBlock(null, range).getLocation(), radius)) {
- Material mat = block.getType();
- if(mat != Material.FIRE && mat != Material.LAVA && mat != Material.SOUL_FIRE)
- continue;
- if (RegionProtection.isRegionProtected(player, block.getLocation(), ability))
- continue;
- if (((mat == Material.FIRE || mat == Material.SOUL_FIRE) && fire)||(mat == Material.LAVA && lava)) {
- block.setType(mat != Material.LAVA ? Material.AIR : isLiquidSource(block) ? Material.OBSIDIAN : Material.COBBLESTONE);
- block.getWorld().playEffect(block.getLocation(), Effect.EXTINGUISH, 0);
- }
- }
- }
-
- /**
- * Checks if 3 blocks around the block are of the required type.
- * @param block
- * @param type
- * @return
- */
- public static boolean isAdjacentToThreeOrMoreSources(Block block, Material type) {
- if (TempBlock.isTempBlock(block)) {
- return false;
- }
- int sources = 0;
- BlockFace[] faces = { BlockFace.EAST, BlockFace.WEST, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.UP, BlockFace.DOWN };
- for (BlockFace face : faces) {
- Block blocki = block.getRelative(face);
- if ((blocki.getType() == type)) {
- sources++;
- }
- }
- if (sources >= 2)
- return true;
- return false;
- }
-
- static Material[] unbreakables = { Material.BEDROCK, Material.BARRIER,
- Material.NETHER_PORTAL, Material.END_PORTAL,
- Material.END_PORTAL_FRAME, Material.OBSIDIAN};
-
- public static boolean isUnbreakable(Block block) {
- if (block.getState() instanceof InventoryHolder) {
- return true;
- }
- if (Arrays.asList(unbreakables).contains(block.getType()))
- return true;
- return false;
- }
-
- public static boolean isLiquidSource(Block block) {
- if (!block.isLiquid()) {
- return false;
- }
-
- if (!(block.getBlockData() instanceof Levelled)) {
- return false;
- }
-
- Levelled levelData = (Levelled) block.getBlockData();
-
- return levelData.getLevel() == 0;
- }
-
- // TODO: Should this be reimplemented or has the rpg plugin been abandoned?
- public static boolean isSozinsComet(World world) {
- return false;
- }
-
- // TODO: Should this be reimplemented or has the rpg plugin been abandoned?
- public static boolean isLunarEclipse(World world) {
- return false;
- }
-
- public static boolean isDoublePlant(Material material) {
- return material == Material.SUNFLOWER || material == Material.LILAC || material == Material.TALL_GRASS ||
- material == Material.LARGE_FERN || material == Material.ROSE_BUSH || material == Material.PEONY;
- }
-
- public static boolean isSmallPlant(Block block) {
- return isSmallPlant(block.getType());
- }
-
- public static boolean isSmallPlant(Material material) {
- return SMALL_PLANTS.contains(material);
- }
-
- public static void displayColoredParticles(String hex, Location location, int amount, double offsetX, double offsetY, double offsetZ, double extra) {
- displayColoredParticles(hex, location, amount, offsetX, offsetY, offsetZ, extra, 255);
- }
-
- public static void displayColoredParticles(String hex, Location location, int amount, double offsetX, double offsetY, double offsetZ, double extra, int alpha) {
- JedCore.plugin.getParticleAdapter().displayColoredParticles(hex, location, amount, offsetX, offsetY, offsetZ, extra, alpha);
- }
-
- public static void emitLight(Location loc) {
- ConfigurationSection config = JedCoreConfig.getConfig((Player)null);
- if (config.getBoolean("Properties.Fire.DynamicLight.Enabled")) {
- int brightness = config.getInt("Properties.Fire.DynamicLight.Brightness");
- long keepAlive = config.getLong("Properties.Fire.DynamicLight.KeepAlive");
-
- LightManager.createLight(loc).brightness(brightness).timeUntilFadeout(keepAlive).emit();
- }
- }
-
- public static void reload() {
- JedCore.log.info("JedCore Reloaded.");
- JedCore.plugin.reloadConfig();
- JedCore.logDebug = JedCoreConfig.getConfig((World)null).getBoolean("Properties.LogDebug");
- JedCoreConfig.board.reloadConfig();
- CoreAbility.registerPluginAbilities(JedCore.plugin, "com.jedk1.jedcore.ability");
- registerDisabledWorlds();
- registerCombos();
- RegenTempBlock.revertAll();
- BendingBoard.setFields();
- BendingBoard.updateOnline();
- JedCore.plugin.initializeCollisions();
- FireTick.loadMethod();
-
- BendingBoard.loadOtherCooldowns();
- }
-}
+
+ // todo: either use PKs isPlant or the registry/tags (with config)
+ private static final ArrayList SMALL_PLANTS = new ArrayList(){{
+ addAll(Arrays.asList(Material.GRASS, Material.FERN, Material.POPPY, Material.DANDELION, Material.OAK_SAPLING,
+ Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING,
+ Material.DARK_OAK_SAPLING, Material.ALLIUM, Material.ORANGE_TULIP, Material.PINK_TULIP, Material.RED_TULIP,
+ Material.WHITE_TULIP, Material.ROSE_BUSH, Material.BLUE_ORCHID, Material.LILAC, Material.OXEYE_DAISY,
+ Material.AZURE_BLUET, Material.PEONY, Material.SUNFLOWER, Material.LARGE_FERN, Material.RED_MUSHROOM,
+ Material.BROWN_MUSHROOM, Material.PUMPKIN_STEM, Material.MELON_STEM, Material.WHEAT, Material.TALL_GRASS,
+ Material.BEETROOTS, Material.CARROTS, Material.POTATOES, Material.CRIMSON_FUNGUS, Material.WARPED_FUNGUS,
+ Material.BAMBOO, Material.BAMBOO_SAPLING));
+
+ int serverVersion = GeneralMethods.getMCVersion();
+ if (serverVersion >= 1170) {
+ add(Material.getMaterial("AZALEA"));
+ add(Material.getMaterial("FLOWERING_AZALEA"));
+ add(Material.getMaterial("FLOWERING_AZALEA_LEAVES"));
+ add(Material.getMaterial("AZALEA_LEAVES"));
+ add(Material.getMaterial("BIG_DRIPLEAF"));
+ add(Material.getMaterial("BIG_DRIPLEAF_STEM"));
+ add(Material.getMaterial("SMALL_DRIPLEAF"));
+ add(Material.getMaterial("HANGING_ROOTS"));
+ add(Material.getMaterial("GLOW_LICHEN"));
+ add(Material.getMaterial("CAVE_VINES"));
+ add(Material.getMaterial("CAVE_VINES_PLANT"));
+ }
+ }};
+
+ private static List worlds = new ArrayList<>();
+ private static List combos = new ArrayList<>();
+
+ public static List getDisabledWorlds() {
+ return JCMethods.worlds;
+ }
+
+ public static void registerDisabledWorlds() {
+ worlds.clear();
+ List registeredworlds = ProjectKorra.plugin.getConfig().getStringList("Properties.DisabledWorlds");
+ if (!registeredworlds.isEmpty()) {
+ worlds.addAll(registeredworlds);
+ }
+ }
+
+ public static boolean isDisabledWorld(World world) {
+ return getDisabledWorlds().contains(world.getName());
+ }
+
+ public static List getCombos() {
+ return JCMethods.combos;
+ }
+
+ public static void registerCombos() {
+ combos.clear();
+ combos.addAll(ComboManager.getComboAbilities().keySet());
+ }
+
+ /**
+ * Gets the points of a line between two points.
+ * @param startLoc
+ * @param endLoc
+ * @param points
+ * @return locations
+ */
+ public static List getLinePoints(Location startLoc, Location endLoc, int points){
+ List locations = new ArrayList();
+ Location diff = endLoc.subtract(startLoc);
+ double diffX = diff.getX() / points;
+ double diffY = diff.getY() / points;
+ double diffZ = diff.getZ() / points;
+ Location loc = startLoc;
+ for(int i = 0; i < points; i++){
+ loc.add(new Location(startLoc.getWorld(), diffX, diffY, diffZ));
+ locations.add(loc.clone());
+ }
+ return locations;
+ }
+
+ public static List getCirclePoints(Location location, int points, double size) {
+ return getCirclePoints(location, points, size, 0);
+ }
+
+ /**
+ * Gets points in a circle.
+ * @param location
+ * @param points
+ * @param size
+ * @return
+ */
+ public static List getCirclePoints(Location location, int points, double size, double startangle){
+ List locations = new ArrayList();
+ for(int i = 0; i < 360; i += 360/points){
+ double angle = (i * Math.PI / 180);
+ double x = size * Math.cos(angle + startangle);
+ double z = size * Math.sin(angle + startangle);
+ Location loc = location.clone();
+ loc.add(x, 0, z);
+ locations.add(loc);
+ }
+ return locations;
+ }
+
+ /**
+ * Gets points in a vertical circle.
+ * @param location
+ * @param points
+ * @param size
+ * @param yawOffset
+ * @return
+ */
+ public static List getVerticalCirclePoints(Location location, int points, double size, float yawOffset) {
+ List locations = new ArrayList<>();
+ Location fakeLoc = location.clone();
+ fakeLoc.setPitch(0);
+ fakeLoc.setYaw(yawOffset);
+ Vector direction = fakeLoc.getDirection();
+
+ for(double j = -180; j <= 180; j += points){
+ Location tempLoc = fakeLoc.clone();
+ Vector newDir = direction.clone().multiply(size * Math.cos(Math.toRadians(j)));
+ tempLoc.add(newDir);
+ tempLoc.setY(tempLoc.getY() + size + (size * Math.sin(Math.toRadians(j))));
+ locations.add(tempLoc.clone());
+ }
+ return locations;
+ }
+
+ /**
+ * Remove an item from a players inventory.
+ * @param player
+ * @param material
+ * @param amount
+ * @return
+ */
+ public static boolean removeItemFromInventory(Player player, Material material, int amount) {
+ for (ItemStack item : player.getInventory().getContents()) {
+ if (item != null && item.getType() == material) {
+ if (item.getAmount() == amount) {
+ Map remaining = player.getInventory().removeItem(item);
+
+ if (!remaining.isEmpty()) {
+ ItemStack offhand = player.getInventory().getItemInOffHand();
+
+ // Spigot seems to not handle offhand correctly with removeItem, so try to manually remove it.
+ if (offhand != null && offhand.getType() == material && offhand.getAmount() == amount) {
+ player.getInventory().setItemInOffHand(null);
+ }
+ }
+ } else if (item.getAmount() > amount) {
+ item.setAmount(item.getAmount() - amount);
+ }
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Gets points in a spiral shape.
+ * @param location
+ * @param points
+ * @param spiralCount
+ * @param startAngle
+ * @param startSize
+ * @param finalSize
+ * @param noClip
+ * @return
+ */
+ public static List getSpiralPoints(Location location, int points, int spiralCount, int startAngle, double startSize, double finalSize, boolean noClip){
+ return getSpiralPoints(location, points, spiralCount, 0.0D, startAngle, startSize, finalSize, noClip);
+ }
+
+ /**
+ * Gets points in a vertical spiral shape, could be used for a tornado.
+ * @param location
+ * @param points
+ * @param spiralCount
+ * @param height
+ * @param startAngle
+ * @param startSize
+ * @param finalSize
+ * @param noClip
+ * @return
+ */
+ public static List getSpiralPoints(Location location, int points, int spiralCount, double height, int startAngle, double startSize, double finalSize, boolean noClip){
+ List locations = new ArrayList();
+
+ points = points/spiralCount;
+ double sizeIncr = ((finalSize - startSize) / points)/spiralCount;
+ double hightIncr = (height/points)/spiralCount;
+ double size = startSize;
+ for(int i = 0; i < spiralCount; i++){
+ for(int j = 0; j < 360; j += 360/points){
+ hightIncr = hightIncr + ((height/points)/spiralCount);
+ size = size + sizeIncr;
+ double angle = (j * Math.PI / 180);
+ double x = size * Math.cos(angle + startAngle);
+ double z = size * Math.sin(angle + startAngle);
+ Location loc = location.clone();
+ loc.add(x, hightIncr, z);
+ if(!noClip && ElementalAbility.isAir(loc.getBlock().getType()))
+ locations.add(loc);
+ else if(noClip)
+ locations.add(loc);
+ }
+ }
+
+ return locations;
+ }
+
+ public static void extinguishBlocks(Player player, String ability, int range, int radius, boolean fire, boolean lava){
+ for (Block block : GeneralMethods.getBlocksAroundPoint(player.getTargetBlock(null, range).getLocation(), radius)) {
+ Material mat = block.getType();
+ if(mat != Material.FIRE && mat != Material.LAVA && mat != Material.SOUL_FIRE)
+ continue;
+ if (RegionProtection.isRegionProtected(player, block.getLocation(), ability))
+ continue;
+ if (((mat == Material.FIRE || mat == Material.SOUL_FIRE) && fire)||(mat == Material.LAVA && lava)) {
+ block.setType(mat != Material.LAVA ? Material.AIR : isLiquidSource(block) ? Material.OBSIDIAN : Material.COBBLESTONE);
+ block.getWorld().playEffect(block.getLocation(), Effect.EXTINGUISH, 0);
+ }
+ }
+ }
+
+ /**
+ * Checks if 3 blocks around the block are of the required type.
+ * @param block
+ * @param type
+ * @return
+ */
+ public static boolean isAdjacentToThreeOrMoreSources(Block block, Material type) {
+ if (TempBlock.isTempBlock(block)) {
+ return false;
+ }
+ int sources = 0;
+ BlockFace[] faces = { BlockFace.EAST, BlockFace.WEST, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.UP, BlockFace.DOWN };
+ for (BlockFace face : faces) {
+ Block blocki = block.getRelative(face);
+ if ((blocki.getType() == type)) {
+ sources++;
+ }
+ }
+ if (sources >= 2)
+ return true;
+ return false;
+ }
+
+ static Material[] unbreakables = { Material.BEDROCK, Material.BARRIER,
+ Material.NETHER_PORTAL, Material.END_PORTAL,
+ Material.END_PORTAL_FRAME, Material.OBSIDIAN};
+
+ public static boolean isUnbreakable(Block block) {
+ if (block.getState() instanceof InventoryHolder) {
+ return true;
+ }
+ if (Arrays.asList(unbreakables).contains(block.getType()))
+ return true;
+ return false;
+ }
+
+ public static boolean isLiquidSource(Block block) {
+ if (!block.isLiquid()) {
+ return false;
+ }
+
+ if (!(block.getBlockData() instanceof Levelled)) {
+ return false;
+ }
+
+ Levelled levelData = (Levelled) block.getBlockData();
+
+ return levelData.getLevel() == 0;
+ }
+
+ // TODO: Should this be reimplemented or has the rpg plugin been abandoned?
+ public static boolean isSozinsComet(World world) {
+ return false;
+ }
+
+ // TODO: Should this be reimplemented or has the rpg plugin been abandoned?
+ public static boolean isLunarEclipse(World world) {
+ return false;
+ }
+
+ // todo: see SMALL_PLANTS
+ public static boolean isDoublePlant(Material material) {
+ return material == Material.SUNFLOWER || material == Material.LILAC || material == Material.TALL_GRASS ||
+ material == Material.LARGE_FERN || material == Material.ROSE_BUSH || material == Material.PEONY;
+ }
+
+ public static boolean isSmallPlant(Block block) {
+ return isSmallPlant(block.getType());
+ }
+
+ public static boolean isSmallPlant(Material material) {
+ return WaterAbility.isPlant(material);
+ //return SMALL_PLANTS.contains(material);
+ }
+
+ public static void displayColoredParticles(String hex, Location location, int amount, double offsetX, double offsetY, double offsetZ, double extra) {
+ displayColoredParticles(hex, location, amount, offsetX, offsetY, offsetZ, extra, 255);
+ }
+
+ public static void displayColoredParticles(String hex, Location location, int amount, double offsetX, double offsetY, double offsetZ, double extra, int alpha) {
+ JedCore.plugin.getParticleAdapter().displayColoredParticles(hex, location, amount, offsetX, offsetY, offsetZ, extra, alpha);
+ }
+
+ public static void emitLight(Location loc) {
+ LightManagerUtil.emitFirebendingLight(loc);
+ }
+
+ public static void reload() {
+ JedCore.log.info("JedCore Reloaded.");
+ JedCore.plugin.reloadConfig();
+ JedCore.logDebug = JedCoreConfig.getConfig((World)null).getBoolean("Properties.LogDebug");
+ CoreAbility.registerPluginAbilities(JedCore.plugin, "com.jedk1.jedcore.ability");
+ registerDisabledWorlds();
+ registerCombos();
+ RegenTempBlock.revertAll();
+ JedCore.plugin.initializeCollisions();
+ FireTick.loadMethod();
+ new Commands();
+ }
+}
\ No newline at end of file
diff --git a/src/com/jedk1/jedcore/JedCore.java b/src/com/jedk1/jedcore/JedCore.java
index b29466e..2ae6116 100644
--- a/src/com/jedk1/jedcore/JedCore.java
+++ b/src/com/jedk1/jedcore/JedCore.java
@@ -1,25 +1,27 @@
package com.jedk1.jedcore;
-import java.io.IOException;
-import java.util.logging.*;
+import com.cjcrafter.foliascheduler.FoliaCompatibility;
+import com.cjcrafter.foliascheduler.ServerImplementation;
import com.google.common.reflect.ClassPath;
import com.jedk1.jedcore.util.*;
+import com.jedk1.jedcore.command.Commands;
+import com.jedk1.jedcore.configuration.JedCoreConfig;
+import com.jedk1.jedcore.listener.AbilityListener;
+import com.jedk1.jedcore.listener.CommandListener;
+import com.jedk1.jedcore.listener.JCListener;
+import com.jedk1.jedcore.util.ChiRestrictor;
import com.jedk1.jedcore.util.versionadapter.ParticleAdapter;
import com.jedk1.jedcore.util.versionadapter.ParticleAdapterFactory;
import com.jedk1.jedcore.util.versionadapter.PotionEffectAdapter;
import com.jedk1.jedcore.util.versionadapter.PotionEffectAdapterFactory;
+import com.projectkorra.projectkorra.ability.CoreAbility;
+import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.plugin.java.JavaPlugin;
-import com.jedk1.jedcore.command.Commands;
-import com.jedk1.jedcore.configuration.JedCoreConfig;
-import com.jedk1.jedcore.listener.AbilityListener;
-import com.jedk1.jedcore.listener.CommandListener;
-import com.jedk1.jedcore.listener.JCListener;
-import com.jedk1.jedcore.scoreboard.BendingBoard;
-import com.projectkorra.projectkorra.ability.CoreAbility;
-import org.bukkit.scheduler.BukkitRunnable;
+import java.io.IOException;
+import java.util.logging.Logger;
public class JedCore extends JavaPlugin {
@@ -28,61 +30,100 @@ public class JedCore extends JavaPlugin {
public static String dev;
public static String version;
public static boolean logDebug;
+ public static boolean isFolia;
+ public static boolean luminol;
+ public static boolean paper;
+ public static boolean spigot;
+ public static ServerImplementation scheduler;
- private ParticleAdapter particleAdapter;
+ private ParticleAdapter particleAdapter;
private PotionEffectAdapter potionEffectAdapter;
@Override
public void onEnable() {
+ scheduler = new FoliaCompatibility(this).getServerImplementation();
plugin = this;
- JedCore.log = this.getLogger();
+ log = this.getLogger();
new JedCoreConfig(this);
- logDebug = JedCoreConfig.getConfig((World)null).getBoolean("Properties.LogDebug");
-
+ logDebug = JedCoreConfig.getConfig((World) null).getBoolean("Properties.LogDebug");
+
dev = this.getDescription().getAuthors().toString().replace("[", "").replace("]", "");
version = this.getDescription().getVersion();
+ try {
+ Class.forName("io.papermc.paper.threadedregions.RegionizedServer");
+ isFolia = true;
+ } catch (ClassNotFoundException ignored) {}
+
+ try {
+ Class.forName("com.destroystokyo.paper.PaperConfig");
+ paper = true;
+ } catch (ClassNotFoundException ignored) {}
+
+ try {
+ Class.forName("me.earthme.luminol.api.ThreadedRegion");
+ luminol = true;
+ } catch (ClassNotFoundException ignored) {}
+
+
+ if (paper && !luminol) {
+ getLogger().info("Server is running on Paper/Folia");
+ }
+
+ if (luminol) {
+ getLogger().info("Server is running on Luminol");
+ }
+
+ if (!luminol && !isFolia && !paper) {
+ spigot = true;
+ getLogger().info("Server is running on Spigot");
+ }
+
JCMethods.registerDisabledWorlds();
- CoreAbility.registerPluginAbilities(plugin, "com.jedk1.jedcore.ability");
+ CoreAbility.registerPluginAbilities(this, "com.jedk1.jedcore.ability");
+
getServer().getPluginManager().registerEvents(new AbilityListener(this), this);
getServer().getPluginManager().registerEvents(new CommandListener(this), this);
getServer().getPluginManager().registerEvents(new JCListener(this), this);
getServer().getPluginManager().registerEvents(new ChiRestrictor(), this);
- getServer().getScheduler().scheduleSyncRepeatingTask(this, new JCManager(this), 0, 1);
-
- BendingBoard.updateOnline();
- new Commands();
+ // Repeating logic task - uses ThreadUtil
+ ThreadUtil.runGlobalTimer(new JCManager(this), 0L, 1L);
+ ThreadUtil.runGlobalTimer(RegenTempBlock::manage, 0L, 1L);
+
+ new Commands();
FireTick.loadMethod();
- ParticleAdapterFactory particleAdapterFactory = new ParticleAdapterFactory();
- particleAdapter = particleAdapterFactory.getAdapter();
+ particleAdapter = new ParticleAdapterFactory().getAdapter();
+ potionEffectAdapter = new PotionEffectAdapterFactory().getAdapter();
- PotionEffectAdapterFactory potionEffectAdapterFactory = new PotionEffectAdapterFactory();
- potionEffectAdapter = potionEffectAdapterFactory.getAdapter();
+ checkMaintainer();
- new BukkitRunnable() {
- @Override
- public void run() {
- JCMethods.registerCombos();
- BendingBoard.loadOtherCooldowns();
- initializeCollisions();
- }
- }.runTaskLater(this, 1);
-
- try {
- MetricsLite metrics = new MetricsLite(this);
- metrics.start();
- log.info("Initialized Metrics.");
- } catch (IOException e) {
- log.info("Failed to submit statistics for MetricsLite.");
- }
+ // Delayed combo/collision init
+ ThreadUtil.runGlobalLater(() -> {
+ JCMethods.registerCombos();
+ initializeCollisions();
+ }, 1L);
+
+
+ try {
+ MetricsLite metrics = new MetricsLite(this);
+ metrics.start();
+ log.info("Initialized Metrics.");
+ } catch (IOException e) {
+ log.info("Failed to submit statistics for MetricsLite.");
+ }
}
- public void initializeCollisions() {
- boolean enabled = this.getConfig().getBoolean("Properties.AbilityCollisions.Enabled");
+ public static void checkMaintainer() {
+ if (!dev.contains("Cozmyc (Maintainer), Hihelloy (Updater)")) {
+ dev = dev + ", Cozmyc (Maintainer), Hihelloy (Updater)";
+ }
+ }
+ public void initializeCollisions() {
+ boolean enabled = getConfig().getBoolean("Properties.AbilityCollisions.Enabled");
if (!enabled) {
getLogger().info("Collisions disabled.");
return;
@@ -94,21 +135,19 @@ public void initializeCollisions() {
for (ClassPath.ClassInfo info : cp.getTopLevelClassesRecursive("com.jedk1.jedcore.ability")) {
try {
@SuppressWarnings("unchecked")
- Class extends CoreAbility> abilityClass = (Class extends CoreAbility>)Class.forName(info.getName());
-
+ Class extends CoreAbility> abilityClass = (Class extends CoreAbility>) Class.forName(info.getName());
if (abilityClass == null) continue;
CollisionInitializer initializer = new CollisionInitializer<>(abilityClass);
initializer.initialize();
- } catch (Exception e) {
-
- }
+ } catch (Exception ignored) {}
}
} catch (IOException e) {
e.printStackTrace();
}
}
-
+
+ @Override
public void onDisable() {
RegenTempBlock.revertAll();
}
@@ -120,10 +159,30 @@ public static void logDebug(String message) {
}
public ParticleAdapter getParticleAdapter() {
- return this.particleAdapter;
+ return particleAdapter;
}
public PotionEffectAdapter getPotionEffectAdapter() {
- return this.potionEffectAdapter;
+ return potionEffectAdapter;
+ }
+
+ /**
+ *
+ * Determines if the server is running Folia or not
+ */
+ public static boolean isFolia() {
+ return isFolia;
+ }
+
+ public static boolean isPaper() {
+ return paper;
}
+
+ public static boolean isLuminol() {
+ return luminol;
+ }
+
+ public static boolean isSpigot() {
+ return spigot;
+ }
}
diff --git a/src/com/jedk1/jedcore/ability/airbending/AirBlade.java b/src/com/jedk1/jedcore/ability/airbending/AirBlade.java
index 08b814b..c627a35 100644
--- a/src/com/jedk1/jedcore/ability/airbending/AirBlade.java
+++ b/src/com/jedk1/jedcore/ability/airbending/AirBlade.java
@@ -9,257 +9,322 @@
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.region.RegionProtection;
import com.projectkorra.projectkorra.util.DamageHandler;
-
-import org.bukkit.Location;
+import com.projectkorra.projectkorra.util.TempBlock;
+import org.bukkit.*;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
+import org.jetbrains.annotations.NotNull;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
public class AirBlade extends AirAbility implements AddonAbility {
- private Location location;
- private Vector direction;
- private double travelled;
-
- @Attribute("Growth")
- private double growth = 1;
- @Attribute(Attribute.COOLDOWN)
- private long cooldown;
- @Attribute(Attribute.RANGE)
- private double range;
- @Attribute(Attribute.DAMAGE)
- private double damage;
- @Attribute("CollisionRadius")
- private double entityCollisionRadius;
-
- public AirBlade(Player player) {
- super(player);
- if (!bPlayer.canBend(this)) {
- return;
- }
-
- setFields();
-
- this.location = player.getEyeLocation().clone();
- this.direction = player.getEyeLocation().getDirection().clone();
-
- start();
- if (!isRemoved())
- bPlayer.addCooldown(this);
- }
-
- public void setFields() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- cooldown = config.getLong("Abilities.Air.AirBlade.Cooldown");
- range = config.getDouble("Abilities.Air.AirBlade.Range");
- damage = config.getDouble("Abilities.Air.AirBlade.Damage");
- entityCollisionRadius = config.getDouble("Abilities.Air.AirBlade.EntityCollisionRadius");
- }
-
- @Override
- public void progress() {
- if (player.isDead() || !player.isOnline()) {
- remove();
- return;
- }
-
- if (travelled >= range) {
- remove();
- return;
- }
-
- progressBlade();
- }
-
- private void progressBlade() {
- for (int j = 0; j < 2; j++) {
- location = location.add(direction.multiply(1));
- playAirbendingSound(location);
- travelled++;
- growth += 0.125;
- if (travelled >= range) {
- remove();
- return;
- }
-
- if (!isTransparent(location.getBlock())) {
- remove();
- return;
- }
-
- if (RegionProtection.isRegionProtected(player, player.getLocation(), this)) {
- remove();
- return;
- }
-
- double pitch = -location.getPitch();
- Location lastLoc = location.clone();
- for (double i = -90 + pitch; i <= 90 + pitch; i += 8) {
- Location tempLoc = location.clone();
- tempLoc.setPitch(0);
- Vector tempDir = tempLoc.getDirection().clone();
- tempDir.setY(0);
- Vector newDir = tempDir.clone().multiply(growth * Math.cos(Math.toRadians(i)));
- tempLoc.add(newDir);
- tempLoc.setY(tempLoc.getY() + (growth * Math.sin(Math.toRadians(i))));
- playAirbendingParticles(tempLoc, 1, (float) Math.random() / 2, (float) Math.random() / 2, (float) Math.random() / 2);
-
- if (j == 0) {
- // Only check collisions for each block.
- if (!lastLoc.getBlock().getLocation().equals(tempLoc.getBlock().getLocation())) {
- lastLoc = tempLoc;
-
- boolean hit = CollisionDetector.checkEntityCollisions(player, new Sphere(tempLoc.toVector(), entityCollisionRadius), (entity) -> {
- DamageHandler.damageEntity(entity, damage, this);
- remove();
- return true;
- });
-
- if (hit) {
- remove();
- return;
- }
- }
- }
- }
- }
- }
-
- public Player getPlayer() {
- return player;
- }
-
- @Override
- public Location getLocation() {
- return location;
- }
-
- @Override
- public List getLocations() {
- List locations = new ArrayList<>();
-
- double pitch = -location.getPitch();
- for (double i = -90 + pitch; i <= 90 + pitch; i += 8) {
- Location tempLoc = location.clone();
- tempLoc.setPitch(0);
- Vector tempDir = tempLoc.getDirection().clone();
- tempDir.setY(0);
- Vector newDir = tempDir.clone().multiply(growth * Math.cos(Math.toRadians(i)));
- tempLoc.add(newDir);
- tempLoc.setY(tempLoc.getY() + (growth * Math.sin(Math.toRadians(i))));
-
- locations.add(tempLoc);
- }
-
- return locations;
- }
-
- @Override
- public double getCollisionRadius() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getDouble("Abilities.Air.AirBlade.AbilityCollisionRadius");
- }
-
- public long getCooldown() {
- return cooldown;
- }
-
- public void setCooldown(long cooldown) {
- this.cooldown = cooldown;
- }
-
- @Override
- public String getName() {
- return "AirBlade";
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return false;
- }
-
- @Override
- public String getAuthor() {
- return JedCore.dev;
- }
-
- @Override
- public String getVersion() {
- return JedCore.version;
- }
-
- @Override
- public String getDescription() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return "* JedCore Addon *\n" + config.getString("Abilities.Air.AirBlade.Description");
- }
-
- public Vector getDirection() {
- return direction;
- }
-
- public void setDirection(Vector direction) {
- this.direction = direction;
- }
-
- public double getTravelled() {
- return travelled;
- }
-
- public void setTravelled(double travelled) {
- this.travelled = travelled;
- }
-
- public double getGrowth() {
- return growth;
- }
-
- public void setGrowth(double growth) {
- this.growth = growth;
- }
-
- public double getRange() {
- return range;
- }
-
- public void setRange(double range) {
- this.range = range;
- }
-
- public double getDamage() {
- return damage;
- }
-
- public void setDamage(double damage) {
- this.damage = damage;
- }
-
- public double getEntityCollisionRadius() {
- return entityCollisionRadius;
- }
-
- public void setEntityCollisionRadius(double entityCollisionRadius) {
- this.entityCollisionRadius = entityCollisionRadius;
- }
-
- @Override
- public void load() {}
-
- @Override
- public void stop() {}
-
- @Override
- public boolean isEnabled() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getBoolean("Abilities.Air.AirBlade.Enabled");
- }
-}
+ private Set cuttableBlocks;
+
+ private Location location;
+ private Vector direction;
+ private double travelled;
+ private boolean blockCuttingEnabled;
+ private boolean revertCutBlocks;
+ private long revertTime;
+
+ @Attribute("Growth")
+ private double growth = 1;
+ @Attribute(Attribute.COOLDOWN)
+ private long cooldown;
+ @Attribute(Attribute.RANGE)
+ private double range;
+ @Attribute(Attribute.DAMAGE)
+ private double damage;
+ @Attribute("CollisionRadius")
+ private double entityCollisionRadius;
+ @Attribute(Attribute.SPEED)
+ private double speed;
+ @Attribute(Attribute.KNOCKBACK)
+ private double knockback;
+
+ public AirBlade(Player player) {
+ super(player);
+ if (!bPlayer.canBend(this)) {
+ return;
+ }
+
+ setFields();
+
+ this.location = player.getEyeLocation().clone();
+ this.direction = player.getEyeLocation().getDirection().clone();
+
+ start();
+ if (!isRemoved())
+ bPlayer.addCooldown(this);
+ }
+
+ public void setFields() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ cooldown = config.getLong("Abilities.Air.AirBlade.Cooldown");
+ range = config.getDouble("Abilities.Air.AirBlade.Range");
+ damage = config.getDouble("Abilities.Air.AirBlade.Damage");
+ entityCollisionRadius = config.getDouble("Abilities.Air.AirBlade.EntityCollisionRadius");
+ speed = config.getDouble("Abilities.Air.AirBlade.Speed");
+ knockback = config.getDouble("Abilities.Air.AirBlade.Knockback");
+
+ @NotNull ConfigurationSection cuttingConfig = Objects.requireNonNull(config.getConfigurationSection("Abilities.Air.AirBlade.BlockCutting"));
+
+ assert cuttingConfig != null;
+ blockCuttingEnabled = cuttingConfig.getBoolean("Enabled");
+ revertCutBlocks = cuttingConfig.getBoolean("Revert");
+ revertTime = cuttingConfig.getLong("RevertTime");
+ cuttableBlocks = loadCuttableBlocks(cuttingConfig.getStringList("Materials"));
+ }
+
+ @Override
+ public void progress() {
+ if (player.isDead() || !player.isOnline()) {
+ remove();
+ return;
+ }
+
+ if (travelled >= range) {
+ remove();
+ return;
+ }
+
+ progressBlade();
+ }
+
+ private void progressBlade() {
+ for (int j = 0; j < 2; j++) {
+ if (!moveAndCheckCollision()) {
+ return;
+ }
+
+ double pitch = -location.getPitch();
+ Location lastLoc = location.clone();
+
+ for (double i = -90 + pitch; i <= 90 + pitch; i += 8) {
+ Location tempLoc = calculateParticleLocation(i);
+ playAirbendingParticles(tempLoc, 1, (float) Math.random() / 2, (float) Math.random() / 2, (float) Math.random() / 2);
+
+ if (j == 0 && blockCuttingEnabled && cuttableBlocks.contains(tempLoc.getBlock().getType()) && !RegionProtection.isRegionProtected(this.player, tempLoc)) {
+ if (revertCutBlocks) {
+ new TempBlock(tempLoc.getBlock(), Material.AIR.createBlockData(), revertTime);
+ } else {
+ tempLoc.getBlock().breakNaturally();
+ }
+ }
+
+ if (j == 0 && !lastLoc.getBlock().getLocation().equals(tempLoc.getBlock().getLocation())) {
+ if (handleEntityCollision(tempLoc)) {
+ return;
+ }
+ lastLoc = tempLoc;
+ }
+ }
+ }
+ }
+
+ private boolean moveAndCheckCollision() {
+ location = location.add(direction.multiply(speed));
+ playAirbendingSound(location);
+ travelled += speed;
+ growth += 0.125;
+
+ if (travelled >= range ||
+ !isTransparent(location.getBlock()) ||
+ RegionProtection.isRegionProtected(player, player.getLocation(), this)) {
+ remove();
+ return false;
+ }
+ return true;
+ }
+
+ private Location calculateParticleLocation(double angle) {
+ Location tempLoc = location.clone();
+ tempLoc.setPitch(0);
+ Vector tempDir = tempLoc.getDirection().clone();
+ tempDir.setY(0);
+ Vector newDir = tempDir.clone().multiply(growth * Math.cos(Math.toRadians(angle)));
+ tempLoc.add(newDir);
+ tempLoc.setY(tempLoc.getY() + (growth * Math.sin(Math.toRadians(angle))));
+ return tempLoc;
+ }
+
+ private boolean handleEntityCollision(Location tempLoc) {
+ return CollisionDetector.checkEntityCollisions(player, new Sphere(tempLoc.toVector(), entityCollisionRadius), entity -> {
+ DamageHandler.damageEntity(entity, damage, this);
+
+ if (knockback > 0) {
+ Vector knockDir = entity.getLocation().toVector().subtract(location.toVector()).normalize();
+ entity.setVelocity(entity.getVelocity().add(knockDir.multiply(knockback)));
+ }
+
+ remove();
+ return true;
+ });
+ }
+
+ private Set loadCuttableBlocks(List entries) {
+ Set result = new HashSet<>();
+ for (String entry : entries) {
+ if (entry.startsWith("#")) {
+ String tagKey = entry.substring(1).toLowerCase();
+ NamespacedKey ns = NamespacedKey.minecraft(tagKey);
+ Tag tag = Bukkit.getTag(Tag.REGISTRY_BLOCKS, ns, Material.class);
+ if (tag != null) tag.getValues().forEach(result::add);
+ } else {
+ try {
+ result.add(Material.valueOf(entry.toUpperCase()));
+ } catch (IllegalArgumentException ignored) {}
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public Player getPlayer() {
+ return player;
+ }
+
+ @Override
+ public Location getLocation() {
+ return location;
+ }
+
+ @Override
+ public List getLocations() {
+ List locations = new ArrayList<>();
+
+ double pitch = -location.getPitch();
+
+ for (double i = -90 + pitch; i <= 90 + pitch; i += 8) {
+ Location tempLoc = location.clone();
+ tempLoc.setPitch(0);
+
+ Vector tempDir = tempLoc.getDirection().clone();
+ tempDir.setY(0);
+
+ Vector newDir = tempDir.clone().multiply(growth * Math.cos(Math.toRadians(i)));
+ tempLoc.add(newDir);
+ tempLoc.setY(tempLoc.getY() + (growth * Math.sin(Math.toRadians(i))));
+
+ locations.add(tempLoc);
+ }
+
+ return locations;
+ }
+
+ @Override
+ public double getCollisionRadius() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getDouble("Abilities.Air.AirBlade.AbilityCollisionRadius");
+ }
+
+ public long getCooldown() {
+ return cooldown;
+ }
+
+ public void setCooldown(long cooldown) {
+ this.cooldown = cooldown;
+ }
+
+ @Override
+ public String getName() {
+ return "AirBlade";
+ }
+
+ @Override
+ public boolean isHarmlessAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isSneakAbility() {
+ return false;
+ }
+
+ @Override
+ public String getAuthor() {
+ return JedCore.dev;
+ }
+
+ @Override
+ public String getVersion() {
+ return JedCore.version;
+ }
+
+ @Override
+ public String getDescription() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return "* JedCore Addon *\n" + config.getString("Abilities.Air.AirBlade.Description");
+ }
+
+ public Vector getDirection() {
+ return direction;
+ }
+
+ public void setDirection(Vector direction) {
+ this.direction = direction;
+ }
+
+ public double getTravelled() {
+ return travelled;
+ }
+
+ public void setTravelled(double travelled) {
+ this.travelled = travelled;
+ }
+
+ public double getGrowth() {
+ return growth;
+ }
+
+ public void setGrowth(double growth) {
+ this.growth = growth;
+ }
+
+ public double getRange() {
+ return range;
+ }
+
+ public void setRange(double range) {
+ this.range = range;
+ }
+
+ public double getDamage() {
+ return damage;
+ }
+
+ public void setDamage(double damage) {
+ this.damage = damage;
+ }
+
+ public double getEntityCollisionRadius() {
+ return entityCollisionRadius;
+ }
+
+ public void setEntityCollisionRadius(double entityCollisionRadius) {
+ this.entityCollisionRadius = entityCollisionRadius;
+ }
+
+ public double getSpeed() {
+ return speed;
+ }
+
+ public void setSpeed(double speed) {
+ this.speed = speed;
+ }
+
+ @Override
+ public void load() {}
+
+ @Override
+ public void stop() {}
+
+ @Override
+ public boolean isEnabled() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getBoolean("Abilities.Air.AirBlade.Enabled");
+ }
+}
\ No newline at end of file
diff --git a/src/com/jedk1/jedcore/ability/airbending/AirBreath.java b/src/com/jedk1/jedcore/ability/airbending/AirBreath.java
index d563d70..497af20 100644
--- a/src/com/jedk1/jedcore/ability/airbending/AirBreath.java
+++ b/src/com/jedk1/jedcore/ability/airbending/AirBreath.java
@@ -11,10 +11,7 @@
import com.projectkorra.projectkorra.region.RegionProtection;
import com.projectkorra.projectkorra.util.DamageHandler;
import com.projectkorra.projectkorra.util.ParticleEffect;
-
-import org.bukkit.Color;
import org.bukkit.Location;
-import org.bukkit.Particle;
import org.bukkit.block.Block;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.ArmorStand;
@@ -27,37 +24,30 @@
public class AirBreath extends AirAbility implements AddonAbility {
- private boolean isAvatar;
-
- @Attribute(Attribute.COOLDOWN)
- private long cooldown;
- @Attribute(Attribute.DURATION)
- private long duration;
private int particles;
-
private boolean coolLava;
private boolean extinguishFire;
private boolean extinguishMobs;
-
private boolean damageEnabled;
+ private double launch;
+ private boolean regenOxygen;
+ private boolean avatarAmplify;
+ private int avatarRange;
+ private double avatarKnockback;
+
+ @Attribute(Attribute.COOLDOWN)
+ private long cooldown;
+ @Attribute(Attribute.DURATION)
+ private long duration;
@Attribute(Attribute.DAMAGE)
private double playerDamage;
@Attribute(Attribute.DAMAGE)
private double mobDamage;
-
@Attribute(Attribute.KNOCKBACK)
private double knockback;
@Attribute(Attribute.RANGE)
private int range;
- private double launch;
-
- private boolean regenOxygen;
-
- private boolean avatarAmplify;
- private int avatarRange;
- private double avatarKnockback;
-
public AirBreath(Player player) {
super(player);
if (!bPlayer.canBend(this)) {
@@ -65,8 +55,8 @@ public AirBreath(Player player) {
}
setFields();
- isAvatar = bPlayer.isAvatarState();
- if (isAvatar && avatarAmplify) {
+
+ if (bPlayer.isAvatarState() && avatarAmplify) {
range = avatarRange;
knockback = avatarKnockback;
}
@@ -100,16 +90,19 @@ public void progress() {
remove();
return;
}
+
if (!(bPlayer.getBoundAbility() instanceof AirBreath)) {
bPlayer.addCooldown(this);
remove();
return;
}
+
if (!player.isSneaking()) {
bPlayer.addCooldown(this);
remove();
return;
}
+
if (System.currentTimeMillis() < getStartTime() + duration) {
playAirbendingSound(player.getLocation());
createBeam();
@@ -121,9 +114,11 @@ public void progress() {
private boolean isLocationSafe(Location loc) {
Block block = loc.getBlock();
+
if (RegionProtection.isRegionProtected(player, loc, this)) {
return false;
}
+
return isTransparent(block);
}
@@ -139,62 +134,91 @@ private void createBeam() {
size += 0.005;
damageregion += 0.01;
- if (!isLocationSafe(loc)) {
- if (!isTransparent(loc.getBlock())) {
- if (player.getLocation().getPitch() > 30) {
- GeneralMethods.setVelocity(this, player, player.getLocation().getDirection().multiply(-launch));
- }
- }
+ if (!handleLocationSafety(loc)) {
return;
}
- for (Entity entity : GeneralMethods.getEntitiesAroundPoint(loc, damageregion)) {
- if (entity.getEntityId() != player.getEntityId() && !(entity instanceof ArmorStand)) {
- if (RegionProtection.isRegionProtected(this, entity.getLocation()) || ((entity instanceof Player) && Commands.invincible.contains(entity.getName()))){
- continue;
- }
- if (entity instanceof LivingEntity) {
- if (damageEnabled) {
- if (entity instanceof Player)
- DamageHandler.damageEntity(entity, playerDamage, this);
- else
- DamageHandler.damageEntity(entity, mobDamage, this);
- }
-
- if (regenOxygen && isWater(entity.getLocation().getBlock())) {
- if (!((LivingEntity) entity).hasPotionEffect(PotionEffectType.WATER_BREATHING))
- ((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.WATER_BREATHING, 100, 2));
- }
-
- if (extinguishMobs)
- entity.setFireTicks(0);
- }
-
- dir.multiply(knockback);
- GeneralMethods.setVelocity(this, entity, dir);
- }
+ handleEntityCollisions(loc, dir, damageregion);
+ displayBeamParticles(loc, size);
+ handleBlockEffects();
+ }
+ }
+
+ private boolean handleLocationSafety(Location loc) {
+ if (!isLocationSafe(loc)) {
+ if (!isTransparent(loc.getBlock()) && player.getLocation().getPitch() > 30) {
+ GeneralMethods.setVelocity(this, player, player.getLocation().getDirection().multiply(-launch));
}
+ return false;
+ }
+ return true;
+ }
- if (isWater(loc.getBlock())) {
- ParticleEffect.WATER_BUBBLE.display(loc, particles, Math.random(), Math.random(), Math.random(), size);
+ private void handleEntityCollisions(Location loc, Vector dir, double damageregion) {
+ for (Entity entity : GeneralMethods.getEntitiesAroundPoint(loc, damageregion)) {
+ if (isValidTarget(entity)) {
+ if (isEntityProtected(entity)) {
+ continue;
+ }
+ applyEntityEffects(entity, dir);
}
+ }
+ }
- JCMethods.extinguishBlocks(player, "AirBreath", range, 2, extinguishFire, coolLava);
+ private boolean isValidTarget(Entity entity) {
+ return entity.getEntityId() != player.getEntityId() && !(entity instanceof ArmorStand);
+ }
- if (getAirbendingParticles() == ParticleEffect.CLOUD) {
- ParticleEffect.CLOUD.display(loc, particles, Math.random(), Math.random(), Math.random(), size);
- JCMethods.displayColoredParticles("#FFFFFF", loc, particles, Math.random(), Math.random(), Math.random(), 0f);
- JCMethods.displayColoredParticles("#FFFFFF", player.getLocation(), particles, Math.random(), Math.random(), Math.random(), size, 50);
+ private boolean isEntityProtected(Entity entity) {
+ return RegionProtection.isRegionProtected(this, entity.getLocation()) || (entity instanceof Player && Commands.invincible.contains(entity.getName()));
+ }
+
+ private void applyEntityEffects(Entity entity, Vector dir) {
+ if (entity instanceof LivingEntity livingEntity) {
+ applyDamage(livingEntity);
+ applyOxygenRegen(livingEntity);
+ if (extinguishMobs) {
+ livingEntity.setFireTicks(0);
+ }
+ }
+ dir.multiply(knockback);
+ GeneralMethods.setVelocity(this, entity, dir);
+ }
+
+ private void applyDamage(LivingEntity entity) {
+ if (damageEnabled) {
+ if (entity instanceof Player) {
+ DamageHandler.damageEntity(entity, playerDamage, this);
} else {
- getAirbendingParticles().display(loc, particles, Math.random(), Math.random(), Math.random(), size);
+ DamageHandler.damageEntity(entity, mobDamage, this);
}
}
}
- /*
- * @Override public void remove() { if (player.isOnline()) {
- * bPlayer.addCooldown("AirBreath", cooldown); } super.remove(); }
- */
+ private void applyOxygenRegen(LivingEntity entity) {
+ if (regenOxygen && isWater(entity.getLocation().getBlock()) && !entity.hasPotionEffect(PotionEffectType.WATER_BREATHING)) {
+ entity.addPotionEffect(new PotionEffect(PotionEffectType.WATER_BREATHING, 100, 2));
+ }
+ }
+
+ private void displayBeamParticles(Location loc, double size) {
+ if (isWater(loc.getBlock())) {
+ ParticleEffect.WATER_BUBBLE.display(loc, particles, Math.random(), Math.random(), Math.random(), size);
+ }
+
+ ParticleEffect mainParticle = getAirbendingParticles();
+ if (mainParticle == ParticleEffect.CLOUD) {
+ ParticleEffect.CLOUD.display(loc, particles, Math.random(), Math.random(), Math.random(), size);
+ JCMethods.displayColoredParticles("#FFFFFF", loc, particles, Math.random(), Math.random(), Math.random(), 0f);
+ JCMethods.displayColoredParticles("#FFFFFF", player.getLocation(), particles, Math.random(), Math.random(), Math.random(), size, 50);
+ } else if (mainParticle != null) {
+ mainParticle.display(loc, particles, Math.random(), Math.random(), Math.random(), size);
+ }
+ }
+
+ private void handleBlockEffects() {
+ JCMethods.extinguishBlocks(player, "AirBreath", range, 2, extinguishFire, coolLava);
+ }
@Override
public long getCooldown() {
@@ -368,4 +392,4 @@ public boolean isEnabled() {
ConfigurationSection config = JedCoreConfig.getConfig(this.player);
return config.getBoolean("Abilities.Air.AirBreath.Enabled");
}
-}
\ No newline at end of file
+}
diff --git a/src/com/jedk1/jedcore/ability/airbending/AirGlide.java b/src/com/jedk1/jedcore/ability/airbending/AirGlide.java
index 054af57..77c0b1d 100644
--- a/src/com/jedk1/jedcore/ability/airbending/AirGlide.java
+++ b/src/com/jedk1/jedcore/ability/airbending/AirGlide.java
@@ -7,7 +7,6 @@
import com.projectkorra.projectkorra.ability.AddonAbility;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.airbending.AirSpout;
-
import com.projectkorra.projectkorra.attribute.Attribute;
import org.bukkit.Location;
import org.bukkit.block.BlockFace;
@@ -17,19 +16,20 @@
public class AirGlide extends AirAbility implements AddonAbility {
+ private double fallSpeed;
+ private int particles;
+ private boolean airspout;
+ private long lastCooldown;
+ private boolean progressing;
// The player must touch the ground for the cooldown to start if this is true.
private boolean requireGround;
+
@Attribute(Attribute.SPEED)
private double speed;
- private double fallSpeed;
- private int particles;
- private boolean airspout;
@Attribute(Attribute.COOLDOWN)
private long cooldown;
@Attribute(Attribute.DURATION)
private long duration;
- private long lastCooldown;
- private boolean progressing;
public AirGlide(Player player) {
super(player);
@@ -76,13 +76,10 @@ public void progress() {
}
if (CollisionDetector.isOnGround(this.player)) {
- // Flip this so remove() actually removes the instance.
this.requireGround = false;
remove();
} else {
- // Limit how frequently addCooldown is called so bending board isn't spammed with updates.
if (time > lastCooldown + cooldown / 2) {
- // Keep resetting the cooldown until the player touches the ground.
bPlayer.addCooldown(this);
lastCooldown = time;
}
@@ -90,6 +87,7 @@ public void progress() {
}
}
+ @SuppressWarnings("deprecation")
private void update(long time) {
if (this.duration > 0 && time >= this.getStartTime() + this.duration) {
remove();
@@ -113,12 +111,15 @@ private void update(long time) {
if (!player.isOnGround()) {
Location firstLocation = player.getEyeLocation();
+
Vector directionVector = firstLocation.getDirection().normalize();
double distanceFromPlayer = speed;
+
Vector shootFromPlayer = new Vector(directionVector.getX() * distanceFromPlayer, -fallSpeed, directionVector.getZ() * distanceFromPlayer);
firstLocation.add(shootFromPlayer.getX(), shootFromPlayer.getY(), shootFromPlayer.getZ());
GeneralMethods.setVelocity(this, player, shootFromPlayer);
+
playAirbendingParticles(player.getLocation(), particles);
} else if (!isTransparent(player.getLocation().getBlock().getRelative(BlockFace.DOWN))) {
remove();
diff --git a/src/com/jedk1/jedcore/ability/airbending/AirPunch.java b/src/com/jedk1/jedcore/ability/airbending/AirPunch.java
index d776d46..eac83b2 100644
--- a/src/com/jedk1/jedcore/ability/airbending/AirPunch.java
+++ b/src/com/jedk1/jedcore/ability/airbending/AirPunch.java
@@ -11,12 +11,12 @@
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.region.RegionProtection;
import com.projectkorra.projectkorra.util.DamageHandler;
-
import org.bukkit.Location;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -25,6 +25,9 @@ public class AirPunch extends AirAbility implements AddonAbility {
private final Map locations = new ConcurrentHashMap<>();
+ private int shots;
+ private long lastShotTime;
+
@Attribute(Attribute.COOLDOWN)
private long cooldown;
private long threshold;
@@ -35,9 +38,6 @@ public class AirPunch extends AirAbility implements AddonAbility {
@Attribute("CollisionRadius")
private double entityCollisionRadius;
- private int shots;
- private long lastShotTime;
-
public AirPunch(Player player) {
super(player);
@@ -54,8 +54,8 @@ public AirPunch(Player player) {
setFields();
start();
- if (!isRemoved())
- createShot();
+
+ if (!isRemoved()) createShot();
}
public void setFields() {
@@ -107,38 +107,70 @@ private void createShot() {
}
private void progressShots() {
- for (Location l : locations.keySet()) {
- Location loc = l.clone();
- double dist = locations.get(l);
- boolean cancel = false;
- for (int i = 0; i < 3; i++) {
- dist++;
- if (cancel || dist >= range) {
- cancel = true;
- break;
- }
- loc = loc.add(loc.getDirection().clone().multiply(1));
- if (GeneralMethods.isSolid(loc.getBlock()) || isWater(loc.getBlock()) || RegionProtection.isRegionProtected(player, loc, this)) {
- cancel = true;
- break;
- }
+ Iterator> iterator = locations.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry entry = iterator.next();
+ Location originalLoc = entry.getKey();
+ double dist = entry.getValue();
+ ShotResult result = simulateShotProgression(originalLoc, dist);
- getAirbendingParticles().display(loc, 2, Math.random() / 5, Math.random() / 5, Math.random() / 5, 0.0);
- playAirbendingSound(loc);
+ iterator.remove();
- cancel = CollisionDetector.checkEntityCollisions(player, new Sphere(loc.toVector(), entityCollisionRadius), (entity) -> {
- DamageHandler.damageEntity(entity, damage, this);
- return true;
- });
+ if (result.moved) {
+ locations.put(result.newLoc, result.newDist);
}
+ }
+ }
- if (cancel) {
- locations.remove(l);
+ private record ShotResult(Location newLoc, double newDist, boolean moved) {}
+
+ private ShotResult simulateShotProgression(Location startLoc, double startDist) {
+ Location loc = startLoc.clone();
+ double dist = startDist;
+ boolean shouldRemove = false;
+ boolean moved = false;
+
+ for (int i = 0; i < 3 && !shouldRemove; i++) {
+ dist++;
+ if (dist >= range) {
+ shouldRemove = true;
} else {
- locations.remove(l);
- locations.put(loc, dist);
+ Location nextLoc = calculateNextLocation(loc);
+ if (isPathBlocked(nextLoc)) {
+ shouldRemove = true;
+ } else {
+ applyShotEffects(nextLoc);
+ if (checkAndHandleCollision(nextLoc)) {
+ shouldRemove = true;
+ } else {
+ loc = nextLoc;
+ moved = true;
+ }
+ }
}
}
+
+ return new ShotResult(loc, dist, moved);
+ }
+
+ private Location calculateNextLocation(Location currentLocation) {
+ return currentLocation.add(currentLocation.getDirection().clone().multiply(1));
+ }
+
+ private boolean isPathBlocked(Location location) {
+ return GeneralMethods.isSolid(location.getBlock()) || isWater(location.getBlock()) || RegionProtection.isRegionProtected(player, location, this);
+ }
+
+ private void applyShotEffects(Location location) {
+ getAirbendingParticles().display(location, 2, Math.random() / 5, Math.random() / 5, Math.random() / 5, 0.0);
+ playAirbendingSound(location);
+ }
+
+ private boolean checkAndHandleCollision(Location location) {
+ return CollisionDetector.checkEntityCollisions(player, new Sphere(location.toVector(), entityCollisionRadius), entity -> {
+ DamageHandler.damageEntity(entity, damage, this);
+ return true;
+ });
}
@Override
diff --git a/src/com/jedk1/jedcore/ability/airbending/Meditate.java b/src/com/jedk1/jedcore/ability/airbending/Meditate.java
index 8f40caa..c240829 100644
--- a/src/com/jedk1/jedcore/ability/airbending/Meditate.java
+++ b/src/com/jedk1/jedcore/ability/airbending/Meditate.java
@@ -7,7 +7,6 @@
import com.projectkorra.projectkorra.ability.AddonAbility;
import com.projectkorra.projectkorra.ability.SpiritualAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
-
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.configuration.ConfigurationSection;
@@ -18,19 +17,19 @@
public class Meditate extends SpiritualAbility implements AddonAbility {
private double startHealth;
-
private String unfocusMsg;
private long warmup;
- @Attribute(Attribute.COOLDOWN)
- private long cooldown;
- @Attribute(Attribute.DURATION)
- private int boostDuration;
private int particleDensity;
private boolean lossFocusMessage;
private int absorptionBoost;
private int speedBoost;
private int jumpBoost;
+ @Attribute(Attribute.COOLDOWN)
+ private long cooldown;
+ @Attribute(Attribute.DURATION)
+ private int boostDuration;
+
public Meditate(Player player) {
super(player);
if (!bPlayer.canBend(this)) {
@@ -63,20 +62,23 @@ public void progress() {
remove();
return;
}
+
if (!bPlayer.canBendIgnoreCooldowns(this)) {
remove();
return;
}
+
if (player.getHealth() < startHealth) {
- if (lossFocusMessage) {
- player.sendMessage(Element.SPIRITUAL.getColor() + unfocusMsg);
- }
+ if (lossFocusMessage) player.sendMessage(Element.SPIRITUAL.getColor() + unfocusMsg);
remove();
return;
}
+
if (System.currentTimeMillis() > getStartTime() + warmup) {
player.spawnParticle(Particle.ELECTRIC_SPARK, player.getLocation(), 3, 0.5, 0.5, 0.5, 0.003F);
+
JCMethods.displayColoredParticles("#FFFFFF", player.getLocation(), particleDensity, Math.random(), Math.random(), Math.random(), 0f);
+
if (!player.isSneaking()) {
bPlayer.addCooldown(this);
givePlayerBuffs();
@@ -93,6 +95,7 @@ private void givePlayerBuffs() {
if (player.hasPotionEffect(PotionEffectType.SPEED)) {
player.removePotionEffect(PotionEffectType.SPEED);
}
+
player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, boostDuration/50, speedBoost - 1));
JedCore.plugin.getPotionEffectAdapter().applyJumpBoost(player, boostDuration, jumpBoost);
@@ -100,6 +103,7 @@ private void givePlayerBuffs() {
if (player.hasPotionEffect(PotionEffectType.ABSORPTION)) {
player.removePotionEffect(PotionEffectType.ABSORPTION);
}
+
player.addPotionEffect(new PotionEffect(PotionEffectType.ABSORPTION, boostDuration/50, absorptionBoost - 1));
}
diff --git a/src/com/jedk1/jedcore/ability/airbending/SonicBlast.java b/src/com/jedk1/jedcore/ability/airbending/SonicBlast.java
index 0edeb08..5ae22f2 100644
--- a/src/com/jedk1/jedcore/ability/airbending/SonicBlast.java
+++ b/src/com/jedk1/jedcore/ability/airbending/SonicBlast.java
@@ -10,7 +10,6 @@
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.util.DamageHandler;
-
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.configuration.ConfigurationSection;
@@ -26,6 +25,9 @@ public class SonicBlast extends AirAbility implements AddonAbility {
private Vector direction;
private boolean isCharged;
private int travelled;
+ private int nauseaDur;
+ private int blindDur;
+ private boolean chargeSwapping;
@Attribute(Attribute.DAMAGE)
private double damage;
@@ -37,9 +39,6 @@ public class SonicBlast extends AirAbility implements AddonAbility {
private long cooldown;
@Attribute("WarmUp")
private long warmup;
- private int nauseaDur;
- private int blindDur;
- private boolean chargeSwapping;
public SonicBlast(Player player) {
super(player);
@@ -67,40 +66,52 @@ public void setFields() {
@Override
public void progress() {
- if (player.isDead() || !player.isOnline()) {
- remove();
+ if (!checkPlayerState()) {
return;
}
- CoreAbility boundAbility = bPlayer.getBoundAbility();
-
- if (!this.chargeSwapping && this.travelled == 0 && !(boundAbility instanceof SonicBlast)) {
+ if (!canStartAbility()) {
remove();
return;
}
if (player.isSneaking() && travelled == 0) {
- direction = player.getEyeLocation().getDirection().normalize();
+ handleCharging();
+ } else {
+ handleProgression();
+ }
+ }
+
+ private boolean checkPlayerState() {
+ return !player.isDead() && player.isOnline();
+ }
+
+ private boolean canStartAbility() {
+ CoreAbility boundAbility = bPlayer.getBoundAbility();
+ return chargeSwapping || travelled > 0 || boundAbility instanceof SonicBlast;
+ }
- if (isCharged) {
- playAirbendingParticles(player.getLocation().add(0, 1, 0), 5, (float) Math.random(), (float) Math.random(), (float) Math.random());
- } else if (System.currentTimeMillis() > getStartTime() + warmup) {
- isCharged = true;
+ private void handleCharging() {
+ direction = player.getEyeLocation().getDirection().normalize();
+ if (isCharged) {
+ playAirbendingParticles(player.getLocation().add(0, 1, 0), 5, (float) Math.random(), (float) Math.random(), (float) Math.random());
+ } else if (System.currentTimeMillis() > getStartTime() + warmup) {
+ isCharged = true;
+ }
+ }
+
+ private void handleProgression() {
+ if (isCharged) {
+ if (!bPlayer.isOnCooldown(this)) {
+ bPlayer.addCooldown(this);
}
- } else {
- if (isCharged) {
- if (!bPlayer.isOnCooldown(this)) {
- bPlayer.addCooldown(this);
- }
-
- if (travelled < range && isLocationSafe()) {
- advanceLocation();
- } else {
- remove();
- }
+ if (travelled < range && isLocationSafe()) {
+ advanceLocation();
} else {
remove();
}
+ } else {
+ remove();
}
}
@@ -129,7 +140,7 @@ private void advanceLocation() {
playAirbendingParticles(temp, 1, 0, 0, 0);
}
- boolean hit = CollisionDetector.checkEntityCollisions(player, new Sphere(location.toVector(), entityCollisionRadius), (entity) -> {
+ boolean hit = CollisionDetector.checkEntityCollisions(player, new Sphere(location.toVector(), entityCollisionRadius), entity -> {
DamageHandler.damageEntity(entity, damage, this);
LivingEntity lE = (LivingEntity) entity;
diff --git a/src/com/jedk1/jedcore/ability/airbending/combo/AirSlam.java b/src/com/jedk1/jedcore/ability/airbending/combo/AirSlam.java
index de6bbf3..f2f99b3 100644
--- a/src/com/jedk1/jedcore/ability/airbending/combo/AirSlam.java
+++ b/src/com/jedk1/jedcore/ability/airbending/combo/AirSlam.java
@@ -13,8 +13,6 @@
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.object.HorizontalVelocityTracker;
import com.projectkorra.projectkorra.region.RegionProtection;
-import com.projectkorra.projectkorra.util.ClickType;
-
import org.bukkit.Location;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity;
@@ -44,14 +42,16 @@ public AirSlam(Player player) {
setFields();
- Entity target = GeneralMethods.getTargetedEntity(player, range, new ArrayList<>());
- if (!(target instanceof LivingEntity)
- || RegionProtection.isRegionProtected(this, target.getLocation())
- || ((target instanceof Player) && Commands.invincible.contains(target.getName())))
+ Entity targetEntity = GeneralMethods.getTargetedEntity(player, range, new ArrayList<>());
+ if (!(targetEntity instanceof LivingEntity)
+ || RegionProtection.isRegionProtected(this, targetEntity.getLocation())
+ || ((targetEntity instanceof Player) && Commands.invincible.contains(targetEntity.getName())))
return;
- this.target = (LivingEntity) target;
+
+ this.target = (LivingEntity) targetEntity;
start();
+
if (!isRemoved()) {
bPlayer.addCooldown(this);
GeneralMethods.setVelocity(this, target, new Vector(0, 2, 0));
@@ -72,6 +72,7 @@ public void progress() {
remove();
return;
}
+
if (System.currentTimeMillis() > getStartTime() + 50) {
Vector dir = player.getLocation().getDirection();
GeneralMethods.setVelocity(this, target, new Vector(dir.getX(), 0.05, dir.getZ()).multiply(power));
@@ -79,10 +80,12 @@ public void progress() {
new ThrownEntityTracker(this, target, player, 0L);
target.setFallDistance(0);
}
+
if (System.currentTimeMillis() > getStartTime() + 400) {
remove();
return;
}
+
playAirbendingParticles(target.getLocation(), 10);
}
@@ -182,4 +185,4 @@ public boolean isEnabled() {
ConfigurationSection config = JedCoreConfig.getConfig(this.player);
return config.getBoolean("Abilities.Air.AirCombo.AirSlam.Enabled");
}
-}
\ No newline at end of file
+}
diff --git a/src/com/jedk1/jedcore/ability/airbending/combo/SwiftStream.java b/src/com/jedk1/jedcore/ability/airbending/combo/SwiftStream.java
index f5ce42c..0b2929c 100644
--- a/src/com/jedk1/jedcore/ability/airbending/combo/SwiftStream.java
+++ b/src/com/jedk1/jedcore/ability/airbending/combo/SwiftStream.java
@@ -10,8 +10,6 @@
import com.projectkorra.projectkorra.ability.util.ComboUtil;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.object.HorizontalVelocityTracker;
-import com.projectkorra.projectkorra.util.ClickType;
-
import org.bukkit.Location;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity;
@@ -24,22 +22,25 @@
public class SwiftStream extends FlightAbility implements AddonAbility, ComboAbility {
+ private final List affectedEntities = new ArrayList<>();
+
@Attribute(Attribute.COOLDOWN)
public long cooldown;
+ @Attribute("DragFactor")
public double dragFactor;
@Attribute(Attribute.DURATION)
public long duration;
- private final List affectedEntities = new ArrayList<>();
-
public SwiftStream(Player player) {
super(player);
+
if (!bPlayer.canBendIgnoreBinds(this) || !bPlayer.canUseFlight()) {
return;
}
setFields();
start();
+
if (!isRemoved()) {
launch();
bPlayer.addCooldown(this);
@@ -65,17 +66,16 @@ public void launch() {
public void affectNearby() {
for (Entity e : GeneralMethods.getEntitiesAroundPoint(player.getLocation(), 2.5)) {
- if (e instanceof LivingEntity && !affectedEntities.contains(e) && e.getEntityId() != player.getEntityId()) {
+ if (e instanceof LivingEntity livingEntity && !affectedEntities.contains(e) && e.getEntityId() != player.getEntityId()) {
Vector v = player.getVelocity().clone();
-
v = v.multiply(dragFactor);
-
v = v.setY(player.getVelocity().getY());
-
v = v.add(new Vector(0, 0.15, 0));
GeneralMethods.setVelocity(this, e, v);
- affectedEntities.add((LivingEntity) e);
+
+ affectedEntities.add(livingEntity);
+
new HorizontalVelocityTracker(e, player, 200, this);
}
}
@@ -194,4 +194,4 @@ public boolean isEnabled() {
ConfigurationSection config = JedCoreConfig.getConfig(this.player);
return config.getBoolean("Abilities.Air.AirCombo.SwiftStream.Enabled");
}
-}
\ No newline at end of file
+}
diff --git a/src/com/jedk1/jedcore/ability/avatar/SpiritBeam.java b/src/com/jedk1/jedcore/ability/avatar/SpiritBeam.java
index 923b772..689a3b5 100644
--- a/src/com/jedk1/jedcore/ability/avatar/SpiritBeam.java
+++ b/src/com/jedk1/jedcore/ability/avatar/SpiritBeam.java
@@ -11,13 +11,9 @@
import com.projectkorra.projectkorra.region.RegionProtection;
import com.projectkorra.projectkorra.util.DamageHandler;
import com.projectkorra.projectkorra.util.ParticleEffect;
-
-import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.Material;
-import org.bukkit.Particle;
import org.bukkit.configuration.ConfigurationSection;
-import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
@@ -25,33 +21,31 @@
public class SpiritBeam extends AvatarAbility implements AddonAbility {
- private Location location;
+ private Location location;
private Vector direction;
+ private boolean damagesBlocks;
+ private long regen;
+ private boolean avatarOnly;
+
@Attribute(Attribute.DURATION)
private long duration;
@Attribute(Attribute.COOLDOWN)
private long cooldown;
@Attribute(Attribute.RANGE)
private double range;
- private boolean avatarOnly;
@Attribute(Attribute.DAMAGE)
private double damage;
- private boolean damagesBlocks;
- private long regen;
@Attribute(Attribute.RADIUS)
private double radius;
public SpiritBeam(Player player) {
super(player);
- if (bPlayer.isOnCooldown(this)) {
- return;
- }
+
+ if (bPlayer.isOnCooldown(this)) return;
setFields();
- if (avatarOnly && !bPlayer.isAvatarState()) {
- return;
- }
+ if (avatarOnly && !bPlayer.isAvatarState()) return;
start();
}
@@ -75,64 +69,93 @@ public void progress() {
remove();
return;
}
+
if (!bPlayer.canBendIgnoreBindsCooldowns(this)) {
bPlayer.addCooldown(this);
remove();
return;
}
+
if (System.currentTimeMillis() > getStartTime() + duration) {
bPlayer.addCooldown(this);
remove();
return;
}
+
if (!player.isSneaking()) {
bPlayer.addCooldown(this);
remove();
return;
}
+
if (avatarOnly && !bPlayer.isAvatarState()) {
bPlayer.addCooldown(this);
remove();
return;
}
+
createBeam();
}
private void createBeam() {
location = player.getLocation().add(0, 1.2, 0);
- direction = location.getDirection();
+ Vector beamDirection = location.getDirection().normalize().multiply(0.5);
+
for (double i = 0; i < range; i += 0.5) {
- location = location.add(direction.multiply(0.5).normalize());
+ location = location.add(beamDirection);
- if (RegionProtection.isRegionProtected(player, location, this)) {
+ if (isBeamObstructed(location)) {
return;
}
- JCMethods.displayColoredParticles("#A020F0", location, 1, 0f, 0f, 0f, 0f);
- JCMethods.displayColoredParticles("#A020F0", location, 1, (float) Math.random() / 3, (float) Math.random() / 3, (float) Math.random() / 3, 0f);
+ displayBeamParticles(location, beamDirection);
+ JCMethods.emitLight(location);
+ damageNearbyEntities(location);
+
+ if (handleBlockCollision(location)) {
+ return;
+ }
+ }
+ }
- ParticleEffect.BLOCK_CRACK.display(location, 1,(float) Math.random() / 3, (float) Math.random() / 3, (float) Math.random() / 3, 0.1F, Material.NETHER_PORTAL.createBlockData());
- ParticleEffect.BLOCK_CRACK.display(location, 1, direction.getX(), direction.getY(), direction.getZ(), 0.1F, Material.NETHER_PORTAL.createBlockData());
+ private boolean isBeamObstructed(Location location) {
+ return RegionProtection.isRegionProtected(player, location, this);
+ }
- JCMethods.emitLight(location);
+ private void displayBeamParticles(Location location, Vector direction) {
+ String purple = "#A020F0";
+ JCMethods.displayColoredParticles(purple, location, 1, 0f, 0f, 0f, 0f);
+ JCMethods.displayColoredParticles(purple, location, 1, (float) Math.random() / 3, (float) Math.random() / 3, (float) Math.random() / 3, 0f);
- for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2)) {
- if (entity instanceof LivingEntity && entity.getEntityId() != player.getEntityId() && !(entity instanceof ArmorStand)) {
- entity.setFireTicks(100);
- DamageHandler.damageEntity(entity, damage, this);
- }
+ float randomOffset = (float) Math.random() / 3;
+ ParticleEffect.BLOCK_CRACK.display(location, 1, randomOffset, randomOffset, randomOffset, 0.1F, Material.NETHER_PORTAL.createBlockData());
+ ParticleEffect.BLOCK_CRACK.display(location, 1, (float) direction.getX(), (float) direction.getY(), (float) direction.getZ(), 0.1F, Material.NETHER_PORTAL.createBlockData());
+ }
+
+ private void damageNearbyEntities(Location location) {
+ for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2)) {
+ if (entity instanceof LivingEntity livingEntity && livingEntity.getEntityId() != player.getEntityId()) {
+ livingEntity.setFireTicks(100);
+ DamageHandler.damageEntity(livingEntity, damage, this);
}
+ }
+ }
- if (location.getBlock().getType().isSolid()) {
- location.getWorld().createExplosion(location, 0F);
- if (damagesBlocks) {
- //new TempExplosion(player, location.getBlock(), "SpiritBeam", radius, regen, damage, false);
- for (Location loc : GeneralMethods.getCircle(location, (int) radius, 0, false, true, 0)) {
- if (JCMethods.isUnbreakable(loc.getBlock())) continue;
- new RegenTempBlock(loc.getBlock(), Material.AIR, Material.AIR.createBlockData(), regen, false);
- }
- }
- return;
+ private boolean handleBlockCollision(Location location) {
+ if (location.getBlock().getType().isSolid()) {
+ location.getWorld().createExplosion(location, 0F);
+ if (damagesBlocks) {
+ damageBlocksInRadius(location);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private void damageBlocksInRadius(Location center) {
+ for (Location loc : GeneralMethods.getCircle(center, (int) radius, 0, false, true, 0)) {
+ if (!JCMethods.isUnbreakable(loc.getBlock())) {
+ new RegenTempBlock(loc.getBlock(), Material.AIR, Material.AIR.createBlockData(), regen, false);
}
}
}
diff --git a/src/com/jedk1/jedcore/ability/avatar/elementsphere/ESAir.java b/src/com/jedk1/jedcore/ability/avatar/elementsphere/ESAir.java
index bff4481..a7e0820 100644
--- a/src/com/jedk1/jedcore/ability/avatar/elementsphere/ESAir.java
+++ b/src/com/jedk1/jedcore/ability/avatar/elementsphere/ESAir.java
@@ -10,7 +10,6 @@
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.region.RegionProtection;
import com.projectkorra.projectkorra.util.DamageHandler;
-
import org.bukkit.Location;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.ArmorStand;
@@ -36,22 +35,30 @@ public class ESAir extends AvatarAbility implements AddonAbility {
public ESAir(Player player) {
super(player);
+
if (!hasAbility(player, ElementSphere.class)) {
return;
}
+
ElementSphere currES = getAbility(player, ElementSphere.class);
if (currES.getAirUses() == 0) {
return;
}
+
if (bPlayer.isOnCooldown("ESAir")) {
return;
}
+
setFields();
+
if (RegionProtection.isRegionProtected(this, player.getTargetBlock(getTransparentMaterialSet(), (int) range).getLocation())) {
return;
}
+
location = player.getEyeLocation().clone().add(player.getEyeLocation().getDirection().multiply(1));
+
start();
+
if (!isRemoved()) {
bPlayer.addCooldown("ESAir", getCooldown());
currES.setAirUses(currES.getAirUses() - 1);
@@ -74,23 +81,27 @@ public void progress() {
remove();
return;
}
+
if (travelled >= range) {
remove();
return;
}
+
advanceAttack();
}
private void advanceAttack() {
for (int i = 0; i < speed; i++) {
travelled++;
- if (travelled >= range)
- return;
+ if (travelled >= range) return;
+
location = location.add(location.getDirection().clone().multiply(1));
+
if (RegionProtection.isRegionProtected(this, location)) {
travelled = range;
return;
}
+
if (GeneralMethods.isSolid(location.getBlock()) || isWater(location.getBlock())) {
travelled = range;
return;
@@ -100,7 +111,11 @@ private void advanceAttack() {
AirAbility.playAirbendingSound(location);
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2.5)) {
- if (entity instanceof LivingEntity && entity.getEntityId() != player.getEntityId() && !(entity instanceof ArmorStand) && !RegionProtection.isRegionProtected(this, entity.getLocation()) && !((entity instanceof Player) && Commands.invincible.contains(((Player) entity).getName()))) {
+ if (entity instanceof LivingEntity && entity.getEntityId() != player.getEntityId()
+ && !(entity instanceof ArmorStand)
+ && !RegionProtection.isRegionProtected(this, entity.getLocation())
+ && !((entity instanceof Player targetPlayer)
+ && Commands.invincible.contains((targetPlayer).getName()))) {
DamageHandler.damageEntity(entity, damage, this);
GeneralMethods.setVelocity(this, entity, location.getDirection().multiply(knockback));
travelled = range;
diff --git a/src/com/jedk1/jedcore/ability/avatar/elementsphere/ESEarth.java b/src/com/jedk1/jedcore/ability/avatar/elementsphere/ESEarth.java
index 9113ecf..05832ec 100644
--- a/src/com/jedk1/jedcore/ability/avatar/elementsphere/ESEarth.java
+++ b/src/com/jedk1/jedcore/ability/avatar/elementsphere/ESEarth.java
@@ -13,7 +13,6 @@
import com.projectkorra.projectkorra.region.RegionProtection;
import com.projectkorra.projectkorra.util.DamageHandler;
import com.projectkorra.projectkorra.util.ParticleEffect;
-
import com.projectkorra.projectkorra.util.TempFallingBlock;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -21,204 +20,196 @@
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.configuration.ConfigurationSection;
-import org.bukkit.entity.ArmorStand;
-import org.bukkit.entity.Entity;
-import org.bukkit.entity.FallingBlock;
-import org.bukkit.entity.LivingEntity;
-import org.bukkit.entity.Player;
+import org.bukkit.entity.*;
import java.util.Arrays;
-import java.util.Random;
+import java.util.concurrent.ThreadLocalRandom;
public class ESEarth extends AvatarAbility implements AddonAbility {
- private long revertDelay;
- @Attribute(Attribute.DAMAGE)
- private double damage;
- @Attribute("Size")
- private int impactSize;
- @Attribute(Attribute.COOLDOWN)
- private long cooldown;
- private TempFallingBlock tfb;
-
- static Random rand = new Random();
-
- public ESEarth(Player player) {
- super(player);
- if (!hasAbility(player, ElementSphere.class)) {
- return;
- }
- ElementSphere currES = getAbility(player, ElementSphere.class);
- if (currES.getEarthUses() == 0) {
- return;
- }
- if (bPlayer.isOnCooldown("ESEarth")) {
- return;
- }
- if (RegionProtection.isRegionProtected(this, player.getTargetBlock(getTransparentMaterialSet(), 40).getLocation())) {
- return;
- }
- setFields();
- start();
- if (!isRemoved()) {
- bPlayer.addCooldown("ESEarth", getCooldown());
- currES.setEarthUses(currES.getEarthUses() - 1);
- Location location = player.getEyeLocation().clone().add(player.getEyeLocation().getDirection().multiply(1));
- tfb = new TempFallingBlock(location, Material.DIRT.createBlockData(), location.getDirection().multiply(3), this);
- }
- }
-
- public void setFields() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- revertDelay = config.getLong("Abilities.Avatar.ElementSphere.Earth.ImpactRevert");
- damage = config.getDouble("Abilities.Avatar.ElementSphere.Earth.Damage");
- impactSize = config.getInt("Abilities.Avatar.ElementSphere.Earth.ImpactCraterSize");
- cooldown = config.getLong("Abilities.Avatar.ElementSphere.Earth.Cooldown");
- }
-
- @Override
- public void progress() {
- if (player == null || !player.isOnline()) {
- tfb.remove();
- remove();
- return;
- }
- if (tfb.getFallingBlock().isDead()) {
- remove();
- return;
- }
- if (RegionProtection.isRegionProtected(this, tfb.getLocation())){
- remove();
- return;
- }
-
- EarthAbility.playEarthbendingSound(tfb.getLocation());
-
- for (Entity entity : GeneralMethods.getEntitiesAroundPoint(tfb.getLocation(), 2.5)) {
- if (entity instanceof LivingEntity && !(entity instanceof ArmorStand) && entity.getEntityId() != player.getEntityId() && !RegionProtection.isRegionProtected(this, entity.getLocation()) && !((entity instanceof Player) && Commands.invincible.contains(((Player) entity).getName()))) {
- //explodeEarth(fb);
- DamageHandler.damageEntity(entity, damage, this);
- }
- }
- }
-
- public static void explodeEarth(TempFallingBlock tempfallingblock) {
- FallingBlock fb = tempfallingblock.getFallingBlock();
- ESEarth es = (ESEarth) tempfallingblock.getAbility();
- Player player = es.getPlayer();
-
- ParticleEffect.SMOKE_LARGE.display(fb.getLocation(), 0, 0, 0, 0.3F, 25);
- fb.getWorld().playSound(fb.getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 2f, 0.5f);
-
- for (Location l : GeneralMethods.getCircle(fb.getLocation(), es.impactSize, 1, false, true, 0)) {
- //if (TempBlock.isTempBlock(l.getBlock())) {
- // TempBlock.revertBlock(l.getBlock(), Material.AIR);
- // TempBlock.removeBlock(l.getBlock());
- //}
- if (isBreakable(l.getBlock()) && !RegionProtection.isRegionProtected(player, l, "ElementSphere") && EarthAbility.isEarthbendable(player, l.getBlock())) {
- ParticleEffect.SMOKE_LARGE.display(l, 0, 0, 0, 0.1F, 2);
- //new RegenTempBlock(l.getBlock(), Material.AIR, (byte) 0, (long) rand.nextInt((int) es.revertDelay - (int) (es.revertDelay - 1000)) + (es.revertDelay - 1000));
- new RegenTempBlock(l.getBlock(), Material.AIR, Material.AIR.createBlockData(), (long) rand.nextInt((int) es.revertDelay - (int) (es.revertDelay - 1000)) + (es.revertDelay - 1000), false);
- }
-
- if (GeneralMethods.isSolid(l.getBlock().getRelative(BlockFace.DOWN)) && isBreakable(l.getBlock()) && ElementalAbility.isAir(l.getBlock().getType()) && rand.nextInt(20) == 0 && EarthAbility.isEarthbendable(player, l.getBlock().getRelative(BlockFace.DOWN))) {
- Material type = l.getBlock().getRelative(BlockFace.DOWN).getType();
- new RegenTempBlock(l.getBlock(), type, type.createBlockData(), (long) rand.nextInt((int) es.revertDelay - (int) (es.revertDelay - 1000)) + (es.revertDelay - 1000));
- }
- }
-
- tempfallingblock.remove();
- }
-
- static Material[] unbreakables = { Material.BEDROCK, Material.BARRIER, Material.NETHER_PORTAL, Material.END_PORTAL,
- Material.END_PORTAL_FRAME, Material.ENDER_CHEST, Material.CHEST, Material.TRAPPED_CHEST };
-
- public static boolean isBreakable(Block block) {
- return !Arrays.asList(unbreakables).contains(block.getType());
- }
-
- @Override
- public long getCooldown() {
- return cooldown;
- }
-
- @Override
- public Location getLocation() {
- return tfb != null ? tfb.getLocation() : null;
- }
-
- @Override
- public String getName() {
- return "ElementSphereEarth";
- }
-
- @Override
- public boolean isHiddenAbility() {
- return true;
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return false;
- }
-
- @Override
- public String getAuthor() {
- return JedCore.dev;
- }
-
- @Override
- public String getVersion() {
- return JedCore.version;
- }
-
- @Override
- public String getDescription() {
- return null;
- }
-
- public long getRevertDelay() {
- return revertDelay;
- }
-
- public void setRevertDelay(long revertDelay) {
- this.revertDelay = revertDelay;
- }
-
- public double getDamage() {
- return damage;
- }
-
- public void setDamage(double damage) {
- this.damage = damage;
- }
-
- public int getImpactSize() {
- return impactSize;
- }
-
- public void setImpactSize(int impactSize) {
- this.impactSize = impactSize;
- }
-
- public TempFallingBlock getTempFallingBlock() {
- return tfb;
- }
-
- @Override
- public void load() {}
-
- @Override
- public void stop() {}
-
- @Override
- public boolean isEnabled() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getBoolean("Abilities.Avatar.ElementSphere.Enabled");
- }
-}
+ static Material[] unbreakables = { Material.BEDROCK, Material.BARRIER, Material.NETHER_PORTAL, Material.END_PORTAL,
+ Material.END_PORTAL_FRAME, Material.ENDER_CHEST, Material.CHEST, Material.TRAPPED_CHEST };
+
+ private TempFallingBlock tfb;
+ private long revertDelay;
+
+ @Attribute(Attribute.DAMAGE)
+ private double damage;
+ @Attribute("Size")
+ private int impactSize;
+ @Attribute(Attribute.COOLDOWN)
+ private long cooldown;
+
+ public ESEarth(Player player) {
+ super(player);
+ if (!hasAbility(player, ElementSphere.class)) {
+ return;
+ }
+ ElementSphere currES = getAbility(player, ElementSphere.class);
+ if (currES.getEarthUses() == 0) {
+ return;
+ }
+ if (bPlayer.isOnCooldown("ESEarth")) {
+ return;
+ }
+ if (RegionProtection.isRegionProtected(this, player.getTargetBlock(getTransparentMaterialSet(), 40).getLocation())) {
+ return;
+ }
+ setFields();
+ start();
+ if (!isRemoved()) {
+ bPlayer.addCooldown("ESEarth", getCooldown());
+ currES.setEarthUses(currES.getEarthUses() - 1);
+ Location location = player.getEyeLocation().clone().add(player.getEyeLocation().getDirection().multiply(1));
+ tfb = new TempFallingBlock(location, Material.DIRT.createBlockData(), location.getDirection().multiply(3), this);
+ }
+ }
+
+ public void setFields() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ revertDelay = config.getLong("Abilities.Avatar.ElementSphere.Earth.ImpactRevert");
+ damage = config.getDouble("Abilities.Avatar.ElementSphere.Earth.Damage");
+ impactSize = config.getInt("Abilities.Avatar.ElementSphere.Earth.ImpactCraterSize");
+ cooldown = config.getLong("Abilities.Avatar.ElementSphere.Earth.Cooldown");
+ }
+
+ @Override
+ public void progress() {
+ if (player == null || !player.isOnline()) {
+ tfb.remove();
+ remove();
+ return;
+ }
+ if (tfb.getFallingBlock().isDead()) {
+ remove();
+ return;
+ }
+ if (RegionProtection.isRegionProtected(this, tfb.getLocation())){
+ remove();
+ return;
+ }
+
+ EarthAbility.playEarthbendingSound(tfb.getLocation());
+
+ for (Entity entity : GeneralMethods.getEntitiesAroundPoint(tfb.getLocation(), 2.5)) {
+ if (entity instanceof LivingEntity && !(entity instanceof ArmorStand) && entity.getEntityId() != player.getEntityId() && !RegionProtection.isRegionProtected(this, entity.getLocation()) && !((entity instanceof Player targetPlayer) && Commands.invincible.contains(targetPlayer.getName()))) {
+ DamageHandler.damageEntity(entity, damage, this);
+ }
+ }
+ }
+
+ // Unused
+ public static void explodeEarth(TempFallingBlock tempfallingblock) {
+ FallingBlock fb = tempfallingblock.getFallingBlock();
+ ESEarth es = (ESEarth) tempfallingblock.getAbility();
+ Player player = es.getPlayer();
+
+ ParticleEffect.SMOKE_LARGE.display(fb.getLocation(), 0, 0, 0, 0.3F, 25);
+ fb.getWorld().playSound(fb.getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 2f, 0.5f);
+
+ ThreadLocalRandom rand = ThreadLocalRandom.current();
+
+ for (Location l : GeneralMethods.getCircle(fb.getLocation(), es.impactSize, 1, false, true, 0)) {
+ if (isBreakable(l.getBlock()) && !RegionProtection.isRegionProtected(player, l, "ElementSphere") && EarthAbility.isEarthbendable(player, l.getBlock())) {
+ ParticleEffect.SMOKE_LARGE.display(l, 0, 0, 0, 0.1F, 2);
+ new RegenTempBlock(l.getBlock(), Material.AIR, Material.AIR.createBlockData(), rand.nextInt((int) es.revertDelay - (int) (es.revertDelay - 1000)) + (es.revertDelay - 1000), false);
+ }
+
+ if (GeneralMethods.isSolid(l.getBlock().getRelative(BlockFace.DOWN)) && isBreakable(l.getBlock()) && ElementalAbility.isAir(l.getBlock().getType()) && rand.nextInt(20) == 0 && EarthAbility.isEarthbendable(player, l.getBlock().getRelative(BlockFace.DOWN))) {
+ Material type = l.getBlock().getRelative(BlockFace.DOWN).getType();
+ new RegenTempBlock(l.getBlock(), type, type.createBlockData(), rand.nextInt((int) es.revertDelay - (int) (es.revertDelay - 1000)) + (es.revertDelay - 1000));
+ }
+ }
+
+ tempfallingblock.remove();
+ }
+
+ public static boolean isBreakable(Block block) {
+ return !Arrays.asList(unbreakables).contains(block.getType());
+ }
+
+ @Override
+ public long getCooldown() {
+ return cooldown;
+ }
+
+ @Override
+ public Location getLocation() {
+ return tfb != null ? tfb.getLocation() : null;
+ }
+
+ @Override
+ public String getName() {
+ return "ElementSphereEarth";
+ }
+
+ @Override
+ public boolean isHiddenAbility() {
+ return true;
+ }
+
+ @Override
+ public boolean isHarmlessAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isSneakAbility() {
+ return false;
+ }
+
+ @Override
+ public String getAuthor() {
+ return JedCore.dev;
+ }
+
+ @Override
+ public String getVersion() {
+ return JedCore.version;
+ }
+
+ @Override
+ public String getDescription() {
+ return null;
+ }
+
+ public long getRevertDelay() {
+ return revertDelay;
+ }
+
+ public void setRevertDelay(long revertDelay) {
+ this.revertDelay = revertDelay;
+ }
+
+ public double getDamage() {
+ return damage;
+ }
+
+ public void setDamage(double damage) {
+ this.damage = damage;
+ }
+
+ public int getImpactSize() {
+ return impactSize;
+ }
+
+ public void setImpactSize(int impactSize) {
+ this.impactSize = impactSize;
+ }
+
+ public TempFallingBlock getTempFallingBlock() {
+ return tfb;
+ }
+
+ @Override
+ public void load() {}
+
+ @Override
+ public void stop() {}
+
+ @Override
+ public boolean isEnabled() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getBoolean("Abilities.Avatar.ElementSphere.Enabled");
+ }
+}
\ No newline at end of file
diff --git a/src/com/jedk1/jedcore/ability/avatar/elementsphere/ESFire.java b/src/com/jedk1/jedcore/ability/avatar/elementsphere/ESFire.java
index a377d39..32ec393 100644
--- a/src/com/jedk1/jedcore/ability/avatar/elementsphere/ESFire.java
+++ b/src/com/jedk1/jedcore/ability/avatar/elementsphere/ESFire.java
@@ -4,8 +4,8 @@
import com.jedk1.jedcore.JedCore;
import com.jedk1.jedcore.configuration.JedCoreConfig;
import com.projectkorra.projectkorra.Element;
-import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.Element.SubElement;
+import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AddonAbility;
import com.projectkorra.projectkorra.ability.AvatarAbility;
import com.projectkorra.projectkorra.ability.BlueFireAbility;
@@ -16,7 +16,6 @@
import com.projectkorra.projectkorra.region.RegionProtection;
import com.projectkorra.projectkorra.util.DamageHandler;
import com.projectkorra.projectkorra.util.ParticleEffect;
-
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
@@ -32,6 +31,7 @@ public class ESFire extends AvatarAbility implements AddonAbility {
private Location location;
private Vector direction;
private double travelled;
+ private boolean controllable;
@Attribute(Attribute.COOLDOWN)
private long cooldown;
@@ -43,22 +43,26 @@ public class ESFire extends AvatarAbility implements AddonAbility {
private long burnTime;
@Attribute(Attribute.SPEED)
private int speed;
- private boolean controllable;
public ESFire(Player player) {
super(player);
+
if (!hasAbility(player, ElementSphere.class)) {
return;
}
+
ElementSphere currES = getAbility(player, ElementSphere.class);
if (currES.getFireUses() == 0) {
return;
}
+
if (bPlayer.isOnCooldown("ESFire")) {
return;
}
+
setFields();
start();
+
if (!isRemoved()) {
bPlayer.addCooldown("ESFire", getCooldown());
currES.setFireUses(currES.getFireUses() - 1);
@@ -82,7 +86,7 @@ public void setFields() {
private void applyModifiers() {
if (bPlayer.canUseSubElement(SubElement.BLUE_FIRE)) {
- cooldown *= BlueFireAbility.getCooldownFactor();
+ cooldown *= (long) BlueFireAbility.getCooldownFactor();
range *= BlueFireAbility.getRangeFactor();
damage *= BlueFireAbility.getDamageFactor();
}
@@ -94,51 +98,85 @@ public void progress() {
remove();
return;
}
+
if (travelled >= range) {
remove();
return;
}
+
advanceAttack();
}
private void advanceAttack() {
for (int i = 0; i < speed; i++) {
- travelled++;
- if (travelled >= range)
+ if (!incrementTravelledAndCheckRange()) {
return;
+ }
- if (!player.isDead() && controllable)
- direction = GeneralMethods.getDirection(player.getLocation(), GeneralMethods.getTargetedLocation(player, range, Material.WATER)).normalize();
+ updateDirectionIfControllable();
- location = location.add(direction.clone().multiply(1));
- if (RegionProtection.isRegionProtected(this, location)) {
- travelled = range;
- return;
- }
- if (GeneralMethods.isSolid(location.getBlock()) || isWater(location.getBlock())) {
- travelled = range;
+ location.add(direction.clone().multiply(1));
+
+ if (checkEnvironmentCollision()) {
return;
}
- ParticleEffect flame = bPlayer.hasSubElement(Element.BLUE_FIRE) ? ParticleEffect.SOUL_FIRE_FLAME : ParticleEffect.FLAME;
- flame.display(location, 5, Math.random(), Math.random(), Math.random(), 0.02);
- ParticleEffect.SMOKE_LARGE.display(location, 2, Math.random(), Math.random(), Math.random(), 0.01);
- FireAbility.playFirebendingSound(location);
+ displayAttackParticles();
+ playAttackSoundsAndLight();
+ placeFire();
+ handleEntityCollisions();
+ }
+ }
- JCMethods.emitLight(location);
+ private boolean incrementTravelledAndCheckRange() {
+ travelled++;
+ return travelled < range;
+ }
- placeFire();
+ private void updateDirectionIfControllable() {
+ if (!player.isDead() && controllable) {
+ direction = GeneralMethods.getDirection(player.getLocation(), GeneralMethods.getTargetedLocation(player, range, Material.WATER)).normalize();
+ }
+ }
+
+ private boolean checkEnvironmentCollision() {
+ if (RegionProtection.isRegionProtected(this, location) || GeneralMethods.isSolid(location.getBlock()) || isWater(location.getBlock())) {
+ travelled = range;
+ return true;
+ }
+ return false;
+ }
+
+ private void displayAttackParticles() {
+ ParticleEffect flame = bPlayer.hasSubElement(Element.BLUE_FIRE) ? ParticleEffect.SOUL_FIRE_FLAME : ParticleEffect.FLAME;
+ flame.display(location, 5, Math.random(), Math.random(), Math.random(), 0.02);
+ ParticleEffect.SMOKE_LARGE.display(location, 2, Math.random(), Math.random(), Math.random(), 0.01);
+ }
+
+ private void playAttackSoundsAndLight() {
+ FireAbility.playFirebendingSound(location);
+ JCMethods.emitLight(location);
+ }
- for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2.5)) {
- if (entity instanceof LivingEntity && entity.getEntityId() != player.getEntityId() && !(entity instanceof ArmorStand) && !RegionProtection.isRegionProtected(this, entity.getLocation()) && !((entity instanceof Player) && Commands.invincible.contains(((Player) entity).getName()))) {
- DamageHandler.damageEntity(entity, damage, this);
- entity.setFireTicks(Math.round(burnTime / 50F));
- travelled = range;
- }
+ private void handleEntityCollisions() {
+ for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2.5)) {
+ if (isAttackableEntity(entity)) {
+ DamageHandler.damageEntity(entity, damage, this);
+ entity.setFireTicks(Math.round(burnTime / 50F));
+ travelled = range;
+ return;
}
}
}
+ private boolean isAttackableEntity(Entity entity) {
+ return entity instanceof LivingEntity &&
+ entity.getEntityId() != player.getEntityId() &&
+ !(entity instanceof ArmorStand) &&
+ !RegionProtection.isRegionProtected(this, entity.getLocation()) &&
+ !((entity instanceof Player targetPlayer) && Commands.invincible.contains((targetPlayer).getName()));
+ }
+
private void placeFire() {
if (GeneralMethods.isSolid(location.getBlock().getRelative(BlockFace.DOWN))) {
location.getBlock().setType(Material.FIRE);
diff --git a/src/com/jedk1/jedcore/ability/avatar/elementsphere/ESStream.java b/src/com/jedk1/jedcore/ability/avatar/elementsphere/ESStream.java
index 41b16c7..efc8577 100644
--- a/src/com/jedk1/jedcore/ability/avatar/elementsphere/ESStream.java
+++ b/src/com/jedk1/jedcore/ability/avatar/elementsphere/ESStream.java
@@ -13,9 +13,10 @@
import com.projectkorra.projectkorra.region.RegionProtection;
import com.projectkorra.projectkorra.util.DamageHandler;
import com.projectkorra.projectkorra.util.ParticleEffect;
-
import com.projectkorra.projectkorra.util.TempFallingBlock;
-import org.bukkit.*;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.Sound;
import org.bukkit.block.BlockState;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity;
@@ -25,7 +26,7 @@
import java.util.ArrayList;
import java.util.List;
-import java.util.Random;
+import java.util.concurrent.ThreadLocalRandom;
/**
* @author jedk1
@@ -33,6 +34,14 @@
*/
public class ESStream extends AvatarAbility implements AddonAbility {
+ private boolean cancelAbility;
+ private int requiredUses;
+ private long regen;
+ private Location stream;
+ private Location origin;
+ private Vector dir;
+ private int angle;
+
@Attribute(Attribute.COOLDOWN)
private long cooldown;
@Attribute(Attribute.KNOCKBACK)
@@ -41,29 +50,22 @@ public class ESStream extends AvatarAbility implements AddonAbility {
private double range;
@Attribute(Attribute.DAMAGE)
private double damage;
- private boolean cancelAbility;
- private int requiredUses;
-
@Attribute(Attribute.RADIUS)
private double radius;
- private long regen;
-
- private Location stream;
- private Location origin;
- private Vector dir;
-
- private int an;
- Random rand = new Random();
public ESStream(Player player) {
super(player);
+
if (!hasAbility(player, ElementSphere.class)) {
return;
}
+
ElementSphere currES = getAbility(player, ElementSphere.class);
+
if (bPlayer.isOnCooldown("ESStream")) {
return;
}
+
setFields();
if (currES.getAirUses() < requiredUses
@@ -89,9 +91,10 @@ public ESStream(Player player) {
stream = player.getEyeLocation();
origin = player.getEyeLocation();
dir = player.getEyeLocation().getDirection();
- an = 0;
+ angle = 0;
start();
+
if (!isRemoved()) {
bPlayer.addCooldown("ESStream", getCooldown());
}
@@ -112,118 +115,163 @@ public void setFields() {
@Override
public void progress() {
- if (player == null || !player.isOnline()) {
- remove();
+ if (!checkStreamValidity()) {
return;
}
- if (origin.distance(stream) >= range) {
- remove();
+ if (checkStreamRangeAndProtection()) {
return;
}
- if (RegionProtection.isRegionProtected(player, stream, this)) {
- remove();
+ handleNearbyEntities();
+
+ updateStreamDirection();
+
+ stream.add(dir);
+
+ if (handleBlockCollision()) {
return;
}
+ playStreamParticles();
+ }
+
+ private boolean checkStreamValidity() {
+ return player != null && player.isOnline();
+ }
+
+ private boolean checkStreamRangeAndProtection() {
+ if (origin.distance(stream) >= range || RegionProtection.isRegionProtected(player, stream, this)) {
+ remove();
+ return true;
+ }
+ return false;
+ }
+
+ private void handleNearbyEntities() {
for (Entity e : GeneralMethods.getEntitiesAroundPoint(stream, 1.5)) {
if (e instanceof Player && e == player) {
continue;
}
- GeneralMethods.setVelocity(this, e, dir.normalize().multiply(knockback));
- if (e instanceof LivingEntity) {
- DamageHandler.damageEntity(e, damage, this);
- }
+ applyStreamEffects(e);
}
+ }
+
+ private void applyStreamEffects(Entity entity) {
+ GeneralMethods.setVelocity(this, entity, dir.normalize().multiply(knockback));
+ if (entity instanceof LivingEntity) {
+ DamageHandler.damageEntity(entity, damage, this);
+ }
+ }
+ private void updateStreamDirection() {
if (!player.isDead() && hasAbility(player, ElementSphere.class)) {
Location loc = stream.clone();
dir = GeneralMethods.getDirection(loc, player.getTargetBlock(null, (int) range).getLocation()).normalize().multiply(1.2);
}
+ }
- stream.add(dir);
-
+ private boolean handleBlockCollision() {
if (!isTransparent(stream.getBlock())) {
- List blocks = new ArrayList<>();
- for (Location loc : GeneralMethods.getCircle(stream, (int) radius, 0, false, true, 0)) {
- if (JCMethods.isUnbreakable(loc.getBlock())) continue;
- if (RegionProtection.isRegionProtected(this, loc)) continue;
- blocks.add(loc.getBlock().getState());
- new RegenTempBlock(loc.getBlock(), Material.AIR, Material.AIR.createBlockData(), regen, false);
- }
- for (Entity e : GeneralMethods.getEntitiesAroundPoint(stream, radius)) {
- if (e instanceof Player && e == player) {
- continue;
- }
- if (RegionProtection.isRegionProtected(this, e.getLocation()) || ((e instanceof Player) && Commands.invincible.contains(((Player) e).getName()))){
- continue;
- }
- GeneralMethods.setVelocity(this, e, dir.normalize().multiply(knockback));
- if (e instanceof LivingEntity) {
- DamageHandler.damageEntity(e, damage, this);
- }
- }
+ triggerCollisionEffects();
+ remove();
+ return true;
+ }
+ return false;
+ }
+
+ private void triggerCollisionEffects() {
+ ThreadLocalRandom rand = ThreadLocalRandom.current();
+ List blocks = getAffectedBlocks();
+ damageNearbyEntitiesOnCollision();
+ displayCollisionParticles();
+ playCollisionSounds(rand);
+ spawnFallingBlocks(rand, blocks);
+ }
- ParticleEffect.FLAME.display(stream, 20, Math.random(), Math.random(), Math.random(), 0.5);
- ParticleEffect.SMOKE_LARGE.display(stream, 20, Math.random(), Math.random(), Math.random(), 0.5);
- ParticleEffect.FIREWORKS_SPARK.display(stream, 20, Math.random(), Math.random(), Math.random(), 0.5);
- ParticleEffect.SMOKE_LARGE.display(stream, 20, Math.random(), Math.random(), Math.random(), 0.5);
- ParticleEffect.EXPLOSION_HUGE.display(stream, 5, Math.random(), Math.random(), Math.random(), 0.5);
+ private List getAffectedBlocks() {
+ List blocks = new ArrayList<>();
+ for (Location loc : GeneralMethods.getCircle(stream, (int) radius, 0, false, true, 0)) {
+ if (JCMethods.isUnbreakable(loc.getBlock()) || RegionProtection.isRegionProtected(this, loc)) continue;
+ blocks.add(loc.getBlock().getState());
+ new RegenTempBlock(loc.getBlock(), Material.AIR, Material.AIR.createBlockData(), regen, false);
+ }
+ return blocks;
+ }
- stream.getWorld().playSound(stream, (rand.nextBoolean()) ? Sound.ENTITY_FIREWORK_ROCKET_BLAST : Sound.ENTITY_FIREWORK_ROCKET_BLAST_FAR, 1f, 1f);
- stream.getWorld().playSound(stream, (rand.nextBoolean()) ? Sound.ENTITY_FIREWORK_ROCKET_TWINKLE : Sound.ENTITY_FIREWORK_ROCKET_TWINKLE_FAR, 1f, 1f);
+ private void damageNearbyEntitiesOnCollision() {
+ GeneralMethods.getEntitiesAroundPoint(stream, radius).stream().filter(e -> !(e instanceof Player) || e != player).filter(e -> !RegionProtection.isRegionProtected(this, e.getLocation()) && (!(e instanceof Player targetPlayer) || !Commands.invincible.contains((targetPlayer).getName()))).forEach(e -> {
+ GeneralMethods.setVelocity(this, e, dir.normalize().multiply(knockback));
+ if (e instanceof LivingEntity) DamageHandler.damageEntity(e, damage, this);
+ });
+ }
- for (BlockState block : blocks) {
- double x = rand.nextDouble() / 3;
- double z = rand.nextDouble() / 3;
+ private void displayCollisionParticles() {
+ ParticleEffect.FLAME.display(stream, 20, 0.5F, 0.5F, 0.5F, 0.5F);
+ ParticleEffect.SMOKE_LARGE.display(stream, 20, 0.5F, 0.5F, 0.5F, 0.5F);
+ ParticleEffect.FIREWORKS_SPARK.display(stream, 20, 0.5F, 0.5F, 0.5F, 0.5F);
+ ParticleEffect.SMOKE_LARGE.display(stream, 20, 0.5F, 0.5F, 0.5F, 0.5F);
+ ParticleEffect.EXPLOSION_HUGE.display(stream, 5, 0.5F, 0.5F, 0.5F, 0.5F);
+ }
- x = (rand.nextBoolean()) ? -x : x;
- z = (rand.nextBoolean()) ? -z : z;
+ private void playCollisionSounds(ThreadLocalRandom rand) {
+ stream.getWorld().playSound(stream, rand.nextBoolean() ? Sound.ENTITY_FIREWORK_ROCKET_BLAST : Sound.ENTITY_FIREWORK_ROCKET_BLAST_FAR, 1f, 1f);
+ stream.getWorld().playSound(stream, rand.nextBoolean() ? Sound.ENTITY_FIREWORK_ROCKET_TWINKLE : Sound.ENTITY_FIREWORK_ROCKET_TWINKLE_FAR, 1f, 1f);
+ }
- new TempFallingBlock(block.getLocation().add(0, 1, 0), block.getBlockData(), dir.clone().add(new Vector(x, 0, z)).normalize().multiply(-1), this);
- }
- remove();
- return;
+ private void spawnFallingBlocks(ThreadLocalRandom rand, List blocks) {
+ for (BlockState block : blocks) {
+ double x = (rand.nextBoolean() ? -1 : 1) * rand.nextDouble() / 3;
+ double z = (rand.nextBoolean() ? -1 : 1) * rand.nextDouble() / 3;
+ new TempFallingBlock(block.getLocation().add(0, 1, 0), block.getBlockData(), dir.clone().add(new Vector(x, 0, z)).normalize().multiply(-1), this);
}
-
- an += 20;
- if (an > 360) {
- an = 0;
+ }
+
+ private void playStreamParticles() {
+ angle += 20;
+ if (angle > 360) {
+ angle = 0;
}
for (int i = 0; i < 4; i++) {
- for (double d = -4; d <= 0; d += .1) {
- if (origin.distance(stream) < d) {
- continue;
- }
- Location l = stream.clone().add(dir.clone().normalize().multiply(d));
- double r = d * -1 / 5;
- if (r > .75) {
- r = .75;
- }
+ playIndividualStreamParticles(i);
+ }
+ }
- Vector ov = GeneralMethods.getOrthogonalVector(dir, an + (90 * i) + d, r);
- Location pl = l.clone().add(ov.clone());
- switch (i) {
- case 0:
- ParticleEffect flame = bPlayer.hasSubElement(Element.BLUE_FIRE) ? ParticleEffect.SOUL_FIRE_FLAME : ParticleEffect.FLAME;
- flame.display(pl, 1, 0.05F, 0.05F, 0.05F, 0.005F);
- break;
- case 1:
- if (rand.nextInt(30) == 0) {
- JCMethods.displayColoredParticles("#FFFFFF", pl, 1, 0, 0, 0, 0.003f);
- } else {
- JCMethods.displayColoredParticles("#FFFFFF", pl, 1, 0.05, 0.05, 0.05, 0.005f, 50);
- }
- break;
- case 2:
- GeneralMethods.displayColoredParticle("06C1FF", pl);
- break;
- case 3:
- GeneralMethods.displayColoredParticle("754719", pl);
- break;
+ private void playIndividualStreamParticles(int particleIndex) {
+ for (double d = -4; d <= 0; d += 0.1) {
+ if (origin.distance(stream) < d) continue;
+ Location l = stream.clone().add(dir.clone().normalize().multiply(d));
+ double r = Math.min(0.75, d * -1 / 5);
+ Vector ov = GeneralMethods.getOrthogonalVector(dir, angle + (90 * particleIndex) + d, r);
+ Location pl = l.clone().add(ov.clone());
+ displayStreamParticle(pl, particleIndex);
+ }
+ }
+
+ private void displayStreamParticle(Location location, int index) {
+ ThreadLocalRandom rand = ThreadLocalRandom.current();
+ switch (index) {
+ case 0:
+ ParticleEffect flame = bPlayer.hasSubElement(Element.BLUE_FIRE) ? ParticleEffect.SOUL_FIRE_FLAME : ParticleEffect.FLAME;
+ flame.display(location, 1, 0.05F, 0.05F, 0.05F, 0.005F);
+ break;
+ case 1:
+ String color = "#FFFFFF";
+ float offset = 0.05F;
+ float speed = 0.005F;
+ int viewDistance = 50;
+ if (rand.nextInt(30) == 0) {
+ JCMethods.displayColoredParticles(color, location, 1, 0, 0, 0, speed);
+ } else {
+ JCMethods.displayColoredParticles(color, location, 1, offset, offset, offset, speed, viewDistance);
}
- }
+ break;
+ case 2:
+ GeneralMethods.displayColoredParticle("06C1FF", location);
+ break;
+ case 3:
+ GeneralMethods.displayColoredParticle("754719", location);
+ break;
}
}
diff --git a/src/com/jedk1/jedcore/ability/avatar/elementsphere/ESWater.java b/src/com/jedk1/jedcore/ability/avatar/elementsphere/ESWater.java
index 76e92e0..4d0fbb3 100644
--- a/src/com/jedk1/jedcore/ability/avatar/elementsphere/ESWater.java
+++ b/src/com/jedk1/jedcore/ability/avatar/elementsphere/ESWater.java
@@ -12,7 +12,6 @@
import com.projectkorra.projectkorra.region.RegionProtection;
import com.projectkorra.projectkorra.util.DamageHandler;
import com.projectkorra.projectkorra.util.ParticleEffect;
-
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.data.Levelled;
@@ -40,19 +39,26 @@ public class ESWater extends AvatarAbility implements AddonAbility {
public ESWater(Player player) {
super(player);
+
if (!hasAbility(player, ElementSphere.class)) {
return;
}
+
ElementSphere currES = getAbility(player, ElementSphere.class);
if (currES.getWaterUses() == 0) {
return;
}
+
if (bPlayer.isOnCooldown("ESWater")) {
return;
}
+
setFields();
+
location = player.getEyeLocation().clone().add(player.getEyeLocation().getDirection().multiply(1));
+
start();
+
if (!isRemoved()) {
bPlayer.addCooldown("ESWater", getCooldown());
currES.setWaterUses(currES.getWaterUses() - 1);
@@ -74,44 +80,82 @@ public void progress() {
remove();
return;
}
+
if (travelled >= range) {
remove();
return;
}
+
advanceAttack();
}
- private void advanceAttack() {
- for (int i = 0; i < speed; i++) {
- travelled++;
- if (travelled >= range)
- return;
-
- if (!player.isDead())
- direction = GeneralMethods.getDirection(player.getLocation(), GeneralMethods.getTargetedLocation(player, range, Material.WATER)).normalize();
- location = location.add(direction.clone().multiply(1));
- if (RegionProtection.isRegionProtected(this, location)){
- travelled = range;
- return;
- }
- if (GeneralMethods.isSolid(location.getBlock()) || !isTransparent(location.getBlock())) {
- travelled = range;
- return;
- }
-
- WaterAbility.playWaterbendingSound(location);
- if (isWater(location.getBlock()))
- ParticleEffect.WATER_BUBBLE.display(location, 3, 0.5, 0.5, 0.5);
- new RegenTempBlock(location.getBlock(), Material.WATER, Material.WATER.createBlockData(bd -> ((Levelled) bd).setLevel(0)), 100L);
-
- for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2.5)) {
- if (entity instanceof LivingEntity && entity.getEntityId() != player.getEntityId() && !(entity instanceof ArmorStand) && !RegionProtection.isRegionProtected(this, entity.getLocation()) && !((entity instanceof Player) && Commands.invincible.contains(((Player) entity).getName()))) {
- DamageHandler.damageEntity(entity, damage, this);
- travelled = range;
- }
- }
- }
- }
+ private void advanceAttack() {
+ for (int i = 0; i < speed; i++) {
+ if (!incrementTravelledAndCheckRange()) {
+ return;
+ }
+
+ updateDirection();
+
+ location.add(direction.clone().multiply(1));
+
+ if (checkCollision()) {
+ return;
+ }
+
+ playAttackEffects();
+ handleBlockTransformation();
+ handleEntityCollisions();
+ }
+ }
+
+ private boolean incrementTravelledAndCheckRange() {
+ travelled++;
+ return travelled < range;
+ }
+
+ private void updateDirection() {
+ if (!player.isDead()) {
+ direction = GeneralMethods.getDirection(player.getLocation(), GeneralMethods.getTargetedLocation(player, range, Material.WATER)).normalize();
+ }
+ }
+
+ private boolean checkCollision() {
+ if (RegionProtection.isRegionProtected(this, location) || GeneralMethods.isSolid(location.getBlock()) || !isTransparent(location.getBlock())) {
+ travelled = range;
+ return true;
+ }
+ return false;
+ }
+
+ private void playAttackEffects() {
+ WaterAbility.playWaterbendingSound(location);
+ if (isWater(location.getBlock())) {
+ ParticleEffect.WATER_BUBBLE.display(location, 3, 0.5, 0.5, 0.5);
+ }
+ }
+
+ private void handleBlockTransformation() {
+ new RegenTempBlock(location.getBlock(), Material.WATER, Material.WATER.createBlockData(bd -> ((Levelled) bd).setLevel(0)), 100L);
+ }
+
+ private void handleEntityCollisions() {
+ for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2.5)) {
+ if (isAttackableEntity(entity)) {
+ DamageHandler.damageEntity(entity, damage, this);
+ travelled = range;
+ return;
+ }
+ }
+ }
+
+ private boolean isAttackableEntity(Entity entity) {
+ return entity instanceof LivingEntity &&
+ entity.getEntityId() != player.getEntityId() &&
+ !(entity instanceof ArmorStand) &&
+ !RegionProtection.isRegionProtected(this, entity.getLocation()) &&
+ !((entity instanceof Player targetPlayer) && Commands.invincible.contains((targetPlayer).getName()));
+ }
@Override
public long getCooldown() {
diff --git a/src/com/jedk1/jedcore/ability/avatar/elementsphere/ElementSphere.java b/src/com/jedk1/jedcore/ability/avatar/elementsphere/ElementSphere.java
index 51e78de..22e9122 100644
--- a/src/com/jedk1/jedcore/ability/avatar/elementsphere/ElementSphere.java
+++ b/src/com/jedk1/jedcore/ability/avatar/elementsphere/ElementSphere.java
@@ -13,7 +13,6 @@
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.region.RegionProtection;
import com.projectkorra.projectkorra.util.ParticleEffect;
-
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
@@ -27,399 +26,495 @@
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ThreadLocalRandom;
public class ElementSphere extends AvatarAbility implements AddonAbility, MultiAbility {
- public static ConcurrentHashMap> abilities = new ConcurrentHashMap>();
-
- private World world;
-
- public int airUses;
- public int fireUses;
- public int waterUses;
- public int earthUses;
-
- @Attribute(Attribute.COOLDOWN)
- public long cooldown;
- @Attribute(Attribute.DURATION)
- public long duration;
- @Attribute(Attribute.HEIGHT)
- private double height;
- @Attribute(Attribute.SPEED)
- private double speed;
-
- private boolean setup;
- private Location location;
- private double yaw;
- private int point;
- private long endTime;
-
- private long lastClickTime;
-
- private static final ArrayList multiAbilityInfo = new ArrayList<>();
-
- static {
- multiAbilityInfo.add(new MultiAbilityInfoSub("", Element.AIR));
- multiAbilityInfo.add(new MultiAbilityInfoSub("", Element.EARTH));
- multiAbilityInfo.add(new MultiAbilityInfoSub("", Element.FIRE));
- multiAbilityInfo.add(new MultiAbilityInfoSub("", Element.WATER));
- multiAbilityInfo.add(new MultiAbilityInfoSub("", Element.AVATAR));
- }
-
- Random rand = new Random();
-
- public ElementSphere(Player player) {
- super(player);
- ElementSphere oldES = getAbility(player, ElementSphere.class);
- if (oldES != null) {
- if (player.isSneaking()) {
- oldES.prepareCancel();
- } else {
- if (oldES.setup) {
- if (!bPlayer.canBendIgnoreBindsCooldowns(this)) {
- return;
- }
-
- switch (player.getInventory().getHeldItemSlot()) {
- case 0:
- if (player.hasPermission("bending.ability.ElementSphere.Air")) {
- new ESAir(player);
- }
- break;
- case 1:
- if (player.hasPermission("bending.ability.ElementSphere.Earth")) {
- new ESEarth(player);
- }
- break;
- case 2:
- if (player.hasPermission("bending.ability.ElementSphere.Fire")) {
- new ESFire(player);
- }
- break;
- case 3:
- if (player.hasPermission("bending.ability.ElementSphere.Water")) {
- new ESWater(player);
- }
- break;
- case 4:
- if (player.hasPermission("bending.ability.ElementSphere.Stream")) {
- new ESStream(player);
- }
- break;
- default:
- break;
- }
- }
- }
- return;
- }
-
- setFields();
- location = player.getLocation().clone().subtract(0, 1, 0);
-
- if (bPlayer.canBend(this)) {
- world = player.getWorld();
- endTime = System.currentTimeMillis() + duration;
- start();
- if (!isRemoved()) {
- MultiAbilityManager.bindMultiAbility(player, "ElementSphere");
- bPlayer.addCooldown(this);
- flightHandler.createInstance(player, this.getName());
- if (ChatColor.stripColor(bPlayer.getBoundAbilityName()) == null) {
- remove();
- }
- }
- }
- }
-
- public void setFields() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- airUses = config.getInt("Abilities.Avatar.ElementSphere.Air.Uses");
- fireUses = config.getInt("Abilities.Avatar.ElementSphere.Fire.Uses");
- waterUses = config.getInt("Abilities.Avatar.ElementSphere.Water.Uses");
- earthUses = config.getInt("Abilities.Avatar.ElementSphere.Earth.Uses");
- cooldown = config.getLong("Abilities.Avatar.ElementSphere.Cooldown");
- duration = config.getLong("Abilities.Avatar.ElementSphere.Duration");
- height = config.getDouble("Abilities.Avatar.ElementSphere.MaxControlledHeight");
- speed = config.getDouble("Abilities.Avatar.ElementSphere.FlySpeed");
- }
-
- @Override
- public void progress() {
- if (player.isDead() || !player.isOnline() || world != player.getWorld()) {
- remove();
- return;
- }
- if (player.getGameMode().equals(GameMode.SPECTATOR)) {
- remove();
- return;
- }
- if (!bPlayer.isToggled()) {
- remove();
- return;
- }
- if (!MultiAbilityManager.hasMultiAbilityBound(player, "ElementSphere")) {
- remove();
- return;
- }
- if (System.currentTimeMillis() > endTime && duration > 0) {
- remove();
- return;
- }
- if (airUses == 0 && fireUses == 0 && waterUses == 0 && earthUses == 0) {
- remove();
- return;
- }
- player.setFallDistance(0);
- if (player.isSneaking())
- player.setVelocity(player.getLocation().getDirection().multiply(speed));
-
- Block block = getGround();
- if (block != null) {
- double dy = player.getLocation().getY() - block.getY();
- if (dy > height) {
- removeFlight();
- } else {
- allowFlight();
- }
- }
-
- for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2.5)) {
- if (!RegionProtection.isRegionProtected(player, entity.getLocation(), this)) {
- if (entity instanceof LivingEntity && entity.getEntityId() != player.getEntityId() && !(entity instanceof ArmorStand)) {
- entity.setVelocity(entity.getLocation().toVector().subtract(player.getLocation().toVector()).multiply(1));
- }
- }
- }
-
- location = player.getLocation().clone().subtract(0, 1, 0);
- playParticles();
- setup = true;
- }
-
- private void allowFlight() {
- if (!player.getAllowFlight()) {
- player.setAllowFlight(true);
- }
- if (!player.isFlying()) {
- player.setFlying(true);
- }
- }
-
- private void removeFlight() {
- if (player.getAllowFlight()) {
- player.setAllowFlight(false);
- }
- if (player.isFlying()) {
- player.setFlying(false);
- }
- }
-
- private Block getGround() {
- Block standingblock = player.getLocation().getBlock();
- for (int i = 0; i <= height + 5; i++) {
- Block block = standingblock.getRelative(BlockFace.DOWN, i);
- if (GeneralMethods.isSolid(block) || block.isLiquid()) {
- return block;
- }
- }
- return null;
- }
-
- private void playParticles() {
- Location fakeLoc = location.clone();
- fakeLoc.setPitch(0);
- fakeLoc.setYaw((float) (yaw += 40));
- Vector direction = fakeLoc.getDirection();
- if (airUses != 0)
- for (double j = -180; j <= 180; j += 45) {
- Location tempLoc = fakeLoc.clone();
- Vector newDir = direction.clone().multiply(2 * Math.cos(Math.toRadians(j)));
- tempLoc.add(newDir);
- tempLoc.setY(tempLoc.getY() + 2 + (2 * Math.sin(Math.toRadians(j))));
- if (rand.nextInt(30) == 0) {
- JCMethods.displayColoredParticles("#FFFFFF", tempLoc, 1, 0, 0, 0, 0.003f);
- } else {
- JCMethods.displayColoredParticles("#FFFFFF", tempLoc, 1, 0, 0, 0, 0.003f, 50);
- }
- }
-
- point++;
- if (fireUses != 0)
- for (int i = -180; i < 180; i += 40) {
- double angle = (i * Math.PI / 180);
- double x = 2 * Math.cos(angle + point);
- double z = 2 * Math.sin(angle + point);
- Location loc = location.clone();
- loc.add(x, 2, z);
- ParticleEffect flame = bPlayer.hasSubElement(Element.BLUE_FIRE) ? ParticleEffect.SOUL_FIRE_FLAME : ParticleEffect.FLAME;
- flame.display(loc, 0, 0, 0, 0, 1);
- JCMethods.emitLight(loc);
- }
-
- point++;
- Location location = this.location.clone().add(0, 2, 0);
- for (int i = -180; i < 180; i += 30) {
- double angle = (i * Math.PI / 180);
- double xRotation = 3.141592653589793D / 3 * 2.1;
- Vector v = new Vector(Math.cos(angle + point), Math.sin(angle + point), 0.0D).multiply(2);
- Vector v1 = v.clone();
- rotateAroundAxisX(v, xRotation);
- rotateAroundAxisY(v, -((location.getYaw() * Math.PI / 180) - 1.575));
- rotateAroundAxisX(v1, -xRotation);
- rotateAroundAxisY(v1, -((location.getYaw() * Math.PI / 180) - 1.575));
-
- if (waterUses != 0)
- GeneralMethods.displayColoredParticle("06C1FF", location.clone().add(v));
-
- if (earthUses != 0)
- GeneralMethods.displayColoredParticle("754719", location.clone().add(v1));
- }
-
- if (point == 360)
- point = 0;
- }
-
- private void rotateAroundAxisX(Vector v, double angle) {
- double cos = Math.cos(angle);
- double sin = Math.sin(angle);
- double y = v.getY() * cos - v.getZ() * sin;
- double z = v.getY() * sin + v.getZ() * cos;
- v.setY(y).setZ(z);
- }
-
- private void rotateAroundAxisY(Vector v, double angle) {
- double cos = Math.cos(angle);
- double sin = Math.sin(angle);
- double x = v.getX() * cos + v.getZ() * sin;
- double z = v.getX() * -sin + v.getZ() * cos;
- v.setX(x).setZ(z);
- }
-
- @Override
- public void remove() {
- super.remove();
- MultiAbilityManager.unbindMultiAbility(player);
- flightHandler.removeInstance(player, this.getName());
- }
-
- public void prepareCancel() {
- if (System.currentTimeMillis() < lastClickTime + 500L) {
- remove();
- } else {
- lastClickTime = System.currentTimeMillis();
- }
- }
-
- public int getAirUses() {
- return airUses;
- }
-
- public void setAirUses(int airuses) {
- this.airUses = airuses;
- }
-
- public int getEarthUses() {
- return earthUses;
- }
-
- public void setEarthUses(int earthuses) {
- this.earthUses = earthuses;
- }
-
- public int getFireUses() {
- return fireUses;
- }
-
- public void setFireUses(int fireuses) {
- this.fireUses = fireuses;
- }
-
- public int getWaterUses() {
- return waterUses;
- }
-
- public void setWaterUses(int wateruses) {
- this.waterUses = wateruses;
- }
-
- @Override
- public long getCooldown() {
- return cooldown;
- }
-
- @Override
- public Location getLocation() {
- return location;
- }
-
- @Override
- public boolean requireAvatar() {
- return false;
- }
-
- @Override
- public String getName() {
- return "ElementSphere";
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return true;
- }
-
- @Override
- public String getAuthor() {
- return JedCore.dev;
- }
-
- @Override
- public String getVersion() {
- return JedCore.version;
- }
-
- @Override
- public String getDescription() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return "* JedCore Addon *\n" + config.getString("Abilities.Avatar.ElementSphere.Description");
- }
-
- @Override
- public void load() {}
-
- @Override
- public void stop() {}
-
- @Override
- public boolean isEnabled() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getBoolean("Abilities.Avatar.ElementSphere.Enabled");
- }
-
- @Override
- public ArrayList getMultiAbilities() {
- FileConfiguration lang = getLanguageConfig();
-
- String airName = lang.getString("Abilities.Avatar.ElementSphereAir.Name");
- String fireName = lang.getString("Abilities.Avatar.ElementSphereFire.Name");
- String waterName = lang.getString("Abilities.Avatar.ElementSphereWater.Name");
- String earthName = lang.getString("Abilities.Avatar.ElementSphereEarth.Name");
- String streamName = lang.getString("Abilities.Avatar.ElementSphereStream.Name");
-
- multiAbilityInfo.get(0).setName(airName);
- multiAbilityInfo.get(1).setName(earthName);
- multiAbilityInfo.get(2).setName(fireName);
- multiAbilityInfo.get(3).setName(waterName);
- multiAbilityInfo.get(4).setName(streamName);
-
- return multiAbilityInfo;
- }
-}
+ protected static final ConcurrentMap> abilities = new ConcurrentHashMap<>();
+ private static final ArrayList multiAbilityInfo = new ArrayList<>();
+
+ static {
+ multiAbilityInfo.add(new MultiAbilityInfoSub("", Element.AIR));
+ multiAbilityInfo.add(new MultiAbilityInfoSub("", Element.EARTH));
+ multiAbilityInfo.add(new MultiAbilityInfoSub("", Element.FIRE));
+ multiAbilityInfo.add(new MultiAbilityInfoSub("", Element.WATER));
+ multiAbilityInfo.add(new MultiAbilityInfoSub("", Element.AVATAR));
+ }
+
+ private World world;
+ private int airUses;
+ private int fireUses;
+ private int waterUses;
+ private int earthUses;
+ private boolean setup;
+ private Location location;
+ private double yaw;
+ private int point;
+ private long endTime;
+ private long lastClickTime;
+
+ @Attribute(Attribute.COOLDOWN)
+ public long cooldown;
+ @Attribute(Attribute.DURATION)
+ public long duration;
+ @Attribute(Attribute.HEIGHT)
+ private double height;
+ @Attribute(Attribute.SPEED)
+ private double speed;
+
+ public ElementSphere(Player player) {
+ super(player);
+
+ ElementSphere oldES = getAbility(player, ElementSphere.class);
+
+ if (handleExistingSphere(player, oldES)) {
+ return;
+ }
+
+ if (canStartNewSphere()) {
+ initializeNewSphere(player);
+ }
+ }
+
+ private boolean handleExistingSphere(Player player, ElementSphere oldES) {
+ if (oldES != null) {
+ if (player.isSneaking()) {
+ oldES.prepareCancel();
+ } else {
+ if (oldES.setup) {
+ handleElementSwitch(player);
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private void handleElementSwitch(Player player) {
+ if (!bPlayer.canBendIgnoreBindsCooldowns(this)) {
+ return;
+ }
+
+ switch (player.getInventory().getHeldItemSlot()) {
+ case 0:
+ if (checkPermission(player, "Air")) new ESAir(player);
+ break;
+ case 1:
+ if (checkPermission(player, "Earth")) new ESEarth(player);
+ break;
+ case 2:
+ if (checkPermission(player, "Fire")) new ESFire(player);
+ break;
+ case 3:
+ if (checkPermission(player, "Water")) new ESWater(player);
+ break;
+ case 4:
+ if (checkPermission(player, "Stream")) new ESStream(player);
+ break;
+ }
+ }
+
+ private boolean checkPermission(Player player, String element) {
+ return player.hasPermission("bending.ability.ElementSphere." + element);
+ }
+
+ private boolean canStartNewSphere() {
+ return bPlayer.canBend(this);
+ }
+
+ private void initializeNewSphere(Player player) {
+ setFields();
+ location = player.getLocation().clone().subtract(0, 1, 0);
+ world = player.getWorld();
+ endTime = System.currentTimeMillis() + duration;
+ start();
+
+ if (!isRemoved()) {
+ bindAndCooldown(player);
+ enableFlight(player);
+ checkBoundAbilityName();
+ }
+ }
+
+ private void bindAndCooldown(Player player) {
+ MultiAbilityManager.bindMultiAbility(player, "ElementSphere");
+ bPlayer.addCooldown(this);
+ }
+
+ private void enableFlight(Player player) {
+ flightHandler.createInstance(player, this.getName());
+ }
+
+ private void checkBoundAbilityName() {
+ if (ChatColor.stripColor(bPlayer.getBoundAbilityName()) == null) {
+ remove();
+ }
+ }
+
+ public void setFields() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ airUses = config.getInt("Abilities.Avatar.ElementSphere.Air.Uses");
+ fireUses = config.getInt("Abilities.Avatar.ElementSphere.Fire.Uses");
+ waterUses = config.getInt("Abilities.Avatar.ElementSphere.Water.Uses");
+ earthUses = config.getInt("Abilities.Avatar.ElementSphere.Earth.Uses");
+ cooldown = config.getLong("Abilities.Avatar.ElementSphere.Cooldown");
+ duration = config.getLong("Abilities.Avatar.ElementSphere.Duration");
+ height = config.getDouble("Abilities.Avatar.ElementSphere.MaxControlledHeight");
+ speed = config.getDouble("Abilities.Avatar.ElementSphere.FlySpeed");
+ }
+
+ @Override
+ public void progress() {
+ if (!checkPlayerValidity()) {
+ return;
+ }
+
+ if (!checkAbilityPrerequisites()) {
+ return;
+ }
+
+ if (isDurationOver()) {
+ remove();
+ return;
+ }
+
+ if (!hasUsableElements()) {
+ remove();
+ return;
+ }
+
+ handlePlayerMovement();
+ handleFlight();
+ handleEntityPush();
+ updateLocationAndPlayParticles();
+
+ setup = true;
+ }
+
+ private boolean checkPlayerValidity() {
+ return !player.isDead() && player.isOnline() && world == player.getWorld() && !player.getGameMode().equals(GameMode.SPECTATOR);
+ }
+
+ private boolean checkAbilityPrerequisites() {
+ return bPlayer.isToggled() && MultiAbilityManager.hasMultiAbilityBound(player, "ElementSphere");
+ }
+
+ private boolean isDurationOver() {
+ return duration > 0 && System.currentTimeMillis() > endTime;
+ }
+
+ private boolean hasUsableElements() {
+ return airUses > 0 || fireUses > 0 || waterUses > 0 || earthUses > 0;
+ }
+
+ private void handlePlayerMovement() {
+ player.setFallDistance(0);
+ if (player.isSneaking()) {
+ player.setVelocity(player.getLocation().getDirection().multiply(speed));
+ }
+ }
+
+ private void handleFlight() {
+ Block block = getGround();
+ if (block != null) {
+ double dy = player.getLocation().getY() - block.getY();
+ if (dy > height) {
+ removeFlight();
+ } else {
+ allowFlight();
+ }
+ }
+ }
+
+ private void handleEntityPush() {
+ for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2.5)) {
+ if (isPushableEntity(entity)) {
+ entity.setVelocity(entity.getLocation().toVector().subtract(player.getLocation().toVector()).multiply(1));
+ }
+ }
+ }
+
+ private boolean isPushableEntity(Entity entity) {
+ return entity instanceof LivingEntity &&
+ entity.getEntityId() != player.getEntityId() &&
+ !(entity instanceof ArmorStand) &&
+ !RegionProtection.isRegionProtected(player, entity.getLocation(), this);
+ }
+
+ private void updateLocationAndPlayParticles() {
+ location = player.getLocation().clone().subtract(0, 1, 0);
+ playParticles();
+ }
+
+ private void allowFlight() {
+ if (!player.getAllowFlight()) {
+ player.setAllowFlight(true);
+ }
+ if (!player.isFlying()) {
+ player.setFlying(true);
+ }
+ }
+
+ private void removeFlight() {
+ if (player.getAllowFlight()) {
+ player.setAllowFlight(false);
+ }
+ if (player.isFlying()) {
+ player.setFlying(false);
+ }
+ }
+
+ private Block getGround() {
+ Block standingblock = player.getLocation().getBlock();
+
+ for (int i = 0; i <= height + 5; i++) {
+ Block block = standingblock.getRelative(BlockFace.DOWN, i);
+ if (GeneralMethods.isSolid(block) || block.isLiquid()) {
+ return block;
+ }
+ }
+
+ return null;
+ }
+
+ private void playParticles() {
+ playAirParticles();
+ playFireParticles();
+ playWaterEarthParticles();
+ updatePointCounter();
+ }
+
+ private void playAirParticles() {
+ if (airUses != 0) {
+ double currentYaw = yaw + 40;
+ yaw = currentYaw;
+ Location fakeLoc = createRotatedLocation(location.clone(), 0, currentYaw);
+ Vector direction = fakeLoc.getDirection();
+ for (double j = -180; j <= 180; j += 45) {
+ Location tempLoc = calculateAirParticleLocation(fakeLoc, direction, j);
+ displayAirParticle(tempLoc);
+ }
+ }
+ }
+
+ private Location createRotatedLocation(Location baseLoc, double pitchOffset, double yawOffset) {
+ Location newLoc = baseLoc.clone();
+ newLoc.setPitch((float) pitchOffset);
+ newLoc.setYaw((float) yawOffset);
+ return newLoc;
+ }
+
+ private Location calculateAirParticleLocation(Location center, Vector direction, double angleDegrees) {
+ Location tempLoc = center.clone();
+ double angleRadians = Math.toRadians(angleDegrees);
+ Vector newDir = direction.clone().multiply(2 * Math.cos(angleRadians));
+ tempLoc.add(newDir);
+ tempLoc.setY(tempLoc.getY() + 2 + (2 * Math.sin(angleRadians)));
+ return tempLoc;
+ }
+
+ private void displayAirParticle(Location loc) {
+ String color = "#FFFFFF";
+ int count = 1;
+ float offsetX = 0;
+ float offsetY = 0;
+ float offsetZ = 0;
+ float particleSpeed = 0.003f;
+ int viewDistance = 50;
+
+ if (ThreadLocalRandom.current().nextInt(30) == 0) {
+ JCMethods.displayColoredParticles(color, loc, count, offsetX, offsetY, offsetZ, particleSpeed);
+ } else {
+ JCMethods.displayColoredParticles(color, loc, count, offsetX, offsetY, offsetZ, particleSpeed, viewDistance);
+ }
+ }
+
+ private void playFireParticles() {
+ if (fireUses != 0) {
+ ParticleEffect flame = bPlayer.hasSubElement(Element.BLUE_FIRE) ? ParticleEffect.SOUL_FIRE_FLAME : ParticleEffect.FLAME;
+ for (int i = -180; i < 180; i += 40) {
+ Location particleLoc = calculateCircularLocation(location, 2, i, 2);
+ flame.display(particleLoc, 0, 0, 0, 0, 1);
+ JCMethods.emitLight(particleLoc);
+ }
+ }
+ }
+
+ private Location calculateCircularLocation(Location center, double radius, double angleOffsetDegrees, double yOffset) {
+ double angleRadians = Math.toRadians(angleOffsetDegrees);
+ double x = radius * Math.cos(angleRadians + point);
+ double z = radius * Math.sin(angleRadians + point);
+ return center.clone().add(x, yOffset, z);
+ }
+
+ private void playWaterEarthParticles() {
+ Location centerLoc = location.clone().add(0, 2, 0);
+ double xRotation = Math.PI * 2.1 / 3;
+ double yawRadians = -(centerLoc.getYaw() * Math.PI / 180 - 1.575);
+
+ for (int i = -180; i < 180; i += 30) {
+ double angle = Math.toRadians(i);
+ Vector v = new Vector(Math.cos(angle + point), Math.sin(angle + point), 0.0D).multiply(2);
+ Vector v1 = v.clone();
+
+ rotateAroundAxisX(v, xRotation);
+ rotateAroundAxisY(v, yawRadians);
+ rotateAroundAxisX(v1, -xRotation);
+ rotateAroundAxisY(v1, yawRadians);
+ if (waterUses != 0) {
+ centerLoc.getWorld().spawnParticle(Particle.WATER_WAKE, centerLoc.clone().add(v), 3, 0.0, 0.0, 0.0, 0.005F);
+ GeneralMethods.displayColoredParticle("06C1FF", centerLoc.clone().add(v));
+ }
+ if (earthUses != 0) {
+ GeneralMethods.displayColoredParticle("754719", centerLoc.clone().add(v1));
+ }
+ }
+ }
+
+ private void updatePointCounter() {
+ point = (point + 1) % 360;
+ }
+
+ private void rotateAroundAxisX(Vector v, double angle) {
+ double cos = Math.cos(angle);
+ double sin = Math.sin(angle);
+ double y = v.getY() * cos - v.getZ() * sin;
+ double z = v.getY() * sin + v.getZ() * cos;
+ v.setY(y).setZ(z);
+ }
+
+ private void rotateAroundAxisY(Vector v, double angle) {
+ double cos = Math.cos(angle);
+ double sin = Math.sin(angle);
+ double x = v.getX() * cos + v.getZ() * sin;
+ double z = v.getX() * -sin + v.getZ() * cos;
+ v.setX(x).setZ(z);
+ }
+
+ @Override
+ public void remove() {
+ super.remove();
+ MultiAbilityManager.unbindMultiAbility(player);
+ flightHandler.removeInstance(player, this.getName());
+ }
+
+ public void prepareCancel() {
+ if (System.currentTimeMillis() < lastClickTime + 500L) {
+ remove();
+ } else {
+ lastClickTime = System.currentTimeMillis();
+ }
+ }
+
+ public int getAirUses() {
+ return airUses;
+ }
+
+ public void setAirUses(int airuses) {
+ this.airUses = airuses;
+ }
+
+ public int getEarthUses() {
+ return earthUses;
+ }
+
+ public void setEarthUses(int earthuses) {
+ this.earthUses = earthuses;
+ }
+
+ public int getFireUses() {
+ return fireUses;
+ }
+
+ public void setFireUses(int fireuses) {
+ this.fireUses = fireuses;
+ }
+
+ public int getWaterUses() {
+ return waterUses;
+ }
+
+ public void setWaterUses(int wateruses) {
+ this.waterUses = wateruses;
+ }
+
+ @Override
+ public long getCooldown() {
+ return cooldown;
+ }
+
+ @Override
+ public Location getLocation() {
+ return location;
+ }
+
+ @Override
+ public boolean requireAvatar() {
+ return false;
+ }
+
+ @Override
+ public String getName() {
+ return "ElementSphere";
+ }
+
+ @Override
+ public boolean isHarmlessAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isSneakAbility() {
+ return true;
+ }
+
+ @Override
+ public String getAuthor() {
+ return JedCore.dev;
+ }
+
+ @Override
+ public String getVersion() {
+ return JedCore.version;
+ }
+
+ @Override
+ public String getDescription() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return "* JedCore Addon *\n" + config.getString("Abilities.Avatar.ElementSphere.Description");
+ }
+
+ @Override
+ public void load() {}
+
+ @Override
+ public void stop() {}
+
+ @Override
+ public boolean isEnabled() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getBoolean("Abilities.Avatar.ElementSphere.Enabled");
+ }
+
+ @Override
+ public ArrayList getMultiAbilities() {
+ FileConfiguration lang = getLanguageConfig();
+
+ String airName = lang.getString("Abilities.Avatar.ElementSphereAir.Name");
+ String fireName = lang.getString("Abilities.Avatar.ElementSphereFire.Name");
+ String waterName = lang.getString("Abilities.Avatar.ElementSphereWater.Name");
+ String earthName = lang.getString("Abilities.Avatar.ElementSphereEarth.Name");
+ String streamName = lang.getString("Abilities.Avatar.ElementSphereStream.Name");
+
+ multiAbilityInfo.get(0).setName(airName);
+ multiAbilityInfo.get(1).setName(earthName);
+ multiAbilityInfo.get(2).setName(fireName);
+ multiAbilityInfo.get(3).setName(waterName);
+ multiAbilityInfo.get(4).setName(streamName);
+
+ return multiAbilityInfo;
+ }
+}
\ No newline at end of file
diff --git a/src/com/jedk1/jedcore/ability/chiblocking/Backstab.java b/src/com/jedk1/jedcore/ability/chiblocking/Backstab.java
index f6c87ec..701121a 100644
--- a/src/com/jedk1/jedcore/ability/chiblocking/Backstab.java
+++ b/src/com/jedk1/jedcore/ability/chiblocking/Backstab.java
@@ -1,18 +1,17 @@
package com.jedk1.jedcore.ability.chiblocking;
+import com.jedk1.jedcore.JedCore;
import com.jedk1.jedcore.configuration.JedCoreConfig;
+import com.projectkorra.projectkorra.BendingPlayer;
+import com.projectkorra.projectkorra.ability.AddonAbility;
+import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
+import com.projectkorra.projectkorra.chiblocking.passive.ChiPassive;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
-
-import com.jedk1.jedcore.JedCore;
-import com.projectkorra.projectkorra.BendingPlayer;
-import com.projectkorra.projectkorra.ability.AddonAbility;
-import com.projectkorra.projectkorra.ability.ChiAbility;
-import com.projectkorra.projectkorra.chiblocking.passive.ChiPassive;
import org.bukkit.util.Vector;
public class Backstab extends ChiAbility implements AddonAbility {
diff --git a/src/com/jedk1/jedcore/ability/chiblocking/DaggerThrow.java b/src/com/jedk1/jedcore/ability/chiblocking/DaggerThrow.java
index 0d94826..1b57acf 100644
--- a/src/com/jedk1/jedcore/ability/chiblocking/DaggerThrow.java
+++ b/src/com/jedk1/jedcore/ability/chiblocking/DaggerThrow.java
@@ -4,6 +4,7 @@
import com.jedk1.jedcore.JedCore;
import com.jedk1.jedcore.configuration.JedCoreConfig;
import com.jedk1.jedcore.util.AbilitySelector;
+import com.jedk1.jedcore.util.ThreadUtil;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.ability.AddonAbility;
import com.projectkorra.projectkorra.ability.ChiAbility;
@@ -12,7 +13,6 @@
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.region.RegionProtection;
import com.projectkorra.projectkorra.util.DamageHandler;
-
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
@@ -28,350 +28,324 @@
import java.util.stream.Collectors;
public class DaggerThrow extends ChiAbility implements AddonAbility {
- private static final List INTERACTIONS = new ArrayList<>();
- private static boolean particles;
- private static double damage;
-
- private long endTime;
- private int shots = 1;
- @Attribute(Attribute.COOLDOWN)
- private long cooldown;
- private boolean limitEnabled;
- @Attribute("MaxShots")
- private int maxShots;
- private int hits = 0;
- private final List arrows = new ArrayList<>();
-
- public DaggerThrow(Player player) {
- super(player);
-
- if (this instanceof DamageAbility) {
- return;
- }
-
- if (!bPlayer.canBend(this)) {
- return;
- }
-
- if (bPlayer.isOnCooldown("DaggerThrowShot")) {
- return;
- }
-
- if (hasAbility(player, DaggerThrow.class)) {
- DaggerThrow dt = getAbility(player, DaggerThrow.class);
- dt.shootArrow();
- return;
- }
-
- setFields();
-
- start();
- if (!isRemoved()) {
- shootArrow();
- }
- }
-
- public void setFields() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- cooldown = config.getLong("Abilities.Chi.DaggerThrow.Cooldown");
- limitEnabled = config.getBoolean("Abilities.Chi.DaggerThrow.MaxDaggers.Enabled");
- maxShots = config.getInt("Abilities.Chi.DaggerThrow.MaxDaggers.Amount");
- particles = config.getBoolean("Abilities.Chi.DaggerThrow.ParticleTrail");
- damage = config.getDouble("Abilities.Chi.DaggerThrow.Damage");
-
- loadInteractions();
- }
-
- private void loadInteractions() {
- INTERACTIONS.clear();
-
- String path = "Abilities.Chi.DaggerThrow.Interactions";
-
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- ConfigurationSection section = config.getConfigurationSection(path);
- for (String abilityName : section.getKeys(false)) {
- INTERACTIONS.add(new AbilityInteraction(abilityName));
- }
- }
-
- @Override
- public void progress() {
- if (player.isDead() || !player.isOnline()) {
- remove();
- return;
- }
- if (System.currentTimeMillis() > endTime) {
- bPlayer.addCooldown(this);
- remove();
- return;
- }
- if (shots > maxShots && limitEnabled) {
- bPlayer.addCooldown(this);
- remove();
- }
- }
-
- private void shootArrow() {
- if (JCMethods.removeItemFromInventory(player, Material.ARROW, 1)) {
- shots++;
- Location location = player.getEyeLocation();
-
- Vector vector = location.toVector().
- add(location.getDirection().multiply(2.5)).
- toLocation(location.getWorld()).toVector().
- subtract(player.getEyeLocation().toVector());
-
- Arrow arrow = player.launchProjectile(Arrow.class);
- arrow.setVelocity(vector);
- arrow.getLocation().setDirection(vector);
- arrow.setKnockbackStrength(0);
- arrow.setBounce(false);
- arrow.setMetadata("daggerthrow", new FixedMetadataValue(JedCore.plugin, "1"));
-
- if (particles) {
- arrow.setCritical(true);
- }
-
- arrows.add(arrow);
- endTime = System.currentTimeMillis() + 500;
- bPlayer.addCooldown("DaggerThrowShot", 100);
- }
- }
-
- public static void damageEntityFromArrow(LivingEntity entity, Arrow arrow) {
- if (RegionProtection.isRegionProtected((Player) arrow.getShooter(), arrow.getLocation(), "DaggerThrow")) {
- return;
- }
-
- arrow.setVelocity(new Vector(0, 0, 0));
- entity.setNoDamageTicks(0);
- double prevHealth = entity.getHealth();
- Player shooter = (Player) arrow.getShooter();
- DamageAbility da = new DamageAbility(shooter);
- DamageHandler.damageEntity(entity, damage, da);
- da.remove();
- if (prevHealth > entity.getHealth()) {
- arrow.remove();
- }
-
- if (!(entity instanceof Player)) {
- return;
- }
-
- DaggerThrow dt = CoreAbility.getAbility(shooter, DaggerThrow.class);
- if (dt == null) {
- return;
- }
-
- ++dt.hits;
-
- Player target = (Player)entity;
- BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(target);
-
- for (AbilityInteraction interaction : INTERACTIONS) {
- if (!interaction.enabled) continue;
- if (dt.hits < interaction.hitRequirement) continue;
-
- CoreAbility abilityDefinition = AbilitySelector.getAbility(interaction.name);
- if (abilityDefinition == null) continue;
-
- CoreAbility ability = CoreAbility.getAbility(target, abilityDefinition.getClass());
- if (ability == null) continue;
-
- ability.remove();
- bPlayer.addCooldown(ability, interaction.cooldown);
- }
- }
-
- @Override
- public long getCooldown() {
- return cooldown;
- }
-
- @Override
- public Location getLocation() {
- return null;
- }
-
- @Override
- public List getLocations() {
- return arrows.stream().map(Arrow::getLocation).collect(Collectors.toList());
- }
-
- @Override
- public double getCollisionRadius() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getDouble("Abilities.Chi.DaggerThrow.AbilityCollisionRadius");
- }
-
- @Override
- public void handleCollision(Collision collision) {
- if (collision.isRemovingFirst()) {
- Location location = collision.getLocationFirst();
-
- Optional collidedObject = arrows.stream().filter(arrow -> arrow.getLocation().equals(location)).findAny();
-
- if (collidedObject.isPresent()) {
- arrows.remove(collidedObject.get());
- collidedObject.get().remove();
- }
- }
- }
-
- @Override
- public String getName() {
- return "DaggerThrow";
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return false;
- }
-
- @Override
- public String getAuthor() {
- return JedCore.dev;
- }
-
- @Override
- public String getVersion() {
- return JedCore.version;
- }
-
- @Override
- public String getDescription() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return "* JedCore Addon *\n" + config.getString("Abilities.Chi.DaggerThrow.Description");
- }
-
- public static boolean hasParticleTrail() {
- return particles;
- }
-
- public static double getDamage() {
- return damage;
- }
-
- public long getEndTime() {
- return endTime;
- }
-
- public void setEndTime(long endTime) {
- this.endTime = endTime;
- }
-
- public int getShots() {
- return shots;
- }
-
- public void setShots(int shots) {
- this.shots = shots;
- }
-
- public void setCooldown(long cooldown) {
- this.cooldown = cooldown;
- }
-
- public boolean isLimitEnabled() {
- return limitEnabled;
- }
-
- public void setLimitEnabled(boolean limitEnabled) {
- this.limitEnabled = limitEnabled;
- }
-
- public int getMaxShots() {
- return maxShots;
- }
-
- public void setMaxShots(int maxShots) {
- this.maxShots = maxShots;
- }
-
- public int getHits() {
- return hits;
- }
-
- public void setHits(int hits) {
- this.hits = hits;
- }
-
- public List getArrows() {
- return arrows;
- }
-
- @Override
- public void load() {}
-
- @Override
- public void stop() {}
-
- @Override
- public boolean isEnabled() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getBoolean("Abilities.Chi.DaggerThrow.Enabled");
- }
-
- public static class DamageAbility extends DaggerThrow {
-
- public DamageAbility(Player player) {
- super(player);
- start();
- }
-
- @Override
- public long getCooldown() {
- return 0;
- }
-
- @Override
- public Location getLocation() {
- return null;
- }
-
- @Override
- public String getName() {
- return "DaggerThrow";
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return false;
- }
-
- @Override
- public void progress() {
- remove();
- }
- }
-
- private class AbilityInteraction {
- public boolean enabled;
- public long cooldown;
- public int hitRequirement;
- public String name;
-
- public AbilityInteraction(String abilityName) {
- this.name = abilityName;
- loadConfig();
- }
-
- public void loadConfig() {
- ConfigurationSection config = JedCoreConfig.getConfig(player);
- this.enabled = config.getBoolean("Abilities.Chi.DaggerThrow.Interactions." + name + ".Enabled", true);
- this.cooldown = config.getLong("Abilities.Chi.DaggerThrow.Interactions." + name + ".Cooldown", 1000);
- this.hitRequirement = config.getInt("Abilities.Chi.DaggerThrow.Interactions." + name + ".HitsRequired", 1);
- }
- }
-}
+ private static final List INTERACTIONS = new ArrayList<>();
+
+ private final List arrows = new ArrayList<>();
+
+ private boolean limitEnabled;
+ private boolean requireArrows;
+ private boolean allowPickup;
+ private boolean particles;
+ private long endTime;
+ private int shots = 1;
+ private int hits = 0;
+
+ @Attribute(Attribute.DAMAGE)
+ private double damage;
+ @Attribute(Attribute.COOLDOWN)
+ private long cooldown;
+ @Attribute("MaxShots")
+ private int maxShots;
+
+ public DaggerThrow(Player player) {
+ super(player);
+
+ if (!bPlayer.canBend(this)) {
+ return;
+ }
+
+ if (bPlayer.isOnCooldown("DaggerThrowShot")) {
+ return;
+ }
+
+ if (hasAbility(player, DaggerThrow.class)) {
+ DaggerThrow dt = getAbility(player, DaggerThrow.class);
+ dt.shootArrow();
+ return;
+ }
+
+ setFields();
+
+ start();
+
+ if (!isRemoved()) {
+ shootArrow();
+ }
+ }
+
+ public void setFields() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ cooldown = config.getLong("Abilities.Chi.DaggerThrow.Cooldown");
+ limitEnabled = config.getBoolean("Abilities.Chi.DaggerThrow.MaxDaggers.Enabled");
+ maxShots = config.getInt("Abilities.Chi.DaggerThrow.MaxDaggers.Amount");
+ particles = config.getBoolean("Abilities.Chi.DaggerThrow.ParticleTrail");
+ damage = config.getDouble("Abilities.Chi.DaggerThrow.Damage");
+ requireArrows = config.getBoolean("Abilities.Chi.DaggerThrow.RequireArrows");
+ allowPickup = config.getBoolean("Abilities.Chi.DaggerThrow.AllowPickup");
+
+ loadInteractions();
+ }
+
+ private void loadInteractions() {
+ INTERACTIONS.clear();
+
+ String path = "Abilities.Chi.DaggerThrow.Interactions";
+
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ ConfigurationSection section = config.getConfigurationSection(path);
+
+ for (String abilityName : section.getKeys(false)) {
+ INTERACTIONS.add(new AbilityInteraction(abilityName));
+ }
+ }
+
+ @Override
+ public void progress() {
+ if (player.isDead() || !player.isOnline()) {
+ remove();
+ return;
+ }
+
+ if (System.currentTimeMillis() > endTime) {
+ bPlayer.addCooldown(this);
+ remove();
+ return;
+ }
+
+ if (shots > maxShots && limitEnabled) {
+ bPlayer.addCooldown(this);
+ remove();
+ }
+ }
+
+ private void shootArrow() {
+ shots++;
+ Location location = player.getEyeLocation();
+
+ Vector vector = location.toVector().
+ add(location.getDirection().multiply(2.5)).
+ toLocation(location.getWorld()).toVector().
+ subtract(player.getEyeLocation().toVector());
+
+ if (requireArrows) JCMethods.removeItemFromInventory(player, Material.ARROW, 1);
+
+ Arrow arrow = player.launchProjectile(Arrow.class);
+ arrow.setVelocity(vector);
+ arrow.getLocation().setDirection(vector);
+ arrow.setKnockbackStrength(0);
+ arrow.setBounce(false);
+ arrow.setMetadata("daggerthrow", new FixedMetadataValue(JedCore.plugin, "1"));
+
+ if (!allowPickup) arrow.setPickupStatus(Arrow.PickupStatus.DISALLOWED);
+
+ if (particles) {
+ arrow.setCritical(true);
+ }
+
+ arrows.add(arrow);
+ endTime = System.currentTimeMillis() + 500;
+ bPlayer.addCooldown("DaggerThrowShot", 100);
+ }
+
+ public void damageEntityFromArrow(LivingEntity entity, Arrow arrow) {
+ if (!(arrow.getShooter() instanceof Player shooter)) return;
+
+ if (RegionProtection.isRegionProtected(shooter, arrow.getLocation(), "DaggerThrow")) return;
+
+ ThreadUtil.ensureEntity(arrow, () -> arrow.setVelocity(new Vector(0, 0, 0)));
+ ThreadUtil.ensureEntity(entity, () -> entity.setNoDamageTicks(0));
+
+ double prevHealth = entity.getHealth();
+
+ ThreadUtil.ensureEntity(entity, () -> DamageHandler.damageEntity(entity, damage, this));
+
+ if (prevHealth > entity.getHealth()) {
+ ThreadUtil.ensureEntity(arrow, arrow::remove);
+ }
+
+ if (!(entity instanceof Player target)) {
+ return;
+ }
+
+ DaggerThrow daggerThrow = CoreAbility.getAbility(shooter, DaggerThrow.class);
+ if (daggerThrow == null) {
+ return;
+ }
+
+ daggerThrow.hits++;
+ BendingPlayer targetBPlayer = BendingPlayer.getBendingPlayer(target);
+
+ for (AbilityInteraction interaction : INTERACTIONS) {
+ if (!interaction.enabled || daggerThrow.hits < interaction.hitRequirement) {
+ continue;
+ }
+
+ CoreAbility abilityDefinition = AbilitySelector.getAbility(interaction.name);
+ if (abilityDefinition == null) {
+ continue;
+ }
+
+ CoreAbility ability = CoreAbility.getAbility(target, abilityDefinition.getClass());
+ if (ability == null) {
+ continue;
+ }
+
+ ability.remove();
+ targetBPlayer.addCooldown(ability, interaction.cooldown);
+ }
+ }
+
+ @Override
+ public long getCooldown() {
+ return cooldown;
+ }
+
+ @Override
+ public Location getLocation() {
+ return null;
+ }
+
+ @Override
+ public List getLocations() {
+ return arrows.stream().map(Arrow::getLocation).collect(Collectors.toList());
+ }
+
+ @Override
+ public double getCollisionRadius() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getDouble("Abilities.Chi.DaggerThrow.AbilityCollisionRadius");
+ }
+
+ @Override
+ public void handleCollision(Collision collision) {
+ if (collision.isRemovingFirst()) {
+ Location location = collision.getLocationFirst();
+
+ Optional collidedObject = arrows.stream().filter(arrow -> arrow.getLocation().equals(location)).findAny();
+
+ if (collidedObject.isPresent()) {
+ arrows.remove(collidedObject.get());
+ collidedObject.get().remove();
+ }
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "DaggerThrow";
+ }
+
+ @Override
+ public boolean isHarmlessAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isSneakAbility() {
+ return false;
+ }
+
+ @Override
+ public String getAuthor() {
+ return JedCore.dev;
+ }
+
+ @Override
+ public String getVersion() {
+ return JedCore.version;
+ }
+
+ @Override
+ public String getDescription() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return "* JedCore Addon *\n" + config.getString("Abilities.Chi.DaggerThrow.Description");
+ }
+
+ public boolean hasParticleTrail() {
+ return particles;
+ }
+
+ public double getDamage() {
+ return damage;
+ }
+
+ public long getEndTime() {
+ return endTime;
+ }
+
+ public void setEndTime(long endTime) {
+ this.endTime = endTime;
+ }
+
+ public int getShots() {
+ return shots;
+ }
+
+ public void setShots(int shots) {
+ this.shots = shots;
+ }
+
+ public void setCooldown(long cooldown) {
+ this.cooldown = cooldown;
+ }
+
+ public boolean isLimitEnabled() {
+ return limitEnabled;
+ }
+
+ public void setLimitEnabled(boolean limitEnabled) {
+ this.limitEnabled = limitEnabled;
+ }
+
+ public int getMaxShots() {
+ return maxShots;
+ }
+
+ public void setMaxShots(int maxShots) {
+ this.maxShots = maxShots;
+ }
+
+ public int getHits() {
+ return hits;
+ }
+
+ public void setHits(int hits) {
+ this.hits = hits;
+ }
+
+ public List getArrows() {
+ return arrows;
+ }
+
+ @Override
+ public void load() {}
+
+ @Override
+ public void stop() {}
+
+ @Override
+ public boolean isEnabled() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getBoolean("Abilities.Chi.DaggerThrow.Enabled");
+ }
+
+ private class AbilityInteraction {
+ public boolean enabled;
+ public long cooldown;
+ public int hitRequirement;
+ public String name;
+
+ public AbilityInteraction(String abilityName) {
+ this.name = abilityName;
+ loadConfig();
+ }
+
+ public void loadConfig() {
+ ConfigurationSection config = JedCoreConfig.getConfig(player);
+ this.enabled = config.getBoolean("Abilities.Chi.DaggerThrow.Interactions." + name + ".Enabled", true);
+ this.cooldown = config.getLong("Abilities.Chi.DaggerThrow.Interactions." + name + ".Cooldown", 1000);
+ this.hitRequirement = config.getInt("Abilities.Chi.DaggerThrow.Interactions." + name + ".HitsRequired", 1);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/com/jedk1/jedcore/ability/earthbending/EarthKick.java b/src/com/jedk1/jedcore/ability/earthbending/EarthKick.java
index 505e17b..31b9e9a 100644
--- a/src/com/jedk1/jedcore/ability/earthbending/EarthKick.java
+++ b/src/com/jedk1/jedcore/ability/earthbending/EarthKick.java
@@ -8,13 +8,14 @@
import com.jedk1.jedcore.util.BlockUtil;
import com.projectkorra.projectkorra.ability.AddonAbility;
import com.projectkorra.projectkorra.ability.EarthAbility;
-import com.projectkorra.projectkorra.ability.ElementalAbility;
import com.projectkorra.projectkorra.ability.util.Collision;
import com.projectkorra.projectkorra.attribute.Attribute;
+import com.projectkorra.projectkorra.earthbending.passive.DensityShift;
import com.projectkorra.projectkorra.region.RegionProtection;
-import com.projectkorra.projectkorra.util.*;
-
-import org.bukkit.Bukkit;
+import com.projectkorra.projectkorra.util.DamageHandler;
+import com.projectkorra.projectkorra.util.ParticleEffect;
+import com.projectkorra.projectkorra.util.TempBlock;
+import com.projectkorra.projectkorra.util.TempFallingBlock;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
@@ -24,291 +25,319 @@
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Random;
-import java.util.Set;
-import java.util.UUID;
+import java.util.*;
+import java.util.concurrent.ThreadLocalRandom;
import static java.util.stream.Collectors.toList;
public class EarthKick extends EarthAbility implements AddonAbility {
- private final List temps = new ArrayList<>();
-
- private BlockData materialData;
- private Location location;
- private final Random rand = new Random();
-
- @Attribute(Attribute.COOLDOWN)
- private long cooldown;
- @Attribute("MaxShots")
- private int earthBlocks;
- @Attribute(Attribute.DAMAGE)
- private double damage;
- @Attribute("CollisionRadius")
- private double entityCollisionRadius;
- private Block block;
-
- private boolean multipleHits;
- private int sourceRange;
- private int spread;
- private double velocity;
-
- private Set hitEntities = new HashSet<>();
-
- public EarthKick(Player player) {
- super(player);
-
- if (!bPlayer.canBend(this)) {
- return;
- }
-
- setFields();
- location = player.getLocation();
- if ((player.getLocation().getPitch() > -5) && prepare()) {
- if (RegionProtection.isRegionProtected(this, block.getLocation())) {
- return;
- }
- launchBlocks();
- start();
- }
- }
-
- public void setFields() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- cooldown = config.getLong("Abilities.Earth.EarthKick.Cooldown");
- earthBlocks = config.getInt("Abilities.Earth.EarthKick.EarthBlocks");
- damage = config.getDouble("Abilities.Earth.EarthKick.Damage");
- entityCollisionRadius = config.getDouble("Abilities.Earth.EarthKick.EntityCollisionRadius");
-
- multipleHits = config.getBoolean("Abilities.Earth.EarthKick.MultipleHits");
- sourceRange = config.getInt("Abilities.Earth.EarthKick.SourceRange");
- spread = config.getInt("Abilities.Earth.EarthKick.Spread");
- velocity = config.getDouble("Abilities.Earth.EarthKick.Velocity");
-
- if (entityCollisionRadius < 1.0) {
- entityCollisionRadius = 1.0;
- }
- }
-
- private boolean prepare() {
- block = player.getTargetBlock(getTransparentMaterialSet(), sourceRange);
- if (!isEarthbendable(player, block)){
- return false;
- }
-
- if (block != null && !isMetal(block)) {
- materialData = block.getBlockData().clone();
- location.setX(block.getX() + 0.5);
- location.setY(block.getY());
- location.setZ(block.getZ() + 0.5);
-
- return true;
- }
-
- return false;
- }
-
- @Override
- public void progress() {
- if (player.isDead() || !player.isOnline()) {
- remove();
- return;
- }
-
- if (!bPlayer.canBendIgnoreBindsCooldowns(this)) {
- remove();
- return;
- }
-
- bPlayer.addCooldown(this);
- track();
-
- if (temps.isEmpty()) {
- remove();
- }
- }
-
- private void launchBlocks() {
- if (getMovedEarth().containsKey(block)) {
- block.setType(Material.AIR);
- }
- if (block.getType() != Material.AIR) {
- TempBlock air = new TempBlock(block, Material.AIR);
- air.setRevertTime(5000L);
- }
-
- location.setPitch(0);
- location.add(location.getDirection());
-
- if (!isAir(location.getBlock().getType())) {
- location.setY(location.getY() + 1.0);
- }
-
- ParticleEffect.CRIT.display(location, 10, Math.random(), Math.random(), Math.random(), 0.1);
-
- int yaw = Math.round(location.getYaw());
-
- playEarthbendingSound(location);
-
- for (int i = 0; i < earthBlocks; i++) {
- location.setYaw(yaw + rand.nextInt((spread * 2) + 1) - spread);
- location.setPitch(rand.nextInt(25) - 45);
-
- Vector v = location.clone().add(0, 0.8, 0).getDirection().normalize();
- Location location1 = location.clone().add(new Vector(v.getX() * 2, v.getY(), v.getZ() * 2));
- Vector dir = location1.setDirection(location.getDirection()).getDirection().multiply(velocity);
-
- temps.add(new TempFallingBlock(location, materialData, dir, this));
- }
- }
-
- public void track() {
- List destroy = new ArrayList<>();
-
- for (TempFallingBlock tfb : temps) {
- FallingBlock fb = tfb.getFallingBlock();
-
- if (fb == null || fb.isDead()) {
- destroy.add(tfb);
- continue;
- }
-
- for (int i = 0; i < 2; i++) {
- ParticleEffect.BLOCK_CRACK.display(fb.getLocation(), 1, 0.0, 0.0, 0.0, 0.1, materialData);
- ParticleEffect.BLOCK_CRACK.display(fb.getLocation(), 1, 0.0, 0.0, 0.0, 0.2, materialData);
- }
-
- AABB collider = BlockUtil.getFallingBlockBoundsFull(fb).scale(entityCollisionRadius * 2.0);
-
- CollisionDetector.checkEntityCollisions(player, collider, (entity) -> {
- UUID uuid = entity.getUniqueId();
- if (this.multipleHits || hitEntities.add(uuid)) {
- DamageHandler.damageEntity(entity, damage, this);
- }
- return false;
- });
- }
-
- temps.removeAll(destroy);
- }
-
- @Override
- public long getCooldown() {
- return cooldown;
- }
-
- @Override
- public Location getLocation() {
- return location;
- }
-
- @Override
- public List getLocations() {
- return temps.stream().map(TempFallingBlock::getLocation).collect(toList());
- }
-
- @Override
- public double getCollisionRadius() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getDouble("Abilities.Earth.EarthKick.AbilityCollisionRadius");
- }
-
- @Override
- public void handleCollision(Collision collision) {
- CollisionUtil.handleFallingBlockCollisions(collision, temps);
- }
-
- @Override
- public String getName() {
- return "EarthKick";
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return true;
- }
-
- @Override
- public String getAuthor() {
- return JedCore.dev;
- }
-
- @Override
- public String getVersion() {
- return JedCore.version;
- }
-
- @Override
- public String getDescription() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return "* JedCore Addon *\n" + config.getString("Abilities.Earth.EarthKick.Description");
- }
-
- public List getTemps() {
- return temps;
- }
-
- public BlockData getMaterialData() {
- return materialData;
- }
-
- public void setMaterialData(BlockData materialData) {
- this.materialData = materialData;
- }
-
- public void setLocation(Location location) {
- this.location = location;
- }
-
- public int getEarthBlocksQuantity() {
- return earthBlocks;
- }
-
- public void setEarthBlocksQuantity(int earthBlocks) {
- this.earthBlocks = earthBlocks;
- }
-
- public double getDamage() {
- return damage;
- }
-
- public void setDamage(double damage) {
- this.damage = damage;
- }
-
- public double getEntityCollisionRadius() {
- return entityCollisionRadius;
- }
-
- public void setEntityCollisionRadius(double entityCollisionRadius) {
- this.entityCollisionRadius = entityCollisionRadius;
- }
-
- public Block getBlock() {
- return block;
- }
-
- public void setBlock(Block block) {
- this.block = block;
- }
-
- @Override
- public void load() {}
-
- @Override
- public void stop() {}
-
- @Override
- public boolean isEnabled() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getBoolean("Abilities.Earth.EarthKick.Enabled");
- }
-}
+ private final List temps = new ArrayList<>();
+ private final Set hitEntities = new HashSet<>();
+
+ private BlockData materialData;
+ private Location location;
+ private Block block;
+ private boolean multipleHits;
+ private int sourceRange;
+ private int spread;
+ private double velocity;
+ private boolean allowMetal;
+ private boolean replaceSource;
+
+ @Attribute(Attribute.COOLDOWN)
+ private long cooldown;
+ @Attribute("MaxShots")
+ private int earthBlocks;
+ @Attribute(Attribute.DAMAGE)
+ private double damage;
+ @Attribute(Attribute.DAMAGE)
+ private double metalDmg;
+ @Attribute("CollisionRadius")
+ private double entityCollisionRadius;
+
+ public EarthKick(Player player) {
+ super(player);
+
+ if (!bPlayer.canBend(this)) {
+ return;
+ }
+
+ setFields();
+
+ location = player.getLocation();
+
+ if ((player.getLocation().getPitch() > -5) && prepare()) {
+ if (RegionProtection.isRegionProtected(this, block.getLocation())) {
+ return;
+ }
+ launchBlocks();
+ start();
+ }
+ }
+
+ public void setFields() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ cooldown = config.getLong("Abilities.Earth.EarthKick.Cooldown");
+ earthBlocks = config.getInt("Abilities.Earth.EarthKick.EarthBlocks");
+ damage = config.getDouble("Abilities.Earth.EarthKick.Damage.Normal");
+ metalDmg = config.getDouble("Abilities.Earth.EarthKick.Damage.Metal");
+ entityCollisionRadius = config.getDouble("Abilities.Earth.EarthKick.EntityCollisionRadius");
+ multipleHits = config.getBoolean("Abilities.Earth.EarthKick.MultipleHits");
+ sourceRange = config.getInt("Abilities.Earth.EarthKick.SourceRange");
+ spread = config.getInt("Abilities.Earth.EarthKick.Spread");
+ velocity = config.getDouble("Abilities.Earth.EarthKick.Velocity");
+ allowMetal = config.getBoolean("Abilities.Earth.EarthKick.AllowMetal");
+ replaceSource = config.getBoolean("Abilities.Earth.EarthKick.ReplaceSource");
+
+ if (entityCollisionRadius < 1.0) {
+ entityCollisionRadius = 1.0;
+ }
+ }
+
+ private boolean prepare() {
+ block = player.getTargetBlock(getTransparentMaterialSet(), sourceRange);
+
+ if (EarthAbility.getMovedEarth().containsKey(block)) {
+ return false;
+ }
+
+ if (!isEarthbendable(player, block)) {
+ return false;
+ }
+
+ if (TempBlock.isTempBlock(block)) {
+ TempBlock.get(block).revertBlock();
+ }
+
+ if (DensityShift.isPassiveSand(block)) {
+ DensityShift.revertSand(block);
+ }
+
+ if (block != null && (allowMetal || !isMetal(block))) {
+ materialData = block.getBlockData().clone();
+ location.setX(block.getX() + 0.5);
+ location.setY(block.getY());
+ location.setZ(block.getZ() + 0.5);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ public void progress() {
+ if (player.isDead() || !player.isOnline()) {
+ remove();
+ return;
+ }
+
+ if (!bPlayer.canBendIgnoreBindsCooldowns(this)) {
+ remove();
+ return;
+ }
+
+ bPlayer.addCooldown(this);
+
+ track();
+
+ if (temps.isEmpty()) {
+ remove();
+ }
+ }
+
+ private void launchBlocks() {
+ if (replaceSource) {
+ if (getMovedEarth().containsKey(block)) {
+ block.setType(Material.AIR);
+ }
+
+ if (block.getType() != Material.AIR) {
+ TempBlock air = new TempBlock(block, Material.AIR);
+ air.setRevertTime(5000L);
+ }
+ }
+
+ location.setPitch(0);
+ location.add(location.getDirection());
+
+ if (!isAir(location.getBlock().getType())) {
+ location.setY(location.getY() + 1.0);
+ }
+
+ ParticleEffect.CRIT.display(location, 10, Math.random(), Math.random(), Math.random(), 0.1);
+
+ int yaw = Math.round(location.getYaw());
+
+ playEarthbendingSound(location);
+
+ ThreadLocalRandom rand = ThreadLocalRandom.current();
+
+ for (int i = 0; i < earthBlocks; i++) {
+ location.setYaw(yaw + rand.nextInt((spread * 2) + 1) - spread);
+ location.setPitch(rand.nextInt(25) - 45);
+
+ Vector v = location.clone().add(0, 0.8, 0).getDirection().normalize();
+ Location location1 = location.clone().add(new Vector(v.getX() * 2, v.getY(), v.getZ() * 2));
+ Vector dir = location1.setDirection(location.getDirection()).getDirection().multiply(velocity);
+
+ temps.add(new TempFallingBlock(location, materialData, dir, this));
+ }
+ }
+
+ public void track() {
+ List destroy = new ArrayList<>();
+
+ for (TempFallingBlock tfb : temps) {
+ FallingBlock fb = tfb.getFallingBlock();
+
+ if (fb == null || fb.isDead()) {
+ destroy.add(tfb);
+ continue;
+ }
+
+ for (int i = 0; i < 2; i++) {
+ ParticleEffect.BLOCK_CRACK.display(fb.getLocation(), 1, 0.0, 0.0, 0.0, 0.1, materialData);
+ ParticleEffect.BLOCK_CRACK.display(fb.getLocation(), 1, 0.0, 0.0, 0.0, 0.2, materialData);
+ }
+
+ AABB collider = BlockUtil.getFallingBlockBoundsFull(fb).scale(entityCollisionRadius * 2.0);
+
+ CollisionDetector.checkEntityCollisions(player, collider, (entity) -> {
+ UUID uuid = entity.getUniqueId();
+ if (this.multipleHits || hitEntities.add(uuid)) {
+ DamageHandler.damageEntity(entity, isMetal(fb.getBlockData().getMaterial()) ? metalDmg : damage, this);
+ }
+ return false;
+ });
+ }
+
+ temps.removeAll(destroy);
+ }
+
+ @Override
+ public long getCooldown() {
+ return cooldown;
+ }
+
+ @Override
+ public Location getLocation() {
+ return location;
+ }
+
+ @Override
+ public List getLocations() {
+ return temps.stream().map(TempFallingBlock::getLocation).collect(toList());
+ }
+
+ @Override
+ public double getCollisionRadius() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getDouble("Abilities.Earth.EarthKick.AbilityCollisionRadius");
+ }
+
+ @Override
+ public void handleCollision(Collision collision) {
+ CollisionUtil.handleFallingBlockCollisions(collision, temps);
+ }
+
+ @Override
+ public String getName() {
+ return "EarthKick";
+ }
+
+ @Override
+ public boolean isHarmlessAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isSneakAbility() {
+ return true;
+ }
+
+ @Override
+ public String getAuthor() {
+ return JedCore.dev;
+ }
+
+ @Override
+ public String getVersion() {
+ return JedCore.version;
+ }
+
+ @Override
+ public String getDescription() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return "* JedCore Addon *\n" + config.getString("Abilities.Earth.EarthKick.Description");
+ }
+
+ public List getTemps() {
+ return temps;
+ }
+
+ public BlockData getMaterialData() {
+ return materialData;
+ }
+
+ public void setMaterialData(BlockData materialData) {
+ this.materialData = materialData;
+ }
+
+ public void setLocation(Location location) {
+ this.location = location;
+ }
+
+ public int getEarthBlocksQuantity() {
+ return earthBlocks;
+ }
+
+ public void setEarthBlocksQuantity(int earthBlocks) {
+ this.earthBlocks = earthBlocks;
+ }
+
+ public double getDamage() {
+ return damage;
+ }
+
+ public void setDamage(double damage) {
+ this.damage = damage;
+ }
+
+ public double getMetalDmg() {
+ return metalDmg;
+ }
+
+ public void setMetalDmg(double metalDmg) {
+ this.metalDmg = metalDmg;
+ }
+
+ public double getEntityCollisionRadius() {
+ return entityCollisionRadius;
+ }
+
+ public void setEntityCollisionRadius(double entityCollisionRadius) {
+ this.entityCollisionRadius = entityCollisionRadius;
+ }
+
+ public Block getBlock() {
+ return block;
+ }
+
+ public void setBlock(Block block) {
+ this.block = block;
+ }
+
+ @Override
+ public void load() {}
+
+ @Override
+ public void stop() {}
+
+ @Override
+ public boolean isEnabled() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getBoolean("Abilities.Earth.EarthKick.Enabled");
+ }
+}
\ No newline at end of file
diff --git a/src/com/jedk1/jedcore/ability/earthbending/EarthLine.java b/src/com/jedk1/jedcore/ability/earthbending/EarthLine.java
index 90e0ba4..e047ed3 100644
--- a/src/com/jedk1/jedcore/ability/earthbending/EarthLine.java
+++ b/src/com/jedk1/jedcore/ability/earthbending/EarthLine.java
@@ -3,9 +3,6 @@
import com.jedk1.jedcore.JedCore;
import com.jedk1.jedcore.configuration.JedCoreConfig;
import com.jedk1.jedcore.policies.removal.*;
-import com.jedk1.jedcore.util.RegenTempBlock;
-
-import com.projectkorra.projectkorra.util.TempBlock;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AddonAbility;
import com.projectkorra.projectkorra.ability.EarthAbility;
@@ -13,12 +10,9 @@
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.earthbending.passive.DensityShift;
import com.projectkorra.projectkorra.region.RegionProtection;
-import com.projectkorra.projectkorra.util.BlockSource;
-import com.projectkorra.projectkorra.util.ClickType;
import com.projectkorra.projectkorra.util.DamageHandler;
-
+import com.projectkorra.projectkorra.util.TempBlock;
import com.projectkorra.projectkorra.util.TempFallingBlock;
-
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -32,79 +26,84 @@
public class EarthLine extends EarthAbility implements AddonAbility {
- private Location location;
- private Location endLocation;
- private Block sourceBlock;
- private Material sourceType;
- private boolean progressing;
- private boolean hitted;
- private int goOnAfterHit;
- private long removalTime = -1;
-
- private long useCooldown;
- private long prepareCooldown;
- @Attribute(Attribute.DURATION)
- private long maxDuration;
- @Attribute(Attribute.RANGE)
- private double range;
- @Attribute(Attribute.SELECT_RANGE)
- private double prepareRange;
- private double sourceKeepRange;
- @Attribute(Attribute.RADIUS)
- private int affectingRadius;
- @Attribute(Attribute.DAMAGE)
- private double damage;
- private boolean allowChangeDirection;
- private CompositeRemovalPolicy removalPolicy;
-
- public EarthLine(Player player) {
- super(player);
-
- if (!isEnabled()) return;
-
- if (!bPlayer.canBend(this)) {
- return;
- }
- goOnAfterHit = 1;
-
- setFields();
- if (prepare()) {
- start();
- if (!isRemoved() && prepareCooldown != 0) {
- bPlayer.addCooldown(this, prepareCooldown);
- }
- }
- }
-
- public void setFields() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- this.removalPolicy = new CompositeRemovalPolicy(this,
- new CannotBendRemovalPolicy(this.bPlayer, this, true, true),
- new IsOfflineRemovalPolicy(this.player),
- new IsDeadRemovalPolicy(this.player),
- new SwappedSlotsRemovalPolicy<>(bPlayer, EarthLine.class)
- );
-
- this.removalPolicy.load(config);
-
- useCooldown = config.getLong("Abilities.Earth.EarthLine.Cooldown");
- prepareCooldown = config.getLong("Abilities.Earth.EarthLine.PrepareCooldown");
- range = config.getInt("Abilities.Earth.EarthLine.Range");
- prepareRange = config.getDouble("Abilities.Earth.EarthLine.PrepareRange");
- sourceKeepRange = config.getDouble("Abilities.Earth.EarthLine.SourceKeepRange");
- affectingRadius = config.getInt("Abilities.Earth.EarthLine.AffectingRadius");
- damage = config.getDouble("Abilities.Earth.EarthLine.Damage");
- allowChangeDirection = config.getBoolean("Abilities.Earth.EarthLine.AllowChangeDirection");
- maxDuration = config.getLong("Abilities.Earth.EarthLine.MaxDuration");
- }
+ private Location location;
+ private Location endLocation;
+ private Block sourceBlock;
+ private TempBlock sourceTempBlock;
+ private Material sourceType;
+ private boolean progressing;
+ private boolean hitted;
+ private int goOnAfterHit;
+ private long removalTime = -1;
+ private boolean allowChangeDirection;
+ private CompositeRemovalPolicy removalPolicy;
+ private long useCooldown;
+ private long prepareCooldown;
+ private double sourceKeepRange;
+
+ @Attribute(Attribute.DURATION)
+ private long maxDuration;
+ @Attribute(Attribute.RANGE)
+ private double range;
+ @Attribute(Attribute.SELECT_RANGE)
+ private double prepareRange;
+ @Attribute(Attribute.RADIUS)
+ private int affectingRadius;
+ @Attribute(Attribute.DAMAGE)
+ private double damage;
+
+ public EarthLine(Player player) {
+ super(player);
+
+ if (!isEnabled()) return;
+
+ if (!bPlayer.canBend(this)) {
+ return;
+ }
+ goOnAfterHit = 1;
+
+ setFields();
+
+ if (prepare()) {
+ start();
+ if (!isRemoved() && prepareCooldown != 0) {
+ bPlayer.addCooldown(this, prepareCooldown);
+ }
+ }
+ }
+
+ public void setFields() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ this.removalPolicy = new CompositeRemovalPolicy(this,
+ new CannotBendRemovalPolicy(this.bPlayer, this, true, true),
+ new IsOfflineRemovalPolicy(this.player),
+ new IsDeadRemovalPolicy(this.player),
+ new SwappedSlotsRemovalPolicy<>(bPlayer, EarthLine.class)
+ );
+
+ this.removalPolicy.load(config);
+
+ useCooldown = config.getLong("Abilities.Earth.EarthLine.Cooldown");
+ prepareCooldown = config.getLong("Abilities.Earth.EarthLine.PrepareCooldown");
+ range = config.getInt("Abilities.Earth.EarthLine.Range");
+ prepareRange = config.getDouble("Abilities.Earth.EarthLine.PrepareRange");
+ sourceKeepRange = config.getDouble("Abilities.Earth.EarthLine.SourceKeepRange");
+ affectingRadius = config.getInt("Abilities.Earth.EarthLine.AffectingRadius");
+ damage = config.getDouble("Abilities.Earth.EarthLine.Damage");
+ allowChangeDirection = config.getBoolean("Abilities.Earth.EarthLine.AllowChangeDirection");
+ maxDuration = config.getLong("Abilities.Earth.EarthLine.MaxDuration");
+ }
public boolean prepare() {
- final Block block = BlockSource.getEarthSourceBlock(this.player, this.range, ClickType.SHIFT_DOWN);
+ final Block block = getEarthSourceBlock(this.range);
+
if (block == null || !this.isEarthbendable(block)) {
return false;
} else if (TempBlock.isTempBlock(block) && !EarthAbility.isBendableEarthTempBlock(block)) {
return false;
+ } else if (EarthAbility.getMovedEarth().containsKey(block)) {
+ return false;
}
boolean selectedABlockInUse = false;
@@ -126,364 +125,366 @@ public boolean prepare() {
this.sourceBlock = block;
this.focusBlock();
+
+ return true;
+ }
+
+ private void focusBlock() {
+ if (DensityShift.isPassiveSand(this.sourceBlock)) {
+ DensityShift.revertSand(this.sourceBlock);
+ }
+
+ if (this.sourceBlock.getType() == Material.SAND) {
+ this.sourceType = Material.SAND;
+ sourceTempBlock = new TempBlock(sourceBlock, Material.SANDSTONE.createBlockData());
+ } else if (this.sourceBlock.getType() == Material.RED_SAND) {
+ this.sourceType = Material.RED_SAND;
+ sourceTempBlock = new TempBlock(sourceBlock, Material.RED_SANDSTONE.createBlockData());
+ } else if (this.sourceBlock.getType() == Material.STONE) {
+ this.sourceType = Material.STONE;
+ sourceTempBlock = new TempBlock(sourceBlock, Material.COBBLESTONE.createBlockData());
+ } else {
+ this.sourceType = this.sourceBlock.getType();
+ sourceTempBlock = new TempBlock(sourceBlock, Material.STONE.createBlockData());
+ }
+
+ this.location = this.sourceBlock.getLocation();
+ }
+
+ private void unfocusBlock() {
+ sourceTempBlock.revertBlock();
+ }
+
+ @Override
+ public void remove() {
+ sourceTempBlock.revertBlock();
+ super.remove();
+ }
+
+ // todo: static
+ private static Location getTargetLocation(Player player) {
+ ConfigurationSection config = JedCoreConfig.getConfig(player);
+
+ double range = config.getInt("Abilities.Earth.EarthLine.Range");
+
+ Entity target = GeneralMethods.getTargetedEntity(player, range, player.getNearbyEntities(range, range, range));
+ Location location;
+
+ if (target == null) {
+ location = GeneralMethods.getTargetedLocation(player, range);
+ } else {
+ location = ((LivingEntity) target).getEyeLocation();
+ }
+
+ return location;
+ }
+
+ public void shootLine(Location endLocation) {
+ if (useCooldown != 0 && bPlayer.getCooldown(this.getName()) < useCooldown) bPlayer.addCooldown(this, useCooldown);
+ if (maxDuration > 0) removalTime = System.currentTimeMillis() + maxDuration;
+ this.endLocation = endLocation;
+ progressing = true;
+ sourceBlock.getWorld().playEffect(sourceBlock.getLocation(), Effect.GHAST_SHOOT, 0, 10);
+ }
+
+ public static void shootLine(Player player) {
+ if (hasAbility(player, EarthLine.class)) {
+ EarthLine el = getAbility(player, EarthLine.class);
+ if (!el.progressing) {
+ el.shootLine(getTargetLocation(player));
+ }
+ }
+ }
+
+ private boolean sourceOutOfRange() {
+ return sourceBlock == null || sourceBlock.getLocation().add(0.5, 0.5, 0.5).distanceSquared(player.getLocation()) > sourceKeepRange * sourceKeepRange || sourceBlock.getWorld() != player.getWorld();
+ }
+
+ public void progress() {
+ if (!progressing) {
+ if (sourceOutOfRange()) {
+ unfocusBlock();
+ remove();
+ }
+ return;
+ }
+
+ if (removalPolicy.shouldRemove()) {
+ remove();
+ return;
+ }
+
+ if (sourceBlock == null || RegionProtection.isRegionProtected(this, location)) {
+ remove();
+ return;
+ }
+
+ if (removalTime > -1 && System.currentTimeMillis() > removalTime) {
+ remove();
+ return;
+ }
+
+ if (sourceOutOfRange()) {
+ remove();
+ return;
+ }
+
+ if (RegionProtection.isRegionProtected(player, location, this)) {
+ remove();
+ return;
+ }
+
+ if (allowChangeDirection && player.isSneaking() && bPlayer.getBoundAbilityName().equalsIgnoreCase("EarthLine")) {
+ endLocation = getTargetLocation(player);
+ }
+
+ double x1 = endLocation.getX();
+ double z1 = endLocation.getZ();
+ double x0 = sourceBlock.getX();
+ double z0 = sourceBlock.getZ();
+
+ Vector looking = new Vector(x1 - x0, 0.0D, z1 - z0);
+ Vector push = new Vector(x1 - x0, 0.34999999999999998D, z1 - z0);
+
+ if (location.distance(sourceBlock.getLocation()) < range) {
+ Material cloneType = location.getBlock().getType();
+ Location locationYUP = location.getBlock().getLocation().clone().add(0.5, 0.1, 0.5);
+
+ playEarthbendingSound(location);
+
+ if (isEarthbendable(location.getBlock())) {
+ new TempBlock(location.getBlock(), Material.AIR.createBlockData(), 700L);
+ new TempFallingBlock(locationYUP, cloneType.createBlockData(), new Vector(0.0, 0.35, 0.0), this);
+ }
+
+ location.add(looking.normalize());
+
+ if (!climb()) {
+ remove();
+ return;
+ }
+
+ if (hitted) {
+ if (goOnAfterHit != 0) {
+ goOnAfterHit--;
+ } else {
+ remove();
+ return;
+ }
+ } else {
+ for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, affectingRadius)) {
+ if (RegionProtection.isRegionProtected(this, entity.getLocation()) || ((entity instanceof Player) && Commands.invincible.contains(entity.getName()))) {
+ return;
+ }
+
+ if ((entity instanceof LivingEntity) && entity.getEntityId() != player.getEntityId()) {
+ GeneralMethods.setVelocity(this, entity, push.normalize().multiply(2));
+ DamageHandler.damageEntity(entity, damage, this);
+ hitted = true;
+ }
+ }
+ }
+ } else {
+ remove();
+ return;
+ }
+
+ if (!isEarthbendable(player, location.getBlock()) && !isTransparent(location.getBlock())) {
+ remove();
+ }
+ }
+
+ private boolean climb() {
+ Block above = location.getBlock().getRelative(BlockFace.UP);
+
+ if (!isTransparent(above)) {
+ // Attempt to climb since the current location has a block above it.
+ location.add(0, 1, 0);
+ above = location.getBlock().getRelative(BlockFace.UP);
+
+ // The new location must be earthbendable and have something transparent above it.
+ return isEarthbendable(location.getBlock()) && isTransparent(above);
+ } else if (isTransparent(location.getBlock()) ) {
+ // Attempt to fall since the current location is transparent and the above block was transparent.
+ location.add(0, -1, 0);
+
+ // The new location must be earthbendable and we already know the block above it is transparent.
+ return isEarthbendable(location.getBlock());
+ }
+
return true;
}
- private void focusBlock() {
- if (DensityShift.isPassiveSand(this.sourceBlock)) {
- DensityShift.revertSand(this.sourceBlock);
- }
- if (this.sourceBlock.getType() == Material.SAND) {
- this.sourceType = Material.SAND;
- this.sourceBlock.setType(Material.SANDSTONE);
- } else if (this.sourceBlock.getType() == Material.RED_SAND) {
- this.sourceType = Material.RED_SAND;
- this.sourceBlock.setType(Material.RED_SANDSTONE);
- } else if (this.sourceBlock.getType() == Material.STONE) {
- this.sourceBlock.setType(Material.COBBLESTONE);
- this.sourceType = Material.STONE;
- } else {
- this.sourceType = this.sourceBlock.getType();
- this.sourceBlock.setType(Material.STONE);
- }
-
- this.location = this.sourceBlock.getLocation();
- }
-
- private void unfocusBlock() {
- sourceBlock.setType(sourceType);
- }
-
- private void breakSourceBlock() {
- sourceBlock.setType(sourceType);
- new RegenTempBlock(sourceBlock, Material.AIR, Material.AIR.createBlockData(), 5000L);
- }
-
- @Override
- public void remove() {
- if (sourceBlock != null && sourceBlock.getType() != Material.AIR) {
- sourceBlock.setType(sourceType); // Ensure no duplication of the source block
- }
- super.remove();
- }
-
- private static Location getTargetLocation(Player player) {
- ConfigurationSection config = JedCoreConfig.getConfig(player);
- double range = config.getInt("Abilities.Earth.EarthLine.Range");
- Entity target = GeneralMethods.getTargetedEntity(player, range, player.getNearbyEntities(range, range, range));
- Location location;
- if (target == null) {
- location = GeneralMethods.getTargetedLocation(player, range);
- } else {
- location = ((LivingEntity) target).getEyeLocation();
- }
- return location;
- }
-
- public void shootLine(Location endLocation) {
- if (useCooldown != 0 && bPlayer.getCooldown(this.getName()) < useCooldown) bPlayer.addCooldown(this, useCooldown);
- if (maxDuration > 0) removalTime = System.currentTimeMillis() + maxDuration;
- this.endLocation = endLocation;
- progressing = true;
- breakSourceBlock();
- sourceBlock.getWorld().playEffect(sourceBlock.getLocation(), Effect.GHAST_SHOOT, 0, 10);
- }
-
- public static void shootLine(Player player) {
- if (hasAbility(player, EarthLine.class)) {
- EarthLine el = getAbility(player, EarthLine.class);
- if (!el.progressing) {
- el.shootLine(getTargetLocation(player));
- }
- }
- }
-
- private boolean sourceOutOfRange() {
- return sourceBlock == null || sourceBlock.getLocation().add(0.5, 0.5, 0.5).distanceSquared(player.getLocation()) > sourceKeepRange * sourceKeepRange || sourceBlock.getWorld() != player.getWorld();
- }
-
- public void progress() {
- if (!progressing) {
- if (sourceOutOfRange()) {
- unfocusBlock();
- remove();
- }
- return;
- }
-
- if (removalPolicy.shouldRemove()) {
- remove();
- return;
- }
-
- if (sourceBlock == null || RegionProtection.isRegionProtected(this, location)) {
- remove();
- return;
- }
-
- if (removalTime > -1 && System.currentTimeMillis() > removalTime) {
- remove();
- return;
- }
-
- if (sourceOutOfRange()) {
- remove();
- return;
- }
-
- if (RegionProtection.isRegionProtected(player, location, this)) {
- remove();
- return;
- }
-
- if (allowChangeDirection && player.isSneaking() && bPlayer.getBoundAbilityName().equalsIgnoreCase("EarthLine")) {
- endLocation = getTargetLocation(player);
- }
-
- double x1 = endLocation.getX();
- double z1 = endLocation.getZ();
- double x0 = sourceBlock.getX();
- double z0 = sourceBlock.getZ();
- Vector looking = new Vector(x1 - x0, 0.0D, z1 - z0);
- Vector push = new Vector(x1 - x0, 0.34999999999999998D, z1 - z0);
- if (location.distance(sourceBlock.getLocation()) < range) {
- Material cloneType = location.getBlock().getType();
- Location locationYUP = location.getBlock().getLocation().clone().add(0.5, 0.1, 0.5);
-
- playEarthbendingSound(location);
-
- if (isEarthbendable(location.getBlock())) {
- new RegenTempBlock(location.getBlock(), Material.AIR, Material.AIR.createBlockData(), 700L);
- new TempFallingBlock(locationYUP, cloneType.createBlockData(), new Vector(0.0, 0.35, 0.0), this);
- }
-
- location.add(looking.normalize());
-
- if (!climb()) {
- remove();
- return;
- }
-
- if (hitted) {
- if (goOnAfterHit != 0) {
- goOnAfterHit--;
- } else {
- remove();
- return;
- }
- } else {
- for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, affectingRadius)) {
- if (RegionProtection.isRegionProtected(this, entity.getLocation()) || ((entity instanceof Player) && Commands.invincible.contains(entity.getName()))){
- return;
- }
- if ((entity instanceof LivingEntity) && entity.getEntityId() != player.getEntityId()) {
- GeneralMethods.setVelocity(this, entity, push.normalize().multiply(2));
- DamageHandler.damageEntity(entity, damage, this);
- hitted = true;
- }
- }
- }
- } else {
- remove();
- return;
- }
-
- if (!isEarthbendable(player, location.getBlock()) && !isTransparent(location.getBlock())) {
- remove();
- }
- }
-
- private boolean climb() {
- Block above = location.getBlock().getRelative(BlockFace.UP);
-
- if (!isTransparent(above)) {
- // Attempt to climb since the current location has a block above it.
- location.add(0, 1, 0);
- above = location.getBlock().getRelative(BlockFace.UP);
-
- // The new location must be earthbendable and have something transparent above it.
- return isEarthbendable(location.getBlock()) && isTransparent(above);
- } else if (isTransparent(location.getBlock()) ) {
- // Attempt to fall since the current location is transparent and the above block was transparent.
- location.add(0, -1, 0);
-
- // The new location must be earthbendable and we already know the block above it is transparent.
- return isEarthbendable(location.getBlock());
- }
-
- return true;
- }
-
- @Override
- public long getCooldown() {
- return useCooldown;
- }
-
- @Override
- public Location getLocation() {
- return location;
- }
-
- @Override
- public String getName() {
- return "EarthLine";
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return true;
- }
-
- @Override
- public String getAuthor() {
- return JedCore.dev;
- }
-
- @Override
- public String getVersion() {
- return JedCore.version;
- }
-
- @Override
- public String getDescription() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return "* JedCore Addon *\n" + config.getString("Abilities.Earth.EarthLine.Description");
- }
-
- public Location getEndLocation() {
- return endLocation;
- }
-
- public void setEndLocation(Location endLocation) {
- this.endLocation = endLocation;
- }
-
- public Block getSourceBlock() {
- return sourceBlock;
- }
-
- public void setSourceBlock(Block sourceBlock) {
- this.sourceBlock = sourceBlock;
- }
-
- public Material getSourceType() {
- return sourceType;
- }
-
- public void setSourceType(Material sourceType) {
- this.sourceType = sourceType;
- }
-
- public boolean isProgressing() {
- return progressing;
- }
-
- public void setProgressing(boolean progressing) {
- this.progressing = progressing;
- }
-
- public int getGoOnAfterHit() {
- return goOnAfterHit;
- }
-
- public void setGoOnAfterHit(int goOnAfterHit) {
- this.goOnAfterHit = goOnAfterHit;
- }
-
- public long getRemovalTime() {
- return removalTime;
- }
-
- public void setRemovalTime(long removalTime) {
- this.removalTime = removalTime;
- }
-
- public long getUseCooldown() {
- return useCooldown;
- }
-
- public void setUseCooldown(long useCooldown) {
- this.useCooldown = useCooldown;
- }
-
- public long getPrepareCooldown() {
- return prepareCooldown;
- }
-
- public void setPrepareCooldown(long prepareCooldown) {
- this.prepareCooldown = prepareCooldown;
- }
-
- public long getMaxDuration() {
- return maxDuration;
- }
-
- public void setMaxDuration(long maxDuration) {
- this.maxDuration = maxDuration;
- }
-
- public double getRange() {
- return range;
- }
-
- public void setRange(double range) {
- this.range = range;
- }
-
- public double getPrepareRange() {
- return prepareRange;
- }
-
- public void setPrepareRange(double prepareRange) {
- this.prepareRange = prepareRange;
- }
-
- public double getSourceKeepRange() {
- return sourceKeepRange;
- }
-
- public void setSourceKeepRange(double sourceKeepRange) {
- this.sourceKeepRange = sourceKeepRange;
- }
-
- public int getAffectingRadius() {
- return affectingRadius;
- }
+ @Override
+ public long getCooldown() {
+ return useCooldown;
+ }
+
+ @Override
+ public Location getLocation() {
+ return location;
+ }
+
+ @Override
+ public String getName() {
+ return "EarthLine";
+ }
+
+ @Override
+ public boolean isHarmlessAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isSneakAbility() {
+ return true;
+ }
+
+ @Override
+ public String getAuthor() {
+ return JedCore.dev;
+ }
+
+ @Override
+ public String getVersion() {
+ return JedCore.version;
+ }
+
+ @Override
+ public String getDescription() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return "* JedCore Addon *\n" + config.getString("Abilities.Earth.EarthLine.Description");
+ }
+
+ public Location getEndLocation() {
+ return endLocation;
+ }
+
+ public void setEndLocation(Location endLocation) {
+ this.endLocation = endLocation;
+ }
+
+ public Block getSourceBlock() {
+ return sourceBlock;
+ }
+
+ public void setSourceBlock(Block sourceBlock) {
+ this.sourceBlock = sourceBlock;
+ }
+
+ public Material getSourceType() {
+ return sourceType;
+ }
+
+ public void setSourceType(Material sourceType) {
+ this.sourceType = sourceType;
+ }
+
+ public boolean isProgressing() {
+ return progressing;
+ }
+
+ public void setProgressing(boolean progressing) {
+ this.progressing = progressing;
+ }
+
+ public int getGoOnAfterHit() {
+ return goOnAfterHit;
+ }
+
+ public void setGoOnAfterHit(int goOnAfterHit) {
+ this.goOnAfterHit = goOnAfterHit;
+ }
+
+ public long getRemovalTime() {
+ return removalTime;
+ }
+
+ public void setRemovalTime(long removalTime) {
+ this.removalTime = removalTime;
+ }
+
+ public long getUseCooldown() {
+ return useCooldown;
+ }
+
+ public void setUseCooldown(long useCooldown) {
+ this.useCooldown = useCooldown;
+ }
+
+ public long getPrepareCooldown() {
+ return prepareCooldown;
+ }
+
+ public void setPrepareCooldown(long prepareCooldown) {
+ this.prepareCooldown = prepareCooldown;
+ }
+
+ public long getMaxDuration() {
+ return maxDuration;
+ }
+
+ public void setMaxDuration(long maxDuration) {
+ this.maxDuration = maxDuration;
+ }
+
+ public double getRange() {
+ return range;
+ }
- public void setAffectingRadius(int affectingRadius) {
- this.affectingRadius = affectingRadius;
- }
+ public void setRange(double range) {
+ this.range = range;
+ }
- public double getDamage() {
- return damage;
- }
+ public double getPrepareRange() {
+ return prepareRange;
+ }
+
+ public void setPrepareRange(double prepareRange) {
+ this.prepareRange = prepareRange;
+ }
- public void setDamage(double damage) {
- this.damage = damage;
- }
+ public double getSourceKeepRange() {
+ return sourceKeepRange;
+ }
- public boolean isAllowChangeDirection() {
- return allowChangeDirection;
- }
+ public void setSourceKeepRange(double sourceKeepRange) {
+ this.sourceKeepRange = sourceKeepRange;
+ }
- public void setAllowChangeDirection(boolean allowChangeDirection) {
- this.allowChangeDirection = allowChangeDirection;
- }
+ public int getAffectingRadius() {
+ return affectingRadius;
+ }
- @Override
- public void load() {}
+ public void setAffectingRadius(int affectingRadius) {
+ this.affectingRadius = affectingRadius;
+ }
- @Override
- public void stop() {}
+ public double getDamage() {
+ return damage;
+ }
- @Override
- public boolean isEnabled() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getBoolean("Abilities.Earth.EarthLine.Enabled");
- }
+ public void setDamage(double damage) {
+ this.damage = damage;
+ }
+
+ public boolean isAllowChangeDirection() {
+ return allowChangeDirection;
+ }
+
+ public void setAllowChangeDirection(boolean allowChangeDirection) {
+ this.allowChangeDirection = allowChangeDirection;
+ }
+
+ @Override
+ public void load() {}
+
+ @Override
+ public void stop() {}
+
+ @Override
+ public boolean isEnabled() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getBoolean("Abilities.Earth.EarthLine.Enabled");
+ }
}
\ No newline at end of file
diff --git a/src/com/jedk1/jedcore/ability/earthbending/EarthPillar.java b/src/com/jedk1/jedcore/ability/earthbending/EarthPillar.java
index 1935c15..2067b0c 100644
--- a/src/com/jedk1/jedcore/ability/earthbending/EarthPillar.java
+++ b/src/com/jedk1/jedcore/ability/earthbending/EarthPillar.java
@@ -8,7 +8,6 @@
import com.projectkorra.projectkorra.earthbending.Collapse;
import com.projectkorra.projectkorra.util.BlockSource;
import com.projectkorra.projectkorra.util.ClickType;
-
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
@@ -22,195 +21,195 @@
public class EarthPillar extends EarthAbility implements AddonAbility {
- private static final ConcurrentHashMap AFFECTED_BLOCKS = new ConcurrentHashMap<>();
- private static final ConcurrentHashMap> AFFECTED = new ConcurrentHashMap<>();
-
- private Block block;
- private BlockFace face;
- @Attribute(Attribute.HEIGHT)
- private int height;
- @Attribute(Attribute.RANGE)
- private int range;
- private int step;
-
- private final List blocks = new ArrayList<>();
-
- public EarthPillar(Player player) {
- super(player);
-
- if (!bPlayer.canBend(this)) {
- return;
- }
-
- setFields();
- Block target = BlockSource.getEarthSourceBlock(player, range, ClickType.SHIFT_DOWN);
- if (target != null && !AFFECTED_BLOCKS.containsKey(target)) {
- List blocks = player.getLastTwoTargetBlocks(null, range);
- if (blocks.size() > 1) {
- this.player = player;
- face = blocks.get(1).getFace(blocks.get(0));
- block = blocks.get(1);
- height = getEarthbendableBlocksLength(block, getDirection(face).clone().multiply(-1), height);
- start();
- }
- } else if (target != null && AFFECTED_BLOCKS.containsKey(target)) {
- List blocks = AFFECTED.get(AFFECTED_BLOCKS.get(target));
- if (blocks != null && !blocks.isEmpty()) {
- for (Block b : blocks) {
- Collapse.revertBlock(b);
- }
- playEarthbendingSound(target.getLocation());
- AFFECTED.remove(AFFECTED_BLOCKS.get(target));
- }
- }
- }
-
- public void setFields() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- height = config.getInt("Abilities.Earth.EarthPillar.Height");
- range = config.getInt("Abilities.Earth.EarthPillar.Range");
- }
-
- @Override
- public void progress() {
- if (step < height) {
- step++;
- movePillar();
- } else {
- AFFECTED.put(this, blocks);
- remove();
- }
- }
-
- private void movePillar() {
- moveEarth(block, getDirection(face), height);
- block = block.getRelative(face);
- AFFECTED_BLOCKS.put(block, this);
- blocks.add(block);
- }
-
- private Vector getDirection(BlockFace face) {
- switch (face) {
- case UP:
- return new Vector(0, 1, 0);
- case DOWN:
- return new Vector(0, -1, 0);
- case NORTH:
- return new Vector(0, 0, -1);
- case SOUTH:
- return new Vector(0, 0, 1);
- case EAST:
- return new Vector(1, 0, 0);
- case WEST:
- return new Vector(-1, 0, 0);
- default:
- return null;
- }
- }
-
- public static void progressAll() {
- for (Block block : AFFECTED_BLOCKS.keySet()) {
- if (!EarthAbility.isEarthbendable(AFFECTED_BLOCKS.get(block).getPlayer(), block)) {
- AFFECTED_BLOCKS.remove(block);
- }
- }
- }
-
- @Override
- public long getCooldown() {
- return 0;
- }
-
- @Override
- public Location getLocation() {
- return block != null ? block.getLocation() : null;
- }
-
- @Override
- public String getName() {
- return "EarthPillar";
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return true;
- }
-
- @Override
- public String getAuthor() {
- return JedCore.dev;
- }
-
- @Override
- public String getVersion() {
- return JedCore.version;
- }
-
- @Override
- public String getDescription() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return "* JedCore Addon *\n" + config.getString("Abilities.Earth.EarthPillar.Description");
- }
-
- public Block getBlock() {
- return block;
- }
-
- public void setBlock(Block block) {
- this.block = block;
- }
-
- public BlockFace getFace() {
- return face;
- }
-
- public void setFace(BlockFace face) {
- this.face = face;
- }
-
- public int getHeight() {
- return height;
- }
-
- public void setHeight(int height) {
- this.height = height;
- }
-
- public int getRange() {
- return range;
- }
-
- public void setRange(int range) {
- this.range = range;
- }
-
- public int getStep() {
- return step;
- }
-
- public void setStep(int step) {
- this.step = step;
- }
-
- public List getBlocks() {
- return blocks;
- }
-
- @Override
- public void load() {}
-
- @Override
- public void stop() {}
-
- @Override
- public boolean isEnabled() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getBoolean("Abilities.Earth.EarthPillar.Enabled");
- }
+ private static final ConcurrentHashMap AFFECTED_BLOCKS = new ConcurrentHashMap<>();
+ private static final ConcurrentHashMap> AFFECTED = new ConcurrentHashMap<>();
+
+ private Block block;
+ private BlockFace face;
+ @Attribute(Attribute.HEIGHT)
+ private int height;
+ @Attribute(Attribute.RANGE)
+ private int range;
+ private int step;
+
+ private final List blocks = new ArrayList<>();
+
+ public EarthPillar(Player player) {
+ super(player);
+
+ if (!bPlayer.canBend(this)) {
+ return;
+ }
+
+ setFields();
+ Block target = BlockSource.getEarthSourceBlock(player, range, ClickType.SHIFT_DOWN);
+ if (target != null && !AFFECTED_BLOCKS.containsKey(target)) {
+ List blocks = player.getLastTwoTargetBlocks(null, range);
+ if (blocks.size() > 1) {
+ this.player = player;
+ face = blocks.get(1).getFace(blocks.get(0));
+ block = blocks.get(1);
+ height = getEarthbendableBlocksLength(block, getDirection(face).clone().multiply(-1), height);
+ start();
+ }
+ } else if (target != null && AFFECTED_BLOCKS.containsKey(target)) {
+ List blocks = AFFECTED.get(AFFECTED_BLOCKS.get(target));
+ if (blocks != null && !blocks.isEmpty()) {
+ for (Block b : blocks) {
+ Collapse.revertBlock(b);
+ }
+ playEarthbendingSound(target.getLocation());
+ AFFECTED.remove(AFFECTED_BLOCKS.get(target));
+ }
+ }
+ }
+
+ public void setFields() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ height = config.getInt("Abilities.Earth.EarthPillar.Height");
+ range = config.getInt("Abilities.Earth.EarthPillar.Range");
+ }
+
+ @Override
+ public void progress() {
+ if (step < height) {
+ step++;
+ movePillar();
+ } else {
+ AFFECTED.put(this, blocks);
+ remove();
+ }
+ }
+
+ private void movePillar() {
+ moveEarth(block, getDirection(face), height);
+ block = block.getRelative(face);
+ AFFECTED_BLOCKS.put(block, this);
+ blocks.add(block);
+ }
+
+ private Vector getDirection(BlockFace face) {
+ switch (face) {
+ case UP:
+ return new Vector(0, 1, 0);
+ case DOWN:
+ return new Vector(0, -1, 0);
+ case NORTH:
+ return new Vector(0, 0, -1);
+ case SOUTH:
+ return new Vector(0, 0, 1);
+ case EAST:
+ return new Vector(1, 0, 0);
+ case WEST:
+ return new Vector(-1, 0, 0);
+ default:
+ return null;
+ }
+ }
+
+ public static void progressAll() {
+ for (Block block : AFFECTED_BLOCKS.keySet()) {
+ if (!EarthAbility.isEarthbendable(AFFECTED_BLOCKS.get(block).getPlayer(), block)) {
+ AFFECTED_BLOCKS.remove(block);
+ }
+ }
+ }
+
+ @Override
+ public long getCooldown() {
+ return 0;
+ }
+
+ @Override
+ public Location getLocation() {
+ return block != null ? block.getLocation() : null;
+ }
+
+ @Override
+ public String getName() {
+ return "EarthPillar";
+ }
+
+ @Override
+ public boolean isHarmlessAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isSneakAbility() {
+ return true;
+ }
+
+ @Override
+ public String getAuthor() {
+ return JedCore.dev;
+ }
+
+ @Override
+ public String getVersion() {
+ return JedCore.version;
+ }
+
+ @Override
+ public String getDescription() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return "* JedCore Addon *\n" + config.getString("Abilities.Earth.EarthPillar.Description");
+ }
+
+ public Block getBlock() {
+ return block;
+ }
+
+ public void setBlock(Block block) {
+ this.block = block;
+ }
+
+ public BlockFace getFace() {
+ return face;
+ }
+
+ public void setFace(BlockFace face) {
+ this.face = face;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public void setHeight(int height) {
+ this.height = height;
+ }
+
+ public int getRange() {
+ return range;
+ }
+
+ public void setRange(int range) {
+ this.range = range;
+ }
+
+ public int getStep() {
+ return step;
+ }
+
+ public void setStep(int step) {
+ this.step = step;
+ }
+
+ public List getBlocks() {
+ return blocks;
+ }
+
+ @Override
+ public void load() {}
+
+ @Override
+ public void stop() {}
+
+ @Override
+ public boolean isEnabled() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getBoolean("Abilities.Earth.EarthPillar.Enabled");
+ }
}
\ No newline at end of file
diff --git a/src/com/jedk1/jedcore/ability/earthbending/EarthShard.java b/src/com/jedk1/jedcore/ability/earthbending/EarthShard.java
index 96c34e1..04a2fe4 100644
--- a/src/com/jedk1/jedcore/ability/earthbending/EarthShard.java
+++ b/src/com/jedk1/jedcore/ability/earthbending/EarthShard.java
@@ -1,449 +1,531 @@
package com.jedk1.jedcore.ability.earthbending;
-import java.util.*;
-import java.util.stream.Collectors;
-
+import com.jedk1.jedcore.JedCore;
import com.jedk1.jedcore.collision.AABB;
import com.jedk1.jedcore.collision.CollisionDetector;
import com.jedk1.jedcore.collision.CollisionUtil;
import com.jedk1.jedcore.configuration.JedCoreConfig;
import com.jedk1.jedcore.util.BlockUtil;
+import com.projectkorra.projectkorra.GeneralMethods;
+import com.projectkorra.projectkorra.ability.AddonAbility;
+import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.util.Collision;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.earthbending.passive.DensityShift;
+import com.projectkorra.projectkorra.util.DamageHandler;
+import com.projectkorra.projectkorra.util.ParticleEffect;
+import com.projectkorra.projectkorra.util.TempBlock;
import com.projectkorra.projectkorra.util.TempFallingBlock;
import org.bukkit.Location;
import org.bukkit.Material;
+import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.entity.Entity;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
-import com.jedk1.jedcore.JedCore;
-import com.projectkorra.projectkorra.GeneralMethods;
-import com.projectkorra.projectkorra.ability.AddonAbility;
-import com.projectkorra.projectkorra.ability.EarthAbility;
-import com.projectkorra.projectkorra.util.DamageHandler;
-import com.projectkorra.projectkorra.util.ParticleEffect;
-import com.projectkorra.projectkorra.util.TempBlock;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
public class EarthShard extends EarthAbility implements AddonAbility {
- @Attribute(Attribute.RANGE)
- public static int range;
- public static int abilityRange;
-
- @Attribute(Attribute.DAMAGE)
- public static double normalDmg;
- @Attribute(Attribute.DAMAGE)
- public static double metalDmg;
-
- @Attribute("MaxShots")
- public static int maxShards;
- @Attribute(Attribute.COOLDOWN)
- public static long cooldown;
-
- private boolean isThrown = false;
- private Location origin;
- private double abilityCollisionRadius;
- private double entityCollisionRadius;
-
- private final List tblockTracker = new ArrayList<>();
- private final List readyBlocksTracker = new ArrayList<>();
- private final List fallingBlocks = new ArrayList<>();
-
- public EarthShard(Player player) {
- super(player);
-
- if (!bPlayer.canBend(this)) {
- return;
- }
-
- if (hasAbility(player, EarthShard.class)) {
- for (EarthShard es : EarthShard.getAbilities(player, EarthShard.class)) {
- if (es.isThrown && System.currentTimeMillis() - es.getStartTime() >= 20000) {
- // Remove the old instance because it got into a broken state.
- // This shouldn't affect normal gameplay because the cooldown is long enough that the
- // shards should have already hit their target.
- es.remove();
- } else {
- es.select();
- return;
- }
- }
- }
-
- setFields();
- origin = player.getLocation().clone();
- raiseEarthBlock(getEarthSourceBlock(range));
- start();
- }
-
- public void setFields() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- range = config.getInt("Abilities.Earth.EarthShard.PrepareRange");
- abilityRange = config.getInt("Abilities.Earth.EarthShard.AbilityRange");
- normalDmg = config.getDouble("Abilities.Earth.EarthShard.Damage.Normal");
- metalDmg = config.getDouble("Abilities.Earth.EarthShard.Damage.Metal");
- maxShards = config.getInt("Abilities.Earth.EarthShard.MaxShards");
- cooldown = config.getLong("Abilities.Earth.EarthShard.Cooldown");
- abilityCollisionRadius = config.getDouble("Abilities.Earth.EarthShard.AbilityCollisionRadius");
- entityCollisionRadius = config.getDouble("Abilities.Earth.EarthShard.EntityCollisionRadius");
- }
-
- public void select() {
- raiseEarthBlock(getEarthSourceBlock(range));
- }
-
- public void raiseEarthBlock(Block block) {
- if (block == null) {
- return;
- }
-
- if (tblockTracker.size() >= maxShards) {
- return;
- }
-
- Vector blockVector = block.getLocation().toVector().toBlockVector().setY(0);
-
- // Don't select from locations that already have an EarthShard block.
- for (TempBlock tempBlock : tblockTracker) {
- if (tempBlock.getLocation().getWorld() != block.getWorld()) {
- continue;
- }
-
- Vector tempBlockVector = tempBlock.getLocation().toVector().toBlockVector().setY(0);
-
- if (tempBlockVector.equals(blockVector)) {
- return;
- }
- }
-
- for (int i = 1; i < 4; i++) {
- if (!isTransparent(block.getRelative(BlockFace.UP, i))) {
- return;
- }
- }
-
- if (isEarthbendable(block)) {
- if (isMetal(block)) {
- playMetalbendingSound(block.getLocation());
- } else {
- ParticleEffect.BLOCK_CRACK.display(block.getLocation().add(0, 1, 0), 20, 0.0, 0.0, 0.0, 0.0, block.getBlockData());
- playEarthbendingSound(block.getLocation());
- }
-
- Material material = getCorrectType(block);
-
- if (DensityShift.isPassiveSand(block)) {
- DensityShift.revertSand(block);
- }
-
- Location loc = block.getLocation().add(0.5, 0, 0.5);
- new TempFallingBlock(loc, material.createBlockData(), new Vector(0, 0.8, 0), this);
- TempBlock tb = new TempBlock(block, Material.AIR.createBlockData());
- tblockTracker.add(tb);
- }
- }
-
- public Material getCorrectType(Block block) {
- if (block.getType() == Material.SAND) {
- return Material.SANDSTONE;
- }
- if (block.getType() == Material.RED_SAND) {
- return Material.RED_SANDSTONE;
- }
- if (block.getType() == Material.GRAVEL) {
- return Material.COBBLESTONE;
- }
- if (block.getType().name().endsWith("CONCRETE_POWDER")) {
- return Material.getMaterial(block.getType().name().replace("_POWDER", ""));
- }
-
- return block.getType();
- }
-
- public void progress() {
- if (player == null || !player.isOnline() || player.isDead()) {
- remove();
- return;
- }
-
- if (!isThrown) {
- if (!bPlayer.canBendIgnoreCooldowns(this)) {
- remove();
- return;
- }
-
- if (tblockTracker.isEmpty()) {
- remove();
- return;
- }
-
- for (TempFallingBlock tfb : TempFallingBlock.getFromAbility(this)) {
- FallingBlock fb = tfb.getFallingBlock();
-
- if (fb.isDead() || fb.getLocation().getBlockY() == origin.getBlockY() + 2) {
- TempBlock tb = new TempBlock(fb.getLocation().getBlock(), fb.getBlockData());
- readyBlocksTracker.add(tb);
- tfb.remove();
- }
- }
- } else {
- for (TempFallingBlock tfb : TempFallingBlock.getFromAbility(this)) {
- FallingBlock fb = tfb.getFallingBlock();
-
- AABB collider = BlockUtil.getFallingBlockBoundsFull(fb).scale(entityCollisionRadius * 2.0);
-
- CollisionDetector.checkEntityCollisions(player, collider, (e) -> {
- DamageHandler.damageEntity(e, isMetal(fb.getBlockData().getMaterial()) ? metalDmg : normalDmg, this);
- ((LivingEntity) e).setNoDamageTicks(0);
- ParticleEffect.BLOCK_CRACK.display(fb.getLocation(), 20, 0, 0, 0, 0, fb.getBlockData());
- tfb.remove();
- return false;
- });
-
- if (fb.isDead()) {
- tfb.remove();
- }
- }
-
- if (TempFallingBlock.getFromAbility(this).isEmpty()) {
- remove();
- }
- }
- }
-
- public static void throwShard(Player player) {
- if (hasAbility(player, EarthShard.class)) {
- for (EarthShard es : EarthShard.getAbilities(player, EarthShard.class)) {
- if (!es.isThrown) {
- es.throwShard();
- break;
- }
- }
- }
- }
-
- public void throwShard() {
- if (isThrown || tblockTracker.size() > readyBlocksTracker.size()) {
- return;
- }
-
- Location targetLocation = GeneralMethods.getTargetedLocation(player, abilityRange);
-
- if (GeneralMethods.getTargetedEntity(player, abilityRange, new ArrayList<>()) != null) {
- targetLocation = GeneralMethods.getTargetedEntity(player, abilityRange, new ArrayList<>()).getLocation();
- }
-
- Vector vel = null;
-
- for (TempBlock tb : readyBlocksTracker) {
- Location target = player.getTargetBlock(null, 30).getLocation();
-
- if (target.getBlockX() == tb.getBlock().getX() && target.getBlockY() == tb.getBlock().getY() && target.getBlockZ() == tb.getBlock().getZ()) {
- vel = player.getEyeLocation().getDirection().multiply(2).add(new Vector(0, 0.2, 0));
- break;
- }
-
- vel = GeneralMethods.getDirection(tb.getLocation(), targetLocation).normalize().multiply(2).add(new Vector(0, 0.2, 0));
- }
-
- for (TempBlock tb : readyBlocksTracker) {
- fallingBlocks.add(new TempFallingBlock(tb.getLocation(), tb.getBlock().getBlockData(), vel, this));
- tb.revertBlock();
- }
-
- revertBlocks();
-
- isThrown = true;
-
- if (player.isOnline()) {
- bPlayer.addCooldown(this);
- }
- }
-
- public void revertBlocks() {
- for (TempBlock tb : tblockTracker) {
- tb.revertBlock();
- }
-
- for (TempBlock tb : readyBlocksTracker) {
- tb.revertBlock();
- }
-
- tblockTracker.clear();
- readyBlocksTracker.clear();
- }
-
- @Override
- public void remove() {
- // Destroy any remaining falling blocks.
- for (TempFallingBlock tfb : TempFallingBlock.getFromAbility(this)) {
- tfb.remove();
- }
-
- revertBlocks();
-
- super.remove();
- }
-
- @Override
- public long getCooldown() {
- return cooldown;
- }
-
- @Override
- public Location getLocation() {
- return null;
- }
-
- @Override
- public List getLocations() {
- return fallingBlocks.stream().map(TempFallingBlock::getLocation).collect(Collectors.toList());
- }
-
- @Override
- public void handleCollision(Collision collision) {
- CollisionUtil.handleFallingBlockCollisions(collision, fallingBlocks);
- }
-
- @Override
- public double getCollisionRadius() {
- return abilityCollisionRadius;
- }
-
- @Override
- public String getName() {
- return "EarthShard";
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return true;
- }
-
- @Override
- public String getAuthor() {
- return JedCore.dev;
- }
-
- @Override
- public String getVersion() {
- return JedCore.version;
- }
-
- @Override
- public String getDescription() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return "* JedCore Addon *\n" + config.getString("Abilities.Earth.EarthShard.Description");
- }
-
- public static int getRange() {
- return range;
- }
-
- public static void setRange(int range) {
- EarthShard.range = range;
- }
-
- public static int getAbilityRange() {
- return abilityRange;
- }
-
- public static void setAbilityRange(int abilityRange) {
- EarthShard.abilityRange = abilityRange;
- }
-
- public static double getNormalDmg() {
- return normalDmg;
- }
-
- public static void setNormalDmg(double normalDmg) {
- EarthShard.normalDmg = normalDmg;
- }
-
- public static double getMetalDmg() {
- return metalDmg;
- }
-
- public static void setMetalDmg(double metalDmg) {
- EarthShard.metalDmg = metalDmg;
- }
-
- public static int getMaxShards() {
- return maxShards;
- }
-
- public static void setMaxShards(int maxShards) {
- EarthShard.maxShards = maxShards;
- }
-
- public static void setCooldown(long cooldown) {
- EarthShard.cooldown = cooldown;
- }
-
- public boolean isThrown() {
- return isThrown;
- }
-
- public void setThrown(boolean thrown) {
- isThrown = thrown;
- }
-
- public Location getOrigin() {
- return origin;
- }
-
- public void setOrigin(Location origin) {
- this.origin = origin;
- }
-
- public double getAbilityCollisionRadius() {
- return abilityCollisionRadius;
- }
-
- public void setAbilityCollisionRadius(double abilityCollisionRadius) {
- this.abilityCollisionRadius = abilityCollisionRadius;
- }
-
- public double getEntityCollisionRadius() {
- return entityCollisionRadius;
- }
-
- public void setEntityCollisionRadius(double entityCollisionRadius) {
- this.entityCollisionRadius = entityCollisionRadius;
- }
-
- public List getTblockTracker() {
- return tblockTracker;
- }
-
- public List getReadyBlocksTracker() {
- return readyBlocksTracker;
- }
-
- public List getFallingBlocks() {
- return fallingBlocks;
- }
-
- @Override
- public void load() {}
-
- @Override
- public void stop() {}
+ @Attribute(Attribute.RANGE)
+ public static int range;
+ public static int abilityRange;
+
+ @Attribute(Attribute.DAMAGE)
+ public static double normalDmg;
+ @Attribute(Attribute.DAMAGE)
+ public static double metalDmg;
+
+ @Attribute("MaxShots")
+ public static int maxShards;
+ @Attribute(Attribute.COOLDOWN)
+ public static long cooldown;
+
+ private boolean isThrown = false;
+ private Location origin;
+ private double abilityCollisionRadius;
+ private double entityCollisionRadius;
+
+ private final List tblockTracker = new ArrayList<>();
+ private final List readyBlocksTracker = new ArrayList<>();
+ private final List fallingBlocks = new ArrayList<>();
+
+ private boolean allowKnockup;
+ private double knockupVelocity;
+ private double knockupRange;
+
+ private boolean allowKnockupSelf;
+ private double knockupSelfVelocity;
+ private double knockupSelfRange;
+
+ public EarthShard(Player player) {
+ super(player);
+
+ if (!bPlayer.canBend(this)) {
+ return;
+ }
+
+ if (hasAbility(player, EarthShard.class)) {
+ for (EarthShard es : EarthShard.getAbilities(player, EarthShard.class)) {
+ if (es.isThrown && System.currentTimeMillis() - es.getStartTime() >= 20000) {
+ // Remove the old instance because it got into a broken state.
+ // This shouldn't affect normal gameplay because the cooldown is long enough that the
+ // shards should have already hit their target.
+ es.remove();
+ } else {
+ es.select();
+ return;
+ }
+ }
+ }
+
+ setFields();
+ origin = player.getLocation().clone();
+ raiseEarthBlock(getEarthSourceBlock(range));
+ start();
+ }
+
+ public void setFields() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ range = config.getInt("Abilities.Earth.EarthShard.PrepareRange");
+ abilityRange = config.getInt("Abilities.Earth.EarthShard.AbilityRange");
+ normalDmg = config.getDouble("Abilities.Earth.EarthShard.Damage.Normal");
+ metalDmg = config.getDouble("Abilities.Earth.EarthShard.Damage.Metal");
+ maxShards = config.getInt("Abilities.Earth.EarthShard.MaxShards");
+ cooldown = config.getLong("Abilities.Earth.EarthShard.Cooldown");
+ abilityCollisionRadius = config.getDouble("Abilities.Earth.EarthShard.AbilityCollisionRadius");
+ entityCollisionRadius = config.getDouble("Abilities.Earth.EarthShard.EntityCollisionRadius");
+ allowKnockup = config.getBoolean("Abilities.Earth.EarthShard.KnockUp.Others.Allow");
+ knockupVelocity = config.getDouble("Abilities.Earth.EarthShard.KnockUp.Others.Velocity");
+ knockupRange = config.getDouble("Abilities.Earth.EarthShard.KnockUp.Others.Range");
+ allowKnockupSelf = config.getBoolean("Abilities.Earth.EarthShard.KnockUp.Self.Allow");
+ knockupSelfVelocity = config.getDouble("Abilities.Earth.EarthShard.KnockUp.Self.Velocity");
+ knockupSelfRange = config.getDouble("Abilities.Earth.EarthShard.KnockUp.Self.Range");
+ }
+
+ public void select() {
+ raiseEarthBlock(getEarthSourceBlock(range));
+ }
+
+ public void raiseEarthBlock(Block block) {
+ if (block == null) return;
+ if (EarthAbility.getMovedEarth().containsKey(block)) return;
+ if (tblockTracker.size() >= maxShards) return;
+
+ Vector blockVector = block.getLocation().toVector().toBlockVector().setY(0);
+
+ for (TempBlock tempBlock : tblockTracker) {
+ if (tempBlock.getLocation().getWorld() != block.getWorld()) continue;
+
+ Vector tempBlockVector = tempBlock.getLocation().toVector().toBlockVector().setY(0);
+ if (tempBlockVector.equals(blockVector)) return;
+ }
+
+ for (int i = 1; i < 4; i++) {
+ if (!isTransparent(block.getRelative(BlockFace.UP, i))) return;
+ }
+
+ if (!isEarthbendable(block)) return;
+
+ if (isMetal(block)) {
+ playMetalbendingSound(block.getLocation());
+ } else {
+ ParticleEffect.BLOCK_CRACK.display(
+ block.getLocation().add(0, 1, 0), 20, 0.0, 0.0, 0.0, 0.0, block.getBlockData()
+ );
+ playEarthbendingSound(block.getLocation());
+ }
+
+ Material material = getCorrectType(block);
+
+ if (DensityShift.isPassiveSand(block)) {
+ DensityShift.revertSand(block);
+ }
+
+ Location loc = block.getLocation().add(0.5, 0, 0.5);
+ new TempFallingBlock(loc, material.createBlockData(), new Vector(0, 0.8, 0), this);
+ TempBlock tb = new TempBlock(block, Material.AIR.createBlockData());
+ tblockTracker.add(tb);
+
+ handleKnockup(block);
+ }
+
+ private void handleKnockup(Block origin) {
+ if (!allowKnockup && !allowKnockupSelf) return;
+
+ Location originLoc = origin.getLocation();
+ World world = origin.getWorld();
+
+ for (Entity entity : world.getNearbyEntities(originLoc, Math.max(knockupRange, knockupSelfRange), knockupRange, knockupRange)) {
+ if (entity instanceof FallingBlock) continue;
+
+ if (entity.equals(player)) {
+ if (!allowKnockupSelf) continue;
+ if (entity.getLocation().distance(originLoc) <= knockupSelfRange) {
+ entity.setVelocity(entity.getVelocity().add(new Vector(0, knockupSelfVelocity, 0)));
+ }
+ } else {
+ if (!allowKnockup) continue;
+ if (entity.getLocation().distance(originLoc) <= knockupRange) {
+ entity.setVelocity(entity.getVelocity().add(new Vector(0, knockupVelocity, 0)));
+ }
+ }
+ }
+ }
+
+ public Material getCorrectType(Block block) {
+ if (block.getType() == Material.SAND) {
+ return Material.SANDSTONE;
+ }
+ if (block.getType() == Material.RED_SAND) {
+ return Material.RED_SANDSTONE;
+ }
+ if (block.getType() == Material.GRAVEL) {
+ return Material.COBBLESTONE;
+ }
+ if (block.getType().name().endsWith("CONCRETE_POWDER")) {
+ return Material.getMaterial(block.getType().name().replace("_POWDER", ""));
+ }
+
+ return block.getType();
+ }
+
+ public void progress() {
+ if (player == null || !player.isOnline() || player.isDead()) {
+ remove();
+ return;
+ }
+
+ if (!isThrown) {
+ if (!bPlayer.canBendIgnoreCooldowns(this)) {
+ remove();
+ return;
+ }
+
+ if (tblockTracker.isEmpty()) {
+ remove();
+ return;
+ }
+
+ // iterate over a defensive copy to avoid ConcurrentModificationException
+ for (TempFallingBlock tfb : new ArrayList<>(TempFallingBlock.getFromAbility(this))) {
+ FallingBlock fb = tfb.getFallingBlock();
+
+ if (fb.isDead() || fb.getLocation().getBlockY() == origin.getBlockY() + 2) {
+ TempBlock tb = new TempBlock(fb.getLocation().getBlock(), fb.getBlockData());
+ readyBlocksTracker.add(tb);
+ tfb.remove();
+ }
+ }
+ } else {
+ // iterate over a defensive copy to avoid ConcurrentModificationException
+ for (TempFallingBlock tfb : new ArrayList<>(TempFallingBlock.getFromAbility(this))) {
+ FallingBlock fb = tfb.getFallingBlock();
+
+ AABB collider = BlockUtil.getFallingBlockBoundsFull(fb).scale(entityCollisionRadius * 2.0);
+
+ CollisionDetector.checkEntityCollisions(player, collider, (e) -> {
+ DamageHandler.damageEntity(e, isMetal(fb.getBlockData().getMaterial()) ? metalDmg : normalDmg, this);
+ ((LivingEntity) e).setNoDamageTicks(0);
+ ParticleEffect.BLOCK_CRACK.display(fb.getLocation(), 20, 0, 0, 0, 0, fb.getBlockData());
+ tfb.remove();
+ return false;
+ });
+
+ if (fb.isDead()) {
+ tfb.remove();
+ }
+ }
+
+ if (TempFallingBlock.getFromAbility(this).isEmpty()) {
+ remove();
+ }
+ }
+ }
+
+ public static void throwShard(Player player) {
+ if (hasAbility(player, EarthShard.class)) {
+ for (EarthShard es : EarthShard.getAbilities(player, EarthShard.class)) {
+ if (!es.isThrown) {
+ es.throwShard();
+ break;
+ }
+ }
+ }
+ }
+
+ public void throwShard() {
+ if (isThrown || tblockTracker.size() > readyBlocksTracker.size()) {
+ return;
+ }
+
+ Location targetLocation = GeneralMethods.getTargetedLocation(player, abilityRange);
+
+ if (GeneralMethods.getTargetedEntity(player, abilityRange, new ArrayList<>()) != null) {
+ targetLocation = GeneralMethods.getTargetedEntity(player, abilityRange, new ArrayList<>()).getLocation();
+ }
+
+ Vector vel = null;
+
+ for (TempBlock tb : readyBlocksTracker) {
+ Location target = player.getTargetBlock(null, 30).getLocation();
+
+ if (target.getBlockX() == tb.getBlock().getX() && target.getBlockY() == tb.getBlock().getY() && target.getBlockZ() == tb.getBlock().getZ()) {
+ vel = player.getEyeLocation().getDirection().multiply(2).add(new Vector(0, 0.2, 0));
+ break;
+ }
+
+ vel = GeneralMethods.getDirection(tb.getLocation(), targetLocation).normalize().multiply(2).add(new Vector(0, 0.2, 0));
+ }
+
+ for (TempBlock tb : readyBlocksTracker) {
+ fallingBlocks.add(new TempFallingBlock(tb.getLocation(), tb.getBlock().getBlockData(), vel, this));
+ tb.revertBlock();
+ }
+
+ revertBlocks();
+
+ isThrown = true;
+
+ if (player.isOnline()) {
+ bPlayer.addCooldown(this);
+ }
+ }
+
+ public void revertBlocks() {
+ for (TempBlock tb : tblockTracker) {
+ tb.revertBlock();
+ }
+
+ for (TempBlock tb : readyBlocksTracker) {
+ tb.revertBlock();
+ }
+
+ tblockTracker.clear();
+ readyBlocksTracker.clear();
+ }
+
+ @Override
+ public void remove() {
+ // Destroy any remaining falling blocks.
+ // iterate over a defensive copy to avoid ConcurrentModificationException
+ for (TempFallingBlock tfb : new ArrayList<>(TempFallingBlock.getFromAbility(this))) {
+ tfb.remove();
+ }
+
+ revertBlocks();
+
+ super.remove();
+ }
+
+ @Override
+ public long getCooldown() {
+ return cooldown;
+ }
+
+ @Override
+ public Location getLocation() {
+ return null;
+ }
+
+ @Override
+ public List getLocations() {
+ return fallingBlocks.stream().map(TempFallingBlock::getLocation).collect(Collectors.toList());
+ }
+
+ @Override
+ public void handleCollision(Collision collision) {
+ CollisionUtil.handleFallingBlockCollisions(collision, fallingBlocks);
+ }
+
+ @Override
+ public double getCollisionRadius() {
+ return abilityCollisionRadius;
+ }
+
+ @Override
+ public String getName() {
+ return "EarthShard";
+ }
+
+ @Override
+ public boolean isHarmlessAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isSneakAbility() {
+ return true;
+ }
+
+ @Override
+ public String getAuthor() {
+ return JedCore.dev;
+ }
+
+ @Override
+ public String getVersion() {
+ return JedCore.version;
+ }
+
+ @Override
+ public String getDescription() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return "* JedCore Addon *\n" + config.getString("Abilities.Earth.EarthShard.Description");
+ }
+
+ public static int getRange() {
+ return range;
+ }
+
+ public static void setRange(int range) {
+ EarthShard.range = range;
+ }
+
+ public static int getAbilityRange() {
+ return abilityRange;
+ }
+
+ public static void setAbilityRange(int abilityRange) {
+ EarthShard.abilityRange = abilityRange;
+ }
+
+ public static double getNormalDmg() {
+ return normalDmg;
+ }
+
+ public static void setNormalDmg(double normalDmg) {
+ EarthShard.normalDmg = normalDmg;
+ }
+
+ public static double getMetalDmg() {
+ return metalDmg;
+ }
+
+ public static void setMetalDmg(double metalDmg) {
+ EarthShard.metalDmg = metalDmg;
+ }
+
+ public static int getMaxShards() {
+ return maxShards;
+ }
+
+ public static void setMaxShards(int maxShards) {
+ EarthShard.maxShards = maxShards;
+ }
+
+ public static void setCooldown(long cooldown) {
+ EarthShard.cooldown = cooldown;
+ }
+
+ public boolean isThrown() {
+ return isThrown;
+ }
+
+ public void setThrown(boolean thrown) {
+ isThrown = thrown;
+ }
+
+ public Location getOrigin() {
+ return origin;
+ }
+
+ public void setOrigin(Location origin) {
+ this.origin = origin;
+ }
+
+ public double getAbilityCollisionRadius() {
+ return abilityCollisionRadius;
+ }
+
+ public void setAbilityCollisionRadius(double abilityCollisionRadius) {
+ this.abilityCollisionRadius = abilityCollisionRadius;
+ }
+
+ public double getEntityCollisionRadius() {
+ return entityCollisionRadius;
+ }
+
+ public void setEntityCollisionRadius(double entityCollisionRadius) {
+ this.entityCollisionRadius = entityCollisionRadius;
+ }
+
+ public List getTblockTracker() {
+ return tblockTracker;
+ }
+
+ public List getReadyBlocksTracker() {
+ return readyBlocksTracker;
+ }
+
+ public List getFallingBlocks() {
+ return fallingBlocks;
+ }
+
+ public boolean isAllowKnockup() {
+ return allowKnockup;
+ }
+
+ public void setAllowKnockup(boolean allowKnockup) {
+ this.allowKnockup = allowKnockup;
+ }
+
+ public double getKnockupVelocity() {
+ return knockupVelocity;
+ }
+
+ public void setKnockupVelocity(double knockupVelocity) {
+ this.knockupVelocity = knockupVelocity;
+ }
+
+ public double getKnockupRange() {
+ return knockupRange;
+ }
+
+ public void setKnockupRange(double knockupRange) {
+ this.knockupRange = knockupRange;
+ }
+
+ public boolean isAllowKnockupSelf() {
+ return allowKnockupSelf;
+ }
+
+ public void setAllowKnockupSelf(boolean allowKnockupSelf) {
+ this.allowKnockupSelf = allowKnockupSelf;
+ }
+
+ public double getKnockupSelfVelocity() {
+ return knockupSelfVelocity;
+ }
+
+ public void setKnockupSelfVelocity(double knockupSelfVelocity) {
+ this.knockupSelfVelocity = knockupSelfVelocity;
+ }
+
+ public double getKnockupSelfRange() {
+ return knockupSelfRange;
+ }
+
+ public void setKnockupSelfRange(double knockupSelfRange) {
+ this.knockupSelfRange = knockupSelfRange;
+ }
+
+ @Override
+ public void load() {}
+
+ @Override
+ public void stop() {}
- @Override
- public boolean isEnabled() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getBoolean("Abilities.Earth.EarthShard.Enabled");
- }
+ @Override
+ public boolean isEnabled() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getBoolean("Abilities.Earth.EarthShard.Enabled");
+ }
}
diff --git a/src/com/jedk1/jedcore/ability/earthbending/EarthSurf.java b/src/com/jedk1/jedcore/ability/earthbending/EarthSurf.java
index 83df672..425962b 100644
--- a/src/com/jedk1/jedcore/ability/earthbending/EarthSurf.java
+++ b/src/com/jedk1/jedcore/ability/earthbending/EarthSurf.java
@@ -12,7 +12,6 @@
import com.projectkorra.projectkorra.earthbending.passive.DensityShift;
import com.projectkorra.projectkorra.region.RegionProtection;
import com.projectkorra.projectkorra.util.TempBlock;
-
import com.projectkorra.projectkorra.util.TempFallingBlock;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -24,480 +23,483 @@
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
-import java.util.*;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
public class EarthSurf extends EarthAbility implements AddonAbility {
- private static final double TARGET_HEIGHT = 1.5;
-
- private Location location;
- private double prevHealth;
-
- @Attribute(Attribute.COOLDOWN)
- private long cooldown;
- private long minimumCooldown;
- @Attribute(Attribute.DURATION)
- private long duration;
- private boolean cooldownEnabled;
- private boolean durationEnabled;
- private boolean removeOnAnyDamage;
- @Attribute(Attribute.SPEED)
- private double speed;
- private double springStiffness;
- private final Set ridingBlocks = new HashSet<>();
- private CollisionDetector collisionDetector = new DefaultCollisionDetector();
- private DoubleSmoother heightSmoother;
-
- public EarthSurf(Player player) {
- super(player);
-
- if (!bPlayer.canBend(this)) {
- return;
- }
-
- if (hasAbility(player, EarthSurf.class)) {
- getAbility(player, EarthSurf.class).remove();
- return;
- }
-
- setFields();
-
- location = player.getLocation();
-
- if (canStart()) {
- prevHealth = player.getHealth();
-
- this.flightHandler.createInstance(player, this.getName());
- player.setAllowFlight(true);
- player.setFlying(false);
- start();
- }
- }
-
- private boolean canStart() {
- Block beneath = getBlockBeneath(player.getLocation().clone());
- double maxHeight = getMaxHeight();
-
- return isEarthbendable(player, beneath) && !isMetal(beneath) && beneath.getLocation().distanceSquared(player.getLocation()) <= maxHeight * maxHeight;
- }
-
- public void setFields() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- cooldown = config.getLong("Abilities.Earth.EarthSurf.Cooldown.Cooldown");
- minimumCooldown = config.getLong("Abilities.Earth.EarthSurf.Cooldown.MinimumCooldown");
- duration = config.getLong("Abilities.Earth.EarthSurf.Duration.Duration");
- cooldownEnabled = config.getBoolean("Abilities.Earth.EarthSurf.Cooldown.Enabled");
- durationEnabled = config.getBoolean("Abilities.Earth.EarthSurf.Duration.Enabled");
- removeOnAnyDamage = config.getBoolean("Abilities.Earth.EarthSurf.RemoveOnAnyDamage");
- speed = config.getDouble("Abilities.Earth.EarthSurf.Speed");
- springStiffness = config.getDouble("Abilities.Earth.EarthSurf.SpringStiffness");
-
- int smootherSize = config.getInt("Abilities.Earth.EarthSurf.HeightTolerance");
- this.heightSmoother = new DoubleSmoother(Math.max(smootherSize, 1));
-
- if (config.getBoolean("Abilities.Earth.EarthSurf.RelaxedCollisions")) {
- this.collisionDetector = new RelaxedCollisionDetector();
- }
-
- if (!config.getBoolean("Abilities.Earth.EarthSurf.Cooldown.Scaled")) {
- minimumCooldown = cooldown;
- }
- }
-
- @Override
- public void progress() {
- if (shouldRemove()) {
- remove();
- return;
- }
-
- this.player.setFlying(false);
-
- if (!collisionDetector.isColliding(player) && player.getHealth() >= prevHealth) {
- movePlayer();
-
- if (removeOnAnyDamage) {
- prevHealth = player.getHealth();
- }
- } else {
- remove();
- }
- }
-
- private boolean shouldRemove() {
- if (player == null || player.isDead() || !player.isOnline()) return true;
- if (!bPlayer.canBendIgnoreCooldowns(this)) return true;
- if (!isEarthbendable(player, getBlockBeneath(player.getLocation().clone()))) return true;
- if (durationEnabled && System.currentTimeMillis() > getStartTime() + duration) return true;
-
- return player.isSneaking();
- }
-
- private void movePlayer() {
- location = player.getEyeLocation().clone();
- location.setPitch(0);
- Vector direction = location.getDirection().normalize();
-
- // How far the player is above the ground.
- double height = getPlayerDistance();
- double maxHeight = getMaxHeight();
- double smoothedHeight = heightSmoother.add(height);
-
- // Destroy ability if player gets too far from ground.
- if (smoothedHeight > maxHeight) {
- remove();
- return;
- }
-
- // Calculate the spring force to push the player back to the target height.
- double displacement = height - TARGET_HEIGHT;
- double force = -springStiffness * displacement;
-
- double maxForce = 0.5;
- if (Math.abs(force) > maxForce) {
- // Cap the force to maxForce so the player isn't instantly pulled to the ground.
- force = force / Math.abs(force) * maxForce;
- }
-
- Vector velocity = direction.clone().multiply(speed).setY(force);
-
- rideWave();
-
- player.setVelocity(velocity);
- player.setFallDistance(0);
- }
-
- private double getMaxHeight() {
- return TARGET_HEIGHT + 2.0;
- }
-
- private double getPlayerDistance() {
- Location l = player.getLocation().clone();
- while (true) {
- if (l.getBlockY() <= l.getWorld().getMinHeight()) break;
- if (ElementalAbility.isAir(l.getBlock().getType()) && ridingBlocks.contains(l.getBlock())) break;
- if (GeneralMethods.isSolid(l.getBlock())) break;
-
- l.add(0, -0.1, 0);
- }
- return player.getLocation().getY() - l.getY();
- }
-
- private Block getBlockBeneath(Location l) {
- while (l.getBlockY() > l.getWorld().getMinHeight() && MaterialUtil.isTransparent(l.getBlock())) {
- l.add(0, -0.5, 0);
- }
- return l.getBlock();
- }
-
- private void rideWave() {
- for (int i = 0; i < 3; i++) {
- Location loc = location.clone();
- if (i < 2)
- loc.add(getSideDirection(i));
-
- //Player Positioning
- double distOffset = 2.5;
- Location bL = loc.clone().add(0, -2.9, 0).toVector().add(location.clone().getDirection().multiply(distOffset)).toLocation(player.getWorld());
- while (!ElementalAbility.isAir(loc.clone().add(0, -2.9, 0).toVector().add(location.clone().getDirection().multiply(distOffset)).toLocation(player.getWorld()).getBlock().getType())) {
- loc.add(0, 0.1, 0);
- }
-
- if (isEarthbendable(player, getBlockBeneath(loc.clone().add(0, -2.9, 0).toVector().add(location.clone().getDirection().multiply(distOffset)).toLocation(player.getWorld()))) && getBlockBeneath(bL) != null) {
- Block block = loc.clone().add(0, -3.9, 0).toVector().add(location.clone().getDirection().multiply(distOffset - 0.5)).toLocation(player.getWorld()).getBlock();
- Location temp = loc.clone().add(0, -2.9, 0).toVector().add(location.clone().getDirection().multiply(distOffset)).toLocation(player.getWorld());
-
- if (RegionProtection.isRegionProtected(this, block.getLocation())) {
- continue;
- }
- // Don't render blocks above the player because it looks bad.
- // TODO: Change this check to see if it's a reachable position instead.
- if (block.getLocation().getY() > this.player.getLocation().getY()) {
- continue;
- }
-
- if (DensityShift.isPassiveSand(block)) {
- DensityShift.revertSand(block);
- }
-
- if (!GeneralMethods.isSolid(block.getLocation().add(0, 1, 0).getBlock()) && !ElementalAbility.isAir(block.getLocation().add(0, 1, 0).getBlock().getType())) {
- if (DensityShift.isPassiveSand(block.getRelative(BlockFace.UP))) {
- DensityShift.revertSand(block.getRelative(BlockFace.UP));
- }
-
- new TempBlock(block.getRelative(BlockFace.UP), Material.AIR.createBlockData());
- }
-
- if (GeneralMethods.isSolid(block)) {
- ridingBlocks.add(block);
- new RegenTempBlock(block, Material.AIR, Material.AIR.createBlockData(), 1000L, true, ridingBlocks::remove);
- } else {
- new RegenTempBlock(block, Material.AIR, Material.AIR.createBlockData(), 1000L);
- }
-
- new TempFallingBlock(temp, getBlockBeneath(bL).getBlockData(), new Vector(0, 0.25, 0), this, true);
-
- for (Entity e : GeneralMethods.getEntitiesAroundPoint(loc.clone().add(0, -2.9, 0).toVector().add(location.clone().getDirection().multiply(distOffset)).toLocation(player.getWorld()), 1.5D)) {
- if (e instanceof LivingEntity && e.getEntityId() != player.getEntityId()) {
- e.setVelocity(new Vector(0, 0.3, 0));
- }
- }
- }
- }
- }
-
- private Vector getSideDirection(int side) {
- Vector direction = location.clone().getDirection().normalize();
- switch (side) {
- case 0: // RIGHT
- return new Vector(-direction.getZ(), 0.0, direction.getX()).normalize();
- case 1: // LEFT
- return new Vector(direction.getZ(), 0.0, -direction.getX()).normalize();
- default:
- break;
- }
-
- return null;
- }
-
- @Override
- public void remove() {
- this.flightHandler.removeInstance(player, this.getName());
-
- if (cooldownEnabled && player.isOnline()) {
- long scaledCooldown = cooldown;
-
- if (durationEnabled && duration > 0) {
- double t = Math.min((System.currentTimeMillis() - this.getStartTime()) / (double) duration, 1.0);
- scaledCooldown = Math.max((long) (cooldown * t), minimumCooldown);
- }
-
- bPlayer.addCooldown(this, scaledCooldown);
- }
-
- super.remove();
- }
-
- @Override
- public long getCooldown() {
- return cooldown;
- }
-
- @Override
- public Location getLocation() {
- return location;
- }
-
- @Override
- public String getName() {
- return "EarthSurf";
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return true;
- }
-
- @Override
- public String getAuthor() {
- return JedCore.dev;
- }
-
- @Override
- public String getVersion() {
- return JedCore.version;
- }
-
- @Override
- public String getDescription() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return "* JedCore Addon *\n" + config.getString("Abilities.Earth.EarthSurf.Description");
- }
-
- public static double getTargetHeight() {
- return TARGET_HEIGHT;
- }
-
- public void setLocation(Location location) {
- this.location = location;
- }
-
- public double getPrevHealth() {
- return prevHealth;
- }
-
- public void setPrevHealth(double prevHealth) {
- this.prevHealth = prevHealth;
- }
-
- public void setCooldown(long cooldown) {
- this.cooldown = cooldown;
- }
-
- public long getMinimumCooldown() {
- return minimumCooldown;
- }
-
- public void setMinimumCooldown(long minimumCooldown) {
- this.minimumCooldown = minimumCooldown;
- }
-
- public long getDuration() {
- return duration;
- }
-
- public void setDuration(long duration) {
- this.duration = duration;
- }
-
- public boolean isCooldownEnabled() {
- return cooldownEnabled;
- }
-
- public void setCooldownEnabled(boolean cooldownEnabled) {
- this.cooldownEnabled = cooldownEnabled;
- }
-
- public boolean isDurationEnabled() {
- return durationEnabled;
- }
-
- public void setDurationEnabled(boolean durationEnabled) {
- this.durationEnabled = durationEnabled;
- }
-
- public boolean isRemoveOnAnyDamage() {
- return removeOnAnyDamage;
- }
-
- public void setRemoveOnAnyDamage(boolean removeOnAnyDamage) {
- this.removeOnAnyDamage = removeOnAnyDamage;
- }
-
- public double getSpeed() {
- return speed;
- }
-
- public void setSpeed(double speed) {
- this.speed = speed;
- }
-
- public double getSpringStiffness() {
- return springStiffness;
- }
-
- public void setSpringStiffness(double springStiffness) {
- this.springStiffness = springStiffness;
- }
-
- public Set getRidingBlocks() {
- return ridingBlocks;
- }
-
- public CollisionDetector getCollisionDetector() {
- return collisionDetector;
- }
-
- public void setCollisionDetector(CollisionDetector collisionDetector) {
- this.collisionDetector = collisionDetector;
- }
-
- public DoubleSmoother getHeightSmoother() {
- return heightSmoother;
- }
-
- public void setHeightSmoother(DoubleSmoother heightSmoother) {
- this.heightSmoother = heightSmoother;
- }
-
- @Override
- public void load() {}
-
- @Override
- public void stop() {}
-
- @Override
- public boolean isEnabled() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- return config.getBoolean("Abilities.Earth.EarthSurf.Enabled");
- }
-
- private interface CollisionDetector {
- boolean isColliding(Player player);
- }
-
- private abstract static class AbstractCollisionDetector implements CollisionDetector {
- protected boolean isCollision(Location location) {
- Block block = location.getBlock();
- return !MaterialUtil.isTransparent(block) || block.isLiquid() || block.getType().isSolid();
- }
- }
-
- private class DefaultCollisionDetector extends AbstractCollisionDetector {
- @Override
- public boolean isColliding(Player player) {
- // The location in front of the player, where the player will be in one second.
- Location front = player.getEyeLocation().clone();
- front.setPitch(0);
-
- Vector direction = front.getDirection().clone().setY(0).normalize();
- double playerSpeed = player.getVelocity().clone().setY(0).length();
-
- front.add(direction.clone().multiply(Math.max(speed, playerSpeed)));
-
- for (int i = 0; i < 3; ++i) {
- Location location = front.clone().add(0, -i, 0);
- if (isCollision(location)) {
- return true;
- }
- }
-
- return false;
- }
- }
-
- private class RelaxedCollisionDetector extends AbstractCollisionDetector {
- @Override
- public boolean isColliding(Player player) {
- // The location in front of the player, where the player will be in one second.
- Location front = player.getEyeLocation().clone().subtract(0.0, 0.5, 0.0);
- front.setPitch(0);
-
- Vector direction = front.getDirection().clone().setY(0).normalize();
- double playerSpeed = player.getVelocity().clone().setY(0).length();
-
- front.add(direction.clone().multiply(Math.max(speed, playerSpeed)));
-
- return isCollision(front);
- }
- }
-
- private static class DoubleSmoother {
- private final double[] values;
- private final int size;
- private int index;
-
- public DoubleSmoother(int size) {
- this.size = size;
- this.index = 0;
-
- values = new double[size];
- }
-
- public double add(double value) {
- values[index] = value;
- index = (index + 1) % size;
- return get();
- }
-
- public double get() {
- return Arrays.stream(this.values).sum() / this.size;
- }
- }
-}
+ private static final double TARGET_HEIGHT = 1.5;
+
+ private Location location;
+ private double prevHealth;
+
+ @Attribute(Attribute.COOLDOWN)
+ private long cooldown;
+ private long minimumCooldown;
+ @Attribute(Attribute.DURATION)
+ private long duration;
+ private boolean cooldownEnabled;
+ private boolean durationEnabled;
+ private boolean removeOnAnyDamage;
+ @Attribute(Attribute.SPEED)
+ private double speed;
+ private double springStiffness;
+ private final Set ridingBlocks = new HashSet<>();
+ private CollisionDetector collisionDetector = new DefaultCollisionDetector();
+ private DoubleSmoother heightSmoother;
+
+ public EarthSurf(Player player) {
+ super(player);
+
+ if (!bPlayer.canBend(this)) {
+ return;
+ }
+
+ if (hasAbility(player, EarthSurf.class)) {
+ getAbility(player, EarthSurf.class).remove();
+ return;
+ }
+
+ setFields();
+
+ location = player.getLocation();
+
+ if (canStart()) {
+ prevHealth = player.getHealth();
+
+ this.flightHandler.createInstance(player, this.getName());
+ player.setAllowFlight(true);
+ player.setFlying(false);
+ start();
+ }
+ }
+
+ private boolean canStart() {
+ Block beneath = getBlockBeneath(player.getLocation().clone());
+ double maxHeight = getMaxHeight();
+
+ return isEarthbendable(player, beneath) && !isMetal(beneath) && beneath.getLocation().distanceSquared(player.getLocation()) <= maxHeight * maxHeight && !EarthAbility.getMovedEarth().containsKey(beneath);
+ }
+
+ public void setFields() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ cooldown = config.getLong("Abilities.Earth.EarthSurf.Cooldown.Cooldown");
+ minimumCooldown = config.getLong("Abilities.Earth.EarthSurf.Cooldown.MinimumCooldown");
+ duration = config.getLong("Abilities.Earth.EarthSurf.Duration.Duration");
+ cooldownEnabled = config.getBoolean("Abilities.Earth.EarthSurf.Cooldown.Enabled");
+ durationEnabled = config.getBoolean("Abilities.Earth.EarthSurf.Duration.Enabled");
+ removeOnAnyDamage = config.getBoolean("Abilities.Earth.EarthSurf.RemoveOnAnyDamage");
+ speed = config.getDouble("Abilities.Earth.EarthSurf.Speed");
+ springStiffness = config.getDouble("Abilities.Earth.EarthSurf.SpringStiffness");
+
+ int smootherSize = config.getInt("Abilities.Earth.EarthSurf.HeightTolerance");
+ this.heightSmoother = new DoubleSmoother(Math.max(smootherSize, 1));
+
+ if (config.getBoolean("Abilities.Earth.EarthSurf.RelaxedCollisions")) {
+ this.collisionDetector = new RelaxedCollisionDetector();
+ }
+
+ if (!config.getBoolean("Abilities.Earth.EarthSurf.Cooldown.Scaled")) {
+ minimumCooldown = cooldown;
+ }
+ }
+
+ @Override
+ public void progress() {
+ if (shouldRemove()) {
+ remove();
+ return;
+ }
+
+ this.player.setFlying(false);
+
+ if (!collisionDetector.isColliding(player) && player.getHealth() >= prevHealth) {
+ movePlayer();
+
+ if (removeOnAnyDamage) {
+ prevHealth = player.getHealth();
+ }
+ } else {
+ remove();
+ }
+ }
+
+ private boolean shouldRemove() {
+ if (player == null || player.isDead() || !player.isOnline()) return true;
+ if (!bPlayer.canBendIgnoreCooldowns(this)) return true;
+ if (!isEarthbendable(player, getBlockBeneath(player.getLocation().clone()))) return true;
+ if (durationEnabled && System.currentTimeMillis() > getStartTime() + duration) return true;
+
+ return player.isSneaking();
+ }
+
+ private void movePlayer() {
+ location = player.getEyeLocation().clone();
+ location.setPitch(0);
+ Vector direction = location.getDirection().normalize();
+
+ // How far the player is above the ground.
+ double height = getPlayerDistance();
+ double maxHeight = getMaxHeight();
+ double smoothedHeight = heightSmoother.add(height);
+
+ // Destroy ability if player gets too far from ground.
+ if (smoothedHeight > maxHeight) {
+ remove();
+ return;
+ }
+
+ // Calculate the spring force to push the player back to the target height.
+ double displacement = height - TARGET_HEIGHT;
+ double force = -springStiffness * displacement;
+
+ double maxForce = 0.5;
+ if (Math.abs(force) > maxForce) {
+ // Cap the force to maxForce so the player isn't instantly pulled to the ground.
+ force = force / Math.abs(force) * maxForce;
+ }
+
+ Vector velocity = direction.clone().multiply(speed).setY(force);
+
+ rideWave();
+
+ player.setVelocity(velocity);
+ player.setFallDistance(0);
+ }
+
+ private double getMaxHeight() {
+ return TARGET_HEIGHT + 2.0;
+ }
+
+ private double getPlayerDistance() {
+ Location l = player.getLocation().clone();
+ while (true) {
+ if (l.getBlockY() <= l.getWorld().getMinHeight()) break;
+ if (ElementalAbility.isAir(l.getBlock().getType()) && ridingBlocks.contains(l.getBlock())) break;
+ if (GeneralMethods.isSolid(l.getBlock())) break;
+
+ l.add(0, -0.1, 0);
+ }
+ return player.getLocation().getY() - l.getY();
+ }
+
+ private Block getBlockBeneath(Location l) {
+ while (l.getBlockY() > l.getWorld().getMinHeight() && MaterialUtil.isTransparent(l.getBlock())) {
+ l.add(0, -0.5, 0);
+ }
+ return l.getBlock();
+ }
+
+ private void rideWave() {
+ for (int i = 0; i < 3; i++) {
+ Location loc = location.clone();
+ if (i < 2)
+ loc.add(getSideDirection(i));
+
+ //Player Positioning
+ double distOffset = 2.5;
+ Location bL = loc.clone().add(0, -2.9, 0).toVector().add(location.clone().getDirection().multiply(distOffset)).toLocation(player.getWorld());
+ while (!ElementalAbility.isAir(loc.clone().add(0, -2.9, 0).toVector().add(location.clone().getDirection().multiply(distOffset)).toLocation(player.getWorld()).getBlock().getType())) {
+ loc.add(0, 0.1, 0);
+ }
+
+ Block beneath = getBlockBeneath(loc.clone().add(0, -2.9, 0).toVector().add(location.clone().getDirection().multiply(distOffset)).toLocation(player.getWorld()));
+ if (isEarthbendable(player, beneath) && beneath != null && !EarthAbility.getMovedEarth().containsKey(beneath)) {
+ Block block = loc.clone().add(0, -3.9, 0).toVector().add(location.clone().getDirection().multiply(distOffset - 0.5)).toLocation(player.getWorld()).getBlock();
+ Location temp = loc.clone().add(0, -2.9, 0).toVector().add(location.clone().getDirection().multiply(distOffset)).toLocation(player.getWorld());
+
+ if (RegionProtection.isRegionProtected(this, block.getLocation())) {
+ continue;
+ }
+ // Don't render blocks above the player because it looks bad.
+ // TODO: Change this check to see if it's a reachable position instead.
+ if (block.getLocation().getY() > this.player.getLocation().getY()) {
+ continue;
+ }
+
+ if (DensityShift.isPassiveSand(block)) {
+ DensityShift.revertSand(block);
+ }
+
+ if (!GeneralMethods.isSolid(block.getLocation().add(0, 1, 0).getBlock()) && !ElementalAbility.isAir(block.getLocation().add(0, 1, 0).getBlock().getType())) {
+ if (DensityShift.isPassiveSand(block.getRelative(BlockFace.UP))) {
+ DensityShift.revertSand(block.getRelative(BlockFace.UP));
+ }
+
+ new TempBlock(block.getRelative(BlockFace.UP), Material.AIR.createBlockData());
+ }
+
+ if (GeneralMethods.isSolid(block)) {
+ ridingBlocks.add(block);
+ new RegenTempBlock(block, Material.AIR, Material.AIR.createBlockData(), 1000L, true, ridingBlocks::remove);
+ } else {
+ new RegenTempBlock(block, Material.AIR, Material.AIR.createBlockData(), 1000L);
+ }
+
+ new TempFallingBlock(temp, getBlockBeneath(bL).getBlockData(), new Vector(0, 0.25, 0), this, true);
+
+ for (Entity e : GeneralMethods.getEntitiesAroundPoint(loc.clone().add(0, -2.9, 0).toVector().add(location.clone().getDirection().multiply(distOffset)).toLocation(player.getWorld()), 1.5D)) {
+ if (e instanceof LivingEntity && e.getEntityId() != player.getEntityId()) {
+ e.setVelocity(new Vector(0, 0.3, 0));
+ }
+ }
+ }
+ }
+ }
+
+ private Vector getSideDirection(int side) {
+ Vector direction = location.clone().getDirection().normalize();
+ switch (side) {
+ case 0: // RIGHT
+ return new Vector(-direction.getZ(), 0.0, direction.getX()).normalize();
+ case 1: // LEFT
+ return new Vector(direction.getZ(), 0.0, -direction.getX()).normalize();
+ default:
+ break;
+ }
+
+ return null;
+ }
+
+ @Override
+ public void remove() {
+ this.flightHandler.removeInstance(player, this.getName());
+
+ if (cooldownEnabled && player.isOnline()) {
+ long scaledCooldown = cooldown;
+
+ if (durationEnabled && duration > 0) {
+ double t = Math.min((System.currentTimeMillis() - this.getStartTime()) / (double) duration, 1.0);
+ scaledCooldown = Math.max((long) (cooldown * t), minimumCooldown);
+ }
+
+ bPlayer.addCooldown(this, scaledCooldown);
+ }
+
+ super.remove();
+ }
+
+ @Override
+ public long getCooldown() {
+ return cooldown;
+ }
+
+ @Override
+ public Location getLocation() {
+ return location;
+ }
+
+ @Override
+ public String getName() {
+ return "EarthSurf";
+ }
+
+ @Override
+ public boolean isHarmlessAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isSneakAbility() {
+ return true;
+ }
+
+ @Override
+ public String getAuthor() {
+ return JedCore.dev;
+ }
+
+ @Override
+ public String getVersion() {
+ return JedCore.version;
+ }
+
+ @Override
+ public String getDescription() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return "* JedCore Addon *\n" + config.getString("Abilities.Earth.EarthSurf.Description");
+ }
+
+ public static double getTargetHeight() {
+ return TARGET_HEIGHT;
+ }
+
+ public void setLocation(Location location) {
+ this.location = location;
+ }
+
+ public double getPrevHealth() {
+ return prevHealth;
+ }
+
+ public void setPrevHealth(double prevHealth) {
+ this.prevHealth = prevHealth;
+ }
+
+ public void setCooldown(long cooldown) {
+ this.cooldown = cooldown;
+ }
+
+ public long getMinimumCooldown() {
+ return minimumCooldown;
+ }
+
+ public void setMinimumCooldown(long minimumCooldown) {
+ this.minimumCooldown = minimumCooldown;
+ }
+
+ public long getDuration() {
+ return duration;
+ }
+
+ public void setDuration(long duration) {
+ this.duration = duration;
+ }
+
+ public boolean isCooldownEnabled() {
+ return cooldownEnabled;
+ }
+
+ public void setCooldownEnabled(boolean cooldownEnabled) {
+ this.cooldownEnabled = cooldownEnabled;
+ }
+
+ public boolean isDurationEnabled() {
+ return durationEnabled;
+ }
+
+ public void setDurationEnabled(boolean durationEnabled) {
+ this.durationEnabled = durationEnabled;
+ }
+
+ public boolean isRemoveOnAnyDamage() {
+ return removeOnAnyDamage;
+ }
+
+ public void setRemoveOnAnyDamage(boolean removeOnAnyDamage) {
+ this.removeOnAnyDamage = removeOnAnyDamage;
+ }
+
+ public double getSpeed() {
+ return speed;
+ }
+
+ public void setSpeed(double speed) {
+ this.speed = speed;
+ }
+
+ public double getSpringStiffness() {
+ return springStiffness;
+ }
+
+ public void setSpringStiffness(double springStiffness) {
+ this.springStiffness = springStiffness;
+ }
+
+ public Set getRidingBlocks() {
+ return ridingBlocks;
+ }
+
+ public CollisionDetector getCollisionDetector() {
+ return collisionDetector;
+ }
+
+ public void setCollisionDetector(CollisionDetector collisionDetector) {
+ this.collisionDetector = collisionDetector;
+ }
+
+ public DoubleSmoother getHeightSmoother() {
+ return heightSmoother;
+ }
+
+ public void setHeightSmoother(DoubleSmoother heightSmoother) {
+ this.heightSmoother = heightSmoother;
+ }
+
+ @Override
+ public void load() {}
+
+ @Override
+ public void stop() {}
+
+ @Override
+ public boolean isEnabled() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ return config.getBoolean("Abilities.Earth.EarthSurf.Enabled");
+ }
+
+ private interface CollisionDetector {
+ boolean isColliding(Player player);
+ }
+
+ private abstract static class AbstractCollisionDetector implements CollisionDetector {
+ protected boolean isCollision(Location location) {
+ Block block = location.getBlock();
+ return !MaterialUtil.isTransparent(block) || block.isLiquid() || block.getType().isSolid();
+ }
+ }
+
+ private class DefaultCollisionDetector extends AbstractCollisionDetector {
+ @Override
+ public boolean isColliding(Player player) {
+ // The location in front of the player, where the player will be in one second.
+ Location front = player.getEyeLocation().clone();
+ front.setPitch(0);
+
+ Vector direction = front.getDirection().clone().setY(0).normalize();
+ double playerSpeed = player.getVelocity().clone().setY(0).length();
+
+ front.add(direction.clone().multiply(Math.max(speed, playerSpeed)));
+
+ for (int i = 0; i < 3; ++i) {
+ Location location = front.clone().add(0, -i, 0);
+ if (isCollision(location)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+
+ private class RelaxedCollisionDetector extends AbstractCollisionDetector {
+ @Override
+ public boolean isColliding(Player player) {
+ // The location in front of the player, where the player will be in one second.
+ Location front = player.getEyeLocation().clone().subtract(0.0, 0.5, 0.0);
+ front.setPitch(0);
+
+ Vector direction = front.getDirection().clone().setY(0).normalize();
+ double playerSpeed = player.getVelocity().clone().setY(0).length();
+
+ front.add(direction.clone().multiply(Math.max(speed, playerSpeed)));
+
+ return isCollision(front);
+ }
+ }
+
+ private static class DoubleSmoother {
+ private final double[] values;
+ private final int size;
+ private int index;
+
+ public DoubleSmoother(int size) {
+ this.size = size;
+ this.index = 0;
+
+ values = new double[size];
+ }
+
+ public double add(double value) {
+ values[index] = value;
+ index = (index + 1) % size;
+ return get();
+ }
+
+ public double get() {
+ return Arrays.stream(this.values).sum() / this.size;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/com/jedk1/jedcore/ability/earthbending/Fissure.java b/src/com/jedk1/jedcore/ability/earthbending/Fissure.java
index 7f947a5..c3bbc98 100644
--- a/src/com/jedk1/jedcore/ability/earthbending/Fissure.java
+++ b/src/com/jedk1/jedcore/ability/earthbending/Fissure.java
@@ -2,7 +2,6 @@
import com.jedk1.jedcore.JedCore;
import com.jedk1.jedcore.configuration.JedCoreConfig;
-import com.jedk1.jedcore.util.RegenTempBlock;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AddonAbility;
import com.projectkorra.projectkorra.ability.EarthAbility;
@@ -13,7 +12,6 @@
import com.projectkorra.projectkorra.util.Information;
import com.projectkorra.projectkorra.util.ParticleEffect;
import com.projectkorra.projectkorra.util.TempBlock;
-
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
@@ -30,412 +28,412 @@
public class Fissure extends LavaAbility implements AddonAbility {
- @Attribute(Attribute.RANGE)
- private int slapRange;
- @Attribute(Attribute.WIDTH)
- private int maxWidth;
- private long slapDelay;
- @Attribute(Attribute.DURATION)
- private long duration;
- @Attribute(Attribute.COOLDOWN)
- private long cooldown;
-
- private Location location;
- private Vector direction;
- private Vector blockDirection;
- private long time;
- private long step;
- private int slap;
- private int width;
- private boolean progressed;
-
- static Random rand = new Random();
-
- private final List centerSlap = new ArrayList<>();
- private final List blocks = new ArrayList<>();
- private final List tempblocks = new ArrayList<>();
-
- public Fissure(Player player) {
- super(player);
-
- if (!bPlayer.canBend(this) || hasAbility(player, Fissure.class) || !bPlayer.canLavabend()) {
- return;
- }
-
- setFields();
- time = System.currentTimeMillis();
- step = System.currentTimeMillis() + slapDelay;
- location = player.getLocation().clone();
- location.setPitch(0);
- direction = location.getDirection();
- blockDirection = this.direction.clone().setX(Math.round(this.direction.getX()));
- blockDirection = blockDirection.setZ(Math.round(direction.getZ()));
- if (prepareLine()) {
- start();
- if (!isRemoved()) {
- bPlayer.addCooldown(this);
- }
- }
- }
-
- public void setFields() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- slapRange = config.getInt("Abilities.Earth.Fissure.SlapRange");
- maxWidth = config.getInt("Abilities.Earth.Fissure.MaxWidth");
- slapDelay = config.getInt("Abilities.Earth.Fissure.SlapDelay");
- duration = config.getInt("Abilities.Earth.Fissure.Duration");
- cooldown = config.getInt("Abilities.Earth.Fissure.Cooldown");
- }
-
- @Override
- public void progress() {
- if (player.isDead() || !player.isOnline()) {
- remove();
- return;
- }
- if (System.currentTimeMillis() > step && slap <= centerSlap.size()) {
- time = System.currentTimeMillis();
- step = System.currentTimeMillis() + slapDelay;
- slapCenter();
- slap++;
- }
- if (System.currentTimeMillis() > time + duration) {
- remove();
- }
- }
-
- private boolean prepareLine() {
- direction = player.getEyeLocation().getDirection().setY(0).normalize();
- blockDirection = this.direction.clone().setX(Math.round(this.direction.getX()));
- blockDirection = blockDirection.setZ(Math.round(direction.getZ()));
- Location origin = player.getLocation().add(0, -1, 0).add(blockDirection.multiply(2));
- if (isEarthbendable(player, origin.getBlock())) {
- BlockIterator bi = new BlockIterator(player.getWorld(), origin.toVector(), direction, 0, slapRange);
-
- while (bi.hasNext()) {
- Block b = bi.next();
-
- if (b.getY() > 1 && b.getY() < 255 && !RegionProtection.isRegionProtected(this, b.getLocation())) {
- if (EarthAbility.getMovedEarth().containsKey(b)){
- Information info = EarthAbility.getMovedEarth().get(b);
- if(!info.getBlock().equals(b)) {
- continue;
- }
- }
-
- while (!isEarthbendable(player, b)) {
- b = b.getRelative(BlockFace.DOWN);
- if (b.getY() < b.getWorld().getMinHeight() || b.getY() > b.getWorld().getMaxHeight()) {
- break;
- }
- if (isEarthbendable(player, b)) {
- break;
- }
- }
-
- while (!isTransparent(b.getRelative(BlockFace.UP))) {
- b = b.getRelative(BlockFace.UP);
- if (b.getY() < b.getWorld().getMinHeight() || b.getY() > b.getWorld().getMaxHeight()) {
- break;
- }
- if (isEarthbendable(player, b.getRelative(BlockFace.UP))) {
- break;
- }
- }
-
- if (isEarthbendable(player, b)) {
- centerSlap.add(b.getLocation());
- } else {
- break;
- }
- }
- }
- return true;
- }
- return false;
- }
-
- private void slapCenter() {
- for (Location location : centerSlap) {
- if (centerSlap.indexOf(location) == slap) {
- addTempBlock(location.getBlock(), Material.LAVA);
- }
- }
- if (slap >= centerSlap.size()) {
- progressed = true;
- }
- }
-
- public static void performAction(Player player) {
- if (hasAbility(player, Fissure.class)) {
- getAbility(player, Fissure.class).performAction();
- }
- }
-
- private void performAction() {
- if (width < maxWidth) {
- expandFissure();
- } else if (blocks.contains(player.getTargetBlock(null, 10))) {
- forceRevert();
- }
- }
-
- private void expandFissure() {
- if (progressed && width <= maxWidth) {
- width++;
- for (Location location : centerSlap) {
- Block left = location.getBlock().getRelative(getLeftBlockFace(GeneralMethods.getCardinalDirection(blockDirection)), width);
- expand(left);
-
- Block right = location.getBlock().getRelative(getLeftBlockFace(GeneralMethods.getCardinalDirection(blockDirection)).getOppositeFace(), width);
- expand(right);
- }
- }
- Collections.reverse(blocks);
- }
-
- private void expand(Block block) {
- if (block != null && block.getY() > 1 && block.getY() < 255 && !RegionProtection.isRegionProtected(this, block.getLocation())) {
- if (EarthAbility.getMovedEarth().containsKey(block)){
- Information info = EarthAbility.getMovedEarth().get(block);
- if(!info.getBlock().equals(block)) {
- return;
- }
- }
-
- while (!isEarthbendable(player, block)) {
- block = block.getRelative(BlockFace.DOWN);
- if (block.getY() < 1 || block.getY() > 255) {
- break;
- }
- if (isEarthbendable(player, block)) {
- break;
- }
- }
-
- while (!isTransparent(player, block.getRelative(BlockFace.UP))) {
- block = block.getRelative(BlockFace.UP);
- if (block.getY() < 1 || block.getY() > 255) {
- break;
- }
- if (isEarthbendable(player, block.getRelative(BlockFace.UP))) {
- break;
- }
- }
-
- if (isEarthbendable(player, block)) {
- addTempBlock(block, Material.LAVA);
- }
- }
- }
-
- private void addTempBlock(Block block, Material material) {
- ParticleEffect.LAVA.display(block.getLocation(), 0, 0, 0, 0, 1);
- playEarthbendingSound(block.getLocation());
- if (DensityShift.isPassiveSand(block)) {
+ @Attribute(Attribute.RANGE)
+ private int slapRange;
+ @Attribute(Attribute.WIDTH)
+ private int maxWidth;
+ private long slapDelay;
+ @Attribute(Attribute.DURATION)
+ private long duration;
+ @Attribute(Attribute.COOLDOWN)
+ private long cooldown;
+
+ private Location location;
+ private Vector direction;
+ private Vector blockDirection;
+ private long time;
+ private long step;
+ private int slap;
+ private int width;
+ private boolean progressed;
+
+ static Random rand = new Random();
+
+ private final List centerSlap = new ArrayList<>();
+ private final List blocks = new ArrayList<>();
+ private final List tempblocks = new ArrayList<>();
+
+ public Fissure(Player player) {
+ super(player);
+
+ if (!bPlayer.canBend(this) || hasAbility(player, Fissure.class) || !bPlayer.canLavabend()) {
+ return;
+ }
+
+ setFields();
+ time = System.currentTimeMillis();
+ step = System.currentTimeMillis() + slapDelay;
+ location = player.getLocation().clone();
+ location.setPitch(0);
+ direction = location.getDirection();
+ blockDirection = this.direction.clone().setX(Math.round(this.direction.getX()));
+ blockDirection = blockDirection.setZ(Math.round(direction.getZ()));
+ if (prepareLine()) {
+ start();
+ if (!isRemoved()) {
+ bPlayer.addCooldown(this);
+ }
+ }
+ }
+
+ public void setFields() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ slapRange = config.getInt("Abilities.Earth.Fissure.SlapRange");
+ maxWidth = config.getInt("Abilities.Earth.Fissure.MaxWidth");
+ slapDelay = config.getInt("Abilities.Earth.Fissure.SlapDelay");
+ duration = config.getInt("Abilities.Earth.Fissure.Duration");
+ cooldown = config.getInt("Abilities.Earth.Fissure.Cooldown");
+ }
+
+ @Override
+ public void progress() {
+ if (player.isDead() || !player.isOnline()) {
+ remove();
+ return;
+ }
+ if (System.currentTimeMillis() > step && slap <= centerSlap.size()) {
+ time = System.currentTimeMillis();
+ step = System.currentTimeMillis() + slapDelay;
+ slapCenter();
+ slap++;
+ }
+ if (System.currentTimeMillis() > time + duration) {
+ remove();
+ }
+ }
+
+ private boolean prepareLine() {
+ direction = player.getEyeLocation().getDirection().setY(0).normalize();
+ blockDirection = this.direction.clone().setX(Math.round(this.direction.getX()));
+ blockDirection = blockDirection.setZ(Math.round(direction.getZ()));
+ Location origin = player.getLocation().add(0, -1, 0).add(blockDirection.multiply(2));
+ if (isEarthbendable(player, origin.getBlock())) {
+ BlockIterator bi = new BlockIterator(player.getWorld(), origin.toVector(), direction, 0, slapRange);
+
+ while (bi.hasNext()) {
+ Block b = bi.next();
+
+ if (b.getY() > b.getWorld().getMinHeight() && b.getY() < b.getWorld().getMaxHeight() && !RegionProtection.isRegionProtected(this, b.getLocation())) {
+ if (EarthAbility.getMovedEarth().containsKey(b)){
+ Information info = EarthAbility.getMovedEarth().get(b);
+ if(!info.getBlock().equals(b)) {
+ continue;
+ }
+ }
+
+ while (!isEarthbendable(player, b)) {
+ b = b.getRelative(BlockFace.DOWN);
+ if (b.getY() < b.getWorld().getMinHeight() || b.getY() > b.getWorld().getMaxHeight()) {
+ break;
+ }
+ if (isEarthbendable(player, b)) {
+ break;
+ }
+ }
+
+ while (!isTransparent(b.getRelative(BlockFace.UP))) {
+ b = b.getRelative(BlockFace.UP);
+ if (b.getY() < b.getWorld().getMinHeight() || b.getY() > b.getWorld().getMaxHeight()) {
+ break;
+ }
+ if (isEarthbendable(player, b.getRelative(BlockFace.UP))) {
+ break;
+ }
+ }
+
+ if (isEarthbendable(player, b)) {
+ centerSlap.add(b.getLocation());
+ } else {
+ break;
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private void slapCenter() {
+ for (Location location : centerSlap) {
+ if (centerSlap.indexOf(location) == slap) {
+ addTempBlock(location.getBlock(), Material.LAVA);
+ }
+ }
+ if (slap >= centerSlap.size()) {
+ progressed = true;
+ }
+ }
+
+ public static void performAction(Player player) {
+ if (hasAbility(player, Fissure.class)) {
+ getAbility(player, Fissure.class).performAction();
+ }
+ }
+
+ private void performAction() {
+ if (width < maxWidth) {
+ expandFissure();
+ } else if (blocks.contains(player.getTargetBlock(null, 10))) {
+ forceRevert();
+ }
+ }
+
+ private void expandFissure() {
+ if (progressed && width <= maxWidth) {
+ width++;
+ for (Location location : centerSlap) {
+ Block left = location.getBlock().getRelative(getLeftBlockFace(GeneralMethods.getCardinalDirection(blockDirection)), width);
+ expand(left);
+
+ Block right = location.getBlock().getRelative(getLeftBlockFace(GeneralMethods.getCardinalDirection(blockDirection)).getOppositeFace(), width);
+ expand(right);
+ }
+ }
+ Collections.reverse(blocks);
+ }
+
+ private void expand(Block block) {
+ if (block != null && block.getY() > block.getWorld().getMinHeight() && block.getY() < block.getWorld().getMaxHeight() && !RegionProtection.isRegionProtected(this, block.getLocation())) {
+ if (EarthAbility.getMovedEarth().containsKey(block)){
+ Information info = EarthAbility.getMovedEarth().get(block);
+ if(!info.getBlock().equals(block)) {
+ return;
+ }
+ }
+
+ while (!isEarthbendable(player, block)) {
+ block = block.getRelative(BlockFace.DOWN);
+ if (block.getY() < block.getWorld().getMinHeight() || block.getY() > block.getWorld().getMaxHeight()) {
+ break;
+ }
+ if (isEarthbendable(player, block)) {
+ break;
+ }
+ }
+
+ while (!isTransparent(player, block.getRelative(BlockFace.UP))) {
+ block = block.getRelative(BlockFace.UP);
+ if (block.getY() < block.getWorld().getMinHeight() || block.getY() > block.getWorld().getMaxHeight()) {
+ break;
+ }
+ if (isEarthbendable(player, block.getRelative(BlockFace.UP))) {
+ break;
+ }
+ }
+
+ if (isEarthbendable(player, block)) {
+ addTempBlock(block, Material.LAVA);
+ }
+ }
+ }
+
+ private void addTempBlock(Block block, Material material) {
+ ParticleEffect.LAVA.display(block.getLocation(), 0, 0, 0, 0, 1);
+ playEarthbendingSound(block.getLocation());
+ if (DensityShift.isPassiveSand(block)) {
DensityShift.revertSand(block);
- }
- tempblocks.add(new TempBlock(block, material.createBlockData(), this));
- blocks.add(block);
- }
-
- public BlockFace getLeftBlockFace(BlockFace forward) {
- switch (forward) {
- case NORTH:
- return BlockFace.WEST;
- case SOUTH:
- return BlockFace.EAST;
- case WEST:
- return BlockFace.SOUTH;
- case EAST:
- return BlockFace.NORTH;
- case NORTH_WEST:
- return BlockFace.SOUTH_WEST;
- case NORTH_EAST:
- return BlockFace.NORTH_WEST;
- case SOUTH_WEST:
- return BlockFace.SOUTH_EAST;
- case SOUTH_EAST:
- return BlockFace.NORTH_EAST;
- default:
- return BlockFace.NORTH;
- }
- }
-
- private void forceRevert() {
- coolLava();
- }
-
- private void coolLava() {
- tempblocks.forEach(TempBlock::revertBlock);
- for (Block block : blocks) {
- new TempBlock(block, Material.STONE.createBlockData(), 500 + (long) rand.nextInt((int) 1000));
- }
- blocks.clear();
- tempblocks.clear();
- }
-
- @Override
- public void remove() {
- coolLava();
- super.remove();
- }
-
- @Override
- public long getCooldown() {
- return cooldown;
- }
-
- @Override
- public Location getLocation() {
- return location;
- }
-
- @Override
- public String getName() {
- return "Fissure";
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return true;
- }
-
- @Override
- public String getAuthor() {
- return JedCore.dev;
- }
-
- @Override
- public String getVersion() {
- return JedCore.version;
- }
-
- @Override
- public String getDescription() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return "* JedCore Addon *\n" + config.getString("Abilities.Earth.Fissure.Description");
- }
-
- public int getSlapRange() {
- return slapRange;
- }
-
- public void setSlapRange(int slapRange) {
- this.slapRange = slapRange;
- }
-
- public int getMaxWidth() {
- return maxWidth;
- }
-
- public void setMaxWidth(int maxWidth) {
- this.maxWidth = maxWidth;
- }
-
- public long getSlapDelay() {
- return slapDelay;
- }
-
- public void setSlapDelay(long slapDelay) {
- this.slapDelay = slapDelay;
- }
-
- public long getDuration() {
- return duration;
- }
-
- public void setDuration(long duration) {
- this.duration = duration;
- }
-
- public void setCooldown(long cooldown) {
- this.cooldown = cooldown;
- }
-
- public void setLocation(Location location) {
- this.location = location;
- }
-
- public Vector getDirection() {
- return direction;
- }
-
- public void setDirection(Vector direction) {
- this.direction = direction;
- }
-
- public Vector getBlockDirection() {
- return blockDirection;
- }
-
- public void setBlockDirection(Vector blockDirection) {
- this.blockDirection = blockDirection;
- }
-
- public long getTime() {
- return time;
- }
-
- public void setTime(long time) {
- this.time = time;
- }
-
- public long getStep() {
- return step;
- }
-
- public void setStep(long step) {
- this.step = step;
- }
-
- public int getSlap() {
- return slap;
- }
-
- public void setSlap(int slap) {
- this.slap = slap;
- }
-
- public int getWidth() {
- return width;
- }
-
- public void setWidth(int width) {
- this.width = width;
- }
-
- public boolean isProgressed() {
- return progressed;
- }
-
- public void setProgressed(boolean progressed) {
- this.progressed = progressed;
- }
-
- public List getCenterSlap() {
- return centerSlap;
- }
+ }
+ tempblocks.add(new TempBlock(block, material.createBlockData(), this));
+ blocks.add(block);
+ }
+
+ public BlockFace getLeftBlockFace(BlockFace forward) {
+ switch (forward) {
+ case NORTH:
+ return BlockFace.WEST;
+ case SOUTH:
+ return BlockFace.EAST;
+ case WEST:
+ return BlockFace.SOUTH;
+ case EAST:
+ return BlockFace.NORTH;
+ case NORTH_WEST:
+ return BlockFace.SOUTH_WEST;
+ case NORTH_EAST:
+ return BlockFace.NORTH_WEST;
+ case SOUTH_WEST:
+ return BlockFace.SOUTH_EAST;
+ case SOUTH_EAST:
+ return BlockFace.NORTH_EAST;
+ default:
+ return BlockFace.NORTH;
+ }
+ }
+
+ private void forceRevert() {
+ coolLava();
+ }
+
+ private void coolLava() {
+ tempblocks.forEach(TempBlock::revertBlock);
+ for (Block block : blocks) {
+ new TempBlock(block, Material.STONE.createBlockData(), 500 + (long) rand.nextInt((int) 1000));
+ }
+ blocks.clear();
+ tempblocks.clear();
+ }
+
+ @Override
+ public void remove() {
+ coolLava();
+ super.remove();
+ }
+
+ @Override
+ public long getCooldown() {
+ return cooldown;
+ }
+
+ @Override
+ public Location getLocation() {
+ return location;
+ }
+
+ @Override
+ public String getName() {
+ return "Fissure";
+ }
+
+ @Override
+ public boolean isHarmlessAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isSneakAbility() {
+ return true;
+ }
+
+ @Override
+ public String getAuthor() {
+ return JedCore.dev;
+ }
+
+ @Override
+ public String getVersion() {
+ return JedCore.version;
+ }
+
+ @Override
+ public String getDescription() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return "* JedCore Addon *\n" + config.getString("Abilities.Earth.Fissure.Description");
+ }
+
+ public int getSlapRange() {
+ return slapRange;
+ }
+
+ public void setSlapRange(int slapRange) {
+ this.slapRange = slapRange;
+ }
+
+ public int getMaxWidth() {
+ return maxWidth;
+ }
+
+ public void setMaxWidth(int maxWidth) {
+ this.maxWidth = maxWidth;
+ }
+
+ public long getSlapDelay() {
+ return slapDelay;
+ }
+
+ public void setSlapDelay(long slapDelay) {
+ this.slapDelay = slapDelay;
+ }
+
+ public long getDuration() {
+ return duration;
+ }
+
+ public void setDuration(long duration) {
+ this.duration = duration;
+ }
+
+ public void setCooldown(long cooldown) {
+ this.cooldown = cooldown;
+ }
+
+ public void setLocation(Location location) {
+ this.location = location;
+ }
+
+ public Vector getDirection() {
+ return direction;
+ }
+
+ public void setDirection(Vector direction) {
+ this.direction = direction;
+ }
+
+ public Vector getBlockDirection() {
+ return blockDirection;
+ }
+
+ public void setBlockDirection(Vector blockDirection) {
+ this.blockDirection = blockDirection;
+ }
+
+ public long getTime() {
+ return time;
+ }
+
+ public void setTime(long time) {
+ this.time = time;
+ }
+
+ public long getStep() {
+ return step;
+ }
+
+ public void setStep(long step) {
+ this.step = step;
+ }
+
+ public int getSlap() {
+ return slap;
+ }
+
+ public void setSlap(int slap) {
+ this.slap = slap;
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ }
+
+ public boolean isProgressed() {
+ return progressed;
+ }
+
+ public void setProgressed(boolean progressed) {
+ this.progressed = progressed;
+ }
+
+ public List getCenterSlap() {
+ return centerSlap;
+ }
- public List getBlocks() {
- return blocks;
- }
+ public List getBlocks() {
+ return blocks;
+ }
- @Override
- public void load() {}
+ @Override
+ public void load() {}
- @Override
- public void stop() {}
+ @Override
+ public void stop() {}
- @Override
- public boolean isEnabled() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getBoolean("Abilities.Earth.Fissure.Enabled");
- }
+ @Override
+ public boolean isEnabled() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getBoolean("Abilities.Earth.Fissure.Enabled");
+ }
}
\ No newline at end of file
diff --git a/src/com/jedk1/jedcore/ability/earthbending/LavaDisc.java b/src/com/jedk1/jedcore/ability/earthbending/LavaDisc.java
index 65cdf08..5d64f5f 100644
--- a/src/com/jedk1/jedcore/ability/earthbending/LavaDisc.java
+++ b/src/com/jedk1/jedcore/ability/earthbending/LavaDisc.java
@@ -1,16 +1,19 @@
package com.jedk1.jedcore.ability.earthbending;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
+import com.jedk1.jedcore.JCMethods;
+import com.jedk1.jedcore.JedCore;
import com.jedk1.jedcore.configuration.JedCoreConfig;
import com.jedk1.jedcore.policies.removal.*;
-import com.projectkorra.projectkorra.ability.CoreAbility;
-import com.projectkorra.projectkorra.ability.ElementalAbility;
+import com.jedk1.jedcore.util.RegenTempBlock;
+import com.projectkorra.projectkorra.GeneralMethods;
+import com.projectkorra.projectkorra.ability.*;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.earthbending.passive.DensityShift;
+import com.projectkorra.projectkorra.firebending.util.FireDamageTimer;
import com.projectkorra.projectkorra.region.RegionProtection;
+import com.projectkorra.projectkorra.util.DamageHandler;
+import com.projectkorra.projectkorra.util.ParticleEffect;
+import com.projectkorra.projectkorra.util.TempBlock;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -23,531 +26,530 @@
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
-import com.jedk1.jedcore.JCMethods;
-import com.jedk1.jedcore.JedCore;
-import com.jedk1.jedcore.util.RegenTempBlock;
-import com.projectkorra.projectkorra.GeneralMethods;
-import com.projectkorra.projectkorra.ability.AddonAbility;
-import com.projectkorra.projectkorra.ability.LavaAbility;
-import com.projectkorra.projectkorra.firebending.util.FireDamageTimer;
-import com.projectkorra.projectkorra.util.DamageHandler;
-import com.projectkorra.projectkorra.util.ParticleEffect;
-import com.projectkorra.projectkorra.util.TempBlock;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
public class LavaDisc extends LavaAbility implements AddonAbility {
- private Location location;
- private int recallCount;
-
- private long time;
-
- @Attribute(Attribute.DAMAGE)
- private double damage;
- @Attribute(Attribute.COOLDOWN)
- private long cooldown;
- @Attribute(Attribute.DURATION)
- private long duration;
- private int recallLimit;
- private boolean trailFlow;
-
- private CompositeRemovalPolicy removalPolicy;
- private DiscRenderer discRenderer;
- private State state;
- private final Set trailBlocks = new HashSet<>();
-
- public LavaDisc(Player player) {
- super(player);
-
- if (!bPlayer.canBend(this) || !bPlayer.canLavabend()) {
- return;
- }
-
- // Allow new LavaDisc if all existing instances for that player are in CleanupState.
- for (LavaDisc disc : CoreAbility.getAbilities(player, LavaDisc.class)) {
- if (!(disc.state instanceof CleanupState)) {
- return;
- }
- }
-
- state = new HoldState();
- time = System.currentTimeMillis();
- discRenderer = new DiscRenderer(this.player);
-
- setFields();
-
- if (prepare()) {
- start();
- }
- }
-
- public void setFields() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- damage = config.getDouble("Abilities.Earth.LavaDisc.Damage");
- cooldown = config.getLong("Abilities.Earth.LavaDisc.Cooldown");
- duration = config.getLong("Abilities.Earth.LavaDisc.Duration");
- recallLimit = config.getInt("Abilities.Earth.LavaDisc.RecallLimit") - 1;
- trailFlow = config.getBoolean("Abilities.Earth.LavaDisc.Destroy.TrailFlow");
-
- this.removalPolicy = new CompositeRemovalPolicy(this,
- new CannotBendRemovalPolicy(this.bPlayer, this, true, true),
- new IsOfflineRemovalPolicy(this.player),
- new IsDeadRemovalPolicy(this.player),
- new SwappedSlotsRemovalPolicy<>(bPlayer, LavaDisc.class)
- );
-
- this.removalPolicy.load(config);
- }
-
- private boolean prepare() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- long sourceRegen = config.getLong("Abilities.Earth.LavaDisc.Source.RegenTime");
- boolean lavaOnly = config.getBoolean("Abilities.Earth.LavaDisc.Source.LavaOnly");
- double sourceRange = config.getDouble("Abilities.Earth.LavaDisc.Source.Range");
-
- if (getLavaSourceBlock(player, sourceRange) != null) {
- Block block = getLavaSourceBlock(player, sourceRange);
- new RegenTempBlock(block, Material.LAVA, Material.LAVA.createBlockData(bd -> ((Levelled)bd).setLevel(4)), sourceRegen);
- return true;
- } else if (getEarthSourceBlock(sourceRange) != null) {
- if (lavaOnly)
- return false;
- Block block = getEarthSourceBlock(sourceRange);
- new RegenTempBlock(block, Material.LAVA, Material.LAVA.createBlockData(bd -> ((Levelled)bd).setLevel(4)), sourceRegen);
- return true;
- }
-
- return false;
- }
-
- @Override
- public void progress() {
- if (this.removalPolicy.shouldRemove()) {
- if (!player.isOnline()) {
- // Revert all of the lava blocks if the player goes offline.
- for (Block block : trailBlocks) {
- RegenTempBlock.revert(block);
- }
- bPlayer.addCooldown(this);
- remove();
- return;
- } else if (!(state instanceof CleanupState)) {
- state = new CleanupState();
- }
- }
-
- if (!hasAbility(player, LavaDisc.class)) {
- return;
- }
-
- state.update();
- }
-
- public static boolean canFlowFrom(Block from) {
- Material type = from.getType();
- if (type != Material.LAVA && !ElementalAbility.isAir(type)) {
- return true;
- }
-
- for (LavaDisc disc : CoreAbility.getAbilities(LavaDisc.class)) {
- if (disc.trailFlow) continue;
-
- if (disc.trailBlocks.contains(from)) {
- return false;
- }
- }
-
- return true;
- }
-
- private boolean isLocationSafe() {
- if (!isLocationSafe(location)) {
- return false;
- }
-
- Block block = location.getBlock();
-
- return isTransparent(block);
- }
-
- private boolean isLocationSafe(Location location) {
- if (location == null || location.getWorld() == null) {
- return false;
- }
-
- return location.getY() >= location.getWorld().getMinHeight() && location.getY() <= (location.getWorld().getMaxHeight() - 1);
- }
-
- private void doDamage(Entity entity) {
- DamageHandler.damageEntity(entity, damage, this);
- entity.setFireTicks(20);
- new FireDamageTimer(entity, player, this);
- ParticleEffect.LAVA.display(entity.getLocation(), 15, Math.random(), Math.random(), Math.random(), 0.1);
- }
-
- @Override
- public long getCooldown() {
- return cooldown;
- }
-
- @Override
- public Location getLocation() {
- return location;
- }
-
- @Override
- public String getName() {
- return "LavaDisc";
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return true;
- }
-
- @Override
- public String getAuthor() {
- return JedCore.dev;
- }
-
- @Override
- public String getVersion() {
- return JedCore.version;
- }
-
- @Override
- public String getDescription() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return "* JedCore Addon *\n" + config.getString("Abilities.Earth.LavaDisc.Description");
- }
-
- public void setLocation(Location location) {
- this.location = location;
- }
-
- public int getRecallCount() {
- return recallCount;
- }
-
- public void setRecallCount(int recallCount) {
- this.recallCount = recallCount;
- }
-
- public long getTime() {
- return time;
- }
-
- public void setTime(long time) {
- this.time = time;
- }
-
- public double getDamage() {
- return damage;
- }
-
- public void setDamage(double damage) {
- this.damage = damage;
- }
-
- public void setCooldown(long cooldown) {
- this.cooldown = cooldown;
- }
-
- public long getDuration() {
- return duration;
- }
-
- public void setDuration(long duration) {
- this.duration = duration;
- }
-
- public int getRecallLimit() {
- return recallLimit;
- }
-
- public void setRecallLimit(int recallLimit) {
- this.recallLimit = recallLimit;
- }
-
- public boolean isTrailFlow() {
- return trailFlow;
- }
-
- public void setTrailFlow(boolean trailFlow) {
- this.trailFlow = trailFlow;
- }
-
- public DiscRenderer getDiscRenderer() {
- return discRenderer;
- }
-
- public void setDiscRenderer(DiscRenderer discRenderer) {
- this.discRenderer = discRenderer;
- }
-
- public State getState() {
- return state;
- }
-
- public void setState(State state) {
- this.state = state;
- }
-
- public Set getTrailBlocks() {
- return trailBlocks;
- }
-
- @Override
- public void load() {}
-
- @Override
- public void stop() {}
-
- @Override
- public boolean isEnabled() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getBoolean("Abilities.Earth.LavaDisc.Enabled");
- }
-
- private interface State {
- void update();
- }
-
- // Renders the particles showing that the player is holding lava.
- // Transitions to ForwardTravelState when the player stops sneaking.
- private class HoldState implements State {
- @Override
- public void update() {
- location = player.getEyeLocation();
- Vector dV = location.getDirection().normalize();
- location.add(new Vector(dV.getX() * 3, dV.getY() * 3, dV.getZ() * 3));
-
- dV = dV.multiply(0.1);
-
- while (!isLocationSafe() && isLocationSafe(player.getLocation())) {
- location.subtract(dV);
- if (location.distanceSquared(player.getEyeLocation()) > (3 * 3)) {
- break;
- }
- }
-
- discRenderer.render(location, false);
-
- location.setPitch(0);
-
- if (!player.isSneaking()) {
- time = System.currentTimeMillis();
- state = new ForwardTravelState(location.getDirection().normalize());
- }
- }
- }
-
- private abstract class TravelState implements State {
- private final boolean passHit;
-
- protected Vector direction;
- protected boolean hasHit;
-
- public TravelState() {
- this(player.getEyeLocation().getDirection());
- }
-
- public TravelState(Vector direction) {
- this.direction = direction;
-
- ConfigurationSection config = JedCoreConfig.getConfig(player);
-
- passHit = config.getBoolean("Abilities.Earth.LavaDisc.ContinueAfterEntityHit");
- }
-
- protected void move() {
- for (int i = 0; i < 5; i++) {
- location = location.add(direction.clone().multiply(0.15));
-
- for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2.0D)) {
- if (entity instanceof LivingEntity && entity.getEntityId() != player.getEntityId()) {
- doDamage(entity);
- if (!passHit) {
- hasHit = true;
- return;
- }
- }
- }
- }
- }
- }
-
- // Moves the disc forward. Makes the disc destroy blocks if enabled.
- // Transitions to ReverseTravelState if the player starts sneaking and can recall.
- // Transitions to CleanupState if it times out or hits an entity.
- private class ForwardTravelState extends TravelState {
- public ForwardTravelState() {
- this(player.getEyeLocation().getDirection());
- }
-
- public ForwardTravelState(Vector direction) {
- super(direction);
- }
-
- @Override
- public void update() {
- if (!isLocationSafe() || System.currentTimeMillis() > time + duration) {
- state = new CleanupState();
- return;
- }
-
- if (player.isSneaking() && recallCount <= recallLimit) {
- state = new ReverseTravelState();
- return;
- }
-
- alterPitch();
- move();
- discRenderer.render(location, true);
-
- if (hasHit) {
- state = new CleanupState();
- }
- }
-
- private void alterPitch() {
- Location loc = player.getLocation().clone();
-
- if (loc.getPitch() < -20)
- loc.setPitch(-20);
- if (loc.getPitch() > 20)
- loc.setPitch(20);
-
- direction = loc.getDirection().normalize();
- }
- }
-
- // Returns the disc to the player.
- // Transitions to ForwardTravelState if the player stops sneaking.
- // Transitions to HoldState if the disc gets close enough to the player.
- private class ReverseTravelState extends TravelState {
- @Override
- public void update() {
- if (!player.isSneaking()) {
- state = new ForwardTravelState();
- return;
- }
-
- Location loc = player.getEyeLocation();
- Vector dV = loc.getDirection().normalize();
- loc.add(new Vector(dV.getX() * 3, dV.getY() * 3, dV.getZ() * 3));
-
- Vector vector = loc.toVector().subtract(location.toVector());
- direction = loc.setDirection(vector).getDirection().normalize();
-
- move();
- discRenderer.render(location, true);
-
- double distanceAway = location.distance(loc);
- if (distanceAway < 0.5) {
- recallCount++;
- // Player is holding the disc when it gets close enough to them.
- state = new HoldState();
- }
- }
- }
-
- // Waits for the RegenTempBlocks to revert.
- // This exists so the instance stays alive and block flow events can stop the lava from flowing.
- private class CleanupState implements State {
- private final long startTime;
- private final long regenTime;
-
- public CleanupState() {
- this.startTime = System.currentTimeMillis();
-
- ConfigurationSection config = JedCoreConfig.getConfig(player);
-
- regenTime = config.getLong("Abilities.Earth.LavaDisc.Destroy.RegenTime");
- bPlayer.addCooldown(LavaDisc.this);
- }
-
- @Override
- public void update() {
- if (System.currentTimeMillis() >= startTime + regenTime || trailBlocks.isEmpty()) {
- remove();
- }
- }
- }
-
- private class DiscRenderer {
- private final Player player;
- private int angle;
-
- private final boolean damageBlocks;
- private final List meltable;
- private final long regenTime;
- private final boolean lavaTrail;
-
- private final int particles;
-
-
- public DiscRenderer(Player player) {
- this.player = player;
- this.angle = 0;
-
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- damageBlocks = config.getBoolean("Abilities.Earth.LavaDisc.Destroy.BlockDamage");
- meltable = config.getStringList("Abilities.Earth.LavaDisc.Destroy.AdditionalMeltableBlocks");
- regenTime = config.getLong("Abilities.Earth.LavaDisc.Destroy.RegenTime");
- lavaTrail = config.getBoolean("Abilities.Earth.LavaDisc.Destroy.LavaTrail");
- particles = config.getInt("Abilities.Earth.LavaDisc.Particles");
- }
-
- void render(Location location, boolean largeLava) {
- if (largeLava)
- ParticleEffect.LAVA.display(location, particles * 2, Math.random(), Math.random(), Math.random(), 0.1);
- else
- ParticleEffect.LAVA.display(location, 1, Math.random(), Math.random(), Math.random(), 0.1);
-
- angle += 1;
- if (angle > 360)
- angle = 0;
-
- for (Location l : JCMethods.getCirclePoints(location, 20, 1, angle)) {
- ParticleEffect.REDSTONE.display(l, 0, 196, 93, 0, 0.005F, new Particle.DustOptions(Color.fromRGB(196, 93, 0), 1));
- if (largeLava && damageBlocks)
- damageBlocks(l);
- }
-
- for (Location l : JCMethods.getCirclePoints(location, 10, 0.5, angle)) {
- ParticleEffect.FLAME.display(l, 1, 0, 0, 0, 0.01);
- ParticleEffect.SMOKE_NORMAL.display(l, 1, 0, 0, 0, 0.05);
- if (largeLava && damageBlocks)
- damageBlocks(l);
- }
- }
-
- private void damageBlocks(Location l) {
- if (!RegionProtection.isRegionProtected(player, l, LavaDisc.this)) {
- if (!TempBlock.isTempBlock(l.getBlock()) && (isEarthbendable(player, l.getBlock()) || isMetal(l.getBlock()) || meltable.contains(l.getBlock().getType().name()))) {
- if (DensityShift.isPassiveSand(l.getBlock())) {
- DensityShift.revertSand(l.getBlock());
- }
-
- if (lavaTrail) {
- new RegenTempBlock(l.getBlock(), Material.LAVA, Material.LAVA.createBlockData(bd -> ((Levelled) bd).setLevel(4)), regenTime);
-
- trailBlocks.add(l.getBlock());
- } else {
- new RegenTempBlock(l.getBlock(), Material.AIR, Material.AIR.createBlockData(), regenTime);
- }
-
- ParticleEffect.LAVA.display(l, particles * 2, Math.random(), Math.random(), Math.random(), 0.2);
- }
- }
- }
- }
-}
+ private Location location;
+ private int recallCount;
+
+ private long time;
+
+ @Attribute(Attribute.DAMAGE)
+ private double damage;
+ @Attribute(Attribute.COOLDOWN)
+ private long cooldown;
+ @Attribute(Attribute.DURATION)
+ private long duration;
+ private int recallLimit;
+ private boolean trailFlow;
+
+ private CompositeRemovalPolicy removalPolicy;
+ private DiscRenderer discRenderer;
+ private State state;
+ private final Set trailBlocks = new HashSet<>();
+
+ public LavaDisc(Player player) {
+ super(player);
+
+ if (!bPlayer.canBend(this) || !bPlayer.canLavabend()) {
+ return;
+ }
+
+ // Allow new LavaDisc if all existing instances for that player are in CleanupState.
+ for (LavaDisc disc : CoreAbility.getAbilities(player, LavaDisc.class)) {
+ if (!(disc.state instanceof CleanupState)) {
+ return;
+ }
+ }
+
+ state = new HoldState();
+ time = System.currentTimeMillis();
+ discRenderer = new DiscRenderer(this.player);
+
+ setFields();
+
+ if (prepare()) {
+ start();
+ }
+ }
+
+ public void setFields() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ damage = config.getDouble("Abilities.Earth.LavaDisc.Damage");
+ cooldown = config.getLong("Abilities.Earth.LavaDisc.Cooldown");
+ duration = config.getLong("Abilities.Earth.LavaDisc.Duration");
+ recallLimit = config.getInt("Abilities.Earth.LavaDisc.RecallLimit") - 1;
+ trailFlow = config.getBoolean("Abilities.Earth.LavaDisc.Destroy.TrailFlow");
+
+ this.removalPolicy = new CompositeRemovalPolicy(this,
+ new CannotBendRemovalPolicy(this.bPlayer, this, true, true),
+ new IsOfflineRemovalPolicy(this.player),
+ new IsDeadRemovalPolicy(this.player),
+ new SwappedSlotsRemovalPolicy<>(bPlayer, LavaDisc.class)
+ );
+
+ this.removalPolicy.load(config);
+ }
+
+ private boolean prepare() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ long sourceRegen = config.getLong("Abilities.Earth.LavaDisc.Source.RegenTime");
+ boolean lavaOnly = config.getBoolean("Abilities.Earth.LavaDisc.Source.LavaOnly");
+ double sourceRange = config.getDouble("Abilities.Earth.LavaDisc.Source.Range");
+
+ Block lavaSource = getLavaSourceBlock(player, sourceRange);
+ if (lavaSource != null && !EarthAbility.getMovedEarth().containsKey(lavaSource)) {
+ new RegenTempBlock(lavaSource, Material.LAVA, Material.LAVA.createBlockData(bd -> ((Levelled)bd).setLevel(4)), sourceRegen);
+ return true;
+ } else {
+ Block earthSource = getEarthSourceBlock(sourceRange);
+ if (earthSource != null && !lavaOnly && !EarthAbility.getMovedEarth().containsKey(earthSource)) {
+ new RegenTempBlock(earthSource, Material.LAVA, Material.LAVA.createBlockData(bd -> ((Levelled)bd).setLevel(4)), sourceRegen);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public void progress() {
+ if (this.removalPolicy.shouldRemove()) {
+ if (!player.isOnline()) {
+ // Revert all of the lava blocks if the player goes offline.
+ for (Block block : trailBlocks) {
+ RegenTempBlock.revert(block);
+ }
+ bPlayer.addCooldown(this);
+ remove();
+ return;
+ } else if (!(state instanceof CleanupState)) {
+ state = new CleanupState();
+ }
+ }
+
+ if (!hasAbility(player, LavaDisc.class)) {
+ return;
+ }
+
+ state.update();
+ }
+
+ public static boolean canFlowFrom(Block from) {
+ Material type = from.getType();
+ if (type != Material.LAVA && !ElementalAbility.isAir(type)) {
+ return true;
+ }
+
+ for (LavaDisc disc : CoreAbility.getAbilities(LavaDisc.class)) {
+ if (disc.trailFlow) continue;
+
+ if (disc.trailBlocks.contains(from)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private boolean isLocationSafe() {
+ if (!isLocationSafe(location)) {
+ return false;
+ }
+
+ Block block = location.getBlock();
+
+ return isTransparent(block);
+ }
+
+ private boolean isLocationSafe(Location location) {
+ if (location == null || location.getWorld() == null) {
+ return false;
+ }
+
+ return location.getY() >= location.getWorld().getMinHeight() && location.getY() <= (location.getWorld().getMaxHeight() - 1);
+ }
+
+ private void doDamage(Entity entity) {
+ DamageHandler.damageEntity(entity, damage, this);
+ entity.setFireTicks(20);
+ new FireDamageTimer(entity, player, this);
+ ParticleEffect.LAVA.display(entity.getLocation(), 15, Math.random(), Math.random(), Math.random(), 0.1);
+ }
+
+ @Override
+ public long getCooldown() {
+ return cooldown;
+ }
+
+ @Override
+ public Location getLocation() {
+ return location;
+ }
+
+ @Override
+ public String getName() {
+ return "LavaDisc";
+ }
+
+ @Override
+ public boolean isHarmlessAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isSneakAbility() {
+ return true;
+ }
+
+ @Override
+ public String getAuthor() {
+ return JedCore.dev;
+ }
+
+ @Override
+ public String getVersion() {
+ return JedCore.version;
+ }
+
+ @Override
+ public String getDescription() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return "* JedCore Addon *\n" + config.getString("Abilities.Earth.LavaDisc.Description");
+ }
+
+ public void setLocation(Location location) {
+ this.location = location;
+ }
+
+ public int getRecallCount() {
+ return recallCount;
+ }
+
+ public void setRecallCount(int recallCount) {
+ this.recallCount = recallCount;
+ }
+
+ public long getTime() {
+ return time;
+ }
+
+ public void setTime(long time) {
+ this.time = time;
+ }
+
+ public double getDamage() {
+ return damage;
+ }
+
+ public void setDamage(double damage) {
+ this.damage = damage;
+ }
+
+ public void setCooldown(long cooldown) {
+ this.cooldown = cooldown;
+ }
+
+ public long getDuration() {
+ return duration;
+ }
+
+ public void setDuration(long duration) {
+ this.duration = duration;
+ }
+
+ public int getRecallLimit() {
+ return recallLimit;
+ }
+
+ public void setRecallLimit(int recallLimit) {
+ this.recallLimit = recallLimit;
+ }
+
+ public boolean isTrailFlow() {
+ return trailFlow;
+ }
+
+ public void setTrailFlow(boolean trailFlow) {
+ this.trailFlow = trailFlow;
+ }
+
+ public DiscRenderer getDiscRenderer() {
+ return discRenderer;
+ }
+
+ public void setDiscRenderer(DiscRenderer discRenderer) {
+ this.discRenderer = discRenderer;
+ }
+
+ public State getState() {
+ return state;
+ }
+
+ public void setState(State state) {
+ this.state = state;
+ }
+
+ public Set getTrailBlocks() {
+ return trailBlocks;
+ }
+
+ @Override
+ public void load() {}
+
+ @Override
+ public void stop() {}
+
+ @Override
+ public boolean isEnabled() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getBoolean("Abilities.Earth.LavaDisc.Enabled");
+ }
+
+ private interface State {
+ void update();
+ }
+
+ // Renders the particles showing that the player is holding lava.
+ // Transitions to ForwardTravelState when the player stops sneaking.
+ private class HoldState implements State {
+ @Override
+ public void update() {
+ location = player.getEyeLocation();
+ Vector dV = location.getDirection().normalize();
+ location.add(new Vector(dV.getX() * 3, dV.getY() * 3, dV.getZ() * 3));
+
+ dV = dV.multiply(0.1);
+
+ while (!isLocationSafe() && isLocationSafe(player.getLocation())) {
+ location.subtract(dV);
+ if (location.distanceSquared(player.getEyeLocation()) > (3 * 3)) {
+ break;
+ }
+ }
+
+ discRenderer.render(location, false);
+
+ location.setPitch(0);
+
+ if (!player.isSneaking()) {
+ time = System.currentTimeMillis();
+ state = new ForwardTravelState(location.getDirection().normalize());
+ }
+ }
+ }
+
+ private abstract class TravelState implements State {
+ private final boolean passHit;
+
+ protected Vector direction;
+ protected boolean hasHit;
+
+ public TravelState() {
+ this(player.getEyeLocation().getDirection());
+ }
+
+ public TravelState(Vector direction) {
+ this.direction = direction;
+
+ ConfigurationSection config = JedCoreConfig.getConfig(player);
+
+ passHit = config.getBoolean("Abilities.Earth.LavaDisc.ContinueAfterEntityHit");
+ }
+
+ protected void move() {
+ for (int i = 0; i < 5; i++) {
+ location = location.add(direction.clone().multiply(0.15));
+
+ for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2.0D)) {
+ if (entity instanceof LivingEntity && entity.getEntityId() != player.getEntityId()) {
+ doDamage(entity);
+ if (!passHit) {
+ hasHit = true;
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Moves the disc forward. Makes the disc destroy blocks if enabled.
+ // Transitions to ReverseTravelState if the player starts sneaking and can recall.
+ // Transitions to CleanupState if it times out or hits an entity.
+ private class ForwardTravelState extends TravelState {
+ public ForwardTravelState() {
+ this(player.getEyeLocation().getDirection());
+ }
+
+ public ForwardTravelState(Vector direction) {
+ super(direction);
+ }
+
+ @Override
+ public void update() {
+ if (!isLocationSafe() || System.currentTimeMillis() > time + duration) {
+ state = new CleanupState();
+ return;
+ }
+
+ if (player.isSneaking() && recallCount <= recallLimit) {
+ state = new ReverseTravelState();
+ return;
+ }
+
+ alterPitch();
+ move();
+ discRenderer.render(location, true);
+
+ if (hasHit) {
+ state = new CleanupState();
+ }
+ }
+
+ private void alterPitch() {
+ Location loc = player.getLocation().clone();
+
+ if (loc.getPitch() < -20)
+ loc.setPitch(-20);
+ if (loc.getPitch() > 20)
+ loc.setPitch(20);
+
+ direction = loc.getDirection().normalize();
+ }
+ }
+
+ // Returns the disc to the player.
+ // Transitions to ForwardTravelState if the player stops sneaking.
+ // Transitions to HoldState if the disc gets close enough to the player.
+ private class ReverseTravelState extends TravelState {
+ @Override
+ public void update() {
+ if (!player.isSneaking()) {
+ state = new ForwardTravelState();
+ return;
+ }
+
+ Location loc = player.getEyeLocation();
+ Vector dV = loc.getDirection().normalize();
+ loc.add(new Vector(dV.getX() * 3, dV.getY() * 3, dV.getZ() * 3));
+
+ Vector vector = loc.toVector().subtract(location.toVector());
+ direction = loc.setDirection(vector).getDirection().normalize();
+
+ move();
+ discRenderer.render(location, true);
+
+ double distanceAway = location.distance(loc);
+ if (distanceAway < 0.5) {
+ recallCount++;
+ // Player is holding the disc when it gets close enough to them.
+ state = new HoldState();
+ }
+ }
+ }
+
+ // Waits for the RegenTempBlocks to revert.
+ // This exists so the instance stays alive and block flow events can stop the lava from flowing.
+ private class CleanupState implements State {
+ private final long startTime;
+ private final long regenTime;
+
+ public CleanupState() {
+ this.startTime = System.currentTimeMillis();
+
+ ConfigurationSection config = JedCoreConfig.getConfig(player);
+
+ regenTime = config.getLong("Abilities.Earth.LavaDisc.Destroy.RegenTime");
+ bPlayer.addCooldown(LavaDisc.this);
+ }
+
+ @Override
+ public void update() {
+ if (System.currentTimeMillis() >= startTime + regenTime || trailBlocks.isEmpty()) {
+ remove();
+ }
+ }
+ }
+
+ private class DiscRenderer {
+ private final Player player;
+ private int angle;
+
+ private final boolean damageBlocks;
+ private final List meltable;
+ private final long regenTime;
+ private final boolean lavaTrail;
+
+ private final int particles;
+
+
+ public DiscRenderer(Player player) {
+ this.player = player;
+ this.angle = 0;
+
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ damageBlocks = config.getBoolean("Abilities.Earth.LavaDisc.Destroy.BlockDamage");
+ meltable = config.getStringList("Abilities.Earth.LavaDisc.Destroy.AdditionalMeltableBlocks");
+ regenTime = config.getLong("Abilities.Earth.LavaDisc.Destroy.RegenTime");
+ lavaTrail = config.getBoolean("Abilities.Earth.LavaDisc.Destroy.LavaTrail");
+ particles = config.getInt("Abilities.Earth.LavaDisc.Particles");
+ }
+
+ void render(Location location, boolean largeLava) {
+ if (largeLava)
+ ParticleEffect.LAVA.display(location, particles * 2, Math.random(), Math.random(), Math.random(), 0.1);
+ else
+ ParticleEffect.LAVA.display(location, 1, Math.random(), Math.random(), Math.random(), 0.1);
+
+ angle += 1;
+ if (angle > 360)
+ angle = 0;
+
+ for (Location l : JCMethods.getCirclePoints(location, 20, 1, angle)) {
+ ParticleEffect.REDSTONE.display(l, 0, 196, 93, 0, 0.005F, new Particle.DustOptions(Color.fromRGB(196, 93, 0), 1));
+ if (largeLava && damageBlocks)
+ damageBlocks(l);
+ }
+
+ for (Location l : JCMethods.getCirclePoints(location, 10, 0.5, angle)) {
+ ParticleEffect.FLAME.display(l, 1, 0, 0, 0, 0.01);
+ ParticleEffect.SMOKE_NORMAL.display(l, 1, 0, 0, 0, 0.05);
+ if (largeLava && damageBlocks)
+ damageBlocks(l);
+ }
+ }
+
+ private void damageBlocks(Location l) {
+ Block block = l.getBlock();
+ if (EarthAbility.getMovedEarth().containsKey(block)) {
+ ParticleEffect.LAVA.display(l, 20, 0.5, 0.5, 0.5, 0.2);
+ ParticleEffect.BLOCK_CRACK.display(l, 15, 0.3, 0.3, 0.3, 0.15, Material.LAVA.createBlockData());
+ return;
+ }
+ if (!RegionProtection.isRegionProtected(player, l, LavaDisc.this)) {
+ if (!TempBlock.isTempBlock(block) && (isEarthbendable(player, block) || isMetal(block) || meltable.contains(block.getType().name()))) {
+ if (DensityShift.isPassiveSand(block)) {
+ DensityShift.revertSand(block);
+ }
+
+ if (lavaTrail) {
+ new RegenTempBlock(block, Material.LAVA, Material.LAVA.createBlockData(bd -> ((Levelled) bd).setLevel(4)), regenTime);
+
+ trailBlocks.add(block);
+ } else {
+ new RegenTempBlock(block, Material.AIR, Material.AIR.createBlockData(), regenTime);
+ }
+
+ ParticleEffect.LAVA.display(l, particles * 2, Math.random(), Math.random(), Math.random(), 0.2);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/com/jedk1/jedcore/ability/earthbending/LavaFlux.java b/src/com/jedk1/jedcore/ability/earthbending/LavaFlux.java
index 6368fbf..4b836e2 100644
--- a/src/com/jedk1/jedcore/ability/earthbending/LavaFlux.java
+++ b/src/com/jedk1/jedcore/ability/earthbending/LavaFlux.java
@@ -1,16 +1,17 @@
package com.jedk1.jedcore.ability.earthbending;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-
+import com.jedk1.jedcore.JedCore;
import com.jedk1.jedcore.configuration.JedCoreConfig;
+import com.projectkorra.projectkorra.GeneralMethods;
+import com.projectkorra.projectkorra.ability.AddonAbility;
import com.projectkorra.projectkorra.ability.EarthAbility;
+import com.projectkorra.projectkorra.ability.LavaAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
+import com.projectkorra.projectkorra.firebending.util.FireDamageTimer;
import com.projectkorra.projectkorra.region.RegionProtection;
+import com.projectkorra.projectkorra.util.DamageHandler;
import com.projectkorra.projectkorra.util.Information;
+import com.projectkorra.projectkorra.util.ParticleEffect;
import com.projectkorra.projectkorra.util.TempBlock;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -26,426 +27,419 @@
import org.bukkit.util.BlockIterator;
import org.bukkit.util.Vector;
-import com.jedk1.jedcore.JedCore;
-import com.jedk1.jedcore.util.RegenTempBlock;
-import com.projectkorra.projectkorra.GeneralMethods;
-import com.projectkorra.projectkorra.ability.AddonAbility;
-import com.projectkorra.projectkorra.ability.LavaAbility;
-import com.projectkorra.projectkorra.firebending.util.FireDamageTimer;
-import com.projectkorra.projectkorra.util.DamageHandler;
-import com.projectkorra.projectkorra.util.ParticleEffect;
+import java.util.*;
public class LavaFlux extends LavaAbility implements AddonAbility {
- @Attribute(Attribute.SPEED)
- private int speed;
- @Attribute(Attribute.RANGE)
- private int range;
- @Attribute(Attribute.COOLDOWN)
- private long cooldown;
- @Attribute(Attribute.DURATION)
- private long duration;
- private long cleanup;
- @Attribute(Attribute.DAMAGE)
- private double damage;
- private boolean wave;
-
- private Location location;
- private int step;
- private int counter;
- private long time;
- private boolean complete;
-
- private double knockUp;
- private double knockBack;
-
- Random rand = new Random();
-
- private static final BlockData LAVA = Material.LAVA.createBlockData(bd -> ((Levelled)bd).setLevel(1));
-
- private final List flux = new ArrayList<>();
-
- private Map blocks = new HashMap<>();
- private Map above = new HashMap<>();
-
- public LavaFlux(Player player) {
- super(player);
-
- if (!bPlayer.canBend(this) || !bPlayer.canLavabend()) {
- return;
- }
-
- setFields();
- time = System.currentTimeMillis();
- if (prepareLine()) {
- start();
- if (!isRemoved()) {
- bPlayer.addCooldown(this);
- }
- }
- }
-
- public void setFields() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- speed = config.getInt("Abilities.Earth.LavaFlux.Speed");
- if (speed < 1) speed = 1;
- range = config.getInt("Abilities.Earth.LavaFlux.Range");
- cooldown = config.getLong("Abilities.Earth.LavaFlux.Cooldown");
- duration = config.getLong("Abilities.Earth.LavaFlux.Duration");
- cleanup = config.getLong("Abilities.Earth.LavaFlux.Cleanup");
- damage = config.getDouble("Abilities.Earth.LavaFlux.Damage");
- wave = config.getBoolean("Abilities.Earth.LavaFlux.Wave");
- knockUp = config.getDouble("Abilities.Earth.LavaFlux.KnockUp");
- knockBack = config.getDouble("Abilities.Earth.LavaFlux.KnockBack");
- }
-
- @Override
- public void progress() {
- if (player == null || !player.isOnline()) {
- remove();
- return;
- }
- if (!bPlayer.canBendIgnoreCooldowns(this)) {
- remove();
- return;
- }
- counter++;
- if (!complete) {
- if (speed <= 1 || counter % speed == 0) {
- for (int i = 0; i <= 2; i++) {
- step++;
- progressFlux();
- }
- }
- } else if (duration > cleanup) {
- if (System.currentTimeMillis() > time + duration) {
- for (TempBlock tb : blocks.values()) {
- if (!tb.isReverted()) tb.setType(Material.STONE);
- }
- remove();
- }
- }
- }
-
- private boolean prepareLine() {
- Vector direction = player.getEyeLocation().getDirection().setY(0).normalize();
- Vector blockdirection = direction.clone().setX(Math.round(direction.getX()));
- blockdirection = blockdirection.setZ(Math.round(direction.getZ()));
- Location origin = player.getLocation().add(0, -1, 0).add(blockdirection.multiply(2));
- if (isEarthbendable(player, origin.getBlock())) {
- BlockIterator bi = new BlockIterator(player.getWorld(), origin.toVector(), direction, 0, range);
-
- while (bi.hasNext()) {
- Block b = bi.next();
-
- if (b.getY() > b.getWorld().getMinHeight() && b.getY() < b.getWorld().getMaxHeight() && !RegionProtection.isRegionProtected(this, b.getLocation()) && !EarthAbility.getMovedEarth().containsKey(b)) {
- if (isWater(b)) break;
- while (!isEarthbendable(player, b)) {
- b = b.getRelative(BlockFace.DOWN);
- if (b.getY() < b.getWorld().getMinHeight() || b.getY() > b.getWorld().getMaxHeight()) {
- break;
- }
- if (isEarthbendable(player, b)) {
- break;
- }
- }
-
- while (!isTransparent(b.getRelative(BlockFace.UP))) {
- b = b.getRelative(BlockFace.UP);
- if (b.getY() < b.getWorld().getMinHeight() || b.getY() > b.getWorld().getMaxHeight()) {
- break;
- }
- if (isEarthbendable(player, b.getRelative(BlockFace.UP))) {
- break;
- }
- }
-
- if (isEarthbendable(player, b)) {
- flux.add(b.getLocation());
- Block left = b.getRelative(getLeftBlockFace(GeneralMethods.getCardinalDirection(blockdirection)), 1);
- expand(left);
- Block right = b.getRelative(getLeftBlockFace(GeneralMethods.getCardinalDirection(blockdirection)).getOppositeFace(), 1);
- expand(right);
- } else {
- break;
- }
- }
- }
- return true;
- }
- return false;
- }
-
- private void progressFlux() {
- for (Location location : flux) {
- if (flux.indexOf(location) <= step) {
- if (!blocks.containsKey(location.getBlock())) { //Make a new temp block if we haven't made one there before
- blocks.put(location.getBlock(), new TempBlock(location.getBlock(), LAVA, duration + cleanup, this));
- }
-
- //new RegenTempBlock(location.getBlock(), Material.LAVA, LAVA, duration + cleanup);
- this.location = location;
- if (flux.indexOf(location) == step) {
- Block above = location.getBlock().getRelative(BlockFace.UP);
- ParticleEffect.LAVA.display(above.getLocation(), 2, Math.random(), Math.random(), Math.random(), 0);
- applyDamageFromWave(above.getLocation());
-
- if (isPlant(above) || isSnow(above)) {
- final Block above2 = above.getRelative(BlockFace.UP);
- if (isPlant(above) || isSnow(above)) {
- TempBlock tb = new TempBlock(above, Material.AIR.createBlockData(), duration + cleanup, this);
- this.above.put(above, tb);
- if (isPlant(above2) && above2.getBlockData() instanceof Bisected) {
- TempBlock tb2 = new TempBlock(above2, Material.AIR.createBlockData(), duration + cleanup + 30_000, this);
- tb.addAttachedBlock(tb2);
- }
- }
- } else if (wave && isTransparent(above)) {
- new TempBlock(location.getBlock().getRelative(BlockFace.UP), LAVA, speed * 150L, this);
- }
- }
- }
- }
- if (step >= flux.size()) {
- wave = false;
- complete = true;
- time = System.currentTimeMillis();
-
- for (TempBlock tb : blocks.values()) { //Make sure they all revert at the same time because it looks nice
- long time = duration + cleanup + rand.nextInt(1000);
- tb.setRevertTime(time);
-
- if (this.above.containsKey(tb.getBlock().getRelative(BlockFace.UP))) {
- this.above.get(tb.getBlock().getRelative(BlockFace.UP)).setRevertTime(time);
- }
- }
- }
- }
-
- private void applyDamageFromWave(Location location) {
- for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 1.5)) {
- if (entity instanceof LivingEntity && entity.getEntityId() != player.getEntityId()) {
- LivingEntity livingEntity = (LivingEntity) entity;
-
- DamageHandler.damageEntity(entity, damage, this);
- new FireDamageTimer(entity, player, this);
-
- Vector direction = livingEntity.getLocation().toVector().subtract(player.getLocation().toVector()).normalize();
- Vector knockbackVelocity = direction.multiply(knockBack).setY(knockUp);
-
- livingEntity.setVelocity(knockbackVelocity);
- }
- }
- }
-
- private void expand(Block block) {
- if (block != null && block.getY() > block.getWorld().getMinHeight() && block.getY() < block.getWorld().getMaxHeight() && !RegionProtection.isRegionProtected(this, block.getLocation())) {
- if (EarthAbility.getMovedEarth().containsKey(block)){
- Information info = EarthAbility.getMovedEarth().get(block);
- if(!info.getBlock().equals(block)) {
- return;
- }
- }
-
- if (isWater(block)) return;
- while (!isEarthbendable(block)) {
- block = block.getRelative(BlockFace.DOWN);
- if (block.getY() < block.getWorld().getMinHeight() || block.getY() > block.getWorld().getMaxHeight()) {
- break;
- }
- if (isEarthbendable(block)) {
- break;
- }
- }
-
- while (!isTransparent(block.getRelative(BlockFace.UP))) {
- block = block.getRelative(BlockFace.UP);
- if (block.getY() < block.getWorld().getMinHeight() || block.getY() > block.getWorld().getMaxHeight()) {
- break;
- }
- if (isEarthbendable(block.getRelative(BlockFace.UP))) {
- break;
- }
- }
-
- if (isEarthbendable(block)) {
- flux.add(block.getLocation());
- }
- }
- }
-
- public BlockFace getLeftBlockFace(BlockFace forward) {
- switch (forward) {
- case NORTH:
- return BlockFace.WEST;
- case SOUTH:
- return BlockFace.EAST;
- case WEST:
- return BlockFace.SOUTH;
- case NORTH_WEST:
- return BlockFace.SOUTH_WEST;
- case NORTH_EAST:
- return BlockFace.NORTH_WEST;
- case SOUTH_WEST:
- return BlockFace.SOUTH_EAST;
- case SOUTH_EAST:
- return BlockFace.NORTH_EAST;
- default:
- return BlockFace.NORTH;
- }
- }
-
- @Override
- public long getCooldown() {
- return cooldown;
- }
-
- @Override
- public Location getLocation() {
- return location;
- }
-
- @Override
- public String getName() {
- return "LavaFlux";
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return true;
- }
-
- @Override
- public String getAuthor() {
- return JedCore.dev;
- }
-
- @Override
- public String getVersion() {
- return JedCore.version;
- }
-
- @Override
- public String getDescription() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return "* JedCore Addon *\n" + config.getString("Abilities.Earth.LavaFlux.Description");
- }
-
- public int getSpeed() {
- return speed;
- }
-
- public void setSpeed(int speed) {
- this.speed = speed;
- }
-
- public int getRange() {
- return range;
- }
-
- public void setRange(int range) {
- this.range = range;
- }
-
- public void setCooldown(long cooldown) {
- this.cooldown = cooldown;
- }
-
- public long getDuration() {
- return duration;
- }
-
- public void setDuration(long duration) {
- this.duration = duration;
- }
-
- public long getCleanup() {
- return cleanup;
- }
-
- public void setCleanup(long cleanup) {
- this.cleanup = cleanup;
- }
-
- public double getDamage() {
- return damage;
- }
-
- public void setDamage(double damage) {
- this.damage = damage;
- }
-
- public boolean isWave() {
- return wave;
- }
-
- public void setWave(boolean wave) {
- this.wave = wave;
- }
-
- public void setLocation(Location location) {
- this.location = location;
- }
-
- public int getStep() {
- return step;
- }
-
- public void setStep(int step) {
- this.step = step;
- }
-
- public int getCounter() {
- return counter;
- }
-
- public void setCounter(int counter) {
- this.counter = counter;
- }
-
- public long getTime() {
- return time;
- }
-
- public void setTime(long time) {
- this.time = time;
- }
-
- public boolean isComplete() {
- return complete;
- }
-
- public void setComplete(boolean complete) {
- this.complete = complete;
- }
-
- public List getFlux() {
- return flux;
- }
-
- @Override
- public void load() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- if (config.get("Abilities.Earth.LavaFlux.Speed") instanceof String) {
- config.set("Abilities.Earth.LavaFlux.Speed", 1);
- JedCore.plugin.saveConfig();
- JedCore.plugin.reloadConfig();
- }
- }
-
- @Override
- public void stop() {}
-
- @Override
- public boolean isEnabled() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getBoolean("Abilities.Earth.LavaFlux.Enabled");
- }
+ @Attribute(Attribute.SPEED)
+ private int speed;
+ @Attribute(Attribute.RANGE)
+ private int range;
+ @Attribute(Attribute.COOLDOWN)
+ private long cooldown;
+ @Attribute(Attribute.DURATION)
+ private long duration;
+ private long cleanup;
+ @Attribute(Attribute.DAMAGE)
+ private double damage;
+ private boolean wave;
+
+ private Location location;
+ private int step;
+ private int counter;
+ private long time;
+ private boolean complete;
+
+ private double knockUp;
+ private double knockBack;
+
+ Random rand = new Random();
+
+ private static final BlockData LAVA = Material.LAVA.createBlockData(bd -> ((Levelled)bd).setLevel(1));
+
+ private final List flux = new ArrayList<>();
+
+ private Map blocks = new HashMap<>();
+ private Map above = new HashMap<>();
+
+ public LavaFlux(Player player) {
+ super(player);
+
+ if (!bPlayer.canBend(this) || !bPlayer.canLavabend()) {
+ return;
+ }
+
+ setFields();
+ time = System.currentTimeMillis();
+ if (prepareLine()) {
+ start();
+ if (!isRemoved()) {
+ bPlayer.addCooldown(this);
+ }
+ }
+ }
+
+ public void setFields() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ speed = config.getInt("Abilities.Earth.LavaFlux.Speed");
+ if (speed < 1) speed = 1;
+ range = config.getInt("Abilities.Earth.LavaFlux.Range");
+ cooldown = config.getLong("Abilities.Earth.LavaFlux.Cooldown");
+ duration = config.getLong("Abilities.Earth.LavaFlux.Duration");
+ cleanup = config.getLong("Abilities.Earth.LavaFlux.Cleanup");
+ damage = config.getDouble("Abilities.Earth.LavaFlux.Damage");
+ wave = config.getBoolean("Abilities.Earth.LavaFlux.Wave");
+ knockUp = config.getDouble("Abilities.Earth.LavaFlux.KnockUp");
+ knockBack = config.getDouble("Abilities.Earth.LavaFlux.KnockBack");
+ }
+
+ @Override
+ public void progress() {
+ if (player == null || !player.isOnline()) {
+ remove();
+ return;
+ }
+ if (!bPlayer.canBendIgnoreCooldowns(this)) {
+ remove();
+ return;
+ }
+ counter++;
+ if (!complete) {
+ if (speed <= 1 || counter % speed == 0) {
+ for (int i = 0; i <= 2; i++) {
+ step++;
+ progressFlux();
+ }
+ }
+ } else if (duration > cleanup) {
+ if (System.currentTimeMillis() > time + duration) {
+ for (TempBlock tb : blocks.values()) {
+ if (!tb.isReverted()) tb.setType(Material.STONE);
+ }
+ remove();
+ }
+ }
+ }
+
+ private boolean prepareLine() {
+ Vector direction = player.getEyeLocation().getDirection().setY(0).normalize();
+ Vector blockdirection = direction.clone().setX(Math.round(direction.getX()));
+ blockdirection = blockdirection.setZ(Math.round(direction.getZ()));
+ Location origin = player.getLocation().add(0, -1, 0).add(blockdirection.multiply(2));
+ if (isEarthbendable(player, origin.getBlock())) {
+ BlockIterator bi = new BlockIterator(player.getWorld(), origin.toVector(), direction, 0, range);
+
+ while (bi.hasNext()) {
+ Block b = bi.next();
+
+ if (b.getY() > b.getWorld().getMinHeight() && b.getY() < b.getWorld().getMaxHeight() && !RegionProtection.isRegionProtected(this, b.getLocation()) && !EarthAbility.getMovedEarth().containsKey(b)) {
+ if (isWater(b)) break;
+ while (!isEarthbendable(player, b)) {
+ b = b.getRelative(BlockFace.DOWN);
+ if (b.getY() < b.getWorld().getMinHeight() || b.getY() > b.getWorld().getMaxHeight()) {
+ break;
+ }
+ if (isEarthbendable(player, b)) {
+ break;
+ }
+ }
+
+ while (!isTransparent(b.getRelative(BlockFace.UP))) {
+ b = b.getRelative(BlockFace.UP);
+ if (b.getY() < b.getWorld().getMinHeight() || b.getY() > b.getWorld().getMaxHeight()) {
+ break;
+ }
+ if (isEarthbendable(player, b.getRelative(BlockFace.UP))) {
+ break;
+ }
+ }
+
+ if (isEarthbendable(player, b)) {
+ flux.add(b.getLocation());
+ Block left = b.getRelative(getLeftBlockFace(GeneralMethods.getCardinalDirection(blockdirection)), 1);
+ expand(left);
+ Block right = b.getRelative(getLeftBlockFace(GeneralMethods.getCardinalDirection(blockdirection)).getOppositeFace(), 1);
+ expand(right);
+ } else {
+ break;
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private void progressFlux() {
+ for (Location location : flux) {
+ if (flux.indexOf(location) <= step) {
+ if (!blocks.containsKey(location.getBlock())) { //Make a new temp block if we haven't made one there before
+ blocks.put(location.getBlock(), new TempBlock(location.getBlock(), LAVA, duration + cleanup, this));
+ }
+
+ //new RegenTempBlock(location.getBlock(), Material.LAVA, LAVA, duration + cleanup);
+ this.location = location;
+ if (flux.indexOf(location) == step) {
+ Block above = location.getBlock().getRelative(BlockFace.UP);
+ ParticleEffect.LAVA.display(above.getLocation(), 2, Math.random(), Math.random(), Math.random(), 0);
+ applyDamageFromWave(above.getLocation());
+
+ if (isPlant(above) || isSnow(above)) {
+ final Block above2 = above.getRelative(BlockFace.UP);
+ if (isPlant(above) || isSnow(above)) {
+ TempBlock tb = new TempBlock(above, Material.AIR.createBlockData(), duration + cleanup, this);
+ this.above.put(above, tb);
+ if (isPlant(above2) && above2.getBlockData() instanceof Bisected) {
+ TempBlock tb2 = new TempBlock(above2, Material.AIR.createBlockData(), duration + cleanup + 30_000, this);
+ tb.addAttachedBlock(tb2);
+ }
+ }
+ } else if (wave && isTransparent(above)) {
+ new TempBlock(location.getBlock().getRelative(BlockFace.UP), LAVA, speed * 150L, this);
+ }
+ }
+ }
+ }
+ if (step >= flux.size()) {
+ wave = false;
+ complete = true;
+ time = System.currentTimeMillis();
+
+ for (TempBlock tb : blocks.values()) { //Make sure they all revert at the same time because it looks nice
+ long time = duration + cleanup + rand.nextInt(1000);
+ tb.setRevertTime(time);
+
+ if (this.above.containsKey(tb.getBlock().getRelative(BlockFace.UP))) {
+ this.above.get(tb.getBlock().getRelative(BlockFace.UP)).setRevertTime(time);
+ }
+ }
+ }
+ }
+
+ private void applyDamageFromWave(Location location) {
+ for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 1.5)) {
+ if (entity instanceof LivingEntity && entity.getEntityId() != player.getEntityId()) {
+ LivingEntity livingEntity = (LivingEntity) entity;
+
+ DamageHandler.damageEntity(entity, damage, this);
+ new FireDamageTimer(entity, player, this);
+
+ Vector direction = livingEntity.getLocation().toVector().subtract(player.getLocation().toVector()).normalize();
+ Vector knockbackVelocity = direction.multiply(knockBack).setY(knockUp);
+
+ livingEntity.setVelocity(knockbackVelocity);
+ }
+ }
+ }
+
+ private void expand(Block block) {
+ if (block != null && block.getY() > block.getWorld().getMinHeight() && block.getY() < block.getWorld().getMaxHeight() && !RegionProtection.isRegionProtected(this, block.getLocation())) {
+ if (EarthAbility.getMovedEarth().containsKey(block)){
+ Information info = EarthAbility.getMovedEarth().get(block);
+ if(!info.getBlock().equals(block)) {
+ return;
+ }
+ }
+
+ if (isWater(block)) return;
+ while (!isEarthbendable(block)) {
+ block = block.getRelative(BlockFace.DOWN);
+ if (block.getY() < block.getWorld().getMinHeight() || block.getY() > block.getWorld().getMaxHeight()) {
+ break;
+ }
+ if (isEarthbendable(block)) {
+ break;
+ }
+ }
+
+ while (!isTransparent(block.getRelative(BlockFace.UP))) {
+ block = block.getRelative(BlockFace.UP);
+ if (block.getY() < block.getWorld().getMinHeight() || block.getY() > block.getWorld().getMaxHeight()) {
+ break;
+ }
+ if (isEarthbendable(block.getRelative(BlockFace.UP))) {
+ break;
+ }
+ }
+
+ if (isEarthbendable(block)) {
+ flux.add(block.getLocation());
+ }
+ }
+ }
+
+ public BlockFace getLeftBlockFace(BlockFace forward) {
+ switch (forward) {
+ case NORTH:
+ return BlockFace.WEST;
+ case SOUTH:
+ return BlockFace.EAST;
+ case WEST:
+ return BlockFace.SOUTH;
+ case NORTH_WEST:
+ return BlockFace.SOUTH_WEST;
+ case NORTH_EAST:
+ return BlockFace.NORTH_WEST;
+ case SOUTH_WEST:
+ return BlockFace.SOUTH_EAST;
+ case SOUTH_EAST:
+ return BlockFace.NORTH_EAST;
+ default:
+ return BlockFace.NORTH;
+ }
+ }
+
+ @Override
+ public long getCooldown() {
+ return cooldown;
+ }
+
+ @Override
+ public Location getLocation() {
+ return location;
+ }
+
+ @Override
+ public String getName() {
+ return "LavaFlux";
+ }
+
+ @Override
+ public boolean isHarmlessAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isSneakAbility() {
+ return true;
+ }
+
+ @Override
+ public String getAuthor() {
+ return JedCore.dev;
+ }
+
+ @Override
+ public String getVersion() {
+ return JedCore.version;
+ }
+
+ @Override
+ public String getDescription() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return "* JedCore Addon *\n" + config.getString("Abilities.Earth.LavaFlux.Description");
+ }
+
+ public int getSpeed() {
+ return speed;
+ }
+
+ public void setSpeed(int speed) {
+ this.speed = speed;
+ }
+
+ public int getRange() {
+ return range;
+ }
+
+ public void setRange(int range) {
+ this.range = range;
+ }
+
+ public void setCooldown(long cooldown) {
+ this.cooldown = cooldown;
+ }
+
+ public long getDuration() {
+ return duration;
+ }
+
+ public void setDuration(long duration) {
+ this.duration = duration;
+ }
+
+ public long getCleanup() {
+ return cleanup;
+ }
+
+ public void setCleanup(long cleanup) {
+ this.cleanup = cleanup;
+ }
+
+ public double getDamage() {
+ return damage;
+ }
+
+ public void setDamage(double damage) {
+ this.damage = damage;
+ }
+
+ public boolean isWave() {
+ return wave;
+ }
+
+ public void setWave(boolean wave) {
+ this.wave = wave;
+ }
+
+ public void setLocation(Location location) {
+ this.location = location;
+ }
+
+ public int getStep() {
+ return step;
+ }
+
+ public void setStep(int step) {
+ this.step = step;
+ }
+
+ public int getCounter() {
+ return counter;
+ }
+
+ public void setCounter(int counter) {
+ this.counter = counter;
+ }
+
+ public long getTime() {
+ return time;
+ }
+
+ public void setTime(long time) {
+ this.time = time;
+ }
+
+ public boolean isComplete() {
+ return complete;
+ }
+
+ public void setComplete(boolean complete) {
+ this.complete = complete;
+ }
+
+ public List getFlux() {
+ return flux;
+ }
+
+ @Override
+ public void load() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ if (config.get("Abilities.Earth.LavaFlux.Speed") instanceof String) {
+ config.set("Abilities.Earth.LavaFlux.Speed", 1);
+ JedCore.plugin.saveConfig();
+ JedCore.plugin.reloadConfig();
+ }
+ }
+
+ @Override
+ public void stop() {}
+
+ @Override
+ public boolean isEnabled() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getBoolean("Abilities.Earth.LavaFlux.Enabled");
+ }
}
\ No newline at end of file
diff --git a/src/com/jedk1/jedcore/ability/earthbending/LavaThrow.java b/src/com/jedk1/jedcore/ability/earthbending/LavaThrow.java
index 4fac307..2f3aab8 100644
--- a/src/com/jedk1/jedcore/ability/earthbending/LavaThrow.java
+++ b/src/com/jedk1/jedcore/ability/earthbending/LavaThrow.java
@@ -5,15 +5,15 @@
import com.jedk1.jedcore.util.RegenTempBlock;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AddonAbility;
+import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.LavaAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.region.RegionProtection;
import com.projectkorra.projectkorra.util.DamageHandler;
import com.projectkorra.projectkorra.util.ParticleEffect;
-
-import org.bukkit.Location;
-import org.bukkit.Material;
+import com.projectkorra.projectkorra.util.TempBlock;
+import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.Levelled;
@@ -21,328 +21,320 @@
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
+import org.bukkit.util.RayTraceResult;
import org.bukkit.util.Vector;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
public class LavaThrow extends LavaAbility implements AddonAbility {
- @Attribute(Attribute.COOLDOWN)
- private long cooldown;
- @Attribute(Attribute.RANGE)
- private int range;
- @Attribute(Attribute.DAMAGE)
- private double damage;
- @Attribute(Attribute.SELECT_RANGE)
- private int sourceRange;
- private long sourceRegen;
- @Attribute("MaxShots")
- private int shotMax;
- @Attribute(Attribute.FIRE_TICK)
- private int fireTicks;
-
- private Location location;
- private int shots;
-
- private final ConcurrentHashMap blasts = new ConcurrentHashMap<>();
-
- public LavaThrow(Player player) {
- super(player);
-
- if (hasAbility(player, LavaThrow.class)) {
- LavaThrow.createBlast(player);
- return;
- }
-
- if (!bPlayer.canBend(this) || !bPlayer.canLavabend()) {
- return;
- }
-
- setFields();
-
- location = player.getLocation();
- location.setPitch(0);
- location = location.toVector().add(location.getDirection().multiply(sourceRange)).toLocation(location.getWorld());
-
- sourceRange = Math.round(sourceRange / 2F);
-
- if (prepare()) {
- start();
- if (!isRemoved()) {
- createBlast();
- }
- }
- }
-
- public void setFields() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- cooldown = config.getLong("Abilities.Earth.LavaThrow.Cooldown");
- range = config.getInt("Abilities.Earth.LavaThrow.Range");
- damage = config.getDouble("Abilities.Earth.LavaThrow.Damage");
- sourceRange = config.getInt("Abilities.Earth.LavaThrow.SourceGrabRange");
- sourceRegen = config.getLong("Abilities.Earth.LavaThrow.SourceRegenDelay");
- shotMax = config.getInt("Abilities.Earth.LavaThrow.MaxShots");
- fireTicks = config.getInt("Abilities.Earth.LavaThrow.FireTicks");
- }
-
- @Override
- public void progress() {
- if (player == null || player.isDead() || !player.isOnline()) {
- remove();
- return;
- }
-
- if (player.getWorld() != location.getWorld()) {
- bPlayer.addCooldown(this);
- remove();
- return;
- }
-
- if (!bPlayer.canBendIgnoreCooldowns(this)) {
- bPlayer.addCooldown(this);
- remove();
- return;
- }
-
- if (shots >= shotMax) {
- bPlayer.addCooldown(this);
- }
-
- handleBlasts();
-
- if (blasts.isEmpty()) {
- bPlayer.addCooldown(this);
- remove();
- }
- }
-
- private boolean prepare() {
- Block block = getRandomSourceBlock(location, 3);
-
- return block != null;
- }
-
- public void createBlast() {
- // TODO: This is just the worst. Fix it so it's not hidden distance selection.
- Block source = getRandomSourceBlock(location, 3);
-
- if (source != null) {
- shots++;
-
- Location origin = source.getLocation().clone().add(0, 2, 0);
- double viewRange = range + origin.distance(player.getEyeLocation());
- Location viewTarget = GeneralMethods.getTargetedLocation(player, viewRange, Material.WATER, Material.LAVA);
- Vector direction = viewTarget.clone().subtract(origin).toVector().normalize();
- Location head = origin.clone();
-
- head.setDirection(direction);
- blasts.put(head, origin);
-
- new RegenTempBlock(source.getRelative(BlockFace.UP), Material.LAVA, Material.LAVA.createBlockData(bd -> ((Levelled)bd).setLevel(0)), 200);
- new RegenTempBlock(source, Material.AIR, Material.AIR.createBlockData(), sourceRegen, false);
- }
- }
-
- public void handleBlasts() {
- for (Location l : blasts.keySet()) {
- Location head = l.clone();
- Location origin = blasts.get(l);
-
- if (l.distance(origin) > range) {
- blasts.remove(l);
- continue;
- }
-
- if(RegionProtection.isRegionProtected(this, l)){
- blasts.remove(l);
- continue;
- }
-
- if(GeneralMethods.isSolid(l.getBlock())){
- blasts.remove(l);
- continue;
- }
-
- head = head.add(head.getDirection().multiply(1));
- new RegenTempBlock(l.getBlock(), Material.LAVA, Material.LAVA.createBlockData(bd -> ((Levelled)bd).setLevel(0)), 200);
- ParticleEffect.LAVA.display(head, 1, Math.random(), Math.random(), Math.random(), 0);
-
- boolean hit = false;
-
- for(Entity entity : GeneralMethods.getEntitiesAroundPoint(l, 2.0D)){
- if(entity instanceof LivingEntity && entity.getEntityId() != player.getEntityId() && !RegionProtection.isRegionProtected(this, entity.getLocation()) && !((entity instanceof Player) && Commands.invincible.contains(((Player) entity).getName()))){
- DamageHandler.damageEntity(entity, damage, this);
- blasts.remove(l);
-
- hit = true;
- entity.setFireTicks(this.fireTicks);
- }
- }
-
- if (!hit) {
- blasts.remove(l);
- blasts.put(head, origin);
- }
- }
- }
-
- public static Block getRandomSourceBlock(Location location, int radius) {
- Random rand = new Random();
- List checked = new ArrayList<>();
- List blocks = GeneralMethods.getBlocksAroundPoint(location, radius);
-
- for (int i = 0; i < blocks.size(); i++) {
- int index = rand.nextInt(blocks.size());
-
- while (checked.contains(index)) {
- index = rand.nextInt(blocks.size());
- }
-
- checked.add(index);
-
- Block block = blocks.get(index);
-
- if (!LavaAbility.isLava(block)) {
- continue;
- }
-
- return block;
- }
-
- return null;
- }
-
- public static void createBlast(Player player) {
- if (hasAbility(player, LavaThrow.class)) {
- LavaThrow lt = getAbility(player, LavaThrow.class);
-
- if (lt.shots < lt.shotMax) {
- lt.createBlast();
- }
- }
- }
-
- @Override
- public long getCooldown() {
- return cooldown;
- }
-
- @Override
- public Location getLocation() {
- return location;
- }
-
- @Override
- public String getName() {
- return "LavaThrow";
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return true;
- }
-
- @Override
- public String getAuthor() {
- return JedCore.dev;
- }
-
- @Override
- public String getVersion() {
- return JedCore.version;
- }
-
- @Override
- public String getDescription() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return "* JedCore Addon *\n" + config.getString("Abilities.Earth.LavaThrow.Description");
- }
-
- public void setCooldown(long cooldown) {
- this.cooldown = cooldown;
- }
-
- public int getRange() {
- return range;
- }
-
- public void setRange(int range) {
- this.range = range;
- }
-
- public double getDamage() {
- return damage;
- }
-
- public void setDamage(double damage) {
- this.damage = damage;
- }
-
- public int getSourceRange() {
- return sourceRange;
- }
-
- public void setSourceRange(int sourceRange) {
- this.sourceRange = sourceRange;
- }
-
- public long getSourceRegen() {
- return sourceRegen;
- }
-
- public void setSourceRegen(long sourceRegen) {
- this.sourceRegen = sourceRegen;
- }
-
- public int getShotMax() {
- return shotMax;
- }
-
- public void setShotMax(int shotMax) {
- this.shotMax = shotMax;
- }
-
- public int getFireTicks() {
- return fireTicks;
- }
-
- public void setFireTicks(int fireTicks) {
- this.fireTicks = fireTicks;
- }
-
- public void setLocation(Location location) {
- this.location = location;
- }
-
- public int getShots() {
- return shots;
- }
-
- public void setShots(int shots) {
- this.shots = shots;
- }
-
- public ConcurrentHashMap getBlasts() {
- return blasts;
- }
-
- @Override
- public void load() {}
-
- @Override
- public void stop() {}
-
- @Override
- public boolean isEnabled() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getBoolean("Abilities.Earth.LavaThrow.Enabled");
- }
-}
+ @Attribute(Attribute.COOLDOWN)
+ private long cooldown;
+ @Attribute(Attribute.RANGE)
+ private int range;
+ @Attribute(Attribute.DAMAGE)
+ private double damage;
+ @Attribute(Attribute.SELECT_RANGE)
+ private int sourceRange;
+ private long sourceRegen;
+ @Attribute("MaxShots")
+ private int shotMax;
+ @Attribute(Attribute.FIRE_TICK)
+ private int fireTicks;
+ @Attribute("CurveFactor")
+ private double curveFactor;
+
+ private Location location;
+ private int shots;
+ private Block selectedSource;
+ private boolean isInitialState = true;
+
+ private final ConcurrentHashMap blasts = new ConcurrentHashMap<>();
+
+ public LavaThrow(Player player) {
+ super(player);
+
+ if (!bPlayer.canBend(this) || !bPlayer.canLavabend()) {
+ return;
+ }
+
+ setFields();
+
+ location = player.getLocation();
+ location.setPitch(0);
+
+ if (prepare()) {
+ player.getWorld().playSound(selectedSource.getLocation(), Sound.ITEM_BUCKET_FILL_LAVA, 1.0f, 1.0f);
+ start();
+ }
+ }
+
+ public void setFields() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ cooldown = config.getLong("Abilities.Earth.LavaThrow.Cooldown");
+ range = config.getInt("Abilities.Earth.LavaThrow.Range");
+ damage = config.getDouble("Abilities.Earth.LavaThrow.Damage");
+ sourceRange = config.getInt("Abilities.Earth.LavaThrow.SourceGrabRange");
+ sourceRegen = config.getLong("Abilities.Earth.LavaThrow.SourceRegenDelay");
+ shotMax = config.getInt("Abilities.Earth.LavaThrow.MaxShots");
+ fireTicks = config.getInt("Abilities.Earth.LavaThrow.FireTicks");
+ curveFactor = config.getDouble("Abilities.Earth.LavaThrow.CurveFactor");
+ }
+
+ @Override
+ public void progress() {
+ if (player == null || player.isDead() || !player.isOnline()) {
+ remove();
+ return;
+ }
+
+ if (!bPlayer.getBoundAbilityName().equalsIgnoreCase("LAVATHROW")) {
+ remove();
+ if (shots > 0) bPlayer.addCooldown(this);
+ return;
+ }
+
+ if (player.getLocation().distance(selectedSource.getLocation()) >= sourceRange) {
+ remove();
+ if (shots > 0) bPlayer.addCooldown(this);
+ return;
+ }
+
+ if (blasts.isEmpty() && shots >= shotMax && !isInitialState) {
+ remove();
+ bPlayer.addCooldown(this);
+ return;
+ }
+
+ selectedSource.getWorld().spawnParticle(Particle.FLAME, selectedSource.getLocation(), 2, 0.3, 1.0, 0.3, 0.05);
+ selectedSource.getWorld().spawnParticle(Particle.LAVA, selectedSource.getLocation(), 2, 0.2, 0.2, 0.2, 0);
+
+ handleBlasts();
+ }
+
+ private boolean prepare() {
+ Block targetBlock = getTargetLavaBlock(sourceRange);
+
+ if (targetBlock != null && !TempBlock.isTempBlock(targetBlock) && !EarthAbility.getMovedEarth().containsKey(targetBlock)) {
+ selectedSource = targetBlock;
+ return true;
+ }
+
+ return false;
+ }
+
+ public Block getTargetLavaBlock(int maxDistance) {
+ Location eyeLocation = player.getEyeLocation();
+ Vector direction = eyeLocation.getDirection();
+ World world = player.getWorld();
+
+ RayTraceResult result = world.rayTraceBlocks(
+ eyeLocation, direction, maxDistance,
+ FluidCollisionMode.ALWAYS, true
+ );
+
+ if (result != null) {
+ Block hitBlock = result.getHitBlock();
+ if (LavaAbility.isLava(hitBlock)) {
+ return hitBlock;
+ }
+ }
+ return null;
+ }
+
+ public void createBlast() {
+ if (selectedSource != null && shots < shotMax) {
+ isInitialState = false;
+ shots++;
+
+ if (shots >= shotMax) {
+ bPlayer.addCooldown(this);
+ }
+
+ Location origin = selectedSource.getLocation().clone().add(0, 2, 0);
+ player.getWorld().playSound(origin, Sound.ITEM_BUCKET_EMPTY_LAVA, 1.0f, 1.0f);
+ double viewRange = range + origin.distance(player.getEyeLocation());
+ Location viewTarget = GeneralMethods.getTargetedLocation(player, viewRange, Material.WATER, Material.LAVA);
+ Vector direction = viewTarget.clone().subtract(origin).toVector().normalize();
+ Location head = origin.clone();
+
+ head.setDirection(direction);
+ blasts.put(head, origin);
+
+ new RegenTempBlock(selectedSource.getRelative(BlockFace.UP), Material.LAVA,
+ Material.LAVA.createBlockData(), 200);
+ }
+ }
+
+ public void handleBlasts() {
+ for (Location l : blasts.keySet()) {
+ Location head = l.clone();
+ Location origin = blasts.get(l);
+
+ if (l.distance(origin) > range) {
+ blasts.remove(l);
+ continue;
+ }
+
+ if (GeneralMethods.isSolid(l.getBlock())) {
+ blasts.remove(l);
+ continue;
+ }
+
+ Vector currentDirection = head.getDirection();
+ Vector playerLookDirection = player.getEyeLocation().getDirection();
+
+ Vector curveVector = playerLookDirection.clone()
+ .subtract(currentDirection)
+ .multiply(curveFactor);
+
+ Vector newDirection = currentDirection.clone()
+ .add(curveVector)
+ .normalize();
+
+ head.setDirection(newDirection);
+ head = head.add(newDirection.multiply(1));
+
+ new RegenTempBlock(l.getBlock(), Material.LAVA, Material.LAVA.createBlockData(bd -> ((Levelled)bd).setLevel(0)), 200);
+ ParticleEffect.LAVA.display(head, 1, Math.random(), Math.random(), Math.random(), 0);
+
+ boolean hit = false;
+
+ for (Entity entity : GeneralMethods.getEntitiesAroundPoint(l, 2.0D)) {
+ if (entity instanceof LivingEntity && entity.getEntityId() != player.getEntityId() && !RegionProtection.isRegionProtected(this, entity.getLocation()) && !((entity instanceof Player) && Commands.invincible.contains(((Player) entity).getName()))) {
+ DamageHandler.damageEntity(entity, damage, this);
+ blasts.remove(l);
+
+ hit = true;
+ entity.setFireTicks(this.fireTicks);
+ }
+ }
+
+ if (!hit) {
+ blasts.remove(l);
+ blasts.put(head, origin);
+ }
+ }
+ }
+
+ @Override
+ public long getCooldown() {
+ return cooldown;
+ }
+
+ @Override
+ public Location getLocation() {
+ return location;
+ }
+
+ @Override
+ public String getName() {
+ return "LavaThrow";
+ }
+
+ @Override
+ public boolean isHarmlessAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isSneakAbility() {
+ return true;
+ }
+
+ @Override
+ public String getAuthor() {
+ return JedCore.dev;
+ }
+
+ @Override
+ public String getVersion() {
+ return JedCore.version;
+ }
+
+ @Override
+ public String getDescription() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return "* JedCore Addon *\n" + config.getString("Abilities.Earth.LavaThrow.Description");
+ }
+
+ public void setCooldown(long cooldown) {
+ this.cooldown = cooldown;
+ }
+
+ public int getRange() {
+ return range;
+ }
+
+ public void setRange(int range) {
+ this.range = range;
+ }
+
+ public double getDamage() {
+ return damage;
+ }
+
+ public void setDamage(double damage) {
+ this.damage = damage;
+ }
+
+ public int getSourceRange() {
+ return sourceRange;
+ }
+
+ public void setSourceRange(int sourceRange) {
+ this.sourceRange = sourceRange;
+ }
+
+ public long getSourceRegen() {
+ return sourceRegen;
+ }
+
+ public void setSourceRegen(long sourceRegen) {
+ this.sourceRegen = sourceRegen;
+ }
+
+ public int getShotMax() {
+ return shotMax;
+ }
+
+ public void setShotMax(int shotMax) {
+ this.shotMax = shotMax;
+ }
+
+ public int getFireTicks() {
+ return fireTicks;
+ }
+
+ public void setFireTicks(int fireTicks) {
+ this.fireTicks = fireTicks;
+ }
+
+ public void setLocation(Location location) {
+ this.location = location;
+ }
+
+ public int getShots() {
+ return shots;
+ }
+
+ public void setShots(int shots) {
+ this.shots = shots;
+ }
+
+ public ConcurrentHashMap getBlasts() {
+ return blasts;
+ }
+
+ @Override
+ public void load() {}
+
+ @Override
+ public void stop() {}
+
+ @Override
+ public boolean isEnabled() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getBoolean("Abilities.Earth.LavaThrow.Enabled");
+ }
+}
\ No newline at end of file
diff --git a/src/com/jedk1/jedcore/ability/earthbending/MagnetShield.java b/src/com/jedk1/jedcore/ability/earthbending/MagnetShield.java
index 4373c5c..8eb0e43 100644
--- a/src/com/jedk1/jedcore/ability/earthbending/MagnetShield.java
+++ b/src/com/jedk1/jedcore/ability/earthbending/MagnetShield.java
@@ -2,22 +2,15 @@
import com.jedk1.jedcore.JedCore;
import com.jedk1.jedcore.configuration.JedCoreConfig;
-
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AddonAbility;
import com.projectkorra.projectkorra.ability.MetalAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
-
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.configuration.ConfigurationSection;
-import org.bukkit.entity.Arrow;
-import org.bukkit.entity.Entity;
-import org.bukkit.entity.FallingBlock;
-import org.bukkit.entity.Item;
-import org.bukkit.entity.LivingEntity;
-import org.bukkit.entity.Player;
+import org.bukkit.entity.*;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
@@ -28,254 +21,254 @@
public class MagnetShield extends MetalAbility implements AddonAbility {
- private static List METAL_LIST;
-
- private boolean isClickState = false;
- private long startTime;
-
- @Attribute(Attribute.DURATION)
- private long duration;
- @Attribute(Attribute.RANGE)
- private double range;
-
- private double velocity;
- private boolean repelArrows;
- private boolean repelLivingEntities;
- private long shiftCooldown;
- private long clickCooldown;
-
- public MagnetShield(Player player) {
- super(player);
-
- if (!bPlayer.canBendIgnoreCooldowns(this) || !bPlayer.canMetalbend()) {
- return;
- }
-
- if (!bPlayer.canBend(this)) {
- return;
- }
-
- player.getWorld().playSound(player.getLocation(), Sound.BLOCK_CONDUIT_ACTIVATE, 1.0f, 1.5f);
-
- setFields();
- loadMaterialsFromConfig();
- start();
- }
-
- public MagnetShield(Player player, boolean isClickState) {
- super(player);
-
- if (!bPlayer.canBendIgnoreCooldowns(this) || !bPlayer.canMetalbend()) {
- return;
- }
-
- if (!bPlayer.canBend(this)) {
- return;
- }
-
- if (hasAbility(player, MagnetShield.class)) {
- getAbility(player, MagnetShield.class).remove();
- return;
- }
-
- setFields();
-
- if (isClickState) {
- this.isClickState = true;
- startTime = System.currentTimeMillis();
- bPlayer.addCooldown(this, duration + 1);
- }
-
- player.getWorld().playSound(player.getLocation(), Sound.BLOCK_CONDUIT_ACTIVATE, 1.0f, 1.5f);
-
- loadMaterialsFromConfig();
- start();
- }
-
- @Override
- public void progress() {
- if (player.isDead() || !player.isOnline()) {
- remove();
- return;
- }
-
- if (!bPlayer.canBendIgnoreBindsCooldowns(this)) {
- remove();
- return;
- }
-
- if (isClickState) {
- if (System.currentTimeMillis() - startTime >= duration) {
- bPlayer.addCooldown(this, clickCooldown);
- remove();
- return;
- }
- } else {
- if (!player.isSneaking()) {
- bPlayer.addCooldown(this, shiftCooldown);
- remove();
- return;
- }
- }
-
- renderMagneticFieldLines();
- repelMetal();
- }
-
- @Override
- public long getCooldown() {
- return 0;
- }
-
- @Override
- public Location getLocation() {
- return player.getLocation();
- }
-
- @Override
- public String getName() {
- return "MagnetShield";
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return true;
- }
-
- @Override
- public String getAuthor() {
- return JedCore.dev;
- }
-
- @Override
- public String getVersion() {
- return JedCore.version;
- }
-
- @Override
- public String getDescription() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return "* JedCore Addon *\n" + config.getString("Abilities.Earth.MagnetShield.Description");
- }
-
- @Override
- public void load() {}
-
- @Override
- public void stop() {}
-
- @Override
- public boolean isEnabled() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getBoolean("Abilities.Earth.MagnetShield.Enabled");
- }
-
- private void renderMagneticFieldLines() {
- Location playerLocation = player.getLocation();
- int numLoops = 5;
- int pointsPerLoop = 30;
- double verticalSpacing = 0.06;
-
- for (int loop = 0; loop < numLoops; loop++) {
- double currentRadius = range * (1 - (double) loop / numLoops);
- double currentHeight = ((loop - numLoops / 2.0) * verticalSpacing) + 0.3;
-
- for (int i = 0; i < pointsPerLoop; i++) {
- double angle = 2 * Math.PI * i / pointsPerLoop;
- double x = currentRadius * Math.cos(angle);
- double z = currentRadius * Math.sin(angle);
- Location particleLocation = playerLocation.clone().add(x, currentHeight, z);
- JedCore.plugin.getParticleAdapter().displayMagneticParticles(particleLocation);
- }
- }
- }
-
- private void loadMaterialsFromConfig() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- List materialNames = config.getStringList("Abilities.Earth.MagnetShield.Materials");
- METAL_LIST = new ArrayList<>();
-
- for (String materialName : materialNames) {
- Material material = Material.getMaterial(materialName.toUpperCase());
- if (material != null) {
- METAL_LIST.add(material);
- } else {
- System.out.println("Invalid material in config: " + materialName);
- }
- }
- }
-
- private void repelMetal() {
- for (Entity e : GeneralMethods.getEntitiesAroundPoint(player.getLocation(), range)) {
- if (e instanceof Item) {
- Item i = (Item) e;
- if (isMetalMaterial(i.getItemStack().getType())) {
- Vector direction = GeneralMethods.getDirection(player.getLocation(), i.getLocation()).multiply(velocity);
- i.setVelocity(direction);
- }
- } else if (e instanceof FallingBlock) {
- FallingBlock fb = (FallingBlock) e;
-
- if (isMetalMaterial(fb.getBlockData().getMaterial())) {
- Vector direction = GeneralMethods.getDirection(player.getLocation(), fb.getLocation()).multiply(velocity);
- fb.setVelocity(direction);
- fb.setDropItem(false);
- }
- } else if (e instanceof Arrow && repelArrows) {
- Arrow arrow = (Arrow) e;
- Vector currentVelocity = arrow.getVelocity();
- Vector reversedVelocity = currentVelocity.multiply(-1);
- arrow.setVelocity(reversedVelocity);
- } else if (e instanceof LivingEntity && repelLivingEntities) {
- LivingEntity livingEntity = (LivingEntity) e;
-
- if (livingEntity.getUniqueId().equals(player.getUniqueId())) continue;
-
- EntityEquipment equipment = livingEntity.getEquipment();
- if (equipment == null) continue;
-
- ItemStack mainHand = equipment.getItemInMainHand();
- ItemStack offHand = equipment.getItemInOffHand();
- ItemStack helmet = equipment.getHelmet();
- ItemStack chestplate = equipment.getChestplate();
- ItemStack leggings = equipment.getLeggings();
- ItemStack boots = equipment.getBoots();
-
- boolean isMetal = isMetalItem(mainHand) || isMetalItem(offHand) ||
- isMetalItem(helmet) || isMetalItem(chestplate) ||
- isMetalItem(leggings) || isMetalItem(boots);
-
- if (isMetal) {
- Vector direction = GeneralMethods.getDirection(player.getLocation(), e.getLocation()).multiply(velocity);
- livingEntity.setVelocity(direction);
- }
- }
- }
- }
-
- private boolean isMetalItem(ItemStack itemStack) {
- return itemStack != null && METAL_LIST.contains(itemStack.getType());
- }
-
- private boolean isMetalMaterial(Material material) {
- return METAL_LIST.contains(material);
- }
-
- public void setFields() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- duration = config.getLong("Abilities.Earth.MagnetShield.Duration");
+ private static List METAL_LIST;
+
+ private boolean isClickState = false;
+ private long startTime;
+
+ @Attribute(Attribute.DURATION)
+ private long duration;
+ @Attribute(Attribute.RANGE)
+ private double range;
+
+ private double velocity;
+ private boolean repelArrows;
+ private boolean repelLivingEntities;
+ private long shiftCooldown;
+ private long clickCooldown;
+
+ public MagnetShield(Player player) {
+ super(player);
+
+ if (!bPlayer.canBendIgnoreCooldowns(this) || !bPlayer.canMetalbend()) {
+ return;
+ }
+
+ if (!bPlayer.canBend(this)) {
+ return;
+ }
+
+ player.getWorld().playSound(player.getLocation(), Sound.BLOCK_CONDUIT_ACTIVATE, 1.0f, 1.5f);
+
+ setFields();
+ loadMaterialsFromConfig();
+ start();
+ }
+
+ public MagnetShield(Player player, boolean isClickState) {
+ super(player);
+
+ if (!bPlayer.canBendIgnoreCooldowns(this) || !bPlayer.canMetalbend()) {
+ return;
+ }
+
+ if (!bPlayer.canBend(this)) {
+ return;
+ }
+
+ if (hasAbility(player, MagnetShield.class)) {
+ getAbility(player, MagnetShield.class).remove();
+ return;
+ }
+
+ setFields();
+
+ if (isClickState) {
+ this.isClickState = true;
+ startTime = System.currentTimeMillis();
+ bPlayer.addCooldown(this, duration + 1);
+ }
+
+ player.getWorld().playSound(player.getLocation(), Sound.BLOCK_CONDUIT_ACTIVATE, 1.0f, 1.5f);
+
+ loadMaterialsFromConfig();
+ start();
+ }
+
+ @Override
+ public void progress() {
+ if (player.isDead() || !player.isOnline()) {
+ remove();
+ return;
+ }
+
+ if (!bPlayer.canBendIgnoreBindsCooldowns(this)) {
+ remove();
+ return;
+ }
+
+ if (isClickState) {
+ if (System.currentTimeMillis() - startTime >= duration) {
+ bPlayer.addCooldown(this, clickCooldown);
+ remove();
+ return;
+ }
+ } else {
+ if (!player.isSneaking()) {
+ bPlayer.addCooldown(this, shiftCooldown);
+ remove();
+ return;
+ }
+ }
+
+ renderMagneticFieldLines();
+ repelMetal();
+ }
+
+ @Override
+ public long getCooldown() {
+ return 0;
+ }
+
+ @Override
+ public Location getLocation() {
+ return player.getLocation();
+ }
+
+ @Override
+ public String getName() {
+ return "MagnetShield";
+ }
+
+ @Override
+ public boolean isHarmlessAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isSneakAbility() {
+ return true;
+ }
+
+ @Override
+ public String getAuthor() {
+ return JedCore.dev;
+ }
+
+ @Override
+ public String getVersion() {
+ return JedCore.version;
+ }
+
+ @Override
+ public String getDescription() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return "* JedCore Addon *\n" + config.getString("Abilities.Earth.MagnetShield.Description");
+ }
+
+ @Override
+ public void load() {}
+
+ @Override
+ public void stop() {}
+
+ @Override
+ public boolean isEnabled() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getBoolean("Abilities.Earth.MagnetShield.Enabled");
+ }
+
+ private void renderMagneticFieldLines() {
+ Location playerLocation = player.getLocation();
+ int numLoops = 5;
+ int pointsPerLoop = 30;
+ double verticalSpacing = 0.06;
+
+ for (int loop = 0; loop < numLoops; loop++) {
+ double currentRadius = range * (1 - (double) loop / numLoops);
+ double currentHeight = ((loop - numLoops / 2.0) * verticalSpacing) + 0.3;
+
+ for (int i = 0; i < pointsPerLoop; i++) {
+ double angle = 2 * Math.PI * i / pointsPerLoop;
+ double x = currentRadius * Math.cos(angle);
+ double z = currentRadius * Math.sin(angle);
+ Location particleLocation = playerLocation.clone().add(x, currentHeight, z);
+ JedCore.plugin.getParticleAdapter().displayMagneticParticles(particleLocation);
+ }
+ }
+ }
+
+ private void loadMaterialsFromConfig() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ List materialNames = config.getStringList("Abilities.Earth.MagnetShield.Materials");
+ METAL_LIST = new ArrayList<>();
+
+ for (String materialName : materialNames) {
+ Material material = Material.getMaterial(materialName.toUpperCase());
+ if (material != null) {
+ METAL_LIST.add(material);
+ } else {
+ System.out.println("Invalid material in config: " + materialName);
+ }
+ }
+ }
+
+ private void repelMetal() {
+ for (Entity e : GeneralMethods.getEntitiesAroundPoint(player.getLocation(), range)) {
+ if (e instanceof Item) {
+ Item i = (Item) e;
+ if (isMetalMaterial(i.getItemStack().getType())) {
+ Vector direction = GeneralMethods.getDirection(player.getLocation(), i.getLocation()).multiply(velocity);
+ i.setVelocity(direction);
+ }
+ } else if (e instanceof FallingBlock) {
+ FallingBlock fb = (FallingBlock) e;
+
+ if (isMetalMaterial(fb.getBlockData().getMaterial())) {
+ Vector direction = GeneralMethods.getDirection(player.getLocation(), fb.getLocation()).multiply(velocity);
+ fb.setVelocity(direction);
+ fb.setDropItem(false);
+ }
+ } else if (e instanceof Arrow && repelArrows) {
+ Arrow arrow = (Arrow) e;
+ Vector currentVelocity = arrow.getVelocity();
+ Vector reversedVelocity = currentVelocity.multiply(-1);
+ arrow.setVelocity(reversedVelocity);
+ } else if (e instanceof LivingEntity && repelLivingEntities) {
+ LivingEntity livingEntity = (LivingEntity) e;
+
+ if (livingEntity.getUniqueId().equals(player.getUniqueId())) continue;
+
+ EntityEquipment equipment = livingEntity.getEquipment();
+ if (equipment == null) continue;
+
+ ItemStack mainHand = equipment.getItemInMainHand();
+ ItemStack offHand = equipment.getItemInOffHand();
+ ItemStack helmet = equipment.getHelmet();
+ ItemStack chestplate = equipment.getChestplate();
+ ItemStack leggings = equipment.getLeggings();
+ ItemStack boots = equipment.getBoots();
+
+ boolean isMetal = isMetalItem(mainHand) || isMetalItem(offHand) ||
+ isMetalItem(helmet) || isMetalItem(chestplate) ||
+ isMetalItem(leggings) || isMetalItem(boots);
+
+ if (isMetal) {
+ Vector direction = GeneralMethods.getDirection(player.getLocation(), e.getLocation()).multiply(velocity);
+ livingEntity.setVelocity(direction);
+ }
+ }
+ }
+ }
+
+ private boolean isMetalItem(ItemStack itemStack) {
+ return itemStack != null && METAL_LIST.contains(itemStack.getType());
+ }
+
+ private boolean isMetalMaterial(Material material) {
+ return METAL_LIST.contains(material);
+ }
+
+ public void setFields() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ duration = config.getLong("Abilities.Earth.MagnetShield.Duration");
shiftCooldown = config.getLong("Abilities.Earth.MagnetShield.Cooldowns.Shift");
- clickCooldown = config.getLong("Abilities.Earth.MagnetShield.Cooldowns.Click");
- range = config.getDouble("Abilities.Earth.MagnetShield.Range");
- repelArrows = config.getBoolean("Abilities.Earth.MagnetShield.RepelArrows");
- repelLivingEntities = config.getBoolean("Abilities.Earth.MagnetShield.RepelLivingEntities");
- velocity = config.getDouble("Abilities.Earth.MagnetShield.Velocity");
- }
+ clickCooldown = config.getLong("Abilities.Earth.MagnetShield.Cooldowns.Click");
+ range = config.getDouble("Abilities.Earth.MagnetShield.Range");
+ repelArrows = config.getBoolean("Abilities.Earth.MagnetShield.RepelArrows");
+ repelLivingEntities = config.getBoolean("Abilities.Earth.MagnetShield.RepelLivingEntities");
+ velocity = config.getDouble("Abilities.Earth.MagnetShield.Velocity");
+ }
}
\ No newline at end of file
diff --git a/src/com/jedk1/jedcore/ability/earthbending/MetalArmor.java b/src/com/jedk1/jedcore/ability/earthbending/MetalArmor.java
index ca1861e..8bca0c5 100644
--- a/src/com/jedk1/jedcore/ability/earthbending/MetalArmor.java
+++ b/src/com/jedk1/jedcore/ability/earthbending/MetalArmor.java
@@ -8,7 +8,6 @@
import com.projectkorra.projectkorra.earthbending.EarthArmor;
import com.projectkorra.projectkorra.util.TempArmor;
import com.projectkorra.projectkorra.util.TempPotionEffect;
-
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -23,190 +22,190 @@
public class MetalArmor extends EarthAbility implements AddonAbility {
- private static final int GOLD_BLOCK_COLOR = 0xF2F204;
- private static final List METAL_COLORS = Arrays.asList(
- 0xa39d91, 0xf4f4f4, 0xa2a38f, 0xF2F204, 0xb75656, 0xfff4f4
- );
-
- private boolean useIronArmor;
- private int resistStrength;
- private int resistDuration;
-
- public MetalArmor(Player player) {
- super(player);
-
- if (bPlayer == null || !bPlayer.canBendIgnoreCooldowns(CoreAbility.getAbility(EarthArmor.class)) || !bPlayer.canMetalbend()) {
- return;
- }
-
- if (!CoreAbility.hasAbility(player, EarthArmor.class)) {
- return;
- }
-
- setFields();
- start();
- }
-
- private void setFields() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- useIronArmor = config.getBoolean("Abilities.Earth.EarthArmor.UseIronArmor");
- resistStrength = config.getInt("Abilities.Earth.EarthArmor.Resistance.Strength");
- resistDuration = config.getInt("Abilities.Earth.EarthArmor.Resistance.Duration");
- }
-
- @Override
- public void progress() {
- if (player == null || !player.isOnline() || player.isDead()) {
- remove();
- return;
- }
-
- if (!CoreAbility.hasAbility(player, EarthArmor.class)) {
- remove();
- return;
- }
-
- EarthArmor ea = CoreAbility.getAbility(player, EarthArmor.class);
- if (!bPlayer.isToggled()) {
- remove();
- ea.remove();
- return;
- }
-
- if (ea.isFormed()) {
- if (isMetalHelmet()) {
- ItemStack[] armors = { new ItemStack(Material.CHAINMAIL_BOOTS, 1),
- new ItemStack(Material.CHAINMAIL_LEGGINGS, 1),
- new ItemStack(Material.CHAINMAIL_CHESTPLATE, 1),
- new ItemStack(Material.CHAINMAIL_HELMET, 1) };
-
- if(useIronArmor){
- armors = new ItemStack[]{ new ItemStack(Material.IRON_BOOTS, 1),
- new ItemStack(Material.IRON_LEGGINGS, 1),
- new ItemStack(Material.IRON_CHESTPLATE, 1),
- new ItemStack(Material.IRON_HELMET, 1) };
- }
-
- if(useIronArmor && getHelmetColor().equals(Color.fromRGB(GOLD_BLOCK_COLOR))) {
- armors = new ItemStack[]{ new ItemStack(Material.GOLDEN_BOOTS, 1),
- new ItemStack(Material.GOLDEN_LEGGINGS, 1),
- new ItemStack(Material.GOLDEN_CHESTPLATE, 1),
- new ItemStack(Material.GOLDEN_HELMET, 1) };
- }
-
- player.getInventory().setArmorContents(armors);
-
- PotionEffect resistance = JedCore.plugin.getPotionEffectAdapter().getResistanceEffect(resistDuration, resistStrength);
- new TempPotionEffect(player, resistance);
- }
-
- remove();
- }
- }
-
- private boolean isMetalHelmet() {
- Color color = getHelmetColor();
-
- return METAL_COLORS.contains(color.asRGB());
- }
-
- private Color getHelmetColor() {
- if (!TempArmor.hasTempArmor(player)) {
- return Color.BLACK;
- }
-
- ItemStack helm = player.getInventory().getHelmet();
- if (helm.getType() != Material.LEATHER_HELMET) {
- return Color.BLACK;
- }
-
- LeatherArmorMeta meta = (LeatherArmorMeta)helm.getItemMeta();
- if (meta == null) {
- return Color.BLACK;
- }
-
- return meta.getColor();
- }
-
- @Override
- public long getCooldown() {
- return 0;
- }
-
- @Override
- public Location getLocation() {
- return null;
- }
-
- @Override
- public String getName() {
- return "MetalArmor";
- }
-
- @Override
- public boolean isHiddenAbility() {
- return true;
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return false;
- }
-
- @Override
- public String getAuthor() {
- return JedCore.dev;
- }
-
- @Override
- public String getVersion() {
- return JedCore.version;
- }
-
- @Override
- public String getDescription() {
- return null;
- }
-
- public boolean isUseIronArmor() {
- return useIronArmor;
- }
-
- public void setUseIronArmor(boolean useIronArmor) {
- this.useIronArmor = useIronArmor;
- }
-
- public int getResistStrength() {
- return resistStrength;
- }
-
- public void setResistStrength(int resistStrength) {
- this.resistStrength = resistStrength;
- }
-
- public int getResistDuration() {
- return resistDuration;
- }
-
- public void setResistDuration(int resistDuration) {
- this.resistDuration = resistDuration;
- }
-
- @Override
- public void load() {}
-
- @Override
- public void stop() {}
-
- @Override
- public boolean isEnabled() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getBoolean("Abilities.Earth.EarthArmor.Enabled");
- }
-}
+ private static final int GOLD_BLOCK_COLOR = 0xF2F204;
+ private static final List METAL_COLORS = Arrays.asList(
+ 0xa39d91, 0xf4f4f4, 0xa2a38f, 0xF2F204, 0xb75656, 0xfff4f4
+ );
+
+ private boolean useIronArmor;
+ private int resistStrength;
+ private int resistDuration;
+
+ public MetalArmor(Player player) {
+ super(player);
+
+ if (bPlayer == null || !bPlayer.canBendIgnoreCooldowns(CoreAbility.getAbility(EarthArmor.class)) || !bPlayer.canMetalbend()) {
+ return;
+ }
+
+ if (!CoreAbility.hasAbility(player, EarthArmor.class)) {
+ return;
+ }
+
+ setFields();
+ start();
+ }
+
+ private void setFields() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ useIronArmor = config.getBoolean("Abilities.Earth.EarthArmor.UseIronArmor");
+ resistStrength = config.getInt("Abilities.Earth.EarthArmor.Resistance.Strength");
+ resistDuration = config.getInt("Abilities.Earth.EarthArmor.Resistance.Duration");
+ }
+
+ @Override
+ public void progress() {
+ if (player == null || !player.isOnline() || player.isDead()) {
+ remove();
+ return;
+ }
+
+ if (!CoreAbility.hasAbility(player, EarthArmor.class)) {
+ remove();
+ return;
+ }
+
+ EarthArmor ea = CoreAbility.getAbility(player, EarthArmor.class);
+ if (!bPlayer.isToggled()) {
+ remove();
+ ea.remove();
+ return;
+ }
+
+ if (ea.isFormed()) {
+ if (isMetalHelmet()) {
+ ItemStack[] armors = { new ItemStack(Material.CHAINMAIL_BOOTS, 1),
+ new ItemStack(Material.CHAINMAIL_LEGGINGS, 1),
+ new ItemStack(Material.CHAINMAIL_CHESTPLATE, 1),
+ new ItemStack(Material.CHAINMAIL_HELMET, 1) };
+
+ if(useIronArmor){
+ armors = new ItemStack[]{ new ItemStack(Material.IRON_BOOTS, 1),
+ new ItemStack(Material.IRON_LEGGINGS, 1),
+ new ItemStack(Material.IRON_CHESTPLATE, 1),
+ new ItemStack(Material.IRON_HELMET, 1) };
+ }
+
+ if(useIronArmor && getHelmetColor().equals(Color.fromRGB(GOLD_BLOCK_COLOR))) {
+ armors = new ItemStack[]{ new ItemStack(Material.GOLDEN_BOOTS, 1),
+ new ItemStack(Material.GOLDEN_LEGGINGS, 1),
+ new ItemStack(Material.GOLDEN_CHESTPLATE, 1),
+ new ItemStack(Material.GOLDEN_HELMET, 1) };
+ }
+
+ player.getInventory().setArmorContents(armors);
+
+ PotionEffect resistance = JedCore.plugin.getPotionEffectAdapter().getResistanceEffect(resistDuration, resistStrength);
+ new TempPotionEffect(player, resistance);
+ }
+
+ remove();
+ }
+ }
+
+ private boolean isMetalHelmet() {
+ Color color = getHelmetColor();
+
+ return METAL_COLORS.contains(color.asRGB());
+ }
+
+ private Color getHelmetColor() {
+ if (!TempArmor.hasTempArmor(player)) {
+ return Color.BLACK;
+ }
+
+ ItemStack helm = player.getInventory().getHelmet();
+ if (helm.getType() != Material.LEATHER_HELMET) {
+ return Color.BLACK;
+ }
+
+ LeatherArmorMeta meta = (LeatherArmorMeta)helm.getItemMeta();
+ if (meta == null) {
+ return Color.BLACK;
+ }
+
+ return meta.getColor();
+ }
+
+ @Override
+ public long getCooldown() {
+ return 0;
+ }
+
+ @Override
+ public Location getLocation() {
+ return null;
+ }
+
+ @Override
+ public String getName() {
+ return "MetalArmor";
+ }
+
+ @Override
+ public boolean isHiddenAbility() {
+ return true;
+ }
+
+ @Override
+ public boolean isHarmlessAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isSneakAbility() {
+ return false;
+ }
+
+ @Override
+ public String getAuthor() {
+ return JedCore.dev;
+ }
+
+ @Override
+ public String getVersion() {
+ return JedCore.version;
+ }
+
+ @Override
+ public String getDescription() {
+ return null;
+ }
+
+ public boolean isUseIronArmor() {
+ return useIronArmor;
+ }
+
+ public void setUseIronArmor(boolean useIronArmor) {
+ this.useIronArmor = useIronArmor;
+ }
+
+ public int getResistStrength() {
+ return resistStrength;
+ }
+
+ public void setResistStrength(int resistStrength) {
+ this.resistStrength = resistStrength;
+ }
+
+ public int getResistDuration() {
+ return resistDuration;
+ }
+
+ public void setResistDuration(int resistDuration) {
+ this.resistDuration = resistDuration;
+ }
+
+ @Override
+ public void load() {}
+
+ @Override
+ public void stop() {}
+
+ @Override
+ public boolean isEnabled() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getBoolean("Abilities.Earth.EarthArmor.Enabled");
+ }
+}
\ No newline at end of file
diff --git a/src/com/jedk1/jedcore/ability/earthbending/MetalFragments.java b/src/com/jedk1/jedcore/ability/earthbending/MetalFragments.java
index 9a95cdd..134e1ee 100644
--- a/src/com/jedk1/jedcore/ability/earthbending/MetalFragments.java
+++ b/src/com/jedk1/jedcore/ability/earthbending/MetalFragments.java
@@ -4,27 +4,18 @@
import com.jedk1.jedcore.configuration.JedCoreConfig;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AddonAbility;
+import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.MetalAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.region.RegionProtection;
-import com.projectkorra.projectkorra.util.BlockSource;
-import com.projectkorra.projectkorra.util.ClickType;
-import com.projectkorra.projectkorra.util.DamageHandler;
-import com.projectkorra.projectkorra.util.ParticleEffect;
-import com.projectkorra.projectkorra.util.TempBlock;
-import com.projectkorra.projectkorra.util.TempFallingBlock;
-
+import com.projectkorra.projectkorra.util.*;
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.configuration.ConfigurationSection;
-import org.bukkit.entity.Entity;
-import org.bukkit.entity.FallingBlock;
-import org.bukkit.entity.Item;
-import org.bukkit.entity.LivingEntity;
-import org.bukkit.entity.Player;
+import org.bukkit.entity.*;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
@@ -32,242 +23,247 @@
public class MetalFragments extends MetalAbility implements AddonAbility {
- @Attribute("MaxSources")
- private int maxSources;
- @Attribute(Attribute.SELECT_RANGE)
- private int selectRange;
- @Attribute("MaxShots")
- private int maxFragments;
- @Attribute(Attribute.DAMAGE)
- private double damage;
- @Attribute(Attribute.COOLDOWN)
- private long cooldown;
- private double velocity;
-
- public List sources = new ArrayList<>();
- private final List- thrownFragments = new ArrayList<>();
- private final List tblockTracker = new ArrayList<>();
- //private List fblockTracker = new ArrayList<>();
- private final HashMap counters = new HashMap<>();
-
- public MetalFragments(Player player) {
- super(player);
-
- if (hasAbility(player, MetalFragments.class)) {
- MetalFragments.selectAnotherSource(player);
- return;
- }
-
- if (!bPlayer.canBend(this) || !bPlayer.canMetalbend()) {
- return;
- }
-
- setFields();
-
- if (tblockTracker.size() >= maxSources) {
- return;
- }
-
- if (prepare()) {
- Block b = selectSource();
- if (RegionProtection.isRegionProtected(player, b.getLocation(), this)) {
- return;
- }
-
- start();
- if (!isRemoved()) {
- translateUpward(b);
- }
- }
- }
-
- public void setFields() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- maxSources = config.getInt("Abilities.Earth.MetalFragments.MaxSources");
- selectRange = config.getInt("Abilities.Earth.MetalFragments.SourceRange");
- maxFragments = config.getInt("Abilities.Earth.MetalFragments.MaxFragments");
- damage = config.getDouble("Abilities.Earth.MetalFragments.Damage");
- cooldown = config.getInt("Abilities.Earth.MetalFragments.Cooldown");
- velocity = config.getDouble("Abilities.Earth.MetalFragments.Velocity");
- }
-
- public static void shootFragment(Player player) {
- if (hasAbility(player, MetalFragments.class)) {
- getAbility(player, MetalFragments.class).shootFragment();
- }
- }
-
- private void shootFragment() {
- if (sources.size() <= 0)
- return;
-
- Random randy = new Random();
- int i = randy.nextInt(sources.size());
- Block source = sources.get(i);
- ItemStack is;
-
- switch (source.getType()) {
- case GOLD_BLOCK:
- case GOLD_ORE:
- is = new ItemStack(Material.GOLD_INGOT, 1);
- break;
- case COAL_BLOCK:
- is = new ItemStack(Material.COAL, 1);
- break;
- case COAL_ORE:
- is = new ItemStack(Material.COAL_ORE, 1);
- break;
- default:
- is = new ItemStack(Material.IRON_INGOT, 1);
- break;
- }
-
- Vector direction;
- if (GeneralMethods.getTargetedEntity(player, 30, new ArrayList<>()) != null) {
- direction = GeneralMethods.getDirection(source.getLocation(), GeneralMethods.getTargetedEntity(player, 30, new ArrayList<>()).getLocation());
- } else {
- direction = GeneralMethods.getDirection(source.getLocation(), GeneralMethods.getTargetedLocation(player, 30));
- }
-
- Item ii = player.getWorld().dropItemNaturally(source.getLocation().getBlock().getRelative(GeneralMethods.getCardinalDirection(direction)).getLocation(), is);
- ii.setPickupDelay(Integer.MAX_VALUE);
- ii.setVelocity(direction.normalize().multiply(velocity));
- playMetalbendingSound(ii.getLocation());
- thrownFragments.add(ii);
-
- if (counters.containsKey(source)) {
- int count = counters.get(source);
- count++;
-
- if (count >= maxFragments) {
- counters.remove(source);
- source.getWorld().spawnFallingBlock(source.getLocation().add(0.5, 0, 0.5), source.getBlockData());
- TempBlock tempBlock = TempBlock.get(source);
- if (tempBlock != null) {
- tempBlock.revertBlock();
- }
- sources.remove(source);
- source.getWorld().playSound(source.getLocation(), Sound.ENTITY_ITEM_BREAK, 10, 5);
- } else {
- counters.put(source, count);
- }
-
- if (sources.size() == 0) {
- remove();
- }
- }
- }
-
- public static void selectAnotherSource(Player player) {
- if (hasAbility(player, MetalFragments.class)) {
- getAbility(player, MetalFragments.class).selectAnotherSource();
- }
- }
-
- private void selectAnotherSource() {
- if (tblockTracker.size() >= maxSources)
- return;
-
- if (prepare()) {
- Block b = selectSource();
- translateUpward(b);
- }
- }
-
- public boolean prepare() {
- Block block = BlockSource.getEarthSourceBlock(player, selectRange, ClickType.SHIFT_DOWN);
-
- if (block == null)
- return false;
-
- return isMetal(block);
- }
-
- public Block selectSource() {
- Block block = BlockSource.getEarthSourceBlock(player, selectRange, ClickType.SHIFT_DOWN);
- if (isMetal(block))
- return block;
- return null;
- }
-
- public void translateUpward(Block block) {
- if (block == null)
- return;
-
- if (sources.contains(block))
- return;
-
- if (block.getRelative(BlockFace.UP).getType().isSolid())
- return;
-
- if (isEarthbendable(player, block)) {
- new TempFallingBlock(block.getLocation().add(0.5, 0, 0.5), block.getBlockData(), new Vector(0, 0.8, 0), this);
- block.setType(Material.AIR);
-
- playMetalbendingSound(block.getLocation());
- }
- }
-
- public void progress() {
- if (player == null || player.isDead() || !player.isOnline()) {
- remove();
- return;
- }
- if (!hasAbility(player, MetalFragments.class)) {
- return;
- }
- if (!bPlayer.canBendIgnoreCooldowns(this)) {
- remove();
- return;
- }
-
- Iterator itr = tblockTracker.iterator();
- while (itr.hasNext()) {
- TempBlock tb = itr.next();
- if (player.getLocation().distance(tb.getLocation()) >= 10) {
- player.getWorld().spawnFallingBlock(tb.getLocation().add(0.5,0.0,0.5), tb.getBlockData());
- sources.remove(tb.getBlock());
- tb.revertBlock();
- itr.remove();
- }
- }
-
- for (TempFallingBlock tfb : TempFallingBlock.getFromAbility(this)) {
- FallingBlock fb = tfb.getFallingBlock();
- if (fb.getLocation().getY() >= player.getEyeLocation().getY() + 1) {
- Block block = fb.getLocation().getBlock();
- TempBlock tb = new TempBlock(block, fb.getBlockData());
-
- tblockTracker.add(tb);
- sources.add(tb.getBlock());
- counters.put(tb.getBlock(), 0);
- tfb.remove();
- }
-
- if (fb.isOnGround()) {
- fb.getLocation().getBlock().setBlockData(fb.getBlockData());
- }
- }
- for (ListIterator
- iterator = thrownFragments.listIterator(); iterator.hasNext();) {
- Item f = iterator.next();
-
- boolean touchedLiving = false;
- for (Entity e : GeneralMethods.getEntitiesAroundPoint(f.getLocation(), 1)) {
- if (e instanceof LivingEntity && e.getEntityId() != player.getEntityId()) {
- touchedLiving = true;
- DamageHandler.damageEntity(e, damage, this);
- }
- }
- if (touchedLiving || f.isOnGround() || f.isDead()) {
- ParticleEffect.ITEM_CRACK.display(f.getLocation(), 3, 0.3, 0.3, 0.3, 0.2, f.getItemStack());
- f.remove();
- iterator.remove();
- }
- }
-
- //removeDeadFBlocks();
- }
+ @Attribute("MaxSources")
+ private int maxSources;
+ @Attribute(Attribute.SELECT_RANGE)
+ private int selectRange;
+ @Attribute("MaxShots")
+ private int maxFragments;
+ @Attribute(Attribute.DAMAGE)
+ private double damage;
+ @Attribute(Attribute.COOLDOWN)
+ private long cooldown;
+ private double velocity;
+
+ public List sources = new ArrayList<>();
+ private final List
- thrownFragments = new ArrayList<>();
+ private final List tblockTracker = new ArrayList<>();
+ //private List fblockTracker = new ArrayList<>();
+ private final HashMap counters = new HashMap<>();
+
+ public MetalFragments(Player player) {
+ super(player);
+
+ if (hasAbility(player, MetalFragments.class)) {
+ MetalFragments.selectAnotherSource(player);
+ return;
+ }
+
+ if (!bPlayer.canBend(this) || !bPlayer.canMetalbend()) {
+ return;
+ }
+
+ setFields();
+
+ if (tblockTracker.size() >= maxSources) {
+ return;
+ }
+
+ if (prepare()) {
+ Block b = selectSource();
+ if (RegionProtection.isRegionProtected(player, b.getLocation(), this)) {
+ return;
+ }
+
+ start();
+ if (!isRemoved()) {
+ translateUpward(b);
+ }
+ }
+ }
+
+ public void setFields() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ maxSources = config.getInt("Abilities.Earth.MetalFragments.MaxSources");
+ selectRange = config.getInt("Abilities.Earth.MetalFragments.SourceRange");
+ maxFragments = config.getInt("Abilities.Earth.MetalFragments.MaxFragments");
+ damage = config.getDouble("Abilities.Earth.MetalFragments.Damage");
+ cooldown = config.getInt("Abilities.Earth.MetalFragments.Cooldown");
+ velocity = config.getDouble("Abilities.Earth.MetalFragments.Velocity");
+ }
+
+ public static void shootFragment(Player player) {
+ if (hasAbility(player, MetalFragments.class)) {
+ getAbility(player, MetalFragments.class).shootFragment();
+ }
+ }
+
+ private void shootFragment() {
+ if (sources.size() <= 0)
+ return;
+
+ Random randy = new Random();
+ int i = randy.nextInt(sources.size());
+ Block source = sources.get(i);
+ ItemStack is;
+
+ switch (source.getType()) {
+ case GOLD_BLOCK:
+ case GOLD_ORE:
+ is = new ItemStack(Material.GOLD_INGOT, 1);
+ break;
+ case COAL_BLOCK:
+ is = new ItemStack(Material.COAL, 1);
+ break;
+ case COAL_ORE:
+ is = new ItemStack(Material.COAL_ORE, 1);
+ break;
+ default:
+ is = new ItemStack(Material.IRON_INGOT, 1);
+ break;
+ }
+
+ Vector direction;
+ if (GeneralMethods.getTargetedEntity(player, 30, new ArrayList<>()) != null) {
+ direction = GeneralMethods.getDirection(source.getLocation(), GeneralMethods.getTargetedEntity(player, 30, new ArrayList<>()).getLocation());
+ } else {
+ direction = GeneralMethods.getDirection(source.getLocation(), GeneralMethods.getTargetedLocation(player, 30));
+ }
+
+ Item ii = player.getWorld().dropItemNaturally(source.getLocation().getBlock().getRelative(GeneralMethods.getCardinalDirection(direction)).getLocation(), is);
+ ii.setPickupDelay(Integer.MAX_VALUE);
+ ii.setVelocity(direction.normalize().multiply(velocity));
+ playMetalbendingSound(ii.getLocation());
+ thrownFragments.add(ii);
+
+ if (counters.containsKey(source)) {
+ int count = counters.get(source);
+ count++;
+
+ if (count >= maxFragments) {
+ counters.remove(source);
+ source.getWorld().spawnFallingBlock(source.getLocation().add(0.5, 0, 0.5), source.getBlockData());
+ TempBlock tempBlock = TempBlock.get(source);
+ if (tempBlock != null) {
+ tempBlock.revertBlock();
+ }
+ sources.remove(source);
+ source.getWorld().playSound(source.getLocation(), Sound.ENTITY_ITEM_BREAK, 10, 5);
+ } else {
+ counters.put(source, count);
+ }
+
+ if (sources.size() == 0) {
+ remove();
+ }
+ }
+ }
+
+ public static void selectAnotherSource(Player player) {
+ if (hasAbility(player, MetalFragments.class)) {
+ getAbility(player, MetalFragments.class).selectAnotherSource();
+ }
+ }
+
+ private void selectAnotherSource() {
+ if (tblockTracker.size() >= maxSources)
+ return;
+
+ if (prepare()) {
+ Block b = selectSource();
+ translateUpward(b);
+ }
+ }
+
+ public boolean prepare() {
+ Block block = BlockSource.getEarthSourceBlock(player, selectRange, ClickType.SHIFT_DOWN);
+
+ if (block == null)
+ return false;
+
+ if (EarthAbility.getMovedEarth().containsKey(block))
+ return false;
+
+ return isMetal(block);
+ }
+
+ public Block selectSource() {
+ Block block = BlockSource.getEarthSourceBlock(player, selectRange, ClickType.SHIFT_DOWN);
+ if (EarthAbility.getMovedEarth().containsKey(block))
+ return null;
+ if (isMetal(block))
+ return block;
+ return null;
+ }
+
+ public void translateUpward(Block block) {
+ if (block == null)
+ return;
+
+ if (sources.contains(block))
+ return;
+
+ if (block.getRelative(BlockFace.UP).getType().isSolid())
+ return;
+
+ if (isEarthbendable(player, block)) {
+ new TempFallingBlock(block.getLocation().add(0.5, 0, 0.5), block.getBlockData(), new Vector(0, 0.8, 0), this);
+ block.setType(Material.AIR);
+
+ playMetalbendingSound(block.getLocation());
+ }
+ }
+
+ public void progress() {
+ if (player == null || player.isDead() || !player.isOnline()) {
+ remove();
+ return;
+ }
+ if (!hasAbility(player, MetalFragments.class)) {
+ return;
+ }
+ if (!bPlayer.canBendIgnoreCooldowns(this)) {
+ remove();
+ return;
+ }
+
+ Iterator itr = tblockTracker.iterator();
+ while (itr.hasNext()) {
+ TempBlock tb = itr.next();
+ if (player.getLocation().distance(tb.getLocation()) >= 10) {
+ player.getWorld().spawnFallingBlock(tb.getLocation().add(0.5,0.0,0.5), tb.getBlockData());
+ sources.remove(tb.getBlock());
+ tb.revertBlock();
+ itr.remove();
+ }
+ }
+
+ for (TempFallingBlock tfb : TempFallingBlock.getFromAbility(this)) {
+ FallingBlock fb = tfb.getFallingBlock();
+ if (fb.getLocation().getY() >= player.getEyeLocation().getY() + 1) {
+ Block block = fb.getLocation().getBlock();
+ TempBlock tb = new TempBlock(block, fb.getBlockData());
+
+ tblockTracker.add(tb);
+ sources.add(tb.getBlock());
+ counters.put(tb.getBlock(), 0);
+ tfb.remove();
+ }
+
+ if (fb.isOnGround()) {
+ fb.getLocation().getBlock().setBlockData(fb.getBlockData());
+ }
+ }
+ for (ListIterator
- iterator = thrownFragments.listIterator(); iterator.hasNext();) {
+ Item f = iterator.next();
+
+ boolean touchedLiving = false;
+ for (Entity e : GeneralMethods.getEntitiesAroundPoint(f.getLocation(), 1)) {
+ if (e instanceof LivingEntity && e.getEntityId() != player.getEntityId()) {
+ touchedLiving = true;
+ DamageHandler.damageEntity(e, damage, this);
+ }
+ }
+ if (touchedLiving || f.isOnGround() || f.isDead()) {
+ ParticleEffect.ITEM_CRACK.display(f.getLocation(), 3, 0.3, 0.3, 0.3, 0.2, f.getItemStack());
+ f.remove();
+ iterator.remove();
+ }
+ }
+
+ //removeDeadFBlocks();
+ }
/*
public void removeDeadFBlocks() {
@@ -277,154 +273,154 @@ public void removeDeadFBlocks() {
}
*/
- public void removeDeadItems() {
- thrownFragments.removeIf(Item::isDead);
- }
-
-
- public void dropSources() {
- for (TempBlock tb : tblockTracker) {
- tb.getBlock().getWorld().spawnFallingBlock(tb.getLocation().add(0.5,0.0,0.5), tb.getBlock().getBlockData());
- tb.revertBlock();
- }
-
- tblockTracker.clear();
- }
-
- public void removeFragments() {
- for (Item i : thrownFragments) {
- ParticleEffect.ITEM_CRACK.display(i.getLocation(), 3, 0.3, 0.3, 0.3, 0.2, i.getItemStack());
- i.remove();
- }
- thrownFragments.clear();
- }
-
- public static void remove(Player player, Block block) {
- if (hasAbility(player, MetalFragments.class)) {
- MetalFragments mf = getAbility(player, MetalFragments.class);
- if (mf.sources.contains(block)) {
- mf.remove();
- }
- }
- }
-
- @Override
- public void remove() {
- dropSources();
- removeFragments();
- removeDeadItems();
- if (player.isOnline()) {
- bPlayer.addCooldown(this);
- }
- super.remove();
- }
-
- @Override
- public long getCooldown() {
- return cooldown;
- }
-
- @Override
- public Location getLocation() {
- return null;
- }
-
- @Override
- public String getName() {
- return "MetalFragments";
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return true;
- }
-
- @Override
- public String getAuthor() {
- return JedCore.dev;
- }
-
- @Override
- public String getVersion() {
- return JedCore.version;
- }
-
- @Override
- public String getDescription() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return "* JedCore Addon *\n" + config.getString("Abilities.Earth.MetalFragments.Description");
- }
-
- public int getMaxSources() {
- return maxSources;
- }
-
- public void setMaxSources(int maxSources) {
- this.maxSources = maxSources;
- }
-
- public int getSelectRange() {
- return selectRange;
- }
-
- public void setSelectRange(int selectRange) {
- this.selectRange = selectRange;
- }
-
- public int getMaxFragments() {
- return maxFragments;
- }
-
- public void setMaxFragments(int maxFragments) {
- this.maxFragments = maxFragments;
- }
-
- public double getDamage() {
- return damage;
- }
-
- public void setDamage(double damage) {
- this.damage = damage;
- }
-
- public void setCooldown(long cooldown) {
- this.cooldown = cooldown;
- }
-
- public List getSources() {
- return sources;
- }
-
- public void setSources(List sources) {
- this.sources = sources;
- }
-
- public List
- getThrownFragments() {
- return thrownFragments;
- }
-
- public List getTblockTracker() {
- return tblockTracker;
- }
-
- public HashMap getCounters() {
- return counters;
- }
-
- @Override
- public void load() {}
-
- @Override
- public void stop() {}
-
- @Override
- public boolean isEnabled() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getBoolean("Abilities.Earth.MetalFragments.Enabled");
- }
-}
+ public void removeDeadItems() {
+ thrownFragments.removeIf(Item::isDead);
+ }
+
+
+ public void dropSources() {
+ for (TempBlock tb : tblockTracker) {
+ tb.getBlock().getWorld().spawnFallingBlock(tb.getLocation().add(0.5,0.0,0.5), tb.getBlock().getBlockData());
+ tb.revertBlock();
+ }
+
+ tblockTracker.clear();
+ }
+
+ public void removeFragments() {
+ for (Item i : thrownFragments) {
+ ParticleEffect.ITEM_CRACK.display(i.getLocation(), 3, 0.3, 0.3, 0.3, 0.2, i.getItemStack());
+ i.remove();
+ }
+ thrownFragments.clear();
+ }
+
+ public static void remove(Player player, Block block) {
+ if (hasAbility(player, MetalFragments.class)) {
+ MetalFragments mf = getAbility(player, MetalFragments.class);
+ if (mf.sources.contains(block)) {
+ mf.remove();
+ }
+ }
+ }
+
+ @Override
+ public void remove() {
+ dropSources();
+ removeFragments();
+ removeDeadItems();
+ if (player.isOnline()) {
+ bPlayer.addCooldown(this);
+ }
+ super.remove();
+ }
+
+ @Override
+ public long getCooldown() {
+ return cooldown;
+ }
+
+ @Override
+ public Location getLocation() {
+ return null;
+ }
+
+ @Override
+ public String getName() {
+ return "MetalFragments";
+ }
+
+ @Override
+ public boolean isHarmlessAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isSneakAbility() {
+ return true;
+ }
+
+ @Override
+ public String getAuthor() {
+ return JedCore.dev;
+ }
+
+ @Override
+ public String getVersion() {
+ return JedCore.version;
+ }
+
+ @Override
+ public String getDescription() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return "* JedCore Addon *\n" + config.getString("Abilities.Earth.MetalFragments.Description");
+ }
+
+ public int getMaxSources() {
+ return maxSources;
+ }
+
+ public void setMaxSources(int maxSources) {
+ this.maxSources = maxSources;
+ }
+
+ public int getSelectRange() {
+ return selectRange;
+ }
+
+ public void setSelectRange(int selectRange) {
+ this.selectRange = selectRange;
+ }
+
+ public int getMaxFragments() {
+ return maxFragments;
+ }
+
+ public void setMaxFragments(int maxFragments) {
+ this.maxFragments = maxFragments;
+ }
+
+ public double getDamage() {
+ return damage;
+ }
+
+ public void setDamage(double damage) {
+ this.damage = damage;
+ }
+
+ public void setCooldown(long cooldown) {
+ this.cooldown = cooldown;
+ }
+
+ public List getSources() {
+ return sources;
+ }
+
+ public void setSources(List sources) {
+ this.sources = sources;
+ }
+
+ public List
- getThrownFragments() {
+ return thrownFragments;
+ }
+
+ public List getTblockTracker() {
+ return tblockTracker;
+ }
+
+ public HashMap getCounters() {
+ return counters;
+ }
+
+ @Override
+ public void load() {}
+
+ @Override
+ public void stop() {}
+
+ @Override
+ public boolean isEnabled() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getBoolean("Abilities.Earth.MetalFragments.Enabled");
+ }
+}
\ No newline at end of file
diff --git a/src/com/jedk1/jedcore/ability/earthbending/MetalHook.java b/src/com/jedk1/jedcore/ability/earthbending/MetalHook.java
index 3cbf551..218a17b 100644
--- a/src/com/jedk1/jedcore/ability/earthbending/MetalHook.java
+++ b/src/com/jedk1/jedcore/ability/earthbending/MetalHook.java
@@ -6,7 +6,6 @@
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AddonAbility;
import com.projectkorra.projectkorra.ability.MetalAbility;
-
import com.projectkorra.projectkorra.attribute.Attribute;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -26,371 +25,371 @@
public class MetalHook extends MetalAbility implements AddonAbility {
- @Attribute(Attribute.COOLDOWN)
- private long cooldown;
- @Attribute(Attribute.RANGE)
- private int range;
- @Attribute("MaxHooks")
- private int maxHooks;
- private int totalHooks;
- private int hooksUsed;
- private boolean noSource;
- private boolean barrierHooking;
-
- private boolean hasHook;
- private boolean wasSprinting;
- private long time;
-
- private Location destination;
-
- private final ConcurrentHashMap hooks = new ConcurrentHashMap<>();
- private final List hookIds = new ArrayList<>();
-
- public MetalHook(Player player) {
- super(player);
-
- if (!bPlayer.canBend(this) || !bPlayer.canMetalbend()) {
- return;
- }
-
- if (hasAbility(player, MetalHook.class)) {
- MetalHook mh = getAbility(player, MetalHook.class);
- mh.launchHook();
- return;
- }
-
- setFields();
-
- if (!hasRequiredInv()) {
- return;
- }
-
- wasSprinting = player.isSprinting();
- flightHandler.createInstance(player, this.getName());
- player.setAllowFlight(true);
-
- start();
- launchHook();
- }
-
- public void setFields() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- cooldown = config.getLong("Abilities.Earth.MetalHook.Cooldown");
- range = config.getInt("Abilities.Earth.MetalHook.Range");
- maxHooks = config.getInt("Abilities.Earth.MetalHook.MaxHooks");
- totalHooks = config.getInt("Abilities.Earth.MetalHook.TotalHooks");
- noSource = config.getBoolean("Abilities.Earth.MetalHook.RequireItem");
- barrierHooking = config.getBoolean("Abilities.Earth.MetalHook.BarrierHooking");
- }
-
- @Override
- public void progress() {
- if (player == null || !player.isOnline() || player.isDead()) {
- removeAllArrows();
- remove();
- return;
- }
-
- if (!bPlayer.canBendIgnoreBindsCooldowns(this) || hooks.isEmpty()) {
- removeAllArrows();
- remove();
- return;
- }
-
- if (!wasSprinting && player.isSprinting()) {
- removeAllArrows();
- remove();
- return;
- }
-
- wasSprinting = player.isSprinting();
-
- if (player.isSneaking()) {
- player.setVelocity(new Vector());
-
- if (System.currentTimeMillis() > (time + 1000)) {
- removeAllArrows();
- remove();
- return;
- }
- } else {
- time = System.currentTimeMillis();
- }
-
- Vector target = new Vector();
-
- for (Arrow a : hooks.keySet()) {
- if (a != null) {
- if (!isActiveArrow(a)) {
- hooks.remove(a);
- hookIds.remove(a.getUniqueId());
- a.remove();
- continue;
- }
-
- if (a.getAttachedBlock() == null) {
- hooks.replace(a, hooks.get(a), false);
- } else {
- hooks.replace(a, hooks.get(a), true);
- hasHook = true;
- }
-
- //Draws the particle lines.
- for (Location location : JCMethods.getLinePoints(player.getLocation().add(0, 1, 0), a.getLocation(), ((int) player.getLocation().add(0,1,0).distance(a.getLocation()) * 2))) {
- GeneralMethods.displayColoredParticle("#CCCCCC", location);
- }
-
- if (hooks.get(a)) {
- target.add(GeneralMethods.getDirection(player.getEyeLocation(), a.getLocation()));
- }
- }
- }
-
- if (hasHook) {
- destination = player.getLocation().clone().add(target);
-
- if (player.getLocation().distance(destination) > 2) {
- player.setFlying(false);
- double velocity = 0.8;
-
- GeneralMethods.setVelocity(this, player, target.clone().normalize().multiply(velocity));
- } else if (player.getLocation().distance(destination) < 2 && player.getLocation().distance(destination) >= 1) {
- player.setFlying(false);
- double velocity = 0.35;
-
- GeneralMethods.setVelocity(this, player, target.clone().normalize().multiply(velocity));
- } else {
- GeneralMethods.setVelocity(this, player, new Vector(0, 0, 0));
-
- if (player.getAllowFlight()) {
- player.setFlying(true);
- }
- }
- }
- }
-
- private boolean isActiveArrow(Arrow arrow) {
- if (arrow.isDead()) return false;
- if (player.getWorld() != arrow.getWorld()) return false;
-
- Block attached = arrow.getAttachedBlock();
-
- if (!barrierHooking && attached != null && attached.getType() == Material.BARRIER) return false;
-
- return player.getEyeLocation().distanceSquared(arrow.getLocation()) < range * range;
- }
-
- @Override
- public void remove() {
- if (player.isOnline()) {
- bPlayer.addCooldown(this);
- }
-
- flightHandler.removeInstance(player, this.getName());
-
- super.remove();
- }
-
- public void launchHook() {
- if (!hasRequiredInv()) return;
-
- Vector dir = GeneralMethods.getDirection(player.getEyeLocation(), GeneralMethods.getTargetedLocation(player, range));
-
- if (!hookIds.isEmpty() && hookIds.size() > (maxHooks - 1)) {
- for (Arrow a : hooks.keySet()) {
- if (a.getUniqueId().equals(hookIds.get(0))) {
- hooks.remove(a);
- hookIds.remove(0);
- a.remove();
- break;
- }
- }
- }
-
- if (totalHooks > 0 && hooksUsed++ > totalHooks) {
- remove();
- return;
- }
-
- Arrow a = player.getWorld().spawnArrow(player.getEyeLocation().add(player.getLocation().getDirection().multiply(2)), dir, 3, 0f);
- a.setMetadata("metalhook", new FixedMetadataValue(JedCore.plugin, "1"));
-
- hooks.put(a, false);
- hookIds.add(a.getUniqueId());
- }
-
- public void removeAllArrows() {
- for (Arrow a : hooks.keySet()) {
- a.remove();
- }
- }
-
- public boolean hasRequiredInv() {
- if (noSource) return true;
-
- if (player.getInventory().getChestplate() != null) {
- Material[] chestplates = {Material.IRON_CHESTPLATE, Material.CHAINMAIL_CHESTPLATE};
- Material playerChest = player.getInventory().getChestplate().getType();
-
- if (Arrays.asList(chestplates).contains(playerChest)) {
- return true;
- }
- }
-
- Material[] metals = {Material.IRON_INGOT, Material.IRON_BLOCK};
-
- for (ItemStack items : player.getInventory()) {
- if (items != null && Arrays.asList(metals).contains(items.getType())) {
- return true;
- }
- }
-
- return false;
- }
-
- public int getMaxHooks() {
- return this.maxHooks;
- }
-
- public void setMaxHooks(int maxhooks) {
- this.maxHooks = maxhooks;
- }
-
- @Override
- public long getCooldown() {
- return cooldown;
- }
-
- @Override
- public Location getLocation() {
- return null;
- }
-
- @Override
- public String getName() {
- return "MetalHook";
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return true;
- }
-
- @Override
- public String getAuthor() {
- return JedCore.dev;
- }
-
- @Override
- public String getVersion() {
- return JedCore.version;
- }
-
- @Override
- public String getDescription() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return "* JedCore Addon *\n" + config.getString("Abilities.Earth.MetalHook.Description");
- }
-
- public void setCooldown(long cooldown) {
- this.cooldown = cooldown;
- }
-
- public int getRange() {
- return range;
- }
-
- public void setRange(int range) {
- this.range = range;
- }
-
- public int getTotalHooks() {
- return totalHooks;
- }
-
- public void setTotalHooks(int totalHooks) {
- this.totalHooks = totalHooks;
- }
-
- public int getHooksUsed() {
- return hooksUsed;
- }
-
- public void setHooksUsed(int hooksUsed) {
- this.hooksUsed = hooksUsed;
- }
-
- public boolean isNoSource() {
- return noSource;
- }
-
- public void setNoSource(boolean noSource) {
- this.noSource = noSource;
- }
-
- public boolean isBarrierHooking() {
- return barrierHooking;
- }
-
- public void setBarrierHooking(boolean barrierHooking) {
- this.barrierHooking = barrierHooking;
- }
-
- public boolean isHasHook() {
- return hasHook;
- }
-
- public void setHasHook(boolean hasHook) {
- this.hasHook = hasHook;
- }
-
- public boolean isWasSprinting() {
- return wasSprinting;
- }
-
- public void setWasSprinting(boolean wasSprinting) {
- this.wasSprinting = wasSprinting;
- }
-
- public long getTime() {
- return time;
- }
-
- public void setTime(long time) {
- this.time = time;
- }
-
- public Location getDestination() {
- return destination;
- }
-
- public void setDestination(Location destination) {
- this.destination = destination;
- }
-
- public ConcurrentHashMap getHooks() {
- return hooks;
- }
-
- public List getHookIds() {
- return hookIds;
- }
-
- @Override
- public void load() {}
-
- @Override
- public void stop() {}
-
- @Override
- public boolean isEnabled() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getBoolean("Abilities.Earth.MetalHook.Enabled");
- }
-}
+ @Attribute(Attribute.COOLDOWN)
+ private long cooldown;
+ @Attribute(Attribute.RANGE)
+ private int range;
+ @Attribute("MaxHooks")
+ private int maxHooks;
+ private int totalHooks;
+ private int hooksUsed;
+ private boolean noSource;
+ private boolean barrierHooking;
+
+ private boolean hasHook;
+ private boolean wasSprinting;
+ private long time;
+
+ private Location destination;
+
+ private final ConcurrentHashMap hooks = new ConcurrentHashMap<>();
+ private final List hookIds = new ArrayList<>();
+
+ public MetalHook(Player player) {
+ super(player);
+
+ if (!bPlayer.canBend(this) || !bPlayer.canMetalbend()) {
+ return;
+ }
+
+ if (hasAbility(player, MetalHook.class)) {
+ MetalHook mh = getAbility(player, MetalHook.class);
+ mh.launchHook();
+ return;
+ }
+
+ setFields();
+
+ if (!hasRequiredInv()) {
+ return;
+ }
+
+ wasSprinting = player.isSprinting();
+ flightHandler.createInstance(player, this.getName());
+ player.setAllowFlight(true);
+
+ start();
+ launchHook();
+ }
+
+ public void setFields() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ cooldown = config.getLong("Abilities.Earth.MetalHook.Cooldown");
+ range = config.getInt("Abilities.Earth.MetalHook.Range");
+ maxHooks = config.getInt("Abilities.Earth.MetalHook.MaxHooks");
+ totalHooks = config.getInt("Abilities.Earth.MetalHook.TotalHooks");
+ noSource = config.getBoolean("Abilities.Earth.MetalHook.RequireItem");
+ barrierHooking = config.getBoolean("Abilities.Earth.MetalHook.BarrierHooking");
+ }
+
+ @Override
+ public void progress() {
+ if (player == null || !player.isOnline() || player.isDead()) {
+ removeAllArrows();
+ remove();
+ return;
+ }
+
+ if (!bPlayer.canBendIgnoreBindsCooldowns(this) || hooks.isEmpty()) {
+ removeAllArrows();
+ remove();
+ return;
+ }
+
+ if (!wasSprinting && player.isSprinting()) {
+ removeAllArrows();
+ remove();
+ return;
+ }
+
+ wasSprinting = player.isSprinting();
+
+ if (player.isSneaking()) {
+ player.setVelocity(new Vector());
+
+ if (System.currentTimeMillis() > (time + 1000)) {
+ removeAllArrows();
+ remove();
+ return;
+ }
+ } else {
+ time = System.currentTimeMillis();
+ }
+
+ Vector target = new Vector();
+
+ for (Arrow a : hooks.keySet()) {
+ if (a != null) {
+ if (!isActiveArrow(a)) {
+ hooks.remove(a);
+ hookIds.remove(a.getUniqueId());
+ a.remove();
+ continue;
+ }
+
+ if (a.getAttachedBlock() == null) {
+ hooks.replace(a, hooks.get(a), false);
+ } else {
+ hooks.replace(a, hooks.get(a), true);
+ hasHook = true;
+ }
+
+ //Draws the particle lines.
+ for (Location location : JCMethods.getLinePoints(player.getLocation().add(0, 1, 0), a.getLocation(), ((int) player.getLocation().add(0,1,0).distance(a.getLocation()) * 2))) {
+ GeneralMethods.displayColoredParticle("#CCCCCC", location);
+ }
+
+ if (hooks.get(a)) {
+ target.add(GeneralMethods.getDirection(player.getEyeLocation(), a.getLocation()));
+ }
+ }
+ }
+
+ if (hasHook) {
+ destination = player.getLocation().clone().add(target);
+
+ if (player.getLocation().distance(destination) > 2) {
+ player.setFlying(false);
+ double velocity = 0.8;
+
+ GeneralMethods.setVelocity(this, player, target.clone().normalize().multiply(velocity));
+ } else if (player.getLocation().distance(destination) < 2 && player.getLocation().distance(destination) >= 1) {
+ player.setFlying(false);
+ double velocity = 0.35;
+
+ GeneralMethods.setVelocity(this, player, target.clone().normalize().multiply(velocity));
+ } else {
+ GeneralMethods.setVelocity(this, player, new Vector(0, 0, 0));
+
+ if (player.getAllowFlight()) {
+ player.setFlying(true);
+ }
+ }
+ }
+ }
+
+ private boolean isActiveArrow(Arrow arrow) {
+ if (arrow.isDead()) return false;
+ if (player.getWorld() != arrow.getWorld()) return false;
+
+ Block attached = arrow.getAttachedBlock();
+
+ if (!barrierHooking && attached != null && attached.getType() == Material.BARRIER) return false;
+
+ return player.getEyeLocation().distanceSquared(arrow.getLocation()) < range * range;
+ }
+
+ @Override
+ public void remove() {
+ if (player.isOnline()) {
+ bPlayer.addCooldown(this);
+ }
+
+ flightHandler.removeInstance(player, this.getName());
+
+ super.remove();
+ }
+
+ public void launchHook() {
+ if (!hasRequiredInv()) return;
+
+ Vector dir = GeneralMethods.getDirection(player.getEyeLocation(), GeneralMethods.getTargetedLocation(player, range));
+
+ if (!hookIds.isEmpty() && hookIds.size() > (maxHooks - 1)) {
+ for (Arrow a : hooks.keySet()) {
+ if (a.getUniqueId().equals(hookIds.get(0))) {
+ hooks.remove(a);
+ hookIds.remove(0);
+ a.remove();
+ break;
+ }
+ }
+ }
+
+ if (totalHooks > 0 && hooksUsed++ > totalHooks) {
+ remove();
+ return;
+ }
+
+ Arrow a = player.getWorld().spawnArrow(player.getEyeLocation().add(player.getLocation().getDirection().multiply(2)), dir, 3, 0f);
+ a.setMetadata("metalhook", new FixedMetadataValue(JedCore.plugin, "1"));
+
+ hooks.put(a, false);
+ hookIds.add(a.getUniqueId());
+ }
+
+ public void removeAllArrows() {
+ for (Arrow a : hooks.keySet()) {
+ a.remove();
+ }
+ }
+
+ public boolean hasRequiredInv() {
+ if (noSource) return true;
+
+ if (player.getInventory().getChestplate() != null) {
+ Material[] chestplates = {Material.IRON_CHESTPLATE, Material.CHAINMAIL_CHESTPLATE};
+ Material playerChest = player.getInventory().getChestplate().getType();
+
+ if (Arrays.asList(chestplates).contains(playerChest)) {
+ return true;
+ }
+ }
+
+ Material[] metals = {Material.IRON_INGOT, Material.IRON_BLOCK};
+
+ for (ItemStack items : player.getInventory()) {
+ if (items != null && Arrays.asList(metals).contains(items.getType())) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public int getMaxHooks() {
+ return this.maxHooks;
+ }
+
+ public void setMaxHooks(int maxhooks) {
+ this.maxHooks = maxhooks;
+ }
+
+ @Override
+ public long getCooldown() {
+ return cooldown;
+ }
+
+ @Override
+ public Location getLocation() {
+ return null;
+ }
+
+ @Override
+ public String getName() {
+ return "MetalHook";
+ }
+
+ @Override
+ public boolean isHarmlessAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isSneakAbility() {
+ return true;
+ }
+
+ @Override
+ public String getAuthor() {
+ return JedCore.dev;
+ }
+
+ @Override
+ public String getVersion() {
+ return JedCore.version;
+ }
+
+ @Override
+ public String getDescription() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return "* JedCore Addon *\n" + config.getString("Abilities.Earth.MetalHook.Description");
+ }
+
+ public void setCooldown(long cooldown) {
+ this.cooldown = cooldown;
+ }
+
+ public int getRange() {
+ return range;
+ }
+
+ public void setRange(int range) {
+ this.range = range;
+ }
+
+ public int getTotalHooks() {
+ return totalHooks;
+ }
+
+ public void setTotalHooks(int totalHooks) {
+ this.totalHooks = totalHooks;
+ }
+
+ public int getHooksUsed() {
+ return hooksUsed;
+ }
+
+ public void setHooksUsed(int hooksUsed) {
+ this.hooksUsed = hooksUsed;
+ }
+
+ public boolean isNoSource() {
+ return noSource;
+ }
+
+ public void setNoSource(boolean noSource) {
+ this.noSource = noSource;
+ }
+
+ public boolean isBarrierHooking() {
+ return barrierHooking;
+ }
+
+ public void setBarrierHooking(boolean barrierHooking) {
+ this.barrierHooking = barrierHooking;
+ }
+
+ public boolean isHasHook() {
+ return hasHook;
+ }
+
+ public void setHasHook(boolean hasHook) {
+ this.hasHook = hasHook;
+ }
+
+ public boolean isWasSprinting() {
+ return wasSprinting;
+ }
+
+ public void setWasSprinting(boolean wasSprinting) {
+ this.wasSprinting = wasSprinting;
+ }
+
+ public long getTime() {
+ return time;
+ }
+
+ public void setTime(long time) {
+ this.time = time;
+ }
+
+ public Location getDestination() {
+ return destination;
+ }
+
+ public void setDestination(Location destination) {
+ this.destination = destination;
+ }
+
+ public ConcurrentHashMap getHooks() {
+ return hooks;
+ }
+
+ public List getHookIds() {
+ return hookIds;
+ }
+
+ @Override
+ public void load() {}
+
+ @Override
+ public void stop() {}
+
+ @Override
+ public boolean isEnabled() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getBoolean("Abilities.Earth.MetalHook.Enabled");
+ }
+}
\ No newline at end of file
diff --git a/src/com/jedk1/jedcore/ability/earthbending/MetalShred.java b/src/com/jedk1/jedcore/ability/earthbending/MetalShred.java
index ef79f8c..dac3122 100644
--- a/src/com/jedk1/jedcore/ability/earthbending/MetalShred.java
+++ b/src/com/jedk1/jedcore/ability/earthbending/MetalShred.java
@@ -4,6 +4,7 @@
import com.jedk1.jedcore.configuration.JedCoreConfig;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AddonAbility;
+import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.ElementalAbility;
import com.projectkorra.projectkorra.ability.MetalAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
@@ -13,7 +14,6 @@
import com.projectkorra.projectkorra.util.ClickType;
import com.projectkorra.projectkorra.util.DamageHandler;
import com.projectkorra.projectkorra.util.TempBlock;
-
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
@@ -29,455 +29,458 @@
public class MetalShred extends MetalAbility implements AddonAbility {
- @Attribute(Attribute.SELECT_RANGE)
- private int selectRange;
- private int extendTick;
- @Attribute(Attribute.DAMAGE)
- private double damage;
-
- private boolean horizontal = false;
- private boolean started = false;
- private boolean stop = false;
- private boolean stopCoil = false;
- private boolean extending = false;
- private int length = 0;
- private int fullLength = 0;
- private long lastExtendTime;
- private Block source;
- private Block lastBlock;
- private final List tblocks = new ArrayList<>();
-
- public MetalShred(Player player) {
- super(player);
-
- if (hasAbility(player, MetalShred.class)) {
- getAbility(player, MetalShred.class).remove();
- }
-
- if (!bPlayer.canBend(this)) {
- return;
- }
-
- setFields();
-
- if (selectSource()) {
- if (horizontal) {
- raiseBlock(source, GeneralMethods.getDirection(player.getLocation(), source.getLocation()));
- } else {
- shiftBlock(source, GeneralMethods.getDirection(player.getLocation(), source.getLocation()));
- }
-
- start();
- }
- }
-
- public void setFields() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- selectRange = config.getInt("Abilities.Earth.MetalShred.SourceRange");
- extendTick = config.getInt("Abilities.Earth.MetalShred.ExtendTick");
- damage = config.getDouble("Abilities.Earth.MetalShred.Damage");
- }
-
- public boolean selectSource() {
- Block b = BlockSource.getEarthSourceBlock(player, selectRange, ClickType.SHIFT_DOWN);
-
- if (!isMetal(b))
- return false;
-
- source = b;
-
- if (ElementalAbility.isAir(source.getRelative(BlockFace.UP).getType()) && !isMetal(source.getRelative(BlockFace.DOWN))) {
- horizontal = true;
- }
-
- return true;
- }
-
- public void raiseBlock(Block b, Vector d) {
- Block up = b.getRelative(BlockFace.UP);
- Block away = b.getRelative(GeneralMethods.getCardinalDirection(d));
- Block awayup = away.getRelative(BlockFace.UP);
- Block deeperb = b.getRelative(BlockFace.DOWN);
- Block deepera = away.getRelative(BlockFace.DOWN);
-
- for (TempBlock tb : tblocks) {
- if (!ElementalAbility.isAir(tb.getBlock().getType()))
- tb.setType(Material.AIR);
- }
-
- if (!up.getType().isSolid()) {
- TempBlock tbu = new TempBlock(up, b.getBlockData());
- tblocks.add(tbu);
- }
-
- if (!awayup.getType().isSolid()) {
- TempBlock tbau = new TempBlock(awayup, away.getBlockData());
- tblocks.add(tbau);
- }
-
- if (isMetal(b)) {
- TempBlock tbd = new TempBlock(b, Material.AIR.createBlockData());
- tblocks.add(tbd);
- }
-
- if (isMetal(away)) {
- TempBlock tba = new TempBlock(away, Material.AIR.createBlockData());
- tblocks.add(tba);
- }
-
- if (isMetal(deeperb)) {
- TempBlock tbdb = new TempBlock(deeperb, Material.AIR.createBlockData());
- tblocks.add(tbdb);
- }
-
- if (isMetal(deepera)) {
- TempBlock tbda = new TempBlock(deepera, Material.AIR.createBlockData());
- tblocks.add(tbda);
- }
-
- playMetalbendingSound(b.getLocation());
- }
-
- public void shiftBlock(Block b, Vector d) {
- Block under = b.getRelative(BlockFace.DOWN);
- Block side = b.getRelative(GeneralMethods.getCardinalDirection(d).getOppositeFace());
- Block underside = under.getRelative(GeneralMethods.getCardinalDirection(d).getOppositeFace());
-
- for (TempBlock tb : tblocks) {
- if (!ElementalAbility.isAir(tb.getBlock().getType()))
- tb.setType(Material.AIR);
- }
-
- if (!side.getType().isSolid()) {
- TempBlock tbs = new TempBlock(side, b.getBlockData());
- tblocks.add(tbs);
- }
-
- if (!underside.getType().isSolid()) {
- TempBlock tbus = new TempBlock(underside, under.getBlockData());
- tblocks.add(tbus);
- }
-
- if (isMetal(b)) {
- TempBlock tb1 = new TempBlock(b, Material.AIR.createBlockData());
- tblocks.add(tb1);
- }
-
- if (isMetal(under)) {
- TempBlock tb2 = new TempBlock(under, Material.AIR.createBlockData());
- tblocks.add(tb2);
- }
-
- playMetalbendingSound(b.getLocation());
- }
-
- private void peelCoil(Block b) {
- Block under = b.getRelative(BlockFace.DOWN);
-
- if (length <= 0)
- return;
-
- if (!b.getType().isSolid()) {
- TempBlock tbb = new TempBlock(b, Material.IRON_BLOCK.createBlockData());
- tblocks.add(tbb);
- }
-
- else
- stopCoil = true;
-
- if (!under.getType().isSolid()) {
- TempBlock tbu = new TempBlock(under, Material.IRON_BLOCK.createBlockData());
- tblocks.add(tbu);
- }
-
- else
- stopCoil = true;
-
- playMetalbendingSound(b.getLocation());
-
- length--;
- }
-
- public static void startShred(Player player) {
- if (hasAbility(player, MetalShred.class)) {
- getAbility(player, MetalShred.class).startShred();
- }
- }
-
- private void startShred() {
- started = true;
- }
-
- public static void extend(Player player) {
- if (hasAbility(player, MetalShred.class)) {
- getAbility(player, MetalShred.class).extend();
- }
- }
-
- private void extend() {
- if (extending) {
- extending = false;
- return;
- }
-
- if (!stop)
- return;
-
- lastExtendTime = System.currentTimeMillis();
- fullLength = length;
- if (lastBlock != null)
- lastBlock = lastBlock.getRelative(GeneralMethods.getCardinalDirection(GeneralMethods.getDirection(player.getLocation(), lastBlock.getLocation())).getOppositeFace());
- else {
- return;
- }
- extending = true;
- }
-
- @Override
- public void progress() {
- if (!player.isOnline() || player.isDead()) {
- remove();
- return;
- }
-
- if (!bPlayer.canBendIgnoreCooldowns(this)) {
- remove();
- return;
- }
-
- if (!player.isSprinting()) {
- if (started)
- stop = true;
- }
-
- if (!horizontal && stop && !stopCoil && extending && System.currentTimeMillis() > lastExtendTime + extendTick) {
- lastExtendTime = System.currentTimeMillis();
- if (length > 0) {
-
- Block b = lastBlock.getRelative(GeneralMethods.getCardinalDirection(GeneralMethods.getDirection(lastBlock.getLocation(), GeneralMethods.getTargetedLocation(player, fullLength))));
-
- peelCoil(b);
-
- for (Entity e : GeneralMethods.getEntitiesAroundPoint(b.getLocation(), 2)) {
- if (!(e instanceof LivingEntity) || e.getEntityId() == player.getEntityId()) {
- continue;
- }
- if (RegionProtection.isRegionProtected(this, e.getLocation()) || ((e instanceof Player) && Commands.invincible.contains(e.getName()))) {
- continue;
- }
- DamageHandler.damageEntity(e, damage, this);
- GeneralMethods.setVelocity(this, e, e.getVelocity().add(player.getLocation().getDirection().add(new Vector(0, 0.1, 0))));
- }
-
- lastBlock = b;
- }
-
- return;
- }
-
- if (stop || !started)
- return;
-
- Block b;
-
- if (lastBlock != null) {
- b = lastBlock.getRelative(GeneralMethods.getCardinalDirection(player.getLocation().getDirection()));
- }
-
- else {
- b = source.getRelative(GeneralMethods.getCardinalDirection(player.getLocation().getDirection()));
- }
-
- if (!isMetal(b)) {
- if (!ElementalAbility.isAir(b.getType())) {
- remove();
- }
- return;
- }
-
- if (b.getLocation().getX() == player.getLocation().getBlockX() || b.getLocation().getZ() == player.getLocation().getBlockZ()) {
- if (horizontal)
- raiseBlock(b, GeneralMethods.getDirection(player.getLocation(), b.getLocation()));
- else
- shiftBlock(b, GeneralMethods.getDirection(player.getLocation(), b.getLocation()));
-
- length++;
- lastBlock = b;
- }
- }
-
- private void revertAll() {
- for (TempBlock tb : tblocks) {
- tb.revertBlock();
- }
- }
-
- @Override
- public void remove() {
- revertAll();
- super.remove();
- }
-
- @Override
- public long getCooldown() {
- return 0;
- }
-
- @Override
- public Location getLocation() {
- return null;
- }
-
- @Override
- public String getName() {
- return "MetalShred";
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return true;
- }
-
- @Override
- public String getAuthor() {
- return JedCore.dev;
- }
-
- @Override
- public String getVersion() {
- return JedCore.version;
- }
-
- @Override
- public String getDescription() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return "* JedCore Addon *\n" + config.getString("Abilities.Earth.MetalShred.Description");
- }
-
- public int getSelectRange() {
- return selectRange;
- }
-
- public void setSelectRange(int selectRange) {
- this.selectRange = selectRange;
- }
-
- public int getExtendTick() {
- return extendTick;
- }
-
- public void setExtendTick(int extendTick) {
- this.extendTick = extendTick;
- }
-
- public double getDamage() {
- return damage;
- }
-
- public void setDamage(double damage) {
- this.damage = damage;
- }
-
- public boolean isHorizontal() {
- return horizontal;
- }
-
- public void setHorizontal(boolean horizontal) {
- this.horizontal = horizontal;
- }
-
- @Override
- public boolean isStarted() {
- return started;
- }
-
- public void setStarted(boolean started) {
- this.started = started;
- }
-
- public boolean isStop() {
- return stop;
- }
-
- public void setStop(boolean stop) {
- this.stop = stop;
- }
-
- public boolean isStopCoil() {
- return stopCoil;
- }
-
- public void setStopCoil(boolean stopCoil) {
- this.stopCoil = stopCoil;
- }
-
- public boolean isExtending() {
- return extending;
- }
-
- public void setExtending(boolean extending) {
- this.extending = extending;
- }
-
- public int getLength() {
- return length;
- }
-
- public void setLength(int length) {
- this.length = length;
- }
-
- public int getFullLength() {
- return fullLength;
- }
-
- public void setFullLength(int fullLength) {
- this.fullLength = fullLength;
- }
-
- public long getLastExtendTime() {
- return lastExtendTime;
- }
-
- public void setLastExtendTime(long lastExtendTime) {
- this.lastExtendTime = lastExtendTime;
- }
-
- public Block getSource() {
- return source;
- }
-
- public void setSource(Block source) {
- this.source = source;
- }
-
- public Block getLastBlock() {
- return lastBlock;
- }
-
- public void setLastBlock(Block lastBlock) {
- this.lastBlock = lastBlock;
- }
-
- public List getTblocks() {
- return tblocks;
- }
-
- @Override
- public void load() {}
+ @Attribute(Attribute.SELECT_RANGE)
+ private int selectRange;
+ private int extendTick;
+ @Attribute(Attribute.DAMAGE)
+ private double damage;
+
+ private boolean horizontal = false;
+ private boolean started = false;
+ private boolean stop = false;
+ private boolean stopCoil = false;
+ private boolean extending = false;
+ private int length = 0;
+ private int fullLength = 0;
+ private long lastExtendTime;
+ private Block source;
+ private Block lastBlock;
+ private final List tblocks = new ArrayList<>();
+
+ public MetalShred(Player player) {
+ super(player);
+
+ if (hasAbility(player, MetalShred.class)) {
+ getAbility(player, MetalShred.class).remove();
+ }
+
+ if (!bPlayer.canBend(this)) {
+ return;
+ }
+
+ setFields();
+
+ if (selectSource()) {
+ if (horizontal) {
+ raiseBlock(source, GeneralMethods.getDirection(player.getLocation(), source.getLocation()));
+ } else {
+ shiftBlock(source, GeneralMethods.getDirection(player.getLocation(), source.getLocation()));
+ }
+
+ start();
+ }
+ }
+
+ public void setFields() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ selectRange = config.getInt("Abilities.Earth.MetalShred.SourceRange");
+ extendTick = config.getInt("Abilities.Earth.MetalShred.ExtendTick");
+ damage = config.getDouble("Abilities.Earth.MetalShred.Damage");
+ }
+
+ public boolean selectSource() {
+ Block b = BlockSource.getEarthSourceBlock(player, selectRange, ClickType.SHIFT_DOWN);
+
+ if (EarthAbility.getMovedEarth().containsKey(b))
+ return false;
+
+ if (!isMetal(b))
+ return false;
+
+ source = b;
+
+ if (ElementalAbility.isAir(source.getRelative(BlockFace.UP).getType()) && !isMetal(source.getRelative(BlockFace.DOWN))) {
+ horizontal = true;
+ }
+
+ return true;
+ }
+
+ public void raiseBlock(Block b, Vector d) {
+ Block up = b.getRelative(BlockFace.UP);
+ Block away = b.getRelative(GeneralMethods.getCardinalDirection(d));
+ Block awayup = away.getRelative(BlockFace.UP);
+ Block deeperb = b.getRelative(BlockFace.DOWN);
+ Block deepera = away.getRelative(BlockFace.DOWN);
+
+ for (TempBlock tb : tblocks) {
+ if (!ElementalAbility.isAir(tb.getBlock().getType()))
+ tb.setType(Material.AIR);
+ }
+
+ if (!up.getType().isSolid()) {
+ TempBlock tbu = new TempBlock(up, b.getBlockData());
+ tblocks.add(tbu);
+ }
+
+ if (!awayup.getType().isSolid()) {
+ TempBlock tbau = new TempBlock(awayup, away.getBlockData());
+ tblocks.add(tbau);
+ }
+
+ if (isMetal(b)) {
+ TempBlock tbd = new TempBlock(b, Material.AIR.createBlockData());
+ tblocks.add(tbd);
+ }
+
+ if (isMetal(away)) {
+ TempBlock tba = new TempBlock(away, Material.AIR.createBlockData());
+ tblocks.add(tba);
+ }
+
+ if (isMetal(deeperb)) {
+ TempBlock tbdb = new TempBlock(deeperb, Material.AIR.createBlockData());
+ tblocks.add(tbdb);
+ }
+
+ if (isMetal(deepera)) {
+ TempBlock tbda = new TempBlock(deepera, Material.AIR.createBlockData());
+ tblocks.add(tbda);
+ }
+
+ playMetalbendingSound(b.getLocation());
+ }
+
+ public void shiftBlock(Block b, Vector d) {
+ Block under = b.getRelative(BlockFace.DOWN);
+ Block side = b.getRelative(GeneralMethods.getCardinalDirection(d).getOppositeFace());
+ Block underside = under.getRelative(GeneralMethods.getCardinalDirection(d).getOppositeFace());
+
+ for (TempBlock tb : tblocks) {
+ if (!ElementalAbility.isAir(tb.getBlock().getType()))
+ tb.setType(Material.AIR);
+ }
+
+ if (!side.getType().isSolid()) {
+ TempBlock tbs = new TempBlock(side, b.getBlockData());
+ tblocks.add(tbs);
+ }
+
+ if (!underside.getType().isSolid()) {
+ TempBlock tbus = new TempBlock(underside, under.getBlockData());
+ tblocks.add(tbus);
+ }
+
+ if (isMetal(b)) {
+ TempBlock tb1 = new TempBlock(b, Material.AIR.createBlockData());
+ tblocks.add(tb1);
+ }
+
+ if (isMetal(under)) {
+ TempBlock tb2 = new TempBlock(under, Material.AIR.createBlockData());
+ tblocks.add(tb2);
+ }
+
+ playMetalbendingSound(b.getLocation());
+ }
+
+ private void peelCoil(Block b) {
+ Block under = b.getRelative(BlockFace.DOWN);
+
+ if (length <= 0)
+ return;
+
+ if (!b.getType().isSolid()) {
+ TempBlock tbb = new TempBlock(b, Material.IRON_BLOCK.createBlockData());
+ tblocks.add(tbb);
+ }
+
+ else
+ stopCoil = true;
+
+ if (!under.getType().isSolid()) {
+ TempBlock tbu = new TempBlock(under, Material.IRON_BLOCK.createBlockData());
+ tblocks.add(tbu);
+ }
+
+ else
+ stopCoil = true;
+
+ playMetalbendingSound(b.getLocation());
+
+ length--;
+ }
+
+ public static void startShred(Player player) {
+ if (hasAbility(player, MetalShred.class)) {
+ getAbility(player, MetalShred.class).startShred();
+ }
+ }
+
+ private void startShred() {
+ started = true;
+ }
+
+ public static void extend(Player player) {
+ if (hasAbility(player, MetalShred.class)) {
+ getAbility(player, MetalShred.class).extend();
+ }
+ }
+
+ private void extend() {
+ if (extending) {
+ extending = false;
+ return;
+ }
+
+ if (!stop)
+ return;
+
+ lastExtendTime = System.currentTimeMillis();
+ fullLength = length;
+ if (lastBlock != null)
+ lastBlock = lastBlock.getRelative(GeneralMethods.getCardinalDirection(GeneralMethods.getDirection(player.getLocation(), lastBlock.getLocation())).getOppositeFace());
+ else {
+ return;
+ }
+ extending = true;
+ }
+
+ @Override
+ public void progress() {
+ if (!player.isOnline() || player.isDead()) {
+ remove();
+ return;
+ }
+
+ if (!bPlayer.canBendIgnoreCooldowns(this)) {
+ remove();
+ return;
+ }
+
+ if (!player.isSprinting()) {
+ if (started)
+ stop = true;
+ }
+
+ if (!horizontal && stop && !stopCoil && extending && System.currentTimeMillis() > lastExtendTime + extendTick) {
+ lastExtendTime = System.currentTimeMillis();
+ if (length > 0) {
+
+ Block b = lastBlock.getRelative(GeneralMethods.getCardinalDirection(GeneralMethods.getDirection(lastBlock.getLocation(), GeneralMethods.getTargetedLocation(player, fullLength))));
+
+ peelCoil(b);
+
+ for (Entity e : GeneralMethods.getEntitiesAroundPoint(b.getLocation(), 2)) {
+ if (!(e instanceof LivingEntity) || e.getEntityId() == player.getEntityId()) {
+ continue;
+ }
+ if (RegionProtection.isRegionProtected(this, e.getLocation()) || ((e instanceof Player) && Commands.invincible.contains(e.getName()))) {
+ continue;
+ }
+ DamageHandler.damageEntity(e, damage, this);
+ GeneralMethods.setVelocity(this, e, e.getVelocity().add(player.getLocation().getDirection().add(new Vector(0, 0.1, 0))));
+ }
+
+ lastBlock = b;
+ }
+
+ return;
+ }
+
+ if (stop || !started)
+ return;
+
+ Block b;
+
+ if (lastBlock != null) {
+ b = lastBlock.getRelative(GeneralMethods.getCardinalDirection(player.getLocation().getDirection()));
+ }
+
+ else {
+ b = source.getRelative(GeneralMethods.getCardinalDirection(player.getLocation().getDirection()));
+ }
+
+ if (!isMetal(b)) {
+ if (!ElementalAbility.isAir(b.getType())) {
+ remove();
+ }
+ return;
+ }
+
+ if (b.getLocation().getX() == player.getLocation().getBlockX() || b.getLocation().getZ() == player.getLocation().getBlockZ()) {
+ if (horizontal)
+ raiseBlock(b, GeneralMethods.getDirection(player.getLocation(), b.getLocation()));
+ else
+ shiftBlock(b, GeneralMethods.getDirection(player.getLocation(), b.getLocation()));
+
+ length++;
+ lastBlock = b;
+ }
+ }
+
+ private void revertAll() {
+ for (TempBlock tb : tblocks) {
+ tb.revertBlock();
+ }
+ }
+
+ @Override
+ public void remove() {
+ revertAll();
+ super.remove();
+ }
+
+ @Override
+ public long getCooldown() {
+ return 0;
+ }
+
+ @Override
+ public Location getLocation() {
+ return null;
+ }
+
+ @Override
+ public String getName() {
+ return "MetalShred";
+ }
+
+ @Override
+ public boolean isHarmlessAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isSneakAbility() {
+ return true;
+ }
+
+ @Override
+ public String getAuthor() {
+ return JedCore.dev;
+ }
+
+ @Override
+ public String getVersion() {
+ return JedCore.version;
+ }
+
+ @Override
+ public String getDescription() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return "* JedCore Addon *\n" + config.getString("Abilities.Earth.MetalShred.Description");
+ }
+
+ public int getSelectRange() {
+ return selectRange;
+ }
+
+ public void setSelectRange(int selectRange) {
+ this.selectRange = selectRange;
+ }
+
+ public int getExtendTick() {
+ return extendTick;
+ }
+
+ public void setExtendTick(int extendTick) {
+ this.extendTick = extendTick;
+ }
+
+ public double getDamage() {
+ return damage;
+ }
+
+ public void setDamage(double damage) {
+ this.damage = damage;
+ }
+
+ public boolean isHorizontal() {
+ return horizontal;
+ }
+
+ public void setHorizontal(boolean horizontal) {
+ this.horizontal = horizontal;
+ }
+
+ @Override
+ public boolean isStarted() {
+ return started;
+ }
+
+ public void setStarted(boolean started) {
+ this.started = started;
+ }
+
+ public boolean isStop() {
+ return stop;
+ }
+
+ public void setStop(boolean stop) {
+ this.stop = stop;
+ }
+
+ public boolean isStopCoil() {
+ return stopCoil;
+ }
+
+ public void setStopCoil(boolean stopCoil) {
+ this.stopCoil = stopCoil;
+ }
+
+ public boolean isExtending() {
+ return extending;
+ }
+
+ public void setExtending(boolean extending) {
+ this.extending = extending;
+ }
+
+ public int getLength() {
+ return length;
+ }
+
+ public void setLength(int length) {
+ this.length = length;
+ }
+
+ public int getFullLength() {
+ return fullLength;
+ }
+
+ public void setFullLength(int fullLength) {
+ this.fullLength = fullLength;
+ }
+
+ public long getLastExtendTime() {
+ return lastExtendTime;
+ }
+
+ public void setLastExtendTime(long lastExtendTime) {
+ this.lastExtendTime = lastExtendTime;
+ }
+
+ public Block getSource() {
+ return source;
+ }
+
+ public void setSource(Block source) {
+ this.source = source;
+ }
+
+ public Block getLastBlock() {
+ return lastBlock;
+ }
+
+ public void setLastBlock(Block lastBlock) {
+ this.lastBlock = lastBlock;
+ }
+
+ public List getTblocks() {
+ return tblocks;
+ }
+
+ @Override
+ public void load() {}
- @Override
- public void stop() {}
+ @Override
+ public void stop() {}
- @Override
- public boolean isEnabled() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getBoolean("Abilities.Earth.MetalShred.Enabled");
- }
-}
+ @Override
+ public boolean isEnabled() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getBoolean("Abilities.Earth.MetalShred.Enabled");
+ }
+}
\ No newline at end of file
diff --git a/src/com/jedk1/jedcore/ability/earthbending/MudSurge.java b/src/com/jedk1/jedcore/ability/earthbending/MudSurge.java
index 30e57f6..f704193 100644
--- a/src/com/jedk1/jedcore/ability/earthbending/MudSurge.java
+++ b/src/com/jedk1/jedcore/ability/earthbending/MudSurge.java
@@ -17,7 +17,6 @@
import com.projectkorra.projectkorra.region.RegionProtection;
import com.projectkorra.projectkorra.util.DamageHandler;
import com.projectkorra.projectkorra.util.TempBlock;
-
import com.projectkorra.projectkorra.util.TempFallingBlock;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -36,619 +35,648 @@
import java.util.stream.Collectors;
public class MudSurge extends EarthAbility implements AddonAbility {
- private int prepareRange;
- private int blindChance;
- private int blindTicks;
- private boolean multipleHits;
- @Attribute(Attribute.DAMAGE)
- private double damage;
- private int waves;
- private int waterSearchRadius;
- private boolean wetSource;
- @Attribute(Attribute.COOLDOWN)
- private long cooldown;
- @Attribute("CollisionRadius")
- private double collisionRadius;
-
- public static int surgeInterval = 300;
- public static int mudPoolRadius = 2;
- public static Set mudTypes = new HashSet<>();
-
- static {
- mudTypes.addAll(Arrays.asList(Material.SAND, Material.RED_SAND, Material.CLAY, Material.TERRACOTTA, Material.BLACK_TERRACOTTA, Material.BLUE_TERRACOTTA,
- Material.BROWN_TERRACOTTA, Material.CYAN_TERRACOTTA, Material.GRAY_TERRACOTTA, Material.GREEN_TERRACOTTA,
- Material.LIGHT_BLUE_TERRACOTTA, Material.LIGHT_GRAY_TERRACOTTA, Material.LIME_TERRACOTTA,
- Material.MAGENTA_TERRACOTTA, Material.ORANGE_TERRACOTTA, Material.PINK_TERRACOTTA,
- Material.PURPLE_TERRACOTTA, Material.RED_TERRACOTTA, Material.WHITE_TERRACOTTA, Material.YELLOW_TERRACOTTA,
- Material.GRASS_BLOCK, Material.DIRT, Material.MYCELIUM, Material.COARSE_DIRT,
- Material.SOUL_SAND, Material.SOUL_SOIL, Material.RED_SANDSTONE, Material.SANDSTONE, Material.CHISELED_SANDSTONE,
- Material.CHISELED_RED_SANDSTONE, Material.SMOOTH_SANDSTONE, Material.SMOOTH_RED_SANDSTONE, Material.CUT_SANDSTONE,
- Material.CUT_RED_SANDSTONE));
- if (GeneralMethods.getMCVersion() >= 1170) {
- mudTypes.add(Material.getMaterial("ROOTED_DIRT"));
- }
- if (GeneralMethods.getMCVersion() >= 1190) {
- mudTypes.add(Material.getMaterial("MUD"));
- mudTypes.add(Material.getMaterial("MUDDY_MANGROVE_ROOTS"));
- mudTypes.add(Material.getMaterial("PACKED_MUD"));
- }
- }
-
- private CompositeRemovalPolicy removalPolicy;
-
- private Block source;
-
- private int wavesOnTheRun = 0;
- private boolean mudFormed = false;
- private boolean doNotSurge = false;
- public boolean started = false;
-
- private final List mudArea = new ArrayList<>();
- private ListIterator mudAreaItr;
- private final List mudBlocks = new ArrayList<>();
- private final List blind = new ArrayList<>();
- private final List affectedEntities = new ArrayList<>();
-
- private final List fallingBlocks = new ArrayList<>();
-
- private final Random rand = new Random();
-
- public MudSurge(Player player) {
- super(player);
-
- if (!bPlayer.canBend(this)) {
- return;
- }
-
- if (hasAbility(player, MudSurge.class)) {
- MudSurge ms = getAbility(player, MudSurge.class);
- if (!ms.hasStarted()) {
- ms.remove();
- } else {
- return;
- }
- }
-
- this.removalPolicy = new CompositeRemovalPolicy(this,
- new CannotBendRemovalPolicy(this.bPlayer, this, true, true),
- new IsOfflineRemovalPolicy(this.player),
- new IsDeadRemovalPolicy(this.player),
- new OutOfRangeRemovalPolicy(this.player, 25.0, () -> this.source.getLocation()),
- new SwappedSlotsRemovalPolicy<>(bPlayer, MudSurge.class)
- );
-
- setFields();
-
- if (getSource()) {
- start();
- if (!isRemoved()) {
- loadMudPool();
- }
- }
- }
-
- public void setFields() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- this.removalPolicy.load(config);
-
- prepareRange = config.getInt("Abilities.Earth.MudSurge.SourceRange");
- blindChance = config.getInt("Abilities.Earth.MudSurge.BlindChance");
- damage = config.getDouble("Abilities.Earth.MudSurge.Damage");
- waves = config.getInt("Abilities.Earth.MudSurge.Waves");
- waterSearchRadius = config.getInt("Abilities.Earth.MudSurge.WaterSearchRadius");
- wetSource = config.getBoolean("Abilities.Earth.MudSurge.WetSourceOnly");
- cooldown = config.getLong("Abilities.Earth.MudSurge.Cooldown");
- blindTicks = config.getInt("Abilities.Earth.MudSurge.BlindTicks");
- multipleHits = config.getBoolean("Abilities.Earth.MudSurge.MultipleHits");
- collisionRadius = config.getDouble("Abilities.Earth.MudSurge.CollisionRadius");
- }
-
- @Override
- public void progress() {
- if (removalPolicy.shouldRemove()) {
- remove();
- return;
- }
-
- long lastSurgeTime = 0;
- if (mudFormed && started && System.currentTimeMillis() > lastSurgeTime + surgeInterval) {
- surge();
- affect();
- if (TempFallingBlock.getFromAbility(this).isEmpty()) {
- remove();
- return;
- }
- return;
- }
-
- if (!mudFormed) {
- createMudPool();
- }
- }
-
- private boolean getSource() {
- Block block = getMudSourceBlock(prepareRange);
-
- if (block != null) {
- if (isMudBlock(block)) {
- boolean water = true;
-
- if (wetSource) {
- water = false;
- List nearby = GeneralMethods.getBlocksAroundPoint(block.getLocation(), waterSearchRadius);
-
- for (Block b : nearby) {
- if (b.getType() == Material.WATER) {
- water = true;
- break;
- }
- }
- }
-
- if (water) {
- this.source = block;
- return true;
- }
- }
- }
-
- return false;
- }
-
- private void startSurge() {
- started = true;
- this.bPlayer.addCooldown(this);
-
- // Clear out the policies that only apply while sourcing.
- this.removalPolicy.removePolicyType(IsDeadRemovalPolicy.class);
- this.removalPolicy.removePolicyType(OutOfRangeRemovalPolicy.class);
- this.removalPolicy.removePolicyType(SwappedSlotsRemovalPolicy.class);
- }
-
- private boolean hasStarted() {
- return this.started;
- }
-
- public static boolean isSurgeBlock(Block block) {
- if (block.getType() != Material.BROWN_TERRACOTTA) {
- return false;
- }
-
- for (MudSurge surge : CoreAbility.getAbilities(MudSurge.class)) {
- if (surge.mudArea.contains(block)) {
- return true;
- }
- }
-
- return false;
- }
-
- // Returns true if the event should be cancelled.
- public static boolean onFallDamage(Player player) {
- BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
- if (bPlayer == null || !bPlayer.hasElement(Element.EARTH)) {
- return false;
- }
-
- ConfigurationSection config = JedCoreConfig.getConfig(player);
-
- boolean fallDamage = config.getBoolean("Abilities.Earth.MudSurge.AllowFallDamage");
- if (fallDamage) {
- return false;
- }
-
- Block block = player.getLocation().clone().subtract(0, 0.1, 0).getBlock();
- return isSurgeBlock(block);
- }
-
- public static void mudSurge(Player player) {
- if (!hasAbility(player, MudSurge.class))
- return;
-
- getAbility(player, MudSurge.class).startSurge();
- }
-
- private Block getMudSourceBlock(int range) {
- Block testBlock = GeneralMethods.getTargetedLocation(player, range, ElementalAbility.getTransparentMaterials()).getBlock();
- if (isMudBlock(testBlock))
- return testBlock;
-
- Location loc = player.getEyeLocation();
- Vector dir = player.getEyeLocation().getDirection().clone().normalize();
-
- for (int i = 0; i <= range; i++) {
- Block block = loc.clone().add(dir.clone().multiply(i == 0 ? 1 : i)).getBlock();
- if (RegionProtection.isRegionProtected(player, block.getLocation(), this))
- continue;
-
- if (isMudBlock(block))
- return block;
- }
-
- return null;
- }
-
- private boolean isMudBlock(Block block) {
- for (Material mat : mudTypes) {
- if (mat.name().equalsIgnoreCase(block.getType().name()))
- return true;
- }
-
- return false;
- }
-
- private void createMud(Block block) {
- mudBlocks.add(new TempBlock(block, Material.BROWN_TERRACOTTA.createBlockData()));
- }
-
- private void loadMudPool() {
- List area = GeneralMethods.getCircle(source.getLocation(), mudPoolRadius, 3, false, true, 0);
-
- for (Location l : area) {
- Block b = l.getBlock();
-
- if (isMudBlock(b)) {
- if (isTransparent(b.getRelative(BlockFace.UP))) {
- boolean water = true;
-
- if (wetSource) {
- water = false;
- List nearby = GeneralMethods.getBlocksAroundPoint(l, waterSearchRadius);
-
- for (Block block : nearby) {
- if (block.getType() == Material.WATER) {
- water = true;
- break;
- }
- }
- }
-
- if (water) {
- mudArea.add(b);
- playEarthbendingSound(b.getLocation());
- }
- }
- }
- }
-
- Collections.shuffle(mudArea);
- mudAreaItr = mudArea.listIterator();
- }
-
- private void createMudPool() {
- if (!mudAreaItr.hasNext()) {
- mudFormed = true;
- return;
- }
-
- Block b = mudAreaItr.next();
-
- if (b != null)
- createMud(b);
- }
-
- private void revertMudPool() {
- for (TempBlock tb : mudBlocks)
- tb.revertBlock();
-
- mudBlocks.clear();
- }
-
- private void surge() {
- if (wavesOnTheRun >= waves) {
- doNotSurge = true;
- return;
- }
-
- if (doNotSurge)
- return;
-
- for (TempBlock tb : mudBlocks) {
- Vector direction = GeneralMethods.getDirection(tb.getLocation().add(0, 1, 0), GeneralMethods.getTargetedLocation(player, 30)).multiply(0.07);
-
- double x = rand.nextDouble() / 5;
- double z = rand.nextDouble() / 5;
-
- x = (rand.nextBoolean()) ? -x : x;
- z = (rand.nextBoolean()) ? -z : z;
-
- fallingBlocks.add(new TempFallingBlock(tb.getLocation().add(0.5, 1, 0.5), Material.BROWN_TERRACOTTA.createBlockData(), direction.clone().add(new Vector(x, 0.2, z)), this));
-
- playEarthbendingSound(tb.getLocation());
- }
-
- wavesOnTheRun++;
- }
-
- private void affect() {
- for (TempFallingBlock tfb : TempFallingBlock.getFromAbility(this)) {
- FallingBlock fb = tfb.getFallingBlock();
- if (fb.isDead()) {
- tfb.remove();
- continue;
- }
-
- for (Entity e : GeneralMethods.getEntitiesAroundPoint(fb.getLocation(), 1.5)) {
- if (fb.isDead()) {
- tfb.remove();
- continue;
- }
- if (RegionProtection.isRegionProtected(this, e.getLocation()) || ((e instanceof Player) && Commands.invincible.contains(e.getName()))){
- continue;
- }
-
- if (e instanceof LivingEntity) {
- if (this.multipleHits || !this.affectedEntities.contains(e)) {
- DamageHandler.damageEntity(e, damage, this);
- if (!this.multipleHits) {
- this.affectedEntities.add(e);
- }
- }
-
- if (e instanceof Player) {
- if (e.getEntityId() == player.getEntityId())
- continue;
-
- if (rand.nextInt(100) < blindChance && !blind.contains(e)) {
- ((Player) e).addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, this.blindTicks, 2));
- }
-
- blind.add((Player) e);
- }
-
- e.setVelocity(fb.getVelocity().multiply(0.8));
- tfb.remove();
- }
- }
- }
- }
-
- @Override
- public void remove() {
- revertMudPool();
- super.remove();
- }
-
- @Override
- public long getCooldown() {
- return cooldown;
- }
-
- @Override
- public Location getLocation() {
- return null;
- }
-
- @Override
- public List getLocations() {
- return fallingBlocks.stream().map(TempFallingBlock::getLocation).collect(Collectors.toList());
- }
-
- @Override
- public void handleCollision(Collision collision) {
- CollisionUtil.handleFallingBlockCollisions(collision, fallingBlocks);
- }
-
- @Override
- public double getCollisionRadius() {
- return collisionRadius;
- }
-
- @Override
- public String getName() {
- return "MudSurge";
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return true;
- }
-
- @Override
- public String getAuthor() {
- return JedCore.dev;
- }
-
- @Override
- public String getVersion() {
- return JedCore.version;
- }
-
- @Override
- public String getDescription() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return "* JedCore Addon *\n" + config.getString("Abilities.Earth.MudSurge.Description");
- }
-
- public int getPrepareRange() {
- return prepareRange;
- }
-
- public void setPrepareRange(int prepareRange) {
- this.prepareRange = prepareRange;
- }
-
- public int getBlindChance() {
- return blindChance;
- }
-
- public void setBlindChance(int blindChance) {
- this.blindChance = blindChance;
- }
-
- public int getBlindTicks() {
- return blindTicks;
- }
-
- public void setBlindTicks(int blindTicks) {
- this.blindTicks = blindTicks;
- }
-
- public boolean isMultipleHits() {
- return multipleHits;
- }
-
- public void setMultipleHits(boolean multipleHits) {
- this.multipleHits = multipleHits;
- }
-
- public double getDamage() {
- return damage;
- }
-
- public void setDamage(double damage) {
- this.damage = damage;
- }
-
- public int getWaves() {
- return waves;
- }
-
- public void setWaves(int waves) {
- this.waves = waves;
- }
-
- public int getWaterSearchRadius() {
- return waterSearchRadius;
- }
-
- public void setWaterSearchRadius(int waterSearchRadius) {
- this.waterSearchRadius = waterSearchRadius;
- }
-
- public boolean isWetSource() {
- return wetSource;
- }
-
- public void setWetSource(boolean wetSource) {
- this.wetSource = wetSource;
- }
-
- public void setCooldown(long cooldown) {
- this.cooldown = cooldown;
- }
-
- public void setCollisionRadius(double collisionRadius) {
- this.collisionRadius = collisionRadius;
- }
-
- public static int getSurgeInterval() {
- return surgeInterval;
- }
-
- public static void setSurgeInterval(int surgeInterval) {
- MudSurge.surgeInterval = surgeInterval;
- }
-
- public static int getMudPoolRadius() {
- return mudPoolRadius;
- }
-
- public static void setMudPoolRadius(int mudPoolRadius) {
- MudSurge.mudPoolRadius = mudPoolRadius;
- }
-
- public static Material[] getMudTypes() {
- return mudTypes.toArray(new Material[0]);
- }
-
- public static Set getMudTypesSet() {
- return mudTypes;
- }
-
- public static void setMudTypes(Material[] mudTypes) {
- MudSurge.mudTypes.clear();
- MudSurge.mudTypes.addAll(Arrays.asList(mudTypes));
- }
-
- public CompositeRemovalPolicy getRemovalPolicy() {
- return removalPolicy;
- }
-
- public void setRemovalPolicy(CompositeRemovalPolicy removalPolicy) {
- this.removalPolicy = removalPolicy;
- }
-
- public void setSource(Block source) {
- this.source = source;
- }
-
- public int getWavesOnTheRun() {
- return wavesOnTheRun;
- }
-
- public void setWavesOnTheRun(int wavesOnTheRun) {
- this.wavesOnTheRun = wavesOnTheRun;
- }
-
- public boolean isMudFormed() {
- return mudFormed;
- }
-
- public void setMudFormed(boolean mudFormed) {
- this.mudFormed = mudFormed;
- }
-
- public boolean isDoNotSurge() {
- return doNotSurge;
- }
-
- public void setDoNotSurge(boolean doNotSurge) {
- this.doNotSurge = doNotSurge;
- }
-
- @Override
- public boolean isStarted() {
- return started;
- }
-
- public void setStarted(boolean started) {
- this.started = started;
- }
-
- public List getMudArea() {
- return mudArea;
- }
-
- public ListIterator getMudAreaItr() {
- return mudAreaItr;
- }
-
- public void setMudAreaItr(ListIterator mudAreaItr) {
- this.mudAreaItr = mudAreaItr;
- }
-
- public List getMudBlocks() {
- return mudBlocks;
- }
-
- public List getBlind() {
- return blind;
- }
-
- public List getAffectedEntities() {
- return affectedEntities;
- }
-
- public List getFallingBlocks() {
- return fallingBlocks;
- }
-
- @Override
- public void load() {}
-
- @Override
- public void stop() {}
+ private int prepareRange;
+ private int blindChance;
+ private int blindTicks;
+ private boolean multipleHits;
+ @Attribute(Attribute.DAMAGE)
+ private double damage;
+ private int waves;
+ private int waterSearchRadius;
+ private boolean wetSource;
+ @Attribute(Attribute.COOLDOWN)
+ private long cooldown;
+ @Attribute("CollisionRadius")
+ private double collisionRadius;
+
+ public static int surgeInterval = 300;
+ public static int mudPoolRadius = 2;
+ public static Set mudTypes = new HashSet<>();
+ private static Material mudType;
+
+ static {
+ mudType = Material.valueOf("BROWN_TERRACOTTA");
+ mudTypes.addAll(Arrays.asList(Material.SAND, Material.RED_SAND, Material.CLAY, Material.TERRACOTTA, Material.BLACK_TERRACOTTA, Material.BLUE_TERRACOTTA,
+ Material.BROWN_TERRACOTTA, Material.CYAN_TERRACOTTA, Material.GRAY_TERRACOTTA, Material.GREEN_TERRACOTTA,
+ Material.LIGHT_BLUE_TERRACOTTA, Material.LIGHT_GRAY_TERRACOTTA, Material.LIME_TERRACOTTA,
+ Material.MAGENTA_TERRACOTTA, Material.ORANGE_TERRACOTTA, Material.PINK_TERRACOTTA,
+ Material.PURPLE_TERRACOTTA, Material.RED_TERRACOTTA, Material.WHITE_TERRACOTTA, Material.YELLOW_TERRACOTTA,
+ Material.GRASS_BLOCK, Material.DIRT, Material.MYCELIUM, Material.COARSE_DIRT,
+ Material.SOUL_SAND, Material.SOUL_SOIL, Material.RED_SANDSTONE, Material.SANDSTONE, Material.CHISELED_SANDSTONE,
+ Material.CHISELED_RED_SANDSTONE, Material.SMOOTH_SANDSTONE, Material.SMOOTH_RED_SANDSTONE, Material.CUT_SANDSTONE,
+ Material.CUT_RED_SANDSTONE));
+ if (GeneralMethods.getMCVersion() >= 1170) {
+ mudTypes.add(Material.getMaterial("ROOTED_DIRT"));
+ }
+ if (GeneralMethods.getMCVersion() >= 1190) {
+ mudTypes.add(Material.getMaterial("MUD"));
+ mudTypes.add(Material.getMaterial("MUDDY_MANGROVE_ROOTS"));
+ mudTypes.add(Material.getMaterial("PACKED_MUD"));
+ mudType = Material.valueOf("MUD");
+ }
+ }
+
+ private CompositeRemovalPolicy removalPolicy;
+
+ private Block source;
+
+ private int wavesOnTheRun = 0;
+ private boolean mudFormed = false;
+ private boolean doNotSurge = false;
+ public boolean started = false;
+
+ private final List mudArea = new ArrayList<>();
+ private ListIterator mudAreaItr;
+ private final List mudBlocks = new ArrayList<>();
+ private final List blind = new ArrayList<>();
+ private final List affectedEntities = new ArrayList<>();
+
+ private final List fallingBlocks = new ArrayList<>();
+
+ private final Random rand = new Random();
+
+ public MudSurge(Player player) {
+ super(player);
+
+ if (!bPlayer.canBend(this)) {
+ return;
+ }
+
+ if (hasAbility(player, MudSurge.class)) {
+ MudSurge ms = getAbility(player, MudSurge.class);
+ if (!ms.hasStarted()) {
+ ms.remove();
+ } else {
+ return;
+ }
+ }
+
+ this.removalPolicy = new CompositeRemovalPolicy(this,
+ new CannotBendRemovalPolicy(this.bPlayer, this, true, true),
+ new IsOfflineRemovalPolicy(this.player),
+ new IsDeadRemovalPolicy(this.player),
+ new OutOfRangeRemovalPolicy(this.player, 25.0, () -> this.source.getLocation()),
+ new SwappedSlotsRemovalPolicy<>(bPlayer, MudSurge.class)
+ );
+
+ setFields();
+
+ if (getSource()) {
+ start();
+ if (!isRemoved()) {
+ loadMudPool();
+ }
+ }
+ }
+
+ public void setFields() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ this.removalPolicy.load(config);
+
+ prepareRange = config.getInt("Abilities.Earth.MudSurge.SourceRange");
+ blindChance = config.getInt("Abilities.Earth.MudSurge.BlindChance");
+ damage = config.getDouble("Abilities.Earth.MudSurge.Damage");
+ waves = config.getInt("Abilities.Earth.MudSurge.Waves");
+ waterSearchRadius = config.getInt("Abilities.Earth.MudSurge.WaterSearchRadius");
+ wetSource = config.getBoolean("Abilities.Earth.MudSurge.WetSourceOnly");
+ cooldown = config.getLong("Abilities.Earth.MudSurge.Cooldown");
+ blindTicks = config.getInt("Abilities.Earth.MudSurge.BlindTicks");
+ multipleHits = config.getBoolean("Abilities.Earth.MudSurge.MultipleHits");
+ collisionRadius = config.getDouble("Abilities.Earth.MudSurge.CollisionRadius");
+ }
+
+ @Override
+ public void progress() {
+ if (removalPolicy.shouldRemove()) {
+ remove();
+ return;
+ }
+
+ long lastSurgeTime = 0;
+ if (mudFormed && started && System.currentTimeMillis() > lastSurgeTime + surgeInterval) {
+ surge();
+ affect();
+ if (TempFallingBlock.getFromAbility(this).isEmpty()) {
+ remove();
+ return;
+ }
+ return;
+ }
+
+ if (!mudFormed) {
+ createMudPool();
+ }
+ }
+
+ private boolean getSource() {
+ Block block = getMudSourceBlock(prepareRange);
+
+ if (block != null) {
+ if (isMudBlock(block)) {
+ boolean water = true;
+
+ if (wetSource) {
+ water = false;
+ List nearby = GeneralMethods.getBlocksAroundPoint(block.getLocation(), waterSearchRadius);
+
+ for (Block b : nearby) {
+ if (b.getType() == Material.WATER) {
+ water = true;
+ break;
+ }
+ }
+ }
+
+ if (water) {
+ this.source = block;
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private boolean isValidMudSource(Block block) {
+ return block != null && !EarthAbility.getMovedEarth().containsKey(block);
+ }
+
+ private void startSurge() {
+ started = true;
+ this.bPlayer.addCooldown(this);
+
+ // Clear out the policies that only apply while sourcing.
+ this.removalPolicy.removePolicyType(IsDeadRemovalPolicy.class);
+ this.removalPolicy.removePolicyType(OutOfRangeRemovalPolicy.class);
+ this.removalPolicy.removePolicyType(SwappedSlotsRemovalPolicy.class);
+ }
+
+ private boolean hasStarted() {
+ return this.started;
+ }
+
+ public static boolean isSurgeBlock(Block block) {
+ if (block.getType() != Material.MUD) {
+ return false;
+ }
+
+ for (MudSurge surge : CoreAbility.getAbilities(MudSurge.class)) {
+ if (surge.mudArea.contains(block)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ // Returns true if the event should be cancelled.
+ public static boolean onFallDamage(Player player) {
+ BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
+ if (bPlayer == null || !bPlayer.hasElement(Element.EARTH)) {
+ return false;
+ }
+
+ ConfigurationSection config = JedCoreConfig.getConfig(player);
+
+ boolean fallDamage = config.getBoolean("Abilities.Earth.MudSurge.AllowFallDamage");
+ if (fallDamage) {
+ return false;
+ }
+
+ Block block = player.getLocation().clone().subtract(0, 0.1, 0).getBlock();
+ return isSurgeBlock(block);
+ }
+
+ public static void mudSurge(Player player) {
+ if (!hasAbility(player, MudSurge.class))
+ return;
+
+ getAbility(player, MudSurge.class).startSurge();
+ }
+
+ private Block getMudSourceBlock(int range) {
+ Block testBlock = GeneralMethods.getTargetedLocation(player, range, ElementalAbility.getTransparentMaterials()).getBlock();
+ if (isMudBlock(testBlock))
+ return testBlock;
+
+ Location loc = player.getEyeLocation();
+ Vector dir = player.getEyeLocation().getDirection().clone().normalize();
+
+ for (int i = 0; i <= range; i++) {
+ Block block = loc.clone().add(dir.clone().multiply(i == 0 ? 1 : i)).getBlock();
+ if (RegionProtection.isRegionProtected(player, block.getLocation(), this))
+ continue;
+
+ if (isMudBlock(block))
+ return block;
+ }
+
+ return null;
+ }
+
+ private boolean isMudBlock(Block block) {
+ for (Material mat : mudTypes) {
+ if (mat.name().equalsIgnoreCase(block.getType().name()))
+ return true;
+ }
+
+ return false;
+ }
+
+ private void createMud(Block block) {
+ mudBlocks.add(new TempBlock(block, mudType.createBlockData()));
+ }
+
+ private void loadMudPool() {
+ List area = GeneralMethods.getCircle(source.getLocation(), mudPoolRadius, 3, false, true, 0);
+
+ for (Location l : area) {
+ Block b = l.getBlock();
+
+ if (isMudBlock(b)) {
+ if (isTransparent(b.getRelative(BlockFace.UP))) {
+ boolean water = true;
+
+ if (wetSource) {
+ water = false;
+ List nearby = GeneralMethods.getBlocksAroundPoint(l, waterSearchRadius);
+
+ for (Block block : nearby) {
+ if (block.getType() == Material.WATER) {
+ water = true;
+ break;
+ }
+ }
+ }
+
+ if (water) {
+ mudArea.add(b);
+ playEarthbendingSound(b.getLocation());
+ }
+ }
+ }
+ }
+
+ Collections.shuffle(mudArea);
+ mudAreaItr = mudArea.listIterator();
+ }
+
+ private void createMudPool() {
+ // guard against a null iterator (safety) and handle empty iterator
+ if (mudAreaItr == null || !mudAreaItr.hasNext()) {
+ mudFormed = true;
+ return;
+ }
+
+ Block b = mudAreaItr.next();
+
+ if (b != null)
+ createMud(b);
+ }
+
+ private void revertMudPool() {
+ for (TempBlock tb : mudBlocks)
+ tb.revertBlock();
+
+ mudBlocks.clear();
+ }
+
+ private void surge() {
+ if (wavesOnTheRun >= waves) {
+ doNotSurge = true;
+ return;
+ }
+
+ if (doNotSurge)
+ return;
+
+ for (TempBlock tb : mudBlocks) {
+ Vector direction = GeneralMethods.getDirection(tb.getLocation().add(0, 1, 0), GeneralMethods.getTargetedLocation(player, 30)).multiply(0.07);
+
+ double x = rand.nextDouble() / 5;
+ double z = rand.nextDouble() / 5;
+
+ x = (rand.nextBoolean()) ? -x : x;
+ z = (rand.nextBoolean()) ? -z : z;
+
+ fallingBlocks.add(new TempFallingBlock(tb.getLocation().add(0.5, 1, 0.5), mudType.createBlockData(), direction.clone().add(new Vector(x, 0.2, z)), this));
+
+ playEarthbendingSound(tb.getLocation());
+ }
+
+ wavesOnTheRun++;
+ }
+
+ private void affect() {
+ // Copy the collection to avoid ConcurrentModificationExceptions if the underlying collection is mutated by tfb.remove()
+ List tempList = new ArrayList<>(TempFallingBlock.getFromAbility(this));
+
+ for (TempFallingBlock tfb : tempList) {
+ FallingBlock fb = tfb.getFallingBlock();
+ if (fb == null) {
+ // Defensive: if falling block not present, ensure TFb is removed from the original collection
+ try {
+ tfb.remove();
+ } catch (Exception ignored) {}
+ continue;
+ }
+
+ if (fb.isDead()) {
+ // Remove from both TFb internal registration and our local tracking if needed
+ try {
+ tfb.remove();
+ } catch (Exception ignored) {}
+ continue;
+ }
+
+ // Copy entity list as well just in case another plugin modifies entities mid-iteration
+ List entities = new ArrayList<>(GeneralMethods.getEntitiesAroundPoint(fb.getLocation(), 1.5));
+ for (Entity e : entities) {
+ if (fb.isDead()) {
+ try {
+ tfb.remove();
+ } catch (Exception ignored) {}
+ continue;
+ }
+ if (RegionProtection.isRegionProtected(this, e.getLocation()) || ((e instanceof Player) && Commands.invincible.contains(e.getName()))){
+ continue;
+ }
+
+ if (e instanceof LivingEntity) {
+ if (this.multipleHits || !this.affectedEntities.contains(e)) {
+ DamageHandler.damageEntity(e, damage, this);
+ if (!this.multipleHits) {
+ this.affectedEntities.add(e);
+ }
+ }
+
+ if (e instanceof Player) {
+ if (e.getEntityId() == player.getEntityId())
+ continue;
+
+ if (rand.nextInt(100) < blindChance && !blind.contains(e)) {
+ ((Player) e).addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, this.blindTicks, 2));
+ }
+
+ blind.add((Player) e);
+ }
+
+ // Apply velocity and then remove the falling block (safe because we're iterating a copy)
+ e.setVelocity(fb.getVelocity().multiply(0.8));
+ try {
+ tfb.remove();
+ } catch (Exception ignored) {}
+ }
+ }
+ }
+ }
+
+ @Override
+ public void remove() {
+ revertMudPool();
+ super.remove();
+ }
+
+ @Override
+ public long getCooldown() {
+ return cooldown;
+ }
+
+ @Override
+ public Location getLocation() {
+ return null;
+ }
+
+ @Override
+ public List getLocations() {
+ return fallingBlocks.stream().map(TempFallingBlock::getLocation).collect(Collectors.toList());
+ }
+
+ @Override
+ public void handleCollision(Collision collision) {
+ CollisionUtil.handleFallingBlockCollisions(collision, fallingBlocks);
+ }
+
+ @Override
+ public double getCollisionRadius() {
+ return collisionRadius;
+ }
+
+ @Override
+ public String getName() {
+ return "MudSurge";
+ }
+
+ @Override
+ public boolean isHarmlessAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isSneakAbility() {
+ return true;
+ }
+
+ @Override
+ public String getAuthor() {
+ return JedCore.dev;
+ }
+
+ @Override
+ public String getVersion() {
+ return JedCore.version;
+ }
+
+ @Override
+ public String getDescription() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return "* JedCore Addon *\n" + config.getString("Abilities.Earth.MudSurge.Description");
+ }
+
+ public int getPrepareRange() {
+ return prepareRange;
+ }
+
+ public void setPrepareRange(int prepareRange) {
+ this.prepareRange = prepareRange;
+ }
+
+ public int getBlindChance() {
+ return blindChance;
+ }
+
+ public void setBlindChance(int blindChance) {
+ this.blindChance = blindChance;
+ }
+
+ public int getBlindTicks() {
+ return blindTicks;
+ }
+
+ public void setBlindTicks(int blindTicks) {
+ this.blindTicks = blindTicks;
+ }
+
+ public boolean isMultipleHits() {
+ return multipleHits;
+ }
+
+ public void setMultipleHits(boolean multipleHits) {
+ this.multipleHits = multipleHits;
+ }
+
+ public double getDamage() {
+ return damage;
+ }
+
+ public void setDamage(double damage) {
+ this.damage = damage;
+ }
+
+ public int getWaves() {
+ return waves;
+ }
+
+ public void setWaves(int waves) {
+ this.waves = waves;
+ }
+
+ public int getWaterSearchRadius() {
+ return waterSearchRadius;
+ }
+
+ public void setWaterSearchRadius(int waterSearchRadius) {
+ this.waterSearchRadius = waterSearchRadius;
+ }
+
+ public boolean isWetSource() {
+ return wetSource;
+ }
+
+ public void setWetSource(boolean wetSource) {
+ this.wetSource = wetSource;
+ }
+
+ public void setCooldown(long cooldown) {
+ this.cooldown = cooldown;
+ }
+
+ public void setCollisionRadius(double collisionRadius) {
+ this.collisionRadius = collisionRadius;
+ }
+
+ public static int getSurgeInterval() {
+ return surgeInterval;
+ }
+
+ public static void setSurgeInterval(int surgeInterval) {
+ MudSurge.surgeInterval = surgeInterval;
+ }
+
+ public static int getMudPoolRadius() {
+ return mudPoolRadius;
+ }
+
+ public static void setMudPoolRadius(int mudPoolRadius) {
+ MudSurge.mudPoolRadius = mudPoolRadius;
+ }
+
+ public static Material[] getMudTypes() {
+ return mudTypes.toArray(new Material[0]);
+ }
+
+ public static Set getMudTypesSet() {
+ return mudTypes;
+ }
+
+ public static void setMudTypes(Material[] mudTypes) {
+ MudSurge.mudTypes.clear();
+ MudSurge.mudTypes.addAll(Arrays.asList(mudTypes));
+ }
+
+ public CompositeRemovalPolicy getRemovalPolicy() {
+ return removalPolicy;
+ }
+
+ public void setRemovalPolicy(CompositeRemovalPolicy removalPolicy) {
+ this.removalPolicy = removalPolicy;
+ }
+
+ public void setSource(Block source) {
+ this.source = source;
+ }
+
+ public int getWavesOnTheRun() {
+ return wavesOnTheRun;
+ }
+
+ public void setWavesOnTheRun(int wavesOnTheRun) {
+ this.wavesOnTheRun = wavesOnTheRun;
+ }
+
+ public boolean isMudFormed() {
+ return mudFormed;
+ }
+
+ public void setMudFormed(boolean mudFormed) {
+ this.mudFormed = mudFormed;
+ }
+
+ public boolean isDoNotSurge() {
+ return doNotSurge;
+ }
+
+ public void setDoNotSurge(boolean doNotSurge) {
+ this.doNotSurge = doNotSurge;
+ }
+
+ @Override
+ public boolean isStarted() {
+ return started;
+ }
+
+ public void setStarted(boolean started) {
+ this.started = started;
+ }
+
+ public List getMudArea() {
+ return mudArea;
+ }
+
+ public ListIterator getMudAreaItr() {
+ return mudAreaItr;
+ }
+
+ public void setMudAreaItr(ListIterator mudAreaItr) {
+ this.mudAreaItr = mudAreaItr;
+ }
+
+ public List getMudBlocks() {
+ return mudBlocks;
+ }
+
+ public List getBlind() {
+ return blind;
+ }
+
+ public List getAffectedEntities() {
+ return affectedEntities;
+ }
+
+ public List getFallingBlocks() {
+ return fallingBlocks;
+ }
+
+ @Override
+ public void load() {}
+
+ @Override
+ public void stop() {}
- @Override
- public boolean isEnabled() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getBoolean("Abilities.Earth.MudSurge.Enabled");
- }
+ @Override
+ public boolean isEnabled() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getBoolean("Abilities.Earth.MudSurge.Enabled");
+ }
}
diff --git a/src/com/jedk1/jedcore/ability/earthbending/SandBlast.java b/src/com/jedk1/jedcore/ability/earthbending/SandBlast.java
index cef279e..7c00908 100644
--- a/src/com/jedk1/jedcore/ability/earthbending/SandBlast.java
+++ b/src/com/jedk1/jedcore/ability/earthbending/SandBlast.java
@@ -4,17 +4,15 @@
import com.jedk1.jedcore.configuration.JedCoreConfig;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AddonAbility;
+import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.ElementalAbility;
import com.projectkorra.projectkorra.ability.SandAbility;
import com.projectkorra.projectkorra.ability.util.Collision;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.earthbending.passive.DensityShift;
import com.projectkorra.projectkorra.region.RegionProtection;
-import com.projectkorra.projectkorra.util.BlockSource;
-import com.projectkorra.projectkorra.util.ClickType;
import com.projectkorra.projectkorra.util.DamageHandler;
import com.projectkorra.projectkorra.util.TempBlock;
-
import com.projectkorra.projectkorra.util.TempFallingBlock;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -22,11 +20,7 @@
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.BlockData;
import org.bukkit.configuration.ConfigurationSection;
-import org.bukkit.entity.ArmorStand;
-import org.bukkit.entity.Entity;
-import org.bukkit.entity.FallingBlock;
-import org.bukkit.entity.LivingEntity;
-import org.bukkit.entity.Player;
+import org.bukkit.entity.*;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector;
@@ -39,341 +33,344 @@
public class SandBlast extends SandAbility implements AddonAbility {
- @Attribute(Attribute.COOLDOWN)
- private long cooldown;
- @Attribute(Attribute.SELECT_RANGE)
- private double sourceRange;
- @Attribute(Attribute.RANGE)
- private int range;
- @Attribute("MaxShots")
- private int maxBlasts;
- @Attribute(Attribute.DAMAGE)
- private static double damage;
-
- private Block source;
- private BlockData sourceData;
- private int blasts;
- private boolean blasting;
- private Vector direction;
- private TempBlock tempBlock;
- private final List affectedEntities = new ArrayList<>();
- private final List fallingBlocks = new ArrayList<>();
-
- Random rand = new Random();
-
- public SandBlast(Player player) {
- super(player);
-
- if (!bPlayer.canBend(this)) {
- return;
- }
-
- if (hasAbility(player, SandBlast.class)) {
- SandBlast sb = getAbility(player, SandBlast.class);
- sb.remove();
- }
-
- setFields();
- if (prepare()) {
- start();
- }
- }
-
- public void setFields() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- cooldown = config.getLong("Abilities.Earth.SandBlast.Cooldown");
- sourceRange = config.getDouble("Abilities.Earth.SandBlast.SourceRange");
- range = config.getInt("Abilities.Earth.SandBlast.Range");
- maxBlasts = config.getInt("Abilities.Earth.SandBlast.MaxSandBlocks");
- damage = config.getDouble("Abilities.Earth.SandBlast.Damage");
- }
-
- private boolean prepare() {
- source = BlockSource.getEarthSourceBlock(player, sourceRange, ClickType.SHIFT_DOWN);
-
- if (source != null) {
- if (isSand(source) && ElementalAbility.isAir(source.getRelative(BlockFace.UP).getType())) {
- this.sourceData = source.getBlockData().clone();
- if (DensityShift.isPassiveSand(source)) {
- DensityShift.revertSand(source);
- }
- tempBlock = new TempBlock(source, Material.SANDSTONE.createBlockData());
- return true;
- }
- }
- return false;
- }
-
- @Override
- public void progress() {
- if (!hasAbility(player, SandBlast.class)) {
- return;
- }
- if (player.isDead() || !player.isOnline()) {
- remove();
- return;
- }
- if (player.getWorld() != source.getWorld()) {
- remove();
- return;
- }
- if (blasting) {
- if (blasts <= maxBlasts) {
- blastSand();
- blasts++;
- } else {
- if (TempFallingBlock.getFromAbility(this).isEmpty()) {
- remove();
- return;
- }
- }
- affect();
- }
- }
-
- @Override
- public void remove() {
- if (this.tempBlock != null) {
- this.tempBlock.revertBlock();
- }
- super.remove();
- }
-
- public static void blastSand(Player player) {
- if (hasAbility(player, SandBlast.class)) {
- SandBlast sb = getAbility(player, SandBlast.class);
- if (sb.blasting) {
- return;
- }
- sb.blastSand();
- }
- }
-
- private void blastSand() {
- if (!blasting) {
- blasting = true;
- direction = GeneralMethods.getDirection(source.getLocation().clone().add(0, 1, 0), GeneralMethods.getTargetedLocation(player, range)).multiply(0.07);
- this.bPlayer.addCooldown(this);
- }
- tempBlock.revertBlock();
-
- //FallingBlock fblock = source.getWorld().spawnFallingBlock(source.getLocation().clone().add(0, 1, 0), source.getType(), source.getData());
-
- if (rand.nextInt(2) == 0) {
- DensityShift.playSandbendingSound(source.getLocation().add(0, 1, 0));
- }
-
- double x = rand.nextDouble() / 10;
- double z = rand.nextDouble() / 10;
-
- x = (rand.nextBoolean()) ? -x : x;
- z = (rand.nextBoolean()) ? -z : z;
-
- //fblock.setVelocity(direction.clone().add(new Vector(x, 0.2, z)));
- //fblock.setDropItem(false);
- //fblocks.put(fblock, player);
-
- fallingBlocks.add(new TempFallingBlock(source.getLocation().add(0, 1, 0), sourceData, direction.clone().add(new Vector(x, 0.2, z)), this));
-
- }
-
- public void affect() {
- for (TempFallingBlock tfb : TempFallingBlock.getFromAbility(this)) {
- FallingBlock fblock = tfb.getFallingBlock();
- if (fblock.isDead()) {
- tfb.remove();
- continue;
- }
-
- if (RegionProtection.isRegionProtected(player, fblock.getLocation(), this)) {
- tfb.remove();
- continue;
- }
-
- for (Entity entity : GeneralMethods.getEntitiesAroundPoint(fblock.getLocation(), 1.5)) {
- if (entity instanceof LivingEntity && !(entity instanceof ArmorStand)) {
- if (entity == this.player) continue;
- if (affectedEntities.contains(entity)) continue;
-
- if (!entity.isDead()) {
- DamageHandler.damageEntity(entity, damage, this);
-
- affectedEntities.add(entity);
-
- LivingEntity le = (LivingEntity) entity;
- if (le.hasPotionEffect(PotionEffectType.BLINDNESS)) {
- le.removePotionEffect(PotionEffectType.BLINDNESS);
- }
-
- le.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 60, 1));
- }
- }
- }
- }
- }
-
- @Override
- public long getCooldown() {
- return cooldown;
- }
-
- @Override
- public Location getLocation() {
- return null;
- }
-
- @Override
- public List getLocations() {
- return fallingBlocks.stream().map(TempFallingBlock::getLocation).collect(Collectors.toList());
- }
-
- @Override
- public void handleCollision(Collision collision) {
- if (collision.isRemovingFirst()) {
- Location location = collision.getLocationFirst();
-
- Optional collidedObject = fallingBlocks.stream().filter(temp -> temp.getLocation().equals(location)).findAny();
-
- if (collidedObject.isPresent()) {
- fallingBlocks.remove(collidedObject.get());
- collidedObject.get().remove();
- }
- }
- }
-
- @Override
- public String getName() {
- return "SandBlast";
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return true;
- }
-
- @Override
- public String getAuthor() {
- return JedCore.dev;
- }
-
- @Override
- public String getVersion() {
- return JedCore.version;
- }
-
- @Override
- public String getDescription() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return "* JedCore Addon *\n" + config.getString("Abilities.Earth.SandBlast.Description");
- }
-
- public void setCooldown(long cooldown) {
- this.cooldown = cooldown;
- }
-
- public double getSourceRange() {
- return sourceRange;
- }
-
- public void setSourceRange(double sourceRange) {
- this.sourceRange = sourceRange;
- }
-
- public int getRange() {
- return range;
- }
-
- public void setRange(int range) {
- this.range = range;
- }
-
- public int getMaxBlasts() {
- return maxBlasts;
- }
-
- public void setMaxBlasts(int maxBlasts) {
- this.maxBlasts = maxBlasts;
- }
-
- public static double getDamage() {
- return damage;
- }
-
- public static void setDamage(double damage) {
- SandBlast.damage = damage;
- }
-
- public Block getSource() {
- return source;
- }
-
- public void setSource(Block source) {
- this.source = source;
- }
-
- public BlockData getSourceData() {
- return sourceData;
- }
-
- public void setSourceData(BlockData sourceData) {
- this.sourceData = sourceData;
- }
-
- public int getBlasts() {
- return blasts;
- }
-
- public void setBlasts(int blasts) {
- this.blasts = blasts;
- }
-
- public boolean isBlasting() {
- return blasting;
- }
-
- public void setBlasting(boolean blasting) {
- this.blasting = blasting;
- }
-
- public Vector getDirection() {
- return direction;
- }
-
- public void setDirection(Vector direction) {
- this.direction = direction;
- }
-
- public TempBlock getTempBlock() {
- return tempBlock;
- }
-
- public void setTempBlock(TempBlock tempBlock) {
- this.tempBlock = tempBlock;
- }
-
- public List getAffectedEntities() {
- return affectedEntities;
- }
-
- public List getFallingBlocks() {
- return fallingBlocks;
- }
-
- @Override
- public void load() {}
-
- @Override
- public void stop() {}
+ @Attribute(Attribute.COOLDOWN)
+ private long cooldown;
+ @Attribute(Attribute.SELECT_RANGE)
+ private double sourceRange;
+ @Attribute(Attribute.RANGE)
+ private int range;
+ @Attribute("MaxShots")
+ private int maxBlasts;
+ @Attribute(Attribute.DAMAGE)
+ private static double damage;
+
+ private Block source;
+ private BlockData sourceData;
+ private int blasts;
+ private boolean blasting;
+ private Vector direction;
+ private TempBlock tempBlock;
+ private final List affectedEntities = new ArrayList<>();
+ private final List fallingBlocks = new ArrayList<>();
+
+ Random rand = new Random();
+
+ public SandBlast(Player player) {
+ super(player);
+
+ if (!bPlayer.canBend(this)) {
+ return;
+ }
+
+ if (hasAbility(player, SandBlast.class)) {
+ SandBlast sb = getAbility(player, SandBlast.class);
+ sb.remove();
+ }
+
+ setFields();
+ if (prepare()) {
+ start();
+ }
+ }
+
+ public void setFields() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ cooldown = config.getLong("Abilities.Earth.SandBlast.Cooldown");
+ sourceRange = config.getDouble("Abilities.Earth.SandBlast.SourceRange");
+ range = config.getInt("Abilities.Earth.SandBlast.Range");
+ maxBlasts = config.getInt("Abilities.Earth.SandBlast.MaxSandBlocks");
+ damage = config.getDouble("Abilities.Earth.SandBlast.Damage");
+ }
+
+ private boolean prepare() {
+ source = getEarthSourceBlock(sourceRange);
+
+ if (source != null) {
+ if (EarthAbility.getMovedEarth().containsKey(source)) {
+ return false;
+ }
+ if (isSand(source) && ElementalAbility.isAir(source.getRelative(BlockFace.UP).getType())) {
+ this.sourceData = source.getBlockData().clone();
+ if (DensityShift.isPassiveSand(source)) {
+ DensityShift.revertSand(source);
+ }
+ tempBlock = new TempBlock(source, Material.SANDSTONE.createBlockData());
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void progress() {
+ if (!hasAbility(player, SandBlast.class)) {
+ return;
+ }
+ if (player.isDead() || !player.isOnline()) {
+ remove();
+ return;
+ }
+ if (player.getWorld() != source.getWorld()) {
+ remove();
+ return;
+ }
+ if (blasting) {
+ if (blasts <= maxBlasts) {
+ blastSand();
+ blasts++;
+ } else {
+ if (TempFallingBlock.getFromAbility(this).isEmpty()) {
+ remove();
+ return;
+ }
+ }
+ affect();
+ }
+ }
+
+ @Override
+ public void remove() {
+ if (this.tempBlock != null) {
+ this.tempBlock.revertBlock();
+ }
+ super.remove();
+ }
+
+ public static void blastSand(Player player) {
+ if (hasAbility(player, SandBlast.class)) {
+ SandBlast sb = getAbility(player, SandBlast.class);
+ if (sb.blasting) {
+ return;
+ }
+ sb.blastSand();
+ }
+ }
+
+ private void blastSand() {
+ if (!blasting) {
+ blasting = true;
+ direction = GeneralMethods.getDirection(source.getLocation().clone().add(0, 1, 0), GeneralMethods.getTargetedLocation(player, range)).multiply(0.07);
+ this.bPlayer.addCooldown(this);
+ }
+ tempBlock.revertBlock();
+
+ //FallingBlock fblock = source.getWorld().spawnFallingBlock(source.getLocation().clone().add(0, 1, 0), source.getType(), source.getData());
+
+ if (rand.nextInt(2) == 0) {
+ DensityShift.playSandbendingSound(source.getLocation().add(0, 1, 0));
+ }
+
+ double x = rand.nextDouble() / 10;
+ double z = rand.nextDouble() / 10;
+
+ x = (rand.nextBoolean()) ? -x : x;
+ z = (rand.nextBoolean()) ? -z : z;
+
+ //fblock.setVelocity(direction.clone().add(new Vector(x, 0.2, z)));
+ //fblock.setDropItem(false);
+ //fblocks.put(fblock, player);
+
+ fallingBlocks.add(new TempFallingBlock(source.getLocation().add(0, 1, 0), sourceData, direction.clone().add(new Vector(x, 0.2, z)), this));
+
+ }
+
+ public void affect() {
+ for (TempFallingBlock tfb : TempFallingBlock.getFromAbility(this)) {
+ FallingBlock fblock = tfb.getFallingBlock();
+ if (fblock.isDead()) {
+ tfb.remove();
+ continue;
+ }
+
+ if (RegionProtection.isRegionProtected(player, fblock.getLocation(), this)) {
+ tfb.remove();
+ continue;
+ }
+
+ for (Entity entity : GeneralMethods.getEntitiesAroundPoint(fblock.getLocation(), 1.5)) {
+ if (entity instanceof LivingEntity && !(entity instanceof ArmorStand)) {
+ if (entity == this.player) continue;
+ if (affectedEntities.contains(entity)) continue;
+
+ if (!entity.isDead()) {
+ DamageHandler.damageEntity(entity, damage, this);
+
+ affectedEntities.add(entity);
+
+ LivingEntity le = (LivingEntity) entity;
+ if (le.hasPotionEffect(PotionEffectType.BLINDNESS)) {
+ le.removePotionEffect(PotionEffectType.BLINDNESS);
+ }
+
+ le.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 60, 1));
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public long getCooldown() {
+ return cooldown;
+ }
+
+ @Override
+ public Location getLocation() {
+ return null;
+ }
+
+ @Override
+ public List getLocations() {
+ return fallingBlocks.stream().map(TempFallingBlock::getLocation).collect(Collectors.toList());
+ }
+
+ @Override
+ public void handleCollision(Collision collision) {
+ if (collision.isRemovingFirst()) {
+ Location location = collision.getLocationFirst();
+
+ Optional collidedObject = fallingBlocks.stream().filter(temp -> temp.getLocation().equals(location)).findAny();
+
+ if (collidedObject.isPresent()) {
+ fallingBlocks.remove(collidedObject.get());
+ collidedObject.get().remove();
+ }
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "SandBlast";
+ }
+
+ @Override
+ public boolean isHarmlessAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isSneakAbility() {
+ return true;
+ }
+
+ @Override
+ public String getAuthor() {
+ return JedCore.dev;
+ }
+
+ @Override
+ public String getVersion() {
+ return JedCore.version;
+ }
+
+ @Override
+ public String getDescription() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return "* JedCore Addon *\n" + config.getString("Abilities.Earth.SandBlast.Description");
+ }
+
+ public void setCooldown(long cooldown) {
+ this.cooldown = cooldown;
+ }
+
+ public double getSourceRange() {
+ return sourceRange;
+ }
+
+ public void setSourceRange(double sourceRange) {
+ this.sourceRange = sourceRange;
+ }
+
+ public int getRange() {
+ return range;
+ }
+
+ public void setRange(int range) {
+ this.range = range;
+ }
+
+ public int getMaxBlasts() {
+ return maxBlasts;
+ }
+
+ public void setMaxBlasts(int maxBlasts) {
+ this.maxBlasts = maxBlasts;
+ }
+
+ public static double getDamage() {
+ return damage;
+ }
+
+ public static void setDamage(double damage) {
+ SandBlast.damage = damage;
+ }
+
+ public Block getSource() {
+ return source;
+ }
+
+ public void setSource(Block source) {
+ this.source = source;
+ }
+
+ public BlockData getSourceData() {
+ return sourceData;
+ }
+
+ public void setSourceData(BlockData sourceData) {
+ this.sourceData = sourceData;
+ }
+
+ public int getBlasts() {
+ return blasts;
+ }
+
+ public void setBlasts(int blasts) {
+ this.blasts = blasts;
+ }
+
+ public boolean isBlasting() {
+ return blasting;
+ }
+
+ public void setBlasting(boolean blasting) {
+ this.blasting = blasting;
+ }
+
+ public Vector getDirection() {
+ return direction;
+ }
+
+ public void setDirection(Vector direction) {
+ this.direction = direction;
+ }
+
+ public TempBlock getTempBlock() {
+ return tempBlock;
+ }
+
+ public void setTempBlock(TempBlock tempBlock) {
+ this.tempBlock = tempBlock;
+ }
+
+ public List getAffectedEntities() {
+ return affectedEntities;
+ }
+
+ public List getFallingBlocks() {
+ return fallingBlocks;
+ }
+
+ @Override
+ public void load() {}
+
+ @Override
+ public void stop() {}
- @Override
- public boolean isEnabled() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getBoolean("Abilities.Earth.SandBlast.Enabled");
- }
-}
+ @Override
+ public boolean isEnabled() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getBoolean("Abilities.Earth.SandBlast.Enabled");
+ }
+}
\ No newline at end of file
diff --git a/src/com/jedk1/jedcore/ability/earthbending/combo/Crevice.java b/src/com/jedk1/jedcore/ability/earthbending/combo/Crevice.java
index f4e22c4..a26ae34 100644
--- a/src/com/jedk1/jedcore/ability/earthbending/combo/Crevice.java
+++ b/src/com/jedk1/jedcore/ability/earthbending/combo/Crevice.java
@@ -11,8 +11,6 @@
import com.projectkorra.projectkorra.ability.util.ComboUtil;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.region.RegionProtection;
-import com.projectkorra.projectkorra.util.ClickType;
-
import com.projectkorra.projectkorra.util.TempBlock;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -28,343 +26,349 @@
import java.util.Collections;
import java.util.List;
import java.util.Objects;
-import java.util.Random;
+import java.util.concurrent.ThreadLocalRandom;
public class Crevice extends EarthAbility implements AddonAbility, ComboAbility {
-
- @Attribute(Attribute.RANGE)
- private double range;
- private long regenDelay;
- @Attribute("Depth")
- private int randomDepth;
- private int avatarDepth;
- @Attribute(Attribute.COOLDOWN)
- private long cooldown;
-
- private Location origin;
- private Location location;
- private Vector direction;
- private double travelled;
- private boolean skip;
-
- private final List
> columns = new ArrayList<>();
-
- private final Random rand = new Random();
-
- public Crevice(Player player) {
- super(player);
- if (!bPlayer.canBendIgnoreBinds(this)) {
- return;
- }
-
- setFields();
- createInstance();
- }
-
- public void setFields() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
-
- range = config.getDouble("Abilities.Earth.EarthCombo.Crevice.Range");
- regenDelay = config.getLong("Abilities.Earth.EarthCombo.Crevice.RevertDelay");
- randomDepth = config.getInt("Abilities.Earth.EarthCombo.Crevice.Depth");
- avatarDepth = config.getInt("Abilities.Earth.EarthCombo.Crevice.AvatarStateDepth");
- cooldown = config.getLong("Abilities.Earth.EarthCombo.Crevice.Cooldown");
- }
-
- private void createInstance() {
- origin = player.getTargetBlock(null, 6).getLocation();
- if (isEarthbendable(origin.getBlock())) {
- Location tempLoc = player.getLocation().clone();
- tempLoc.setPitch(0);
- direction = tempLoc.getDirection().clone();
- origin.setDirection(tempLoc.getDirection());
- location = origin.clone();
- if (bPlayer.isAvatarState()) {
- randomDepth = avatarDepth;
- }
-
- start();
- if (!isRemoved()) {
- bPlayer.addCooldown(this);
- }
- }
- }
-
- @Override
- public void progress() {
- if (player.isDead() || !player.isOnline()) {
- prepareRevert();
- remove();
- return;
- }
- if (travelled >= range || skip) {
- if (System.currentTimeMillis() > getStartTime() + regenDelay) {
- prepareRevert();
- remove();
- return;
- }
- return;
- }
- advanceCrevice();
- }
-
- @Override
- public void remove() {
- prepareRevert();
- super.remove();
- }
-
- public static void closeCrevice(Player player) {
- Block target = player.getTargetBlock(null, 10);
- for (Block near : GeneralMethods.getBlocksAroundPoint(target.getLocation(), 2)) {
- for (Crevice c : getAbilities(Crevice.class)) {
- for (List tbs : c.columns) {
- for (TempBlock tb : tbs) {
- if (near.getLocation().equals(tb.getLocation())) {
- c.prepareRevert();
- c.remove();
- return;
- }
- }
- }
- }
- }
- }
-
- private void advanceCrevice() {
- switch (rand.nextInt(2)) {
- case 0:
- if (location.getYaw() <= origin.getYaw()) {
- location.setYaw(location.getYaw() + 40);
- direction = location.getDirection().clone();
- }
- break;
- case 1:
- if (location.getYaw() >= origin.getYaw()) {
- location.setYaw(location.getYaw() - 40);
- direction = location.getDirection().clone();
- }
- break;
- default:
- direction = location.getDirection().clone();
- break;
- }
-
- Location tempLoc = location.clone();
- location = location.add(direction.multiply(1));
- playEarthbendingSound(tempLoc);
- location.getWorld().playSound(location, Sound.ENTITY_ZOMBIE_BREAK_WOODEN_DOOR, (float) 0.5, (float) 0.5);
- if (skip) {
- return;
- }
-
- travelled++;
- if (travelled >= range)
- return;
-
- if (RegionProtection.isRegionProtected(player, location, "RaiseEarth")) {
- return;
- }
-
- if (!isTransparent(location.getBlock().getRelative(BlockFace.UP))) {
- location.add(0, 1, 0);
- if (!isTransparent(location.getBlock().getRelative(BlockFace.UP)) || !isEarthbendable(location.getBlock())) {
- skip = true;
- return;
- }
- } else if (isTransparent(location.getBlock()) || !isEarthbendable(location.getBlock())) {
- location.subtract(0, 1, 0);
- if (isTransparent(location.getBlock()) || !isEarthbendable(location.getBlock())) {
- skip = true;
- return;
- }
- }
-
- removePillar(tempLoc, randInt(randomDepth + 1 - 2, randomDepth + 1 + 2));
- removePillar(GeneralMethods.getRightSide(tempLoc, 1), randInt(randomDepth - 1, randomDepth + 1));
- removePillar(GeneralMethods.getLeftSide(tempLoc, 1), randInt(randomDepth - 1, randomDepth + 1));
- }
-
- private int randInt(int min, int max) {
- return rand.nextInt(max - min) + min;
- }
-
- private void removePillar(Location location, int depth) {
- List blocks = new ArrayList<>();
- Location tempLoc = location.clone().getBlock().getLocation();
- tempLoc.add(0, 1, 0);
- for (int i = 0; i < depth + 1; i++) {
- if (tempLoc.getY() < Objects.requireNonNull(tempLoc.getWorld()).getMinHeight() || tempLoc.getY() > tempLoc.getWorld().getMaxHeight()) {
- break;
- }
- if (RegionProtection.isRegionProtected(player, tempLoc, this)) {
- continue;
- }
- if (i == 0 && !isTransparent(tempLoc.getBlock())) {
- continue;
- }
- if (i > 0 && !isEarthbendable(tempLoc.getBlock())) {
- continue;
- }
-
- for (Entity entity : GeneralMethods.getEntitiesAroundPoint(tempLoc, 1)) {
- entity.setVelocity(new Vector(0, -0.75, 0));
- }
-
-
- blocks.add(new TempBlock(tempLoc.getBlock(), Material.AIR.createBlockData()));
- tempLoc.subtract(0, 1, 0);
- }
-
- Collections.reverse(blocks);
-
- columns.add(blocks);
- }
-
- private void prepareRevert() {
- for (int i = 0; i < columns.size(); ++i) {
- List tbs = columns.get(i);
- for (TempBlock tb : tbs) {
- tb.revertBlock();
- for (Entity entity : GeneralMethods.getEntitiesAroundPoint(tb.getLocation(), 1)) {
- entity.setVelocity(new Vector(0, 0.7, 0));
- }
- new RegenTempBlock(tb.getBlock(), Material.AIR, Material.AIR.createBlockData(), i * 50L);
- }
- }
- columns.clear();
- }
-
- @Override
- public long getCooldown() {
- return cooldown;
- }
-
- @Override
- public Location getLocation() {
- return location;
- }
-
- @Override
- public String getName() {
- return "Crevice";
- }
-
- @Override
- public boolean isHiddenAbility() {
- return false;
- }
-
- @Override
- public boolean isHarmlessAbility() {
- return false;
- }
-
- @Override
- public boolean isSneakAbility() {
- return false;
- }
-
- @Override
- public Object createNewComboInstance(Player player) {
- return new Crevice(player);
- }
-
- @Override
- public ArrayList getCombination() {
- return ComboUtil.generateCombinationFromList(this, JedCoreConfig.getConfig(player).getStringList("Abilities.Earth.EarthCombo.Crevice.Combination"));
- }
-
- @Override
- public String getInstructions() {
- return JedCoreConfig.getConfig(player).getString("Abilities.Earth.EarthCombo.Crevice.Instructions");
- }
-
- @Override
- public String getDescription() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return "* JedCore Addon *\n" + config.getString("Abilities.Earth.EarthCombo.Crevice.Description");
- }
-
- @Override
- public String getAuthor() {
- return JedCore.dev;
- }
-
- @Override
- public String getVersion() {
- return JedCore.version;
- }
-
- public double getRange() {
- return range;
- }
-
- public void setRange(double range) {
- this.range = range;
- }
-
- public long getRegenDelay() {
- return regenDelay;
- }
-
- public void setRegenDelay(long regenDelay) {
- this.regenDelay = regenDelay;
- }
-
- public int getDepth() {
- return randomDepth;
- }
-
- public void setDepth(int depth) {
- this.randomDepth = depth;
- }
-
- public int getAvatarDepth() {
- return avatarDepth;
- }
-
- public void setAvatarDepth(int avatarDepth) {
- this.avatarDepth = avatarDepth;
- }
-
- public Location getOrigin() {
- return origin;
- }
-
- public void setOrigin(Location origin) {
- this.origin = origin;
- }
-
- public Vector getDirection() {
- return direction;
- }
-
- public void setDirection(Vector direction) {
- this.direction = direction;
- }
-
- public double getDistanceTravelled() {
- return travelled;
- }
-
- public void setDistanceTravelled(double travelled) {
- this.travelled = travelled;
- }
-
- public List> getColumns() {
- return columns;
- }
-
- @Override
- public void load() {}
-
- @Override
- public void stop() {}
-
- @Override
- public boolean isEnabled() {
- ConfigurationSection config = JedCoreConfig.getConfig(this.player);
- return config.getBoolean("Abilities.Earth.EarthCombo.Crevice.Enabled");
- }
-}
+ private final List> columns = new ArrayList<>();
+
+ private Location origin;
+ private Location location;
+ private Vector direction;
+ private double travelled;
+ private boolean skip;
+ private int avatarDepth;
+ private long regenDelay;
+
+ @Attribute(Attribute.RANGE)
+ private double range;
+ @Attribute("Depth")
+ private int randomDepth;
+ @Attribute(Attribute.COOLDOWN)
+ private long cooldown;
+
+ public Crevice(Player player) {
+ super(player);
+
+ if (!bPlayer.canBendIgnoreBinds(this)) {
+ return;
+ }
+
+ setFields();
+
+ createInstance();
+ }
+
+ public void setFields() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+
+ range = config.getDouble("Abilities.Earth.EarthCombo.Crevice.Range");
+ regenDelay = config.getLong("Abilities.Earth.EarthCombo.Crevice.RevertDelay");
+ randomDepth = config.getInt("Abilities.Earth.EarthCombo.Crevice.Depth");
+ avatarDepth = config.getInt("Abilities.Earth.EarthCombo.Crevice.AvatarStateDepth");
+ cooldown = config.getLong("Abilities.Earth.EarthCombo.Crevice.Cooldown");
+ }
+
+ private void createInstance() {
+ origin = player.getTargetBlock(null, 6).getLocation();
+
+ if (isEarthbendable(origin.getBlock()) && !EarthAbility.getMovedEarth().containsKey(origin.getBlock())) {
+ Location tempLoc = player.getLocation().clone();
+ tempLoc.setPitch(0);
+
+ direction = tempLoc.getDirection().clone();
+ origin.setDirection(tempLoc.getDirection()); // todo
+ location = origin.clone();
+
+ if (bPlayer.isAvatarState()) {
+ randomDepth = avatarDepth;
+ }
+
+ start();
+
+ if (!isRemoved()) {
+ bPlayer.addCooldown(this);
+ }
+ }
+ }
+
+ @Override
+ public void progress() {
+ if (player.isDead() || !player.isOnline()) {
+ prepareRevert();
+ remove();
+ return;
+ }
+
+ if (travelled >= range || skip) {
+ if (System.currentTimeMillis() > getStartTime() + regenDelay) {
+ prepareRevert();
+ remove();
+ return;
+ }
+ return;
+ }
+
+ advanceCrevice();
+ }
+
+ @Override
+ public void remove() {
+ prepareRevert();
+ super.remove();
+ }
+
+ public static void closeCrevice(Player player) {
+ Block target = player.getTargetBlock(null, 10);
+
+ for (Block near : GeneralMethods.getBlocksAroundPoint(target.getLocation(), 2)) {
+ for (Crevice c : getAbilities(Crevice.class)) {
+ for (List tbs : c.columns) {
+ for (TempBlock tb : tbs) {
+ if (near.getLocation().equals(tb.getLocation())) {
+ c.prepareRevert();
+ c.remove();
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void advanceCrevice() {
+ switch (ThreadLocalRandom.current().nextInt(2)) {
+ case 0:
+ if (location.getYaw() <= origin.getYaw()) {
+ location.setYaw(location.getYaw() + 40);
+ direction = location.getDirection().clone();
+ }
+ break;
+ case 1:
+ if (location.getYaw() >= origin.getYaw()) {
+ location.setYaw(location.getYaw() - 40);
+ direction = location.getDirection().clone();
+ }
+ break;
+ default:
+ direction = location.getDirection().clone();
+ break;
+ }
+
+ Location tempLoc = location.clone();
+ location = location.add(direction.multiply(1));
+ playEarthbendingSound(tempLoc);
+ location.getWorld().playSound(location, Sound.ENTITY_ZOMBIE_BREAK_WOODEN_DOOR, (float) 0.5, (float) 0.5);
+ if (skip) {
+ return;
+ }
+
+ travelled++;
+ if (travelled >= range)
+ return;
+
+ if (RegionProtection.isRegionProtected(player, location, "RaiseEarth")) {
+ return;
+ }
+
+ if (!isTransparent(location.getBlock().getRelative(BlockFace.UP))) {
+ location.add(0, 1, 0);
+ if (!isTransparent(location.getBlock().getRelative(BlockFace.UP)) || !isEarthbendable(location.getBlock())) {
+ skip = true;
+ return;
+ }
+ } else if (isTransparent(location.getBlock()) || !isEarthbendable(location.getBlock())) {
+ location.subtract(0, 1, 0);
+ if (isTransparent(location.getBlock()) || !isEarthbendable(location.getBlock())) {
+ skip = true;
+ return;
+ }
+ }
+
+ removePillar(tempLoc, randInt(randomDepth + 1 - 2, randomDepth + 1 + 2));
+ removePillar(GeneralMethods.getRightSide(tempLoc, 1), randInt(randomDepth - 1, randomDepth + 1));
+ removePillar(GeneralMethods.getLeftSide(tempLoc, 1), randInt(randomDepth - 1, randomDepth + 1));
+ }
+
+ private int randInt(int min, int max) {
+ return ThreadLocalRandom.current().nextInt(max - min) + min; // todo: look into the necessity of this helper
+ }
+
+ private void removePillar(Location location, int depth) {
+ List blocks = new ArrayList<>();
+ Location tempLoc = location.clone().getBlock().getLocation();
+ tempLoc.add(0, 1, 0);
+ for (int i = 0; i < depth + 1; i++) {
+ if (tempLoc.getY() < Objects.requireNonNull(tempLoc.getWorld()).getMinHeight() || tempLoc.getY() > tempLoc.getWorld().getMaxHeight()) {
+ break;
+ }
+ if (RegionProtection.isRegionProtected(player, tempLoc, this)) {
+ continue;
+ }
+ if (i == 0 && !isTransparent(tempLoc.getBlock())) {
+ continue;
+ }
+ if (i > 0 && (!isEarthbendable(tempLoc.getBlock()) || EarthAbility.getMovedEarth().containsKey(tempLoc.getBlock()))) {
+ continue;
+ }
+
+ for (Entity entity : GeneralMethods.getEntitiesAroundPoint(tempLoc, 1)) {
+ entity.setVelocity(new Vector(0, -0.75, 0));
+ }
+
+
+ blocks.add(new TempBlock(tempLoc.getBlock(), Material.AIR.createBlockData()));
+ tempLoc.subtract(0, 1, 0);
+ }
+
+ Collections.reverse(blocks);
+
+ columns.add(blocks);
+ }
+
+ private void prepareRevert() {
+ for (int i = 0; i < columns.size(); ++i) {
+ List tbs = columns.get(i);
+ for (TempBlock tb : tbs) {
+ tb.revertBlock();
+ for (Entity entity : GeneralMethods.getEntitiesAroundPoint(tb.getLocation(), 1)) {
+ entity.setVelocity(new Vector(0, 0.7, 0));
+ }
+ new RegenTempBlock(tb.getBlock(), Material.AIR, Material.AIR.createBlockData(), i * 50L);
+ }
+ }
+ columns.clear();
+ }
+
+ @Override
+ public long getCooldown() {
+ return cooldown;
+ }
+
+ @Override
+ public Location getLocation() {
+ return location;
+ }
+
+ @Override
+ public String getName() {
+ return "Crevice";
+ }
+
+ @Override
+ public boolean isHiddenAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isHarmlessAbility() {
+ return false;
+ }
+
+ @Override
+ public boolean isSneakAbility() {
+ return false;
+ }
+
+ @Override
+ public Object createNewComboInstance(Player player) {
+ return new Crevice(player);
+ }
+
+ @Override
+ public ArrayList getCombination() {
+ return ComboUtil.generateCombinationFromList(this, JedCoreConfig.getConfig(player).getStringList("Abilities.Earth.EarthCombo.Crevice.Combination"));
+ }
+
+ @Override
+ public String getInstructions() {
+ return JedCoreConfig.getConfig(player).getString("Abilities.Earth.EarthCombo.Crevice.Instructions");
+ }
+
+ @Override
+ public String getDescription() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return "* JedCore Addon *\n" + config.getString("Abilities.Earth.EarthCombo.Crevice.Description");
+ }
+
+ @Override
+ public String getAuthor() {
+ return JedCore.dev;
+ }
+
+ @Override
+ public String getVersion() {
+ return JedCore.version;
+ }
+
+ public double getRange() {
+ return range;
+ }
+
+ public void setRange(double range) {
+ this.range = range;
+ }
+
+ public long getRegenDelay() {
+ return regenDelay;
+ }
+
+ public void setRegenDelay(long regenDelay) {
+ this.regenDelay = regenDelay;
+ }
+
+ public int getDepth() {
+ return randomDepth;
+ }
+
+ public void setDepth(int depth) {
+ this.randomDepth = depth;
+ }
+
+ public int getAvatarDepth() {
+ return avatarDepth;
+ }
+
+ public void setAvatarDepth(int avatarDepth) {
+ this.avatarDepth = avatarDepth;
+ }
+
+ public Location getOrigin() {
+ return origin;
+ }
+
+ public void setOrigin(Location origin) {
+ this.origin = origin;
+ }
+
+ public Vector getDirection() {
+ return direction;
+ }
+
+ public void setDirection(Vector direction) {
+ this.direction = direction;
+ }
+
+ public double getDistanceTravelled() {
+ return travelled;
+ }
+
+ public void setDistanceTravelled(double travelled) {
+ this.travelled = travelled;
+ }
+
+ public List> getColumns() {
+ return columns;
+ }
+
+ @Override
+ public void load() {}
+
+ @Override
+ public void stop() {}
+
+ @Override
+ public boolean isEnabled() {
+ ConfigurationSection config = JedCoreConfig.getConfig(this.player);
+ return config.getBoolean("Abilities.Earth.EarthCombo.Crevice.Enabled");
+ }
+}
\ No newline at end of file
diff --git a/src/com/jedk1/jedcore/ability/earthbending/combo/MagmaBlast.java b/src/com/jedk1/jedcore/ability/earthbending/combo/MagmaBlast.java
index 55426ba..9bf8012 100644
--- a/src/com/jedk1/jedcore/ability/earthbending/combo/MagmaBlast.java
+++ b/src/com/jedk1/jedcore/ability/earthbending/combo/MagmaBlast.java
@@ -1,24 +1,17 @@
package com.jedk1.jedcore.ability.earthbending.combo;
-import com.jedk1.jedcore.collision.AABB;
+import com.jedk1.jedcore.JedCore;
import com.jedk1.jedcore.configuration.JedCoreConfig;
import com.jedk1.jedcore.util.MaterialUtil;
-import com.projectkorra.projectkorra.ability.ElementalAbility;
+import com.projectkorra.projectkorra.GeneralMethods;
+import com.projectkorra.projectkorra.ability.*;
+import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation;
import com.projectkorra.projectkorra.ability.util.ComboUtil;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.earthbending.lava.LavaFlow;
-
-import com.jedk1.jedcore.JedCore;
-import com.projectkorra.projectkorra.GeneralMethods;
-import com.projectkorra.projectkorra.ability.AddonAbility;
-import com.projectkorra.projectkorra.ability.ComboAbility;
-import com.projectkorra.projectkorra.ability.LavaAbility;
-import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation;
-import com.projectkorra.projectkorra.util.ClickType;
import com.projectkorra.projectkorra.util.DamageHandler;
import com.projectkorra.projectkorra.util.ParticleEffect;
import com.projectkorra.projectkorra.util.TempBlock;
-
import com.projectkorra.projectkorra.util.TempFallingBlock;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -27,570 +20,598 @@
import org.bukkit.block.BlockFace;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity;
+import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
+import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.util.Vector;
import java.util.*;
+import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
public class MagmaBlast extends LavaAbility implements AddonAbility, ComboAbility {
- private static final int PARTICLE_COUNT = 20;
- private static final int RAISE_HEIGHT = 3;
- private static final Random rand = new Random();
-
- private final Set