/** * */ package net.sf.l2j.gameserver.model.geodata; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.util.List; import javolution.util.FastList; /** * @author zabbix * */ public class GeoEngine { Long size; private List _regions = new FastList(); public static GeoEngine _instance = new GeoEngine(); public GeoEngine() { //parseZone(); } public static GeoEngine getInstance() { return _instance; } public int getHeight(int x, int y) { int region_x = 20 + ((x - x % 32768) / 32768); int region_y = 18 + ((y - y % 32768) / 32768); System.err.println("region " + region_x + ":" + region_y); //System.err.println("offset " + offset_x + ":" + offset_y + " block: [" + block_x + "][" +block_y +"]"); //System.err.println("cell [" + cell_x + "][" + cell_y + "]"); // if(_blocks[block_x][block_y].getType() == 0) // return _blocks[block_x][block_y].getHeight(0); for (GeoRegion r : _regions) { if (r.isValid(region_x,region_y)) return r.getHeight(x,y); } return 0; } public int getFlag(int x, int y) { int region_x = 20 + ((x - x % 32768) / 32768); int region_y = 18 + ((y - y % 32768) / 32768); System.err.println("region " + region_x + ":" + region_y); //System.err.println("offset " + offset_x + ":" + offset_y + " block: [" + block_x + "][" +block_y +"]"); //System.err.println("cell [" + cell_x + "][" + cell_y + "]"); // if(_blocks[block_x][block_y].getType() == 0) // return _blocks[block_x][block_y].getHeight(0); for (GeoRegion r : _regions) { if (r.isValid(region_x,region_y)) return r.getFlag(x,y); } return 0; } private void hashFiles(String dirname, List hash) { File dir = new File("c:/l2j/data/", dirname); if (!dir.exists()) { System.err.println("Dir " + dir.getAbsolutePath() + " not exists"); return; } File[] files = dir.listFiles(); for (File f : files) { if (f.getName().endsWith(".bin")) hash.add(f); } } public void parseZone() { List files = new FastList(); hashFiles("geo", files); try { for (File entry : files) { DataInputStream in = new DataInputStream(new FileInputStream(entry)); size = entry.length(); int _rx = in.readByte(); int _ry = in.readByte(); in.skip(16); size -= 18; GeoRegion region = new GeoRegion(_rx,_ry); System.err.println("[GeoEngine] loading [" + _rx +"_"+ _ry + "][" + (size / 1024) + "kb]"); while (size > 0) { int b = getHeight(in);//in.readShort(); GeoBlock gb = new GeoBlock(b); if (b == 0) // single plane { int h1 = getHeight(in); int h2 = getHeight(in); gb.addHeight(0, h1); gb.addHeight(1, h2); } else if (b == 0x0040) // multiheight plane { for (int p = 0; p < 64; p++) { int h = getHeight(in); gb.addHeight(p, h); //int h3 = h&0xffff; //int h2 = (h>>1);//-(h3^0xffff)>>1; //h = (h&0xf); //System.err.println("movement flag: "+h+" height: "+h2); } } else // multifloor multiheight { for (int i = 0; i < 64; i++) { int floor = getHeight(in); for (int f = 0; f < floor; f++) { int fh = getHeight(in); gb.addHeight(f, fh); } } } region.addBlock(gb); } _regions.add(region); System.gc(); } } catch (Exception e) { System.err.println("Oops: " + e); } System.err.println("[GeoEngine] total "+_regions.size()+" regions loaded"); } int getHeight(DataInputStream in) { try { byte b1 = in.readByte(); byte b2 = in.readByte(); size -= 2; return b1 + (b2 << 8); } catch (Exception e) { System.err.println("height err!: " + e + ", bytes left: "+ size); System.exit(0); } return 0; } }