diff --git a/src/com/projectkorra/ProjectKorra/ConfigManager.java b/src/com/projectkorra/ProjectKorra/ConfigManager.java index f15e357f..4f3ca43c 100644 --- a/src/com/projectkorra/ProjectKorra/ConfigManager.java +++ b/src/com/projectkorra/ProjectKorra/ConfigManager.java @@ -427,10 +427,14 @@ public class ConfigManager { config.addDefault("Abilities.Earth.LavaSurge.Enabled", true); config.addDefault("Abilities.Earth.LavaSurge.Description", "This ability allows an Earthbender to bend an existing Lava Source to create a large wave that deals damage and knocks back anything in its path. To use, simply tap sneak (Default: Shift) while targetting a source of lava. Once a source has been selected, left click to launch the wave off into the direction you are looking. This ability has a small knockback and does a fair amount of damage."); - config.addDefault("Abilities.Earth.LavaSurge.Radius", 3); - config.addDefault("Abilities.Earth.LavaSurge.HorizontalPush", 0.5); - config.addDefault("Abilities.Earth.LavaSurge.VerticalPush", 0.1); + config.addDefault("Abilities.Earth.LavaSurge.Damage", 6); + config.addDefault("Abilities.Earth.LavaSurge.Radius", 1); + config.addDefault("Abilities.Earth.LavaSurge.PrepareRange", 7); + config.addDefault("Abilities.Earth.LavaSurge.TravelRange", 15); + config.addDefault("Abilities.Earth.LavaSurge.MaxLavaWaves", 10); + config.addDefault("Abilities.Earth.LavaSurge.SourceCanBeEarth", true); + config.addDefault("Abilities.Earth.RaiseEarth.Enabled", true); config.addDefault("Abilities.Earth.RaiseEarth.Description", "To use, simply left-click on an earthbendable block. " + "A column of earth will shoot upwards from that location. " diff --git a/src/com/projectkorra/ProjectKorra/PKListener.java b/src/com/projectkorra/ProjectKorra/PKListener.java index 2484e5b0..d716e509 100644 --- a/src/com/projectkorra/ProjectKorra/PKListener.java +++ b/src/com/projectkorra/ProjectKorra/PKListener.java @@ -91,6 +91,7 @@ import com.projectkorra.ProjectKorra.earthbending.EarthTunnel; import com.projectkorra.ProjectKorra.earthbending.EarthWall; import com.projectkorra.ProjectKorra.earthbending.Extraction; import com.projectkorra.ProjectKorra.earthbending.LavaFlow; +import com.projectkorra.ProjectKorra.earthbending.LavaSurge; import com.projectkorra.ProjectKorra.earthbending.LavaWall; import com.projectkorra.ProjectKorra.earthbending.LavaWave; import com.projectkorra.ProjectKorra.earthbending.Shockwave; @@ -454,7 +455,7 @@ public class PKListener implements Listener { } if (abil.equalsIgnoreCase("LavaSurge")) { - LavaWall.form(player); + new LavaSurge(player); } if (abil.equalsIgnoreCase("LavaFlow")) { @@ -791,7 +792,8 @@ public class PKListener implements Listener { } if (abil.equalsIgnoreCase("LavaSurge")) { - new LavaWall(player); + if(LavaSurge.instances.containsKey(player)) + LavaSurge.instances.get(player).launch(); } if (abil.equalsIgnoreCase("LavaFlow")) { diff --git a/src/com/projectkorra/ProjectKorra/earthbending/EarthbendingManager.java b/src/com/projectkorra/ProjectKorra/earthbending/EarthbendingManager.java index 32fdee97..4d9c3a5e 100644 --- a/src/com/projectkorra/ProjectKorra/earthbending/EarthbendingManager.java +++ b/src/com/projectkorra/ProjectKorra/earthbending/EarthbendingManager.java @@ -24,8 +24,7 @@ public class EarthbendingManager implements Runnable { CompactColumn.progressAll(); Shockwave.progressAll(); EarthBlast.progressAll(); - LavaWall.progressAll(); - LavaWave.progressAll(); + LavaSurge.progressAll(); LavaFlow.progressAll(); } } diff --git a/src/com/projectkorra/ProjectKorra/earthbending/LavaSurge.java b/src/com/projectkorra/ProjectKorra/earthbending/LavaSurge.java new file mode 100644 index 00000000..132c72cd --- /dev/null +++ b/src/com/projectkorra/ProjectKorra/earthbending/LavaSurge.java @@ -0,0 +1,310 @@ +package com.projectkorra.ProjectKorra.earthbending; + +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +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.projectkorra.ProjectKorra.BendingPlayer; +import com.projectkorra.ProjectKorra.Methods; +import com.projectkorra.ProjectKorra.TempBlock; +import com.projectkorra.ProjectKorra.Utilities.ParticleEffect; + +import fr.neatmonster.nocheatplus.config.ConfigManager; + +public class LavaSurge +{ + public static ConcurrentHashMap instances = new ConcurrentHashMap(); + public static int impactDamage = ConfigManager.getConfigFile().getInt("Abilities.Earth.LavaSurge.Damage"); + public static int fractureRadius = ConfigManager.getConfigFile().getInt("Abilities.Earth.LavaSurge.Radius"); + public static int prepareRange = ConfigManager.getConfigFile().getInt("Abilities.Earth.LavaSurge.PrepareRange"); + public static int travelRange = ConfigManager.getConfigFile().getInt("Abilities.Earth.LavaSurge.TravelRange"); + public static int maxBlocks = ConfigManager.getConfigFile().getInt("Abilities.Earth.LavaSurge.MaxLavaWaves"); + public static int particleInterval = 100; + public static int fallingBlockInterval = 100; + public static boolean canSourceBeEarth = ConfigManager.getConfigFile().getBoolean("Abilities.Earth.LavaSurge.SourceCanBeEarth"); + + private Player player; + private Block sourceBlock; + private long lastTime; + private long time; + private int fallingBlocksCount = 0; + private boolean surgeStarted = false; + private boolean stopSurge = false; + private boolean fractureOpen; + private Random randy = new Random(); + private Vector direction; + private Location startLocation; + //private Location currentLocation; // Unused. + private List fblocks = new ArrayList(); + private List fracture = new ArrayList(); + private List fracturetb = new ArrayList(); + private ListIterator li; + + public LavaSurge(Player player) + { + this.player = player; + + if(!isEligible()) + return; + + lastTime = System.currentTimeMillis(); + + if(prepare()) + { + instances.put(player, this); + } + } + + public boolean isEligible() + { + final BendingPlayer bplayer = Methods.getBendingPlayer(player.getName()); + + if(!Methods.canBend(player.getName(), "LavaSurge")) + return false; + + if(Methods.getBoundAbility(player) == null) + return false; + + if(!Methods.getBoundAbility(player).equalsIgnoreCase("LavaSurge")) + return false; + + if(Methods.isRegionProtectedFromBuild(player, "LavaSurge", player.getLocation())) + return false; + + if(!Methods.canLavabend(player)) + return false; + + if(bplayer.isOnCooldown("LavaSurge")) + return false; + + return true; + } + + public boolean prepare() + { + Block targetBlock = Methods.getEarthSourceBlock(player, prepareRange); + + if(targetBlock == null || + !(targetBlock.getRelative(BlockFace.UP).getType() == Material.AIR) && + !isLava(targetBlock.getRelative(BlockFace.UP))) + return false; + + if(instances.containsKey(player)) + instances.get(player).revertFracture(); + + if((canSourceBeEarth && Methods.isEarthbendable(player, targetBlock)) || + Methods.isLavabendable(targetBlock, player)) + { + startLocation = targetBlock.getLocation().add(0, 1, 0); + //currentLocation = startLocation; // Not needed. + sourceBlock = targetBlock; + return true; + } + + return false; + } + + public boolean isLava(Block b) + { + if(b.getType() == Material.STATIONARY_LAVA || b.getType() == Material.LAVA) + return true; + return false; + } + + public void launch() + { + Location targetLocation = Methods.getTargetedLocation(player, travelRange); + + try { targetLocation = Methods.getTargetedEntity(player, travelRange*2, null).getLocation(); } + catch(NullPointerException e) {}; + + if(targetLocation == null) + { + remove(); + return; + } + + time = System.currentTimeMillis(); + direction = Methods.getDirection(startLocation, targetLocation).multiply(0.15); + + if(direction.getY() < 0) + direction.setY(0); + + if(canSourceBeEarth) + openFracture(); + else + skipFracture(); + } + + public void openFracture() + { + List affectedBlocks = Methods.getBlocksAroundPoint(sourceBlock.getLocation(), fractureRadius); + + for(Block b : affectedBlocks) + { + if(Methods.isEarthbendable(player, b)) + { + fracture.add(b); + } + } + + li = fracture.listIterator(); + + fractureOpen = true; + } + + public void skipFracture() + { + li = fracture.listIterator(); + + fractureOpen = true; + } + + public void revertFracture() + { + for(TempBlock tb : fracturetb) + { + tb.revertBlock(); + } + + fracture.clear(); + } + + public void remove() + { + revertFracture(); + instances.remove(player); + } + + public boolean canMoveThrough(Block block) + { + if(Methods.isTransparentToEarthbending(player, startLocation.getBlock()) || + Methods.isEarthbendable(player, startLocation.getBlock()) || + Methods.isLavabendable(startLocation.getBlock(), player)) + return true; + return false; + } + + @SuppressWarnings("deprecation") + public void progress() + { + long curTime = System.currentTimeMillis(); + if(!player.isOnline() || player.isDead()) + { + remove(); + return; + } + + if(!surgeStarted && !Methods.getBoundAbility(player).equalsIgnoreCase("LavaSurge")) + { + remove(); + return; + } + + if(!surgeStarted && sourceBlock != null && + curTime > lastTime + particleInterval) + { + lastTime = curTime; + ParticleEffect.LAVA.display(sourceBlock.getLocation(), 0, 0, 0, 0, 1); + } + + else if(surgeStarted && curTime > lastTime + particleInterval) + { + lastTime = curTime; + for(FallingBlock fblock : fblocks) + ParticleEffect.LAVA.display(fblock.getLocation(), 0, 0, 0, 0, 1); + } + + if(fractureOpen && !surgeStarted) + { + if(!li.hasNext()) + surgeStarted = true; + + else + { + Block b = li.next(); + + Methods.playEarthbendingSound(b.getLocation()); + + for(int i = 0; i < 2; i++) + { + TempBlock tb = new TempBlock(b, Material.STATIONARY_LAVA, (byte) 0); + fracturetb.add(tb); + } + } + } + + if(surgeStarted) + { + if(stopSurge) + { + remove(); + return; + } + + if(fallingBlocksCount >= maxBlocks) + { + remove(); + return; + } + + if(curTime > time + (fallingBlockInterval * fallingBlocksCount)) + { + FallingBlock fbs = player.getWorld().spawnFallingBlock(sourceBlock.getLocation().add(0, 1, 0), Material.STATIONARY_LAVA, (byte) 0); + fblocks.add(fbs); + fbs.setVelocity(direction.clone().add(new Vector(randy.nextDouble()/10, 0.1, randy.nextDouble()/10)).multiply(1.2)); + fbs.setDropItem(false); + + for(Block b : fracture) + { + if(randy.nextBoolean() && b != sourceBlock) + { + FallingBlock fb = player.getWorld().spawnFallingBlock(b.getLocation().add(new Vector(0, 1, 0)), Material.STATIONARY_LAVA, (byte) 0); + fblocks.add(fb); + fb.setVelocity(direction.clone().add(new Vector(randy.nextDouble()/10, 0.1, randy.nextDouble()/10)).multiply(1.2)); + fb.setDropItem(false); + } + } + + fallingBlocksCount++; + } + + for(FallingBlock fb : fblocks) + { + for(Entity e : Methods.getEntitiesAroundPoint(fb.getLocation(), 2)) + { + if(e instanceof LivingEntity) + { + if(e.getEntityId() != player.getEntityId()) + { + Methods.damageEntity(player, e, impactDamage); + e.setFireTicks(100); + Methods.setVelocity(e, direction.clone()); + } + } + } + + } + } + } + + public static void progressAll() + { + for(Player p : instances.keySet()) + { + instances.get(p).progress(); + } + } +}