// Path: libuosl/src/org/solhost/folko/uosl/libuosl/types/Point3D.java
// public class Point3D extends Point2D {
//     private static final long serialVersionUID = 1L;
//     public static final int MIN_ELEVATION = -128;
//     public static final int MAX_ELEVATION = 127;
//     protected final int z;
// 
//     public Point3D(int x, int y) {
//         super(x, y);
//         this.z = 0;
//     }
// 
//     public Point3D(int x, int y, int z) {
//         super(x, y);
//         if(z < MIN_ELEVATION || z > MAX_ELEVATION) {
//             throw new IllegalArgumentException("invalid z coordinate: " + z);
//         }
//         this.z = z;
//     }
// 
//     public Point3D(Point2D d2, int z) {
//         super(d2.x, d2.y);
//         if(z < MIN_ELEVATION || z > MAX_ELEVATION) {
//             throw new IllegalArgumentException("invalid z coordinate: " + z);
//         }
//         this.z = z;
//     }
// 
//     public int getZ() {
//         return z;
//     }
// 
//     @Override
//     public int hashCode() {
//         final int prime = 31;
//         int result = super.hashCode();
//         result = prime * result + z;
//         return result;
//     }
// 
//     @Override
//     public boolean equals(Object obj) {
//         if (this == obj)
//             return true;
//         if (!super.equals(obj))
//             return false;
//         if (!(obj instanceof Point3D))
//             return false;
//         Point3D other = (Point3D) obj;
//         if (z != other.z)
//             return false;
//         return true;
//     }
// 
//     @Override
//     public String toString() {
//         return String.format("<Point3D: x = %d, y = %d, z = %d>", x, y, z);
//     }
// }


import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.solhost.folko.uosl.libuosl.types.Point2D;
import org.solhost.folko.uosl.libuosl.types.Point3D;
        }
        cached = true;
    }

    private List<SLStatic> getStatics(int cell) {
        if(cached) {
            return staticCells[cell];
        }

        synchronized(this) {
            int idxOffset = cell * 12;
            staticsIndex.seek(idxOffset);
            long staticsOffset = staticsIndex.readUDWord();
            int staticsCount = (int) staticsIndex.readUDWord() / 11;
            List<SLStatic> res = new ArrayList<SLStatic>(staticsCount);

            if(staticsOffset == -1) { // no statics
                return res;
            }

            staticsFile.seek((int) staticsOffset);

            for(int i = 0; i < staticsCount; i++) {
                long serial = staticsFile.readUDWord();
                int staticID = staticsFile.readUWord();
                byte xOffset = staticsFile.readSByte();
                byte yOffset = staticsFile.readSByte();
                byte z = staticsFile.readSByte();
                int hue = staticsFile.readUWord();

// Path: libuosl/src/org/solhost/folko/uosl/libuosl/types/Point3D.java
// public class Point3D extends Point2D {
//     private static final long serialVersionUID = 1L;
//     public static final int MIN_ELEVATION = -128;
//     public static final int MAX_ELEVATION = 127;
//     protected final int z;
// 
//     public Point3D(int x, int y) {
//         super(x, y);
//         this.z = 0;
//     }
// 
//     public Point3D(int x, int y, int z) {
//         super(x, y);
//         if(z < MIN_ELEVATION || z > MAX_ELEVATION) {
//             throw new IllegalArgumentException("invalid z coordinate: " + z);
//         }
//         this.z = z;
//     }
// 
//     public Point3D(Point2D d2, int z) {
//         super(d2.x, d2.y);
//         if(z < MIN_ELEVATION || z > MAX_ELEVATION) {
//             throw new IllegalArgumentException("invalid z coordinate: " + z);
//         }
//         this.z = z;
//     }
// 
//     public int getZ() {
//         return z;
//     }
// 
//     @Override
//     public int hashCode() {
//         final int prime = 31;
//         int result = super.hashCode();
//         result = prime * result + z;
//         return result;
//     }
// 
//     @Override
//     public boolean equals(Object obj) {
//         if (this == obj)
//             return true;
//         if (!super.equals(obj))
//             return false;
//         if (!(obj instanceof Point3D))
//             return false;
//         Point3D other = (Point3D) obj;
//         if (z != other.z)
//             return false;
//         return true;
//     }
// 
//     @Override
//     public String toString() {
//         return String.format("<Point3D: x = %d, y = %d, z = %d>", x, y, z);
//     }
// }


// Path: libuosl/src/org/solhost/folko/uosl/libuosl/data/SLStatics.java
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.solhost.folko.uosl.libuosl.types.Point2D;
import org.solhost.folko.uosl.libuosl.types.Point3D;

        }
        cached = true;
    }

    private List<SLStatic> getStatics(int cell) {
        if(cached) {
            return staticCells[cell];
        }

        synchronized(this) {
            int idxOffset = cell * 12;
            staticsIndex.seek(idxOffset);
            long staticsOffset = staticsIndex.readUDWord();
            int staticsCount = (int) staticsIndex.readUDWord() / 11;
            List<SLStatic> res = new ArrayList<SLStatic>(staticsCount);

            if(staticsOffset == -1) { // no statics
                return res;
            }

            staticsFile.seek((int) staticsOffset);

            for(int i = 0; i < staticsCount; i++) {
                long serial = staticsFile.readUDWord();
                int staticID = staticsFile.readUWord();
                byte xOffset = staticsFile.readSByte();
                byte yOffset = staticsFile.readSByte();
                byte z = staticsFile.readSByte();
                int hue = staticsFile.readUWord();

                Point3D location = new Point3D(Point2D.fromCell(cell, xOffset, yOffset), z);