diff --git a/src/com/projectkorra/ProjectKorra/firebending/Lightning.java b/src/com/projectkorra/ProjectKorra/firebending/Lightning.java index 468011ad..a3e9cfaf 100644 --- a/src/com/projectkorra/ProjectKorra/firebending/Lightning.java +++ b/src/com/projectkorra/ProjectKorra/firebending/Lightning.java @@ -2,12 +2,14 @@ package com.projectkorra.ProjectKorra.firebending; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import org.bukkit.Bukkit; 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.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; @@ -57,6 +59,7 @@ public class Lightning { private ArrayList affectedEntities = new ArrayList(); private ArrayList arcs = new ArrayList(); private ArrayList tasks = new ArrayList(); + private HashMap isTransparentCache = new HashMap(); public Lightning(Player player) { this.player = player; @@ -160,17 +163,13 @@ public class Lightning { for(int j = 0; j < arc.getAnimLocs().size() - 1; j++) { final Location iterLoc = arc.getAnimLocs().get(j).getLoc().clone(); final Location dest = arc.getAnimLocs().get(j + 1).getLoc().clone(); - - if(!isTransparent(player, iterLoc.getBlock())) { - if(SELF_HIT_CLOSE && player.getLocation().distance(iterLoc) < 3) { - if(!affectedEntities.contains(player)) { + if(SELF_HIT_CLOSE + && player.getLocation().distance(iterLoc) < 3 + && !isTransparent(player, iterLoc.getBlock()) + && !affectedEntities.contains(player)) { affectedEntities.add(player); electrocute(player); - } } - remove(); - return; - } while(iterLoc.distance(dest) > 0.15) { BukkitRunnable task = new LightningParticle(arc, iterLoc.clone()); @@ -190,15 +189,23 @@ public class Lightning { } } - public static boolean isTransparent(Player player, Block block) { + public boolean isTransparent(Player player, Block block) { + if(isTransparentCache.containsKey(block)) + return isTransparentCache.get(block); + + boolean value = false; if (Arrays.asList(Methods.transparentToEarthbending).contains(block.getTypeId())) { if(Methods.isRegionProtectedFromBuild(player, "Lightning", block.getLocation())) - return false; + value = false; else if(isIce(block.getLocation())) - return ARC_ON_ICE; - return true; - } - return false; + value = ARC_ON_ICE; + else + value = true; + } + else + value = false; + isTransparentCache.put(block, new Boolean(value)); + return value; } public void electrocute(LivingEntity lent) { @@ -283,6 +290,8 @@ public class Lightning { public class Arc { private ArrayList points; private ArrayList animLocs; + private ArrayList particles; + private ArrayList subArcs; private Vector direction; private int animCounter; @@ -291,6 +300,8 @@ public class Lightning { points.add(startPoint.clone()); points.add(endPoint.clone()); direction = Methods.getDirection(startPoint, endPoint); + particles = new ArrayList(); + subArcs = new ArrayList(); animLocs = new ArrayList(); animCounter = 0; } @@ -327,6 +338,7 @@ public class Lightning { double randRange = (Math.random() * range) + (range / 3.0); Location loc2 = loc.clone().add(dir.normalize().multiply(randRange)); Arc arc = new Arc(loc, loc2); + subArcs.add(arc); arc.setAnimCounter(animLocs.get(i).getAnimCounter()); arc.generatePoints(POINT_GENERATION); arcs.add(arc); @@ -335,6 +347,16 @@ public class Lightning { } return arcs; } + + public void cancel() { + for(int i = 0; i < particles.size(); i++) { + particles.get(i).cancel(); + } + + for(Arc subArc : subArcs) { + subArc.cancel(); + } + } public ArrayList getPoints() { return points; @@ -367,6 +389,15 @@ public class Lightning { public void setAnimLocs(ArrayList animLocs) { this.animLocs = animLocs; } + + public ArrayList getParticles() { + return particles; + } + + public void setParticles(ArrayList particles) { + this.particles = particles; + } + } public class AnimLocation { @@ -403,6 +434,7 @@ public class Lightning { public LightningParticle(Arc arc, Location loc) { this.arc = arc; this.loc = loc; + arc.particles.add(this); } public void cancel() { @@ -416,7 +448,11 @@ public class Lightning { if(count > 5) this.cancel(); else if(count == 1) { - + if(!isTransparent(player, loc.getBlock())) { + arc.cancel(); + return; + } + // Handle Water electrocution if(!hitWater && (isWater(loc) || (ARC_ON_ICE && isIce(loc)))) { hitWater = true;