package pl.wat.ms4ds.terrain; import pl.wat.ms4ds.terrain.nmt.NMTDataReader; public class Square { /** * The height above the level of the sea. Unit of measure meter [m]. */ public float elevation; /** * Terrain type.
Possible values: * 0 - BARE_GROUND * 1 - GRASS * 2 - SWAMP * 3 - WATER * 4 - SCRUB, BUSHES * 5 - BUILDINGS * 6 - FOREST */ public short terrainType; /** * Type of watercourse (water obstacle) in a given direction. Each index corresponds to a given direction. * Possible values: 0 - no watercourse, 1 - drain, ditch, 2 - canal, stream, 3 - river */ public final byte[] watercourses; /** * Type of road in a given direction. Each index corresponds to a given direction. * Possible values: 0 - no road, 1 - small roads, 2 - minor roads, 3 - major roads */ public final byte[] roads; /// ///////////////////////////////////// /// tymczasowo public float stopienZabudowy; public float stopienZalesienia; public float stopienZawodnienia; public float stopienZabagnienia; public boolean[] jestDroga; public boolean[] jestRow; public boolean[] jestPrzeszkodaWodna; public int roznicaWzniesien; public int wysokoscSrednia; public static final Square EMPTY = new Square(-1, -1); public Square() { this(-2, -2); } public Square(int x, int y) { this.x = x; this.y = y; roads = new byte[8]; watercourses = new byte[8]; } public Square(int x, int y, short elevation, byte terrainType, byte majorRoads, byte minorRoads, byte smallRoads, byte rivers, byte streams, byte drains) { this.x = x; this.y = y; roads = new byte[8]; watercourses = new byte[8]; // Konwersja na metry a[0.25m] -> b[m] this.elevation = (float) (elevation) / 4; this.terrainType = terrainType; int bit = 1; for (int i = 0; i < 8; i++) { int b1 = ((majorRoads & bit) > 0) ? 3 : 0; int b2 = ((minorRoads & bit) > 0) ? 2 : 0; int b3 = ((smallRoads & bit) > 0) ? 1 : 0; roads[i] = (byte) (b1 + b2 + b3); b1 = ((rivers & bit) > 0) ? 3 : 0; b2 = ((streams & bit) > 0) ? 2 : 0; b3 = ((drains & bit) > 0) ? 1 : 0; watercourses[i] = (byte) (b1 + b2 + b3); bit <<= 1; } } public int writeToBufferElevationOnly(byte[] buffer, int offset) { // Konwersja [m] -> [0.25m]. int elev = (short) (elevation * 4); byte b1 = (byte) (elev & 0xFF); elev >>= 8; byte b0 = (byte) (elev & 0xFF); if (b0 == -1 && b1 == -4) { System.out.println("a"); } buffer[offset] = b0; buffer[offset + 1] = b1; buffer[offset + 2] = 0; buffer[offset + 3] = 0; buffer[offset + 4] = 0; buffer[offset + 5] = 0; buffer[offset + 6] = 0; buffer[offset + 7] = 0; buffer[offset + 8] = 0; return offset + 9; } public int writeToBuffer(byte[] buffer, int offset) { // Konwersja [m] -> [0.25m]. int elev = (short) (elevation * 4); byte bit = 1; byte drains = 0; byte streams = 0; byte rivers = 0; byte smallRoads = 0; byte minorRoads = 0; byte majorRoads = 0; for (int i = 0; i < watercourses.length; i++) { switch (watercourses[i]) { case 1: drains |= bit; break; case 2: streams |= bit; break; case 3: rivers |= bit; break; default: break; } switch (roads[i]) { case 1: smallRoads |= bit; break; case 2: minorRoads |= bit; break; case 3: majorRoads |= bit; break; default: break; } bit <<= 1; } byte b1 = (byte) (elev & 0xFF); elev >>= 8; byte b0 = (byte) (elev & 0xFF); if (b0 == -1 && b1 == -4) { System.out.println("a"); } buffer[offset + 1] = b1; buffer[offset] = b0; buffer[offset + 2] = (byte) terrainType; buffer[offset + 3] = smallRoads; buffer[offset + 4] = minorRoads; buffer[offset + 5] = majorRoads; buffer[offset + 6] = drains; buffer[offset + 7] = streams; buffer[offset + 8] = rivers; return offset + 9; } public int readFromBuffer(byte[] buffer, int offset) { int elev = buffer[offset] & 0xFF; // elev = (elev << 8) + (buffer[offset + 1] & 0xFF); elev = (elev << 8) | (buffer[offset + 1] & 0xFF); // Rzutowanie "elev" na short zachowuje znak liczby. short v = (short) elev; elevation = (float) (v) / 4; // Konwersja na metry a[0.25m] -> b[m] // elevation = (float) ((short) elev) / 4; if (elevation > NMTDataReader.H_MAX) { System.out.println("h=" + elevation); } terrainType = buffer[offset + 2]; byte smallRoads = buffer[offset + 3]; byte minorRoads = buffer[offset + 4]; byte majorRoads = buffer[offset + 5]; byte drains = buffer[offset + 6]; byte streams = buffer[offset + 7]; byte rivers = buffer[offset + 8]; int bit = 1; // 8 kierunków geograficznych (0 - NORTH, 1 - NORTH_EAST, ...) for (int i = 0; i < 8; i++) { int b1 = ((majorRoads & bit) > 0) ? 3 : 0; int b2 = ((minorRoads & bit) > 0) ? 2 : 0; int b3 = ((smallRoads & bit) > 0) ? 1 : 0; roads[i] = (byte) (b1 + b2 + b3); b1 = ((rivers & bit) > 0) ? 3 : 0; b2 = ((streams & bit) > 0) ? 2 : 0; b3 = ((drains & bit) > 0) ? 1 : 0; watercourses[i] = (byte) (b1 + b2 + b3); bit <<= 1; } return offset + 9; } public final int x; public final int y; @Override public final boolean equals(Object o) { if (!(o instanceof Square SQUARE)) return false; return x == SQUARE.x && y == SQUARE.y; } @Override public int hashCode() { int result = 7; result = 31 * result + x; result = 31 * result + y; return result; } @Override public String toString() { StringBuilder linia = new StringBuilder(100); linia.append("["); char c = switch (terrainType) { case 1 -> 'G'; case 2 -> 'S'; case 3 -> 'W'; case 4 -> 'R'; case 5 -> 'B'; case 6 -> 'F'; default -> ' '; }; linia.append(c); linia.append(' '); String s = String.format("%7.2f", elevation); linia.append(s); linia.append(' '); for (byte road : roads) { c = switch (road) { case 1 -> '1'; case 2 -> '2'; case 3 -> '3'; default -> '0'; }; linia.append(c); } linia.append(' '); for (byte watercours : watercourses) { c = switch (watercours) { case 1 -> '1'; case 2 -> '2'; case 3 -> '3'; default -> '0'; }; linia.append(c); } linia.append(']'); return linia.toString(); } }