diff --git a/pom.xml b/pom.xml index f3ee692..d2315be 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ net.forestfire Elevators - 3.3.2 + 3.3.3 jar Elevators diff --git a/src/main/java/net/forestfire/elevators/Conf.java b/src/main/java/net/forestfire/elevators/Conf.java index fd7dc85..11c230e 100644 --- a/src/main/java/net/forestfire/elevators/Conf.java +++ b/src/main/java/net/forestfire/elevators/Conf.java @@ -82,141 +82,133 @@ public static void saveConf(boolean f) { } public static void saveConf() { saveConf(false); } private static void doSaveConf() { - SVTMR=null; File f=new File(CONFIG_PATH); String data=""; + SVTMR=null; File f=new File(CONFIG_PATH); String data; //If Not Found, Create New Config File: - if(!f.exists()) data=newConf(f); else { - try { //Read Current Config File: - FileReader r=new FileReader(f); int p=0,l; - while(p < 3000) { l=r.read(); if(l<0) break; data += fromCharCode(l); p++; } - r.close(); - } catch(IOException e) { err("saveConfig", "IOException while reading file!"); return; } - } + if(!f.exists()) data=newConf(f); else try { //Read Current Config File: + StringBuilder d=new StringBuilder(); FileReader r=new FileReader(f); int p=0,l; + while(p < 3000) { l=r.read(); if(l<0) break; d.append((char)l); p++; } + r.close(); data=d.toString(); + } catch(IOException e) { err("saveConfig", "IOException while reading file!"); return; } if(data.length() == 0) { err("saveConfig", "Save data string empty!"); return; } //Separate And Overwrite BLOCKS Section: - int bPos = data.lastIndexOf("blockList:"); String bStr = data.substring(bPos); - - int bEnd = 0, nl = 0; while(bEnd < 600) { - if(nl==1 && bStr.charAt(bEnd) != ' ') nl = 2; - if(nl==2) { if(bStr.charAt(bEnd) == '\n') break; } - else nl = (bStr.charAt(bEnd) == '\n') ? 1 : 0; bEnd++; - } bEnd += bPos; + int bPos=data.lastIndexOf("blockList:"),bEnd=0,nl=0; + String bStr=data.substring(bPos); + while(bEnd<600) { + if(nl==1 && bStr.charAt(bEnd)!=' ') nl=2; + if(nl==2) { if(bStr.charAt(bEnd)=='\n') break; } else nl=(bStr.charAt(bEnd)=='\n')?1:0; + bEnd++; + } + bEnd+=bPos; YamlConfiguration bConf = new YamlConfiguration(); ConfigurationSection bList = bConf.createSection("blockList"); for(int i=0,l=BLOCKS.length; i(); CLTMR = null; + conf.setDefaults(defaults); movingFloors=new ChuList<>(); CLTMR=null; //Load Global Settings: - DEBUG = conf.getBoolean("debug"); - TITLE = c(conf.getString("title")); - CALL = c(conf.getString("call")); - ERROR = c(conf.getString("error")); - L_ST = c(conf.getString("selStart")); - L_END = c(conf.getString("selEnd")); - NODOOR = c(conf.getString("noDoor")); - - MSG_GOTO_ST = c(conf.getString("msgGotoStart")); - MSG_GOTO_END = c(conf.getString("msgGotoEnd")); - MSG_CALL = c(conf.getString("msgCall")); - - MSG_GOTO_ST = c(conf.getString("msgGotoStart")); - MSG_GOTO_END = c(conf.getString("msgGotoEnd")); - MSG_CALL = c(conf.getString("msgCall")); - - NOMV = c(StringEscapeUtils.unescapeJava(conf.getString("noMove"))); - M_ATLV = c(StringEscapeUtils.unescapeJava(conf.getString("mAtLevel"))); - ATLV = c(StringEscapeUtils.unescapeJava(conf.getString("atLevel"))); - C_UP = c(StringEscapeUtils.unescapeJava(conf.getString("callUp"))); - UP = c(StringEscapeUtils.unescapeJava(conf.getString("up"))); - C_DOWN = c(StringEscapeUtils.unescapeJava(conf.getString("callDown"))); - DOWN = c(StringEscapeUtils.unescapeJava(conf.getString("down"))); - - RADIUS_MAX = conf.getInt("floorMaxRadius"); - MOVE_RES = conf.getInt("updateDelay"); - DOOR_HOLD = conf.getInt("doorHoldTime"); - DOOR_SET = Material.valueOf(conf.getString("doorBlock")); - - ConfigurationSection bList = conf.getConfigurationSection("blockList"); - BLOCKS = new ChuList<>(); BL_SPEED = new ChuList<>(); - if(bList != null) { - Object[] bKeys = bList.getKeys(false).toArray(); - for(int b=0,g=bKeys.length; b(); BL_SPEED=new ChuList<>(); + if(bList!=null) for(String k: bList.getKeys(false)) { //Remove non-sold blocks: + if(getMat(k).isSolid()) { BLOCKS.add(k); BL_SPEED.add(bList.getInt(k)); } } - if(BLOCKS.length < 1) { //Load Default Block Settings: - BLOCKS = new ChuList<>("IRON_BLOCK", "GOLD_BLOCK", "EMERALD_BLOCK", "DIAMOND_BLOCK", "LEGACY_STAINED_GLASS", "GLASS"); - BL_SPEED = new ChuList<>(8, 10, 12, 15, 5, 4); + if(BLOCKS.length<1) { //Load Default Block Settings: + BLOCKS=new ChuList<>("IRON_BLOCK", "GOLD_BLOCK", "EMERALD_BLOCK", "DIAMOND_BLOCK", "LEGACY_STAINED_GLASS", "GLASS"); + BL_SPEED=new ChuList<>(8, 10, 12, 15, 5, 4); } //Load Compressed Elevator Data: - elevators.clear(); ConfigurationSection eList = conf.getConfigurationSection("elevators"); int eCnt=0; - if(eList != null) { Object[] eKeys = eList.getKeys(false).toArray(); for(int i=0,l=eKeys.length; i 0) { - String delMsg = MSG_DEL_ST+err+MSG_DEL_END; + if((Integer)err>0) { + String delMsg=MSG_DEL_ST + err + MSG_DEL_END; Bukkit.getServer().getConsoleSender().sendMessage(delMsg); if(s instanceof Player) s.sendMessage(delMsg); - } doSaveConf(); + } + doSaveConf(); } else if(err!=null) { //Error While Loading Config. - Bukkit.getServer().getConsoleSender().sendMessage(MSG_ERR_CONF+"\n"+err); + Bukkit.getServer().getConsoleSender().sendMessage(MSG_ERR_CONF + "\n" + err); if(s instanceof Player) s.sendMessage(MSG_ERR_CONF); } - if(s != null) s.sendMessage("§aElevators Plugin Reloaded!"); -} public static void doConfLoad() { doConfLoad(null); } + if(s!=null) s.sendMessage("§aElevators Plugin Reloaded!"); +} //------------------- Useful Functions ------------------- -public static String locToString(Location loc) { - return loc.getWorld().getName()+"-"+(int)loc.getX()+"-"+(int)loc.getZ(); +private static Material getMat(String m) throws Exception { + try { return Material.valueOf(m); } + catch(IllegalArgumentException e) { throw new Exception("No such material "+m); } } -public static Location locFromString(String str) { - String[] data = str.split("-"); World world = plugin.getServer().getWorld(data[0]); - if(world==null) { err("locFromString", "World '"+data[0]+"' not found!"); return null; } - return new Location(world, Integer.parseInt(data[1]), 0, Integer.parseInt(data[2])); +public static String locToString(Location l) { + return l.getWorld().getName()+"-"+l.getBlockX()+"-"+l.getBlockZ(); } //Open/close doors & gates: @@ -260,7 +252,7 @@ public static void setSign(Block sign, String[] lines) { } public static void setLine(Block sign, int l, String str) { - Sign s = ((Sign)sign.getState()); s.setLine(l, str==null?"":str); s.update(); + Sign s=((Sign)sign.getState()); s.setLine(l, str==null?"":str); s.update(); } //Read lines from sign: @@ -270,8 +262,8 @@ public static String[] lines(Block sign) { //Get block sign is attached to: public static Block getSignBlock(Block s) { - World w = s.getWorld(); int x = s.getX(), y = s.getY(), z = s.getZ(); - BlockFace f = ((WallSign)s.getBlockData()).getFacing(); + World w=s.getWorld(); int x=s.getX(), y=s.getY(), z=s.getZ(); + BlockFace f=((WallSign)s.getBlockData()).getFacing(); switch(f) { case NORTH: return w.getBlockAt(x,y,z+1); case SOUTH: return w.getBlockAt(x,y,z-1); case WEST: return w.getBlockAt(x+1,y,z); case EAST: return w.getBlockAt(x-1,y,z); @@ -281,16 +273,17 @@ public static Block getSignBlock(Block s) { //Ensure there is a solid block behind the sign. public static void addSignBlock(Block s) { - Block b = Conf.getSignBlock(s); if(!b.getType().isSolid()) setDoorBlock(b,true); + Block b=Conf.getSignBlock(s); setDoorBlock(b,true); } public static void setDoorBlock(Block b, boolean on) { - b.setType(on?Conf.DOOR_SET:Conf.AIR); + Material m=b.getType(); + if(on?!m.isSolid():m==Conf.DOOR_SET) b.setType(on?Conf.DOOR_SET:Conf.AIR); if(on && b.getBlockData() instanceof MultipleFacing) { //Connect block faces MultipleFacing f=(MultipleFacing)b.getBlockData(); Location l=b.getLocation(); - f.setFace(BlockFace.EAST, !l.clone().add(1,0,0).getBlock().isEmpty()); - f.setFace(BlockFace.WEST, !l.clone().add(-1,0,0).getBlock().isEmpty()); - f.setFace(BlockFace.NORTH, !l.clone().add(0,0,-1).getBlock().isEmpty()); - f.setFace(BlockFace.SOUTH, !l.clone().add(0,0,1).getBlock().isEmpty()); + f.setFace(BlockFace.EAST, !l.clone().add(1,0,0).getBlock().isPassable()); + f.setFace(BlockFace.WEST, !l.clone().add(-1,0,0).getBlock().isPassable()); + f.setFace(BlockFace.NORTH, !l.clone().add(0,0,-1).getBlock().isPassable()); + f.setFace(BlockFace.SOUTH, !l.clone().add(0,0,1).getBlock().isPassable()); b.setBlockData(f); } } @@ -307,7 +300,7 @@ public static boolean isCallSign(Block b, ConfData ref, Player pl, String perm) } public static boolean isElevPlayer(Player pl, ConfData ref, String perm) { - if(!hasPerm(pl, perm)) return false; ref.data = Elevator.fromPlayer(pl); return (ref.data!=null); + if(!hasPerm(pl, perm)) return false; ref.data=Elevator.fromEntity(pl); return (ref.data!=null); } //Find first null element in a RaichuList: @@ -324,12 +317,12 @@ public static boolean hasPerm(Player pl, String perm) { public static String unpackFile(String intPath, File dest) { InputStream st = plugin.getResource(intPath); String s; try { - StringBuilder sb=new StringBuilder(); int p=0,r; - while(p < 3000) { r=st.read(); if(r<0) break; sb.append(fromCharCode(r)); p++; } - st.close(); s=sb.toString(); + StringBuilder d=new StringBuilder(); int p=0,r; + while(p < 3000) { r=st.read(); if(r<0) break; d.append((char)r); p++; } + st.close(); s=d.toString(); Writer file = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dest), StandardCharsets.UTF_8)); file.write(s); file.close(); - } catch (Exception e) { err("unpackFile", "Caught Exception: "+e.getMessage()); return ""; } + } catch (Exception e) { err("unpackFile", e.getMessage()); return ""; } return s; } @@ -363,11 +356,6 @@ public static String c(String str) { .getByChar(clr[i].charAt(0))).append(clr[i].substring(1)); return c.toString(); } - -public static Block getBlockBelowPlayer(Player p, boolean above) { - Location loc = p.getLocation(); int pX = (int)Math.floor(loc.getX()), pZ = (int)Math.floor(loc.getZ()); - double pY = loc.getY(); return p.getWorld().getBlockAt(pX, (int)(above?Math.ceil(pY+1.99):Math.floor(pY-1)), pZ); -} public static Block getBlockBelowPlayer(Player p) { return getBlockBelowPlayer(p, false); } } class ConfData { diff --git a/src/main/java/net/forestfire/elevators/Elevator.java b/src/main/java/net/forestfire/elevators/Elevator.java index fc7a2b5..f207f24 100644 --- a/src/main/java/net/forestfire/elevators/Elevator.java +++ b/src/main/java/net/forestfire/elevators/Elevator.java @@ -2,10 +2,6 @@ package net.forestfire.elevators; -import java.util.function.BiPredicate; -import java.util.function.Consumer; -import java.util.function.Predicate; - import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Location; @@ -14,6 +10,7 @@ import org.bukkit.block.Block; import org.bukkit.block.data.type.*; import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; @@ -34,9 +31,9 @@ public Elevator(Floor _floor, ChuList> _sGroups, ChuList data) { //TODO World could be calculated from eID using locFromString(). +public static Elevator fromSaveData(java.util.List data) { if(data.size() < 3 || data.size() % 2 == 0) { Conf.err("fromSaveData", "Data length too small or not odd number."); return null; } - World w = Bukkit.getServer().getWorld(data.get(0)); if(w==null) { + World w=Bukkit.getServer().getWorld(data.get(0)); if(w==null) { Conf.err("fromSaveData", "World '"+data.get(0)+"' does not exist!"); return null; } ChuList> sGroups = new ChuList<>(); @@ -44,23 +41,23 @@ public static Elevator fromSaveData(java.util.List data) { //TODO World try { sX = Integer.parseInt(data.get(i)); sZ = Integer.parseInt(data.get(i+1)); } catch(NumberFormatException e) { Conf.err("fromSaveData", "Cannot convert position data to integer."); return null; } ChuList sList = Elevator.rebuildSignList(w, sX, sZ); - if(sList.length!=0) sGroups.push(sList); + if(sList.length!=0) sGroups.add(sList); } if(sGroups.length==0) { Conf.err("fromSaveData", "No elevator signs found!"); return null; } Elevator elev = new Elevator(null, sGroups, null); Block dSign = sGroups.get(0).get(0); - Floor floor = Floor.getFloor(w.getBlockAt(dSign.getX(), elev.getLevel(true)+2, dSign.getZ()), elev); - if(floor==null) { Conf.err("fromSaveData", "No elevator floor detected!"); return null; } - elev.floor = floor; elev.csGroups = elev.rebuildCallSignList(); + Floor f=Floor.getFloor(w.getBlockAt(dSign.getX(), elev.getLevel(true)+2, dSign.getZ()), elev); + if(f==null) { Conf.err("fromSaveData", "No elevator floor detected!"); return null; } + elev.floor=f; elev.rebuildCallSignList(null); //Special Modes: if(Conf.NODOOR.equals(Conf.lines(dSign)[2])) elev.noDoor = true; //Enable NoDoor Mode. return elev; } public ChuList toSaveData() { - ChuList data = new ChuList<>(); data.push(floor.world.getName()); + ChuList data = new ChuList<>(); data.add(floor.world.getName()); for(int i=0,l=sGroups.length; i toSaveData() { //The names Bond. James Bond. public void selfDestruct() { if(floor != null && sGroups.length > 0 && sGroups.get(0).length > 0) { resetElevator(true); setDoors(sGroups.get(0).get(0).getY(), false); } - for(int i=0,l=csGroups.length; i c: csGroups) for(Block s: c) s.setType(Conf.AIR); + for(String s: Conf.elevators.keySet()) if(this.equals(Conf.elevators.get(s))) Conf.elevators.remove(s); } public int yMin() { return sGroups.get(0).get(0).getY()-2; } @@ -79,56 +75,58 @@ public void selfDestruct() { //-- Rebuild Database Functions: //Locate elev signs at X,Z pos. Include Y pos for new sign detection. -public static ChuList rebuildSignList(Location loc) { - World w = loc.getWorld(); int sX=(int)loc.getX(), sZ=(int)loc.getZ(), bY=(int)loc.getY(); - ChuList sList = new ChuList<>(); for(int h=0; h<256; h++) { //Increasing height: - Block bl = w.getBlockAt(sX, h, sZ); if(bl.getBlockData() instanceof WallSign - && (Conf.TITLE.equals(Conf.lines(bl)[0]) || (bY!=0 && h == bY))) sList.push(bl); +public static ChuList rebuildSignList(Location l) { + World w=l.getWorld(); int x=l.getBlockX(), y=l.getBlockY(), z=l.getBlockZ(); + ChuList sList = new ChuList<>(); for(int h=w.getMinHeight(); h rebuildSignList(World w, int x, int z) { return rebuildSignList(new Location(w, x, 0, z)); } //Locate all call signs around elevator. Include newLoc for new sign detection. -public ChuList> rebuildCallSignList(Location newLoc) { - ChuList> csGroups = new ChuList<>(); ChuList sList = sGroups.get(0); - Predicate checkSign = (bl) -> { - return (bl.getBlockData() instanceof WallSign && (Conf.CALL.equals(Conf.lines(bl)[0]) - || (newLoc!=null && bl.getLocation().equals(newLoc)))); - }; - for(int j=0,g=sList.length; j sList = sGroups.get(0); int j=0,g=sList.length; csGroups = new ChuList<>(g); + for(; j()); //Scan perimeter for call signs: - int sY = sList.get(j).getY(), a; for(int dXZ=0; dXZ<4; dXZ++) { - a = (dXZ==0?0:1); - for(int xP=floor.xMin-a; xPfloor.xMin-2; xP--) { Block bl = floor.world.getBlockAt(xP, sY, floor.zMax+1+dXZ); if(checkSign.test(bl)) csGroups.get(j).push(bl); } - for(int zP=floor.zMax+a; zP>floor.zMin-2; zP--) { Block bl = floor.world.getBlockAt(floor.xMin-1-dXZ, sY, zP); if(checkSign.test(bl)) csGroups.get(j).push(bl); } + int sY=sList.get(j).getY(),a; for(int dXZ=0; dXZ<4; dXZ++) { + a=(dXZ==0?0:1); + for(int xP=floor.xMin-a; xPfloor.xMin-2; xP--) chkSign(floor.world.getBlockAt(xP, sY, floor.zMax+1+dXZ), j, newLoc); + for(int zP=floor.zMax+a; zP>floor.zMin-2; zP--) chkSign(floor.world.getBlockAt(floor.xMin-1-dXZ, sY, zP), j, newLoc); } - } return csGroups; -} public ChuList> rebuildCallSignList() { return rebuildCallSignList(null); } + } +} + +private void chkSign(Block s, int i, Location nl) { + if(s.getBlockData() instanceof WallSign && (Conf.CALL.equals(Conf.lines(s)[0]) + || (nl!=null && s.getLocation().equals(nl)))) csGroups.get(i).add(s); +} //-- Find Elevator Functions: //Get elevator for elev sign, if any. public static Elevator fromElevSign(Block sign) { - World sW = sign.getWorld(); int sX = sign.getX(), sZ = sign.getZ(); - Object[] eKeys = Conf.elevators.keySet().toArray(); - for(int s=0,v=eKeys.length; s= fl.xMin && sX <= fl.xMax) && (sZ >= fl.zMin && sZ <= fl.zMax)) return elev; - } Conf.err("fromElevSign", "Elevator not detected for sign: "+sign); return null; + World w=sign.getWorld(); int x=sign.getX(), z=sign.getZ(); + for(Elevator e: Conf.elevators.values()) { //Iterate through elevators: + Floor f=e.floor; if(f.world.equals(w) && (x>=f.xMin && x<=f.xMax) && (z>=f.zMin && z<=f.zMax)) return e; + } + Conf.err("fromElevSign", "Elevator not detected for sign: "+sign); return null; } //Get elevator for call sign, if any. public static CSData fromCallSign(Block sign) { - int x = sign.getX(), y = sign.getY(), z = sign.getZ(); Object[] eKeys = Conf.elevators.keySet().toArray(); - for(int s=0,v=eKeys.length; s sList = elev.sGroups.get(0); + int x=sign.getX(), y=sign.getY(), z=sign.getZ(); + for(Elevator e: Conf.elevators.values()) { //Iterate through elevators: + Floor f=e.floor; if(!f.world.equals(sign.getWorld())) continue; + ChuList sList = e.sGroups.get(0); for(int j=0,g=sList.length; j= fl.xMin-a && x < fl.xMax+2) || (x == fl.xMax+1+dXZ && z >= fl.zMin-a && z < fl.zMax+2) || - (z == fl.zMax+1+dXZ && x <= fl.xMax+a && x > fl.xMin-2) || (x == fl.xMin-1-dXZ && z <= fl.zMax+a && z > fl.zMin-2)) return new CSData(elev, j); + a=(dXZ==0?0:1); if((z == f.zMin-1-dXZ && x >= f.xMin-a && x < f.xMax+2) || + (x == f.xMax+1+dXZ && z >= f.zMin-a && z < f.zMax+2) || + (z == f.zMax+1+dXZ && x <= f.xMax+a && x > f.xMin-2) || + (x == f.xMin-1-dXZ && z <= f.zMax+a && z > f.zMin-2)) return new CSData(e,j); } } } Conf.err("fromCallSign", "Elevator not detected for sign: "+sign); return null; @@ -136,43 +134,39 @@ public static CSData fromCallSign(Block sign) { //Get elevator for block, if any. public static Elevator fromElevBlock(Block bl) { - World w = bl.getWorld(); Material t = bl.getType(); boolean d = (t == Conf.DOOR_SET); - int x = bl.getX(), y = bl.getY(), z = bl.getZ(); Object[] eKeys = Conf.elevators.keySet().toArray(); - for(int s=0,v=eKeys.length; s fl.xMax || z < fl.zMin || z > fl.zMax)) continue; - ChuList sList = elev.sGroups.get(0); - for(int j=0,g=sList.length; j f.xMax || z < f.zMin || z > f.zMax)) continue; + for(Block s: e.sGroups.get(0)) { //Iterate through levels: + int sY=s.getY(); if(d) { //Block Doors: if(y < sY-1 || y > sY+1) continue; - if((z == fl.zMin-1 && x >= fl.xMin && x < fl.xMax+2) || (x == fl.xMax+1 && z >= fl.zMin && z < fl.zMax+2) || - (z == fl.zMax+1 && x <= fl.xMax && x > fl.xMin-2) || (x == fl.xMin-1 && z <= fl.zMax && z > fl.zMin-2)) return elev; - } else if(y == sY-2) return elev; //Elevator Floors. + if((z == f.zMin-1 && x >= f.xMin && x < f.xMax+2) || (x == f.xMax+1 && z >= f.zMin && z < f.zMax+2) || + (z == f.zMax+1 && x <= f.xMax && x > f.xMin-2) || (x == f.xMin-1 && z <= f.zMax && z > f.zMin-2)) return e; + } else if(y == sY-2) return e; //Elevator Floors. } } return null; } -//Get elevator for player, if any. -public static Elevator fromPlayer(Player pl) { - World pW = pl.getWorld(); Location loc = pl.getLocation(); - double pX = loc.getX(), pY = loc.getY(), pZ = loc.getZ(); - Object[] eKeys = Conf.elevators.keySet().toArray(); - for(int s=0,v=eKeys.length; s= fl.xMin && pX < fl.xMax+1) && (pY >= elev.yMin - ()-1 && pY < elev.yMax()+1) && (pZ >= fl.zMin && pZ < fl.zMax+1)) return elev; - } return null; +boolean entityInElev(Entity e) { + Floor f=floor; Location l=e.getLocation(); double x=l.getX(), y=l.getY(), z=l.getZ(); + return f.world.equals(l.getWorld()) && (x >= f.xMin && x < f.xMax+1) && (y >= this.yMin()-1 + && y < this.yMax()+1) && (z >= f.zMin && z < f.zMax+1); +} + +//Get elevator for entity, if any. +public static Elevator fromEntity(Entity en) { + for(Elevator e: Conf.elevators.values()) if(e.entityInElev(en)) return e; + return null; } //Get elevator nearby door, if any. -public static Elevator fromDoor(Location loc) { - int x = loc.getBlockX(), z = loc.getBlockZ(); - Object[] eKeys = Conf.elevators.keySet().toArray(); - for(int s=0,v=eKeys.length; s= fl.xMin && x < fl.xMax+2) || - ((x == fl.xMin-1 || x == fl.xMax+1) && z >= fl.zMin && z < fl.zMax+2)) return elev; +public static Elevator fromDoor(Location l) { + World w=l.getWorld(); int x=l.getBlockX(), z=l.getBlockZ(); + for(Elevator e: Conf.elevators.values()) { //Iterate through elevators: + Floor f=e.floor; if(f.world.equals(w) && ((z == f.zMin-1 || z == f.zMax+1) && x >= f.xMin && x < f.xMax+2) || + ((x == f.xMin-1 || x == f.xMax+1) && z >= f.zMin && z < f.zMax+2)) return e; //Scan perimeter for door } return null; } @@ -210,8 +204,16 @@ else if(locked) { if(fDir>0) { //Going Up. //Update floor name on all elev signs. public void updateFloorName(String flName) { String nFloor = Conf.L_ST+flName+Conf.L_END; - for(int k=0,m=sGroups.length; k ds=sGroups.get(0); String s,sel=Conf.lines(ds.get(0))[1]; int n=0; + if(sel.length()!=0) sel=sel.substring(Conf.L_ST.length(), sel.length()-Conf.L_END.length()); + int i=0,l=ds.length; ChuList fn=new ChuList<>(l); + for(; i isCorner = (x,z) -> ((fl.xMax+1-fl.xMin<=2) ? (x < fl.xMin || x > fl.xMax) - : (x <= fl.xMin || x >= fl.xMax)) && ((fl.zMax+1-fl.zMin<=2) ? (z < fl.zMin || z > fl.zMax) : (z <= fl.zMin || z >= fl.zMax)); - //Open/Close Barrier-Doors: - Consumer setBDoor = (bl) -> { - if(isCorner.test(bl.getX(),bl.getZ())) { if(bl.getType() == Conf.AIR) Conf.setDoorBlock(bl, true); } - else if(bl.getType() == (on?Conf.DOOR_SET:Conf.AIR)) Conf.setDoorBlock(bl, !on); - }; - //Cycle Around Elevator Perimeter: - World w = fl.world; for(int yP=h-1; yP<=h+1; yP++) { - for(int xP=fl.xMin; xPfl.xMin-2; xP--) { Block bl = w.getBlockAt(xP, yP, fl.zMax+1); if(!noDoor) setBDoor.accept(bl); Conf.setDoor(bl,on); } - for(int zP=fl.zMax; zP>fl.zMin-2; zP--) { Block bl = w.getBlockAt(fl.xMin-1, yP, zP); if(!noDoor) setBDoor.accept(bl); Conf.setDoor(bl,on); } + Floor f=floor; World w=f.world; Block b; for(int yP=h-1; yP<=h+1; yP++) { //Cycle Around Elevator Perimeter: + for(int xP=f.xMin; xPf.xMin-2; xP--) { b=w.getBlockAt(xP, yP, f.zMax+1); if(!noDoor) setBDoor(b,on); Conf.setDoor(b,on); } + for(int zP=f.zMax; zP>f.zMin-2; zP--) { b=w.getBlockAt(f.xMin-1, yP, zP); if(!noDoor) setBDoor(b,on); Conf.setDoor(b,on); } } int fNum=-1; for(int q=0,m=sGroups.get(0).length; q remBDoor = (bl) -> { if(bl.getType() == Conf.DOOR_SET) bl.setType(Conf.AIR); }; - World w = fl.world; for(int yP=h-1; yP<=h+1; yP++) { - for(int xP=fl.xMin; xPfl.xMin-2; xP--) remBDoor.accept(w.getBlockAt(xP, yP, fl.zMax+1)); - for(int zP=fl.zMax; zP>fl.zMin-2; zP--) remBDoor.accept(w.getBlockAt(fl.xMin-1, yP, zP)); - } +//Open/Close Barrier-Doors +private void setBDoor(Block b, boolean on) { + if(isCorner(b.getX(),b.getZ())) Conf.setDoorBlock(b, true); else Conf.setDoorBlock(b, !on); +} +private boolean isCorner(int x, int z) { + Floor f=floor; return ((f.xMax+1-f.xMin<=2) ? (xf.xMax) : (x<=f.xMin || x>=f.xMax)) + && ((f.zMax+1-f.zMin<=2) ? (zf.zMax) : (z<=f.zMin || z>=f.zMax)); } -//Turn on/off gravity and adjust height of all entities in elevator: -public void setEntities(boolean gravity, double delta, double hCheck, boolean resetVel) { - World world = floor.world; int yMin = this.yMin(), yMax = this.yMax(); - Object[] eList = world.getEntitiesByClass(org.bukkit.entity.LivingEntity.class).toArray(); //Get LivingEntity list. - for(int i=0,l=eList.length; i= floor.xMin && eX < floor.xMax+1) && (eY >= yMin-1 && eY < yMax+1) && (eZ >= floor.zMin && eZ < floor.zMax+1)) { - e.setGravity(gravity); if(e instanceof Player) { - ((Player)e).setAllowFlight(((Player)e).getGameMode()==GameMode.CREATIVE || !gravity); - } - if(hCheck != 0) { - if(delta != 0 || resetVel) { e.setVelocity(new Vector(0, delta, 0)); e.setFallDistance(0); } - double dist = eY-(hCheck+1); if(delta==0?(dist < 0 || dist > 2):(Math.abs(dist) > 5)) - e.teleport(new Location(world, eX, hCheck+1.1, eZ, loc.getYaw(), loc.getPitch())); - } - } +//Remove block doors +public void remBlockDoor(int h) { + Floor f=floor; World w=f.world; for(int yP=h-1; yP<=h+1; yP++) { + for(int xP=f.xMin; xPf.xMin-2; xP--) Conf.setDoorBlock(w.getBlockAt(xP, yP, f.zMax+1), false); + for(int zP=f.zMax; zP>f.zMin-2; zP--) Conf.setDoorBlock(w.getBlockAt(f.xMin-1, yP, zP), false); } -} public void setEntities(boolean gravity, double hSet, boolean rVel) { setEntities(gravity, 0, hSet, rVel); } -public void setEntities(boolean gravity) { setEntities(gravity, 0, 0, true); } +} //-- Elevator Movement: //Move elevator car from fLevel to sLevel: //Speed is in blocks-per-second. -public void gotoFloor(int fLevel, int sLevel, int selNum, int speed) { +public void gotoFloor(int fLevel, int sLevel, int selNum, boolean msg) { + int speed = Conf.BL_SPEED.get(Conf.BLOCKS.indexOf(floor.fType.toString())); moveDir = (sLevel>fLevel); double step = (double)speed * ((double)Conf.MOVE_RES/1000) * (moveDir?1:-1); if(Conf.CLTMR != null) { Conf.CLTMR.cancel(); Conf.CLTMR = null; } @@ -309,29 +292,51 @@ public void gotoFloor(int fLevel, int sLevel, int selNum, int speed) { Conf.dbg("FROM: "+fLevel+", TO: "+sLevel+" ("+selNum+"), STEP: "+step); Conf.plugin.setTimeout(() -> { - int fID = floor.addFloor(fLevel, true); GotoTimer timer = new GotoTimer(); - timer.set(this, fLevel, sLevel, selNum, speed, step, fID); Conf.plugin.setInterval(timer, Conf.MOVE_RES); + int fID = floor.addFloor(fLevel, true, false); + GotoTimer timer = new GotoTimer(this, fLevel, sLevel, selNum, speed, step, fID, msg); + Conf.plugin.setInterval(timer, Conf.MOVE_RES); }, 500); } } class GotoTimer extends BukkitRunnable { -private final Main plugin = Conf.plugin; private Elevator elev; -private int sLevel, selNum, fID; private double fPos, step, accel; +private final Main pl=Conf.plugin; private final Elevator el; +private final int sLev, sNum, fID; private final double step, accel; +private double fPos; private final ChuList eList = new ChuList<>(5); + +GotoTimer(Elevator _e, int fp, int sl, int sn, double spd, double st, int id, boolean m) { + el=_e; step=st; fPos=fp; sLev=sl; sNum=sn; fID=id; accel=spd*(el.moveDir?1:-1)/20; + FList fl=el.getFloors(); String name=fl.fl.get(fl.sn); + //Find entities in elevator: + for(Entity e: el.floor.world.getEntitiesByClass(LivingEntity.class)) if(el.entityInElev(e)) { + if(m && e instanceof Player) e.sendMessage(Conf.MSG_GOTO_ST+name+Conf.MSG_GOTO_END); + eList.add(e); + } + setEntities(false, 0, fPos); +} -public void set(Elevator elev, int fLevel, int sLevel, int selNum, double speed, double step, int fID) { - this.elev = elev; this.step = step; this.fPos = fLevel; this.sLevel = sLevel; this.selNum = selNum; - this.fID = fID; this.accel = speed*(elev.moveDir?1:-1)/21.2; elev.setEntities(false, fPos, false); +//Turn on/off gravity and adjust height of all entities in elevator +protected void setEntities(boolean grav, double delta, double hSet) { + Floor f=el.floor; World w=f.world; for(Entity e: eList) { //Iterate through entities: + e.setGravity(grav); if(e instanceof Player) { + Player p=(Player)e; if(p.isFlying()) p.setFlying(false); + p.setAllowFlight(p.getGameMode()==GameMode.CREATIVE || !grav); + } + e.setVelocity(new Vector(0,delta,0)); e.setFallDistance(0); + Location l=e.getLocation(); double dis=l.getY()-(hSet+1); boolean ee=el.entityInElev(e); + if(!ee || dis<-1.5 || dis>1.5 || delta==0) e.teleport(new Location(w, ee?l.getX():f.xMin+.5, + hSet+1.1, ee?l.getZ():f.zMin+.5, l.getYaw(), l.getPitch())); + } } public void run() { synchronized(Conf.API_SYNC) { - elev.floor.moveFloor(fID, fPos); elev.updateCallSigns(fPos, elev.moveDir?1:0, selNum); - elev.setEntities(false, accel, fPos, false); - if(elev.moveDir?(fPos >= sLevel):(fPos <= sLevel)) { //At destination floor: - this.cancel(); elev.floor.deleteFloor(fID); plugin.setTimeout(() -> { - elev.floor.addFloor(sLevel, false); elev.setEntities(true, sLevel, true); //Restore solid floor. - elev.updateCallSigns(sLevel+2); plugin.setTimeout(() -> { - elev.floor.moving = false; elev.updateCallSigns(sLevel+2); elev.doorTimer(sLevel+2); + el.floor.moveFloor(fID, fPos); el.updateCallSigns(fPos, el.moveDir?1:0, sNum); + setEntities(false, accel, fPos); + if(el.moveDir?(fPos >= sLev):(fPos <= sLev)) { //At destination floor: + this.cancel(); el.floor.deleteFloor(fID); pl.setTimeout(() -> { + el.floor.addFloor(sLev, false, false); setEntities(true, 0, sLev); //Restore solid floor. + el.updateCallSigns(sLev+2); pl.setTimeout(() -> { + el.floor.moving=false; el.updateCallSigns(sLev+2); el.doorTimer(sLev+2); }, 500); }, 50); } else fPos += step; @@ -340,7 +345,11 @@ public void run() { synchronized(Conf.API_SYNC) { class CSData { Elevator elev; int index; -public CSData(Elevator _elev, int _index) { - elev = _elev; index = _index; +public CSData(Elevator e, int i) { elev=e; index=i; } } + +//Hidden Reference? Maybe~ +class FList { +public final ChuList fl; public final int sn; +FList(ChuList _fl, int _sn) { fl=_fl; sn=_sn; } } \ No newline at end of file diff --git a/src/main/java/net/forestfire/elevators/Floor.java b/src/main/java/net/forestfire/elevators/Floor.java index f387d05..9cc197a 100644 --- a/src/main/java/net/forestfire/elevators/Floor.java +++ b/src/main/java/net/forestfire/elevators/Floor.java @@ -44,18 +44,17 @@ public static Floor getFloor(Block b, Elevator parent) { public int addFloor(double h, boolean isMoving, boolean dontDelete, Integer forceID) { if(!dontDelete) { removeFallingBlocks(); elev.resetElevator(true); } if(isMoving) { //Create FallingBlock Floor: - ChuList blocks = new ChuList<>(); moving = true; + ChuList bl=new ChuList<>((xMax-xMin+1)*(zMax-zMin+1)); moving=true; for(int x=xMin; x<=xMax; x++) for(int z=zMin; z<=zMax; z++) { - blocks.push(fallingBlock(world, x, h, z, fType)); + bl.add(fallingBlock(world, x, h, z, fType)); } int ind; if(forceID!=null) ind = forceID; else ind = Conf.findFirstEmpty(Conf.movingFloors); - Conf.movingFloors.set(ind, blocks); return ind; + Conf.movingFloors.set(ind, bl); return ind; } else { //Create Solid Floor: for(int x=xMin; x<=xMax; x++) for(int z=zMin; z<=zMax; z++) world.getBlockAt(x,(int)h,z).setType(fType); } return 0; } public int addFloor(double h, boolean isMoving, boolean dontDelete) { return addFloor(h, isMoving, dontDelete, null); } -public int addFloor(double h, boolean isMoving) { return addFloor(h, isMoving, false, null); } //Moves a MovingFloor using floorID. public void moveFloor(int floorID, double h) { @@ -72,23 +71,20 @@ public void deleteFloor(int floorID) { ChuList bList = Conf.movingFloors.get(floorID); for(int i=0,l=bList.length; i= xMin-0.5 && loc.getX() <= xMax+0.5) && (loc.getY() >= yMin-0.5 && loc.getY - () <= yMax+0.5) && (loc.getZ() >= zMin-0.5 && loc.getZ() <= zMax+0.5)) ((Entity)el[i]).remove(); + int yMin=elev.yMin(), yMax=elev.yMax(); + for(Entity e: world.getEntitiesByClass(FallingBlock.class)) { + Location l=e.getLocation(); if((l.getX()>=xMin-.5 && l.getX()<=xMax+.5) && + (l.getY()>=yMin-.5 && l.getY()<=yMax+.5) && (l.getZ()>=zMin-.5 && l.getZ()<=zMax+.5)) e.remove(); } } } \ No newline at end of file diff --git a/src/main/java/net/forestfire/elevators/Main.java b/src/main/java/net/forestfire/elevators/Main.java index 805d24c..b756087 100644 --- a/src/main/java/net/forestfire/elevators/Main.java +++ b/src/main/java/net/forestfire/elevators/Main.java @@ -37,7 +37,7 @@ public class Main extends JavaPlugin implements Listener { @Override public void onEnable() { - Conf.initDefaults(this); setTimeout(Conf::doConfLoad, 200); + Conf.initDefaults(this); setTimeout(() -> Conf.doConfLoad(null), 200); getServer().getPluginManager().registerEvents(this, this); Bukkit.getConsoleSender().sendMessage(Conf.MSG_DBG+"§dElevators Plugin Loaded!"); } @@ -72,18 +72,18 @@ public BukkitTask setTimeout(Runnable f, long ms) { //------------------- Elevator Create Sign Events ------------------- @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) -public void onSignChange(SignChangeEvent e) { synchronized(Conf.API_SYNC) { if(e.getBlock().getBlockData() instanceof WallSign) { +public void onSignChange(SignChangeEvent e) { Block sign = e.getBlock(); + synchronized(Conf.API_SYNC) { if(sign.getBlockData() instanceof WallSign) { if(e.getLine(0).equalsIgnoreCase("[call]") && Conf.hasPerm(e.getPlayer(), PERM_CREATE)) { //Call Sign: e.setLine(0, "> ERROR <"); e.setLine(1, ""); e.setLine(2, ""); - Block block = e.getBlock(); //Is sign in elevator? - CSData ret = Elevator.fromCallSign(block); if(ret==null) { e.setLine(0, Conf.ERROR); Conf.err("onSignChange:CallSign", "No elevator found!"); return; } + CSData ret = Elevator.fromCallSign(sign); if(ret==null) { e.setLine(0, Conf.ERROR); Conf.err("onSignChange:CallSign", "No elevator found!"); return; } Elevator elev = ret.elev; int csNum = ret.index; if(elev.floor.moving) { e.setCancelled(true); - block.setType(Conf.AIR); Conf.err("onSignChange:CallSign", "Elevator is moving!"); return; } + sign.setType(Conf.AIR); Conf.err("onSignChange:CallSign", "Elevator is moving!"); return; } //Build sign list: - elev.csGroups = elev.rebuildCallSignList(block.getLocation()); + elev.rebuildCallSignList(sign.getLocation()); //Update call signs: elev.updateCallSigns(elev.getLevel()); @@ -91,31 +91,30 @@ public void onSignChange(SignChangeEvent e) { synchronized(Conf.API_SYNC) { if(e } else if(e.getLine(0).equalsIgnoreCase("[elevator]") && Conf.hasPerm(e.getPlayer(), PERM_CREATE)) { //Elevator Sign: e.setLine(0, "> ERROR <"); e.setLine(1, ""); - Block block = e.getBlock(); //Is sign in elevator? - Elevator elev = Elevator.fromElevSign(block); + Elevator elev = Elevator.fromElevSign(sign); //Build sign list: - ChuList sList = Elevator.rebuildSignList(block.getLocation()); int ind = 0; + ChuList sList = Elevator.rebuildSignList(sign.getLocation()); int col=-1; if(elev!=null) { //Existing Elevator: if(elev.floor.moving) { - e.setCancelled(true); block.setType(Conf.AIR); Conf.err("onSignChange:ElevSign", "Elevator is moving!"); return; + e.setCancelled(true); sign.setType(Conf.AIR); Conf.err("onSignChange:ElevSign", "Elevator is moving!"); return; } - int column = -1; for(int i=0,l=elev.sGroups.length; i oList = elev.sGroups.get(k); int sX = oList.get(0).getX(), sZ = oList.get(0).getZ(); WallSign d = (WallSign)sList.get(0).getBlockData(); World w = elev.floor.world; for(int i=0,l=oList.length; i(); for(int i=0,l=sList.length; i(sl); for(int i=0; i sRef = elev.sGroups.get(0); int sX = sList.get(0).getX(), sZ = sList.get(0).getZ(); WallSign d = (WallSign)sList.get(0).getBlockData(); World w = elev.floor.world; for(int i=0,l=sList.length; i(); for(int i=0,l=sRef.length; i(sl); for(int i=0; i 0 && (sList.get(i).getY() - sList.get(i-1).getY()) < 3) { Conf.setLine(sList.get(i), - 0, Conf.ERROR); if(sList.get(i).getLocation().equals(block.getLocation())) cErr = true; sList.remove(i); i--; } //Signs too close! + if(i > 0 && (sList.get(i).getY() - sList.get(i-1).getY()) < 3) { //Signs too close! + Conf.setLine(sList.get(i), 0, Conf.ERROR); + if(sList.get(i).getLocation().equals(sign.getLocation())) cErr=true; sList.remove(i); i--; + } } //Update Elevator Data: - if(ind == -1) { elev.sGroups = new ChuList>(sList); } else elev.sGroups.set(ind, sList); + if(col == -1) { elev.sGroups = new ChuList>(sList); } else elev.sGroups.set(col, sList); //Line 2 Special Modes: - if(elev.noDoor) { - elev.sGroups.get(0).forEach((s) -> Conf.setLine(s, 2, "")); - } + if(elev.noDoor) elev.sGroups.get(0).forEach((s) -> Conf.setLine(s, 2, "")); + //Set modes: String sLine = e.getLine(2); if(elev.noDoor || sLine.equalsIgnoreCase("[nodoor]")) { //Enable NoDoor Mode: elev.noDoor = true; Block first = elev.sGroups.get(0).get(0); - if(first.equals(e.getBlock())) e.setLine(2, Conf.NODOOR); + if(first.equals(sign)) e.setLine(2, Conf.NODOOR); else { Conf.setLine(first, 2, Conf.NODOOR); e.setLine(2, ""); } } else e.setLine(2, ""); //Update Sign Level Numbers for Non-Custom-Named Signs: for(int k=0,m=elev.sGroups.length; k sList = Elevator.rebuildSignList(b.getLocation()); elev.resetElevator(); //Find sGroups index: - int ind = -1; for(int i=0,l=elev.sGroups.length; i 1) { //Delete Whole Columns: for(int i=0,l=sList.length; i cs = elev.csGroups.get(subInd); if(cs != null) for(int h=0,d=cs.length; h cs = elev.csGroups.get(sInd); + if(cs != null) for(int h=0,d=cs.length; h dsList = elev.sGroups.get(0); - LAST_ELEV = elev; - - //Get Selected Floor: - String selName = Conf.lines(dsList.get(0))[1]; int selNum = 0; if(selName.length()!=0) - selName = selName.substring(Conf.L_ST.length()-(selName.charAt(Conf.L_ST.length()-1) - !=Conf.L_ST.charAt(Conf.L_ST.length()-1)?2:0),selName.length()-Conf.L_END.length()); - - //Get List of Floor Names: - ChuList flNames = new ChuList<>(); - for(int i=0,l=dsList.length; i= flNames.length) selNum = 0; } elev.updateFloorName(flNames.get(selNum)); + //Increment Floor Number: + if(e.getPlayer().isSneaking()) { if(--sn<0) sn=fl.fl.length-1; } else if(++sn >= fl.fl.length) sn=0; + elev.updateFloorName(fl.fl.get(sn)); e.setCancelled(true); } else if(Conf.isCallSign(e.getClickedBlock(), ref, e.getPlayer(), PERM_USE) && !((CSData)ref.data).elev.floor.moving) { //Call Sign Click: - Elevator elev = ((CSData)ref.data).elev; int fLevel = elev.getLevel(), sLevel = e.getClickedBlock().getY()-2; - LAST_ELEV = elev; + Elevator elev=((CSData)ref.data).elev; int fLevel = elev.getLevel(), sLevel = e.getClickedBlock().getY()-2; + LAST_ELEV=elev; //Call Elevator to Floor: if(fLevel != sLevel) { e.getPlayer().sendMessage(Conf.MSG_CALL); - int speed = Conf.BL_SPEED.get(Conf.BLOCKS.indexOf(elev.floor.fType.toString())); - elev.gotoFloor(fLevel, sLevel, ((CSData)ref.data).index, speed); + elev.gotoFloor(fLevel, sLevel, ((CSData)ref.data).index, false); } else elev.doorTimer(sLevel+2); //Re-open doors if already on level. e.setCancelled(true); - }} else if((act == Action.RIGHT_CLICK_BLOCK || act == Action.LEFT_CLICK_AIR) && Conf.isElevPlayer(e.getPlayer(), ref, PERM_USE) //Goto Floor: - && (e.getItem() == null || e.getPlayer().isSneaking()) && !((Elevator)ref.data).floor.moving) { - Elevator elev = ((Elevator)ref.data); ChuList dsList = elev.sGroups.get(0); + }} else if((act == Action.RIGHT_CLICK_BLOCK || act == Action.LEFT_CLICK_AIR) && Conf.isElevPlayer(e.getPlayer(), ref, PERM_USE) + && (e.getItem() == null || e.getPlayer().isSneaking()) && !((Elevator)ref.data).floor.moving) { //Goto Floor: + Elevator elev=((Elevator)ref.data); - //Get Current And Selected Floors: - int fLevel = elev.getLevel(), selNum = 0; String selName = Conf.lines(dsList.get(0))[1]; - if(selName.length()!=0) selName = selName.substring(Conf.L_ST.length()-(selName.charAt(Conf.L_ST - .length()-1)!=Conf.L_ST.charAt(Conf.L_ST.length()-1)?2:0),selName.length()-Conf.L_END.length()); - - //Get Floor Name: - for(int i=0,l=dsList.length; i