Fixed Lightning not arcing in water, added a cache to speed up processing

This commit is contained in:
nathank33 2015-01-18 21:26:12 -08:00
parent bede932459
commit 709b5f76cb

View file

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