rendered paste body/** * */package net.sf.l2j.gameserver.model.geodata;import java.io.DataInputStream;import java.io.File;import java.io.FileInputStream;/** * @author la2 * */public class GeoParser{ Long size; GeoBlock[][] _blocks = new GeoBlock[256][256]; private static int cx = -1; private static int cy = 0; private int tc=0; public static GeoParser _instance = new GeoParser(); public GeoParser() { parseZone(); } public static GeoParser getInstance() { return _instance; } public int getBlockType(int x, int y) { int region_x =(x-x%32768)/32768; int region_y = (y-y%32768)/32768; int geo_x=20+region_x; int geo_y=18+region_y; int offset_x=x-(region_x*32768); int offset_y=y-(region_y*32768); int block_x = (offset_x-offset_x%256)/256; int block_y = (offset_y-offset_y%256)/256; if(block_x < 0) block_x*=-1; if(block_y < 0) block_y*=-1; System.err.println("region "+region_x+":"+region_y+" geo: "+geo_x+"_"+geo_y); System.err.println("offset "+offset_x+":"+offset_y+" block: ["+block_x+"]["+block_y+"]"); return _blocks[block_x][block_y].getType(); } public int getBlockHeight(int x, int y) { int region_x =(x-x%32768)/32768; int region_y = (y-y%32768)/32768; int geo_x=20+region_x; int geo_y=18+region_y; int offset_x=x-(region_x*32768); int offset_y=y-(region_y*32768); int block_x = (offset_x-offset_x%256)/256; int block_y = (offset_y-offset_y%256)/256; if(block_x < 0) block_x*=-1; if(block_y < 0) block_y*=-1; System.err.println("region "+region_x+":"+region_y+" geo: "+geo_x+"_"+geo_y); System.err.println("offset "+offset_x+":"+offset_y+" block: ["+block_x+"]["+block_y+"]"); if(_blocks[block_x][block_y].getType() == 0) return _blocks[block_x][block_y].getHeight(0); return 0; } public void addBlock(GeoBlock b) { cx++; if(cx > 255) { cx = 0; cy++; } _blocks[cx][cy] = b; tc++; //System.err.println("["+cx+"]["+cy+"]"); } public void parseZone() { int c40=0; int c00=0; int c41=0; try { File entry = new File("c:/l2j/data/geo/20_22.bin"); DataInputStream in = new DataInputStream(new FileInputStream(entry)); size = entry.length(); in.skip(18); size-=18; System.err.println("Ok, file size: "+size); System.err.println("MemBefore: "+Runtime.getRuntime().freeMemory()); while(size > 0) { int b = getHeight(in);//in.readShort(); if(b == 0x0000) // single plane { c00++; //System.err.println("Got 00 00 block type "); int h1 = getHeight(in); int h2 = getHeight(in); GeoBlock gb = new GeoBlock(b,2); gb.addHeight(0,h1,0); gb.addHeight(1,h2,0); addBlock(gb); //System.err.println("Heights: "+h1); //System.err.println("Heights: "+h2); //System.exit(0); } else if(b == 0x0040) // multiheight plane { c40++; //System.err.println("Got 40 00 block type "); GeoBlock gb = new GeoBlock(b,64); for(int p=0;p<64;p++) { int h = getHeight(in); int h3 = h&0xffff; int h2 = -(h3^0xffff)>>1; h = (h&0xf); gb.addHeight(p,h2,h); //System.err.println("movement flag: "+h+" h2: "+h2+" h3: "+h3); } addBlock(gb); } else // multifloor multiheight { System.err.println("!!Got "+b+" block type"); int h=0; for(int p=0;p<b*2;p++) { int floor = getHeight(in);h++; if(floor == 1) { int h1 = getHeight(in);h++; System.err.println("floor1 h1: "+(h1>>1)+"/"+h); } else if(floor == 2) { //p++; int h1 = getHeight(in);h++; int h2 = getHeight(in);h++; System.err.println("floor2 h1: "+h1+" h2: "+h2+"/"+h); } else if(floor == 3) { int h1 = getHeight(in);h++; int h2 = getHeight(in);h++; int h3 = getHeight(in);h++; int h4 = getHeight(in);h++; System.err.println("floor3 h1: "+h1+" h2: "+h2+" h3: "+h3+" h4: "+h4+"/"+h); } else { System.err.println("Got floor num: "+floor); } //int h3 = h&0xffff; //int h2 = -(h3^0xffff)>>1; //int flag = (h&0xf); //System.err.println("floor: "+floor+" height: "+h+" h: "+h2); } System.exit(0); } } } catch(Exception e){System.err.println("Oops: "+e);} System.err.println("00 blocks: "+c00+" 40 blocks: "+c40); System.gc(); System.err.println("MemAfter: "+Runtime.getRuntime().freeMemory() +" total: "+tc); } 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+size);System.exit(0);} return 0; } private class GeoBlock { private int _type; //0 for 0x00, 64 for 0x40, 65 for 0x41, etc private int[] _heights; public GeoBlock(int type, int size) { _type = type; _heights = new int[size]; // 2 for 0x00, 64 for 0x4000, 64+ for 0x4000+ } public int getType() { return _type; } public void addHeight(int pos,int height, int flag) { _heights[pos] = height; } public int getHeight(int pos) { return _heights[pos]; } public int getFlag(int pos) { return _heights[pos]; } }}