mirror of
https://github.com/neocturne/MinedMap.git
synced 2025-03-04 09:13:33 +01:00
Remove C++ implementation
This commit is contained in:
parent
c7e04649ff
commit
4b83f6376f
53 changed files with 0 additions and 5375 deletions
16
.github/toolchains/common-w64-mingw32.cmake
vendored
16
.github/toolchains/common-w64-mingw32.cmake
vendored
|
@ -1,16 +0,0 @@
|
|||
set(BUILD_STATIC ON)
|
||||
|
||||
set(CMAKE_SYSTEM_NAME Windows)
|
||||
set(CMAKE_SYSROOT /usr/${TARGET})
|
||||
|
||||
set(CMAKE_C_COMPILER ${TARGET}-gcc)
|
||||
set(CMAKE_CXX_COMPILER ${TARGET}-g++)
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||
|
||||
set(ENV{PKG_CONFIG_LIBDIR} ${CMAKE_SYSROOT}/lib/pkgconfig:${CMAKE_SYSROOT}/share/pkgconfig)
|
||||
set(ENV{PKG_CONFIG_PATH} $ENV{PKG_CONFIG_LIBDIR})
|
||||
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
|
2
.github/toolchains/i686-w64-mingw32.cmake
vendored
2
.github/toolchains/i686-w64-mingw32.cmake
vendored
|
@ -1,2 +0,0 @@
|
|||
set(TARGET i686-w64-mingw32)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/common-w64-mingw32.cmake)
|
0
.github/toolchains/x86_64-linux-gnu.cmake
vendored
0
.github/toolchains/x86_64-linux-gnu.cmake
vendored
2
.github/toolchains/x86_64-w64-mingw32.cmake
vendored
2
.github/toolchains/x86_64-w64-mingw32.cmake
vendored
|
@ -1,2 +0,0 @@
|
|||
set(TARGET x86_64-w64-mingw32)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/common-w64-mingw32.cmake)
|
87
.github/workflows/MinedMap.yml
vendored
87
.github/workflows/MinedMap.yml
vendored
|
@ -2,93 +2,6 @@ name: 'MinedMap'
|
|||
on: ['push', 'pull_request', 'workflow_dispatch']
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: 'Build MinedMap (${{ matrix.host }})'
|
||||
runs-on: 'ubuntu-20.04'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
host:
|
||||
- 'x86_64-linux-gnu'
|
||||
- 'x86_64-w64-mingw32'
|
||||
include:
|
||||
- host: 'x86_64-linux-gnu'
|
||||
label: 'x86_64-linux-gnu'
|
||||
packages: ['g++', 'libpng-dev']
|
||||
prefix: '/usr'
|
||||
build_libpng: false
|
||||
- host: 'x86_64-w64-mingw32'
|
||||
label: 'Win64'
|
||||
packages: ['g++-mingw-w64-x86-64', 'libz-mingw-w64-dev']
|
||||
prefix: '/usr/x86_64-w64-mingw32'
|
||||
build_libpng: true
|
||||
- host: 'i686-w64-mingw32'
|
||||
label: 'Win32'
|
||||
packages: ['g++-mingw-w64-i686', 'libz-mingw-w64-dev']
|
||||
prefix: '/usr/i686-w64-mingw32'
|
||||
build_libpng: true
|
||||
|
||||
env:
|
||||
CMAKE_TOOLCHAIN_FILE: '${{ github.workspace }}/.github/toolchains/${{ matrix.host }}.cmake'
|
||||
|
||||
steps:
|
||||
- name: 'Checkout'
|
||||
uses: 'actions/checkout@v3'
|
||||
|
||||
- name: 'Get version'
|
||||
id: 'tag'
|
||||
run: |
|
||||
set -o pipefail
|
||||
git fetch --prune --unshallow --tags -f
|
||||
echo "tag=$(git describe --abbrev=7 --match='v*' | sed 's/^v//')" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: 'Dependencies (apt)'
|
||||
run: |
|
||||
sudo apt-get -y update
|
||||
sudo apt-get -y install ninja-build ${{ join(matrix.packages, ' ') }}
|
||||
sudo apt-get -y clean
|
||||
|
||||
- name: 'Dependencies (libpng)'
|
||||
if: '${{ matrix.build_libpng }}'
|
||||
run: |
|
||||
pkgver=1.6.37
|
||||
pkghash=505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca
|
||||
|
||||
mkdir -p build/libpng
|
||||
cd build/libpng
|
||||
wget http://downloads.sourceforge.net/sourceforge/libpng/libpng-$pkgver.tar.xz
|
||||
echo "$pkghash libpng-$pkgver.tar.xz" | sha256sum -c -
|
||||
tar xf libpng-$pkgver.tar.xz
|
||||
cd libpng-$pkgver
|
||||
./configure \
|
||||
--prefix=${{ matrix.prefix }} \
|
||||
--host=${{ matrix.host }} \
|
||||
--disable-shared
|
||||
make -j$(nproc)
|
||||
sudo make install
|
||||
sudo rm ${{ matrix.prefix }}/lib/libpng*.la
|
||||
|
||||
- name: 'Build'
|
||||
uses: lukka/run-cmake@v10
|
||||
with:
|
||||
configurePreset: 'ninja'
|
||||
buildPreset: 'ninja-release'
|
||||
|
||||
- name: 'Install'
|
||||
run: |
|
||||
export DESTDIR="$(pwd)/build/install"
|
||||
ninja -C builds/ninja -f build-RelWithDebInfo.ninja install/strip
|
||||
|
||||
pkgdir='build/pkg/MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.label }}'
|
||||
mkdir -p "$pkgdir"
|
||||
cp "$DESTDIR/usr/local/bin"/* "$pkgdir"/
|
||||
|
||||
- name: 'Archive'
|
||||
uses: 'actions/upload-artifact@v3'
|
||||
with:
|
||||
name: 'MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.label }}'
|
||||
path: 'build/pkg'
|
||||
|
||||
viewer:
|
||||
name: 'Package viewer'
|
||||
runs-on: 'ubuntu-20.04'
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.13)
|
||||
project(MINEDMAP CXX)
|
||||
|
||||
# May not work with all toolchains, added for the Windows CI build
|
||||
option(BUILD_STATIC "Create a statically linked MinedMap executable")
|
||||
|
||||
if(BUILD_STATIC)
|
||||
list(REMOVE_ITEM CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".dll.a")
|
||||
add_link_options("-static")
|
||||
endif()
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
pkg_check_modules(ZLIB REQUIRED IMPORTED_TARGET zlib)
|
||||
pkg_check_modules(PNG REQUIRED IMPORTED_TARGET libpng16)
|
||||
|
||||
add_subdirectory(src)
|
|
@ -1,39 +0,0 @@
|
|||
{
|
||||
"version": 3,
|
||||
"cmakeMinimumRequired": {
|
||||
"major": 3,
|
||||
"minor": 7,
|
||||
"patch": 0
|
||||
},
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "ninja",
|
||||
"displayName": "Ninja",
|
||||
"description": "Generate Ninja project files",
|
||||
"binaryDir": "${sourceDir}/builds/${presetName}",
|
||||
"generator": "Ninja Multi-Config",
|
||||
"cacheVariables": {
|
||||
"CMAKE_TOOLCHAIN_FILE": {
|
||||
"type": "FILEPATH",
|
||||
"value": "$env{CMAKE_TOOLCHAIN_FILE}"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "ninja-debug",
|
||||
"configurePreset": "ninja",
|
||||
"displayName": "Build ninja-debug",
|
||||
"description": "Build ninja Debug configuration",
|
||||
"configuration": "Debug"
|
||||
},
|
||||
{
|
||||
"name": "ninja-release",
|
||||
"configurePreset": "ninja",
|
||||
"displayName": "Build ninja-release",
|
||||
"description": "Build ninja Release configuration",
|
||||
"configuration": "RelWithDebInfo"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
|
||||
class Buffer {
|
||||
private:
|
||||
const uint8_t *data;
|
||||
size_t len;
|
||||
|
||||
public:
|
||||
static uint16_t parse16(const uint8_t *buf) {
|
||||
return (buf[0] << 8) | buf[1];
|
||||
}
|
||||
|
||||
static uint32_t parse32(const uint8_t *buf) {
|
||||
return (uint32_t(buf[0]) << 24) | (uint32_t(buf[1]) << 16) | (uint32_t(buf[2]) << 8) | uint32_t(buf[3]);
|
||||
}
|
||||
|
||||
static uint64_t parse64(const uint8_t *buf) {
|
||||
return (uint64_t(buf[0]) << 56) | (uint64_t(buf[1]) << 48) | (uint64_t(buf[2]) << 40) | (uint64_t(buf[3]) << 32)
|
||||
| (uint64_t(buf[4]) << 24) | (uint64_t(buf[5]) << 16) | (uint64_t(buf[6]) << 8) | uint64_t(buf[7]);
|
||||
}
|
||||
|
||||
|
||||
Buffer(const uint8_t *data0, size_t len0) : data(data0), len(len0) {}
|
||||
|
||||
size_t getRemaining() const {
|
||||
return len;
|
||||
}
|
||||
|
||||
const uint8_t * get(size_t n) {
|
||||
if (n > len)
|
||||
throw std::runtime_error("Buffer::get(): buffer underrun");
|
||||
|
||||
data += n;
|
||||
len -= n;
|
||||
return (data - n);
|
||||
}
|
||||
|
||||
uint8_t get8() {
|
||||
return *get(1);
|
||||
}
|
||||
|
||||
uint16_t get16() {
|
||||
return parse16(get(2));
|
||||
}
|
||||
|
||||
uint32_t get32() {
|
||||
return parse32(get(4));
|
||||
}
|
||||
|
||||
uint64_t get64() {
|
||||
return parse64(get(8));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
add_compile_options(-std=c++11 -Wall)
|
||||
|
||||
add_executable(MinedMap
|
||||
MinedMap.cpp
|
||||
GZip.cpp
|
||||
Info.cpp
|
||||
PNG.cpp
|
||||
|
||||
NBT/Tag.cpp
|
||||
Resource/Biome.cpp
|
||||
Resource/BlockType.cpp
|
||||
World/Chunk.cpp
|
||||
World/ChunkData.cpp
|
||||
World/Level.cpp
|
||||
World/Region.cpp
|
||||
World/Section.cpp
|
||||
)
|
||||
target_link_libraries(MinedMap PkgConfig::ZLIB PkgConfig::PNG)
|
||||
|
||||
add_executable(nbtdump
|
||||
nbtdump.cpp
|
||||
GZip.cpp
|
||||
NBT/Tag.cpp
|
||||
)
|
||||
target_link_libraries(nbtdump PkgConfig::ZLIB)
|
||||
|
||||
add_executable(regiondump
|
||||
regiondump.cpp
|
||||
GZip.cpp
|
||||
NBT/Tag.cpp
|
||||
World/ChunkData.cpp
|
||||
World/Region.cpp
|
||||
)
|
||||
target_link_libraries(regiondump PkgConfig::ZLIB)
|
||||
|
||||
install(TARGETS MinedMap RUNTIME DESTINATION bin)
|
49
src/GZip.cpp
49
src/GZip.cpp
|
@ -1,49 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "GZip.hpp"
|
||||
|
||||
#include <system_error>
|
||||
#include <stdexcept>
|
||||
#include <zlib.h>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
|
||||
std::vector<uint8_t> readGZip(const char *filename) {
|
||||
std::vector<uint8_t> buffer;
|
||||
size_t len = 0;
|
||||
|
||||
gzFile f = gzopen(filename, "rb");
|
||||
if (!f)
|
||||
throw std::system_error(
|
||||
errno, std::generic_category(),
|
||||
(std::string("unable to open file ") + filename).c_str()
|
||||
);
|
||||
|
||||
while (true) {
|
||||
if ((buffer.size() - len) < 4096)
|
||||
buffer.resize(buffer.size() + 4096);
|
||||
|
||||
int r = gzread(f, buffer.data()+len, buffer.size()-len);
|
||||
if (r < 0)
|
||||
throw std::system_error(errno, std::generic_category(), "error reading GZip file");
|
||||
|
||||
if (!r)
|
||||
break;
|
||||
|
||||
len += r;
|
||||
}
|
||||
|
||||
gzclose_r(f);
|
||||
|
||||
buffer.resize(len);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
}
|
18
src/GZip.hpp
18
src/GZip.hpp
|
@ -1,18 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
|
||||
std::vector<uint8_t> readGZip(const char *filename);
|
||||
|
||||
}
|
90
src/Info.cpp
90
src/Info.cpp
|
@ -1,90 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "Info.hpp"
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
|
||||
void Info::writeJSON(const char *filename) const {
|
||||
const std::string tmpfile = std::string(filename) + ".tmp";
|
||||
|
||||
FILE *f = std::fopen(tmpfile.c_str(), "w");
|
||||
if (!f) {
|
||||
std::fprintf(stderr, "Unable to open %s: %s\n", tmpfile.c_str(), std::strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
std::fprintf(f, "{");
|
||||
std::fprintf(f, "\"mipmaps\":[");
|
||||
|
||||
bool first_level = true;
|
||||
for (const auto &level : levels) {
|
||||
if (!first_level)
|
||||
std::fprintf(f, ",");
|
||||
first_level = false;
|
||||
|
||||
int minX, maxX, minZ, maxZ;
|
||||
std::tie(minX, maxX, minZ, maxZ) = level.bounds;
|
||||
|
||||
std::fprintf(f, "{");
|
||||
std::fprintf(f, "\"bounds\":{");
|
||||
std::fprintf(f, "\"minX\":%i,", minX);
|
||||
std::fprintf(f, "\"maxX\":%i,", maxX);
|
||||
std::fprintf(f, "\"minZ\":%i,", minZ);
|
||||
std::fprintf(f, "\"maxZ\":%i", maxZ);
|
||||
std::fprintf(f, "},");
|
||||
std::fprintf(f, "\"regions\":{");
|
||||
|
||||
bool first_z = true;
|
||||
for (const auto &item : level.regions) {
|
||||
if (!first_z)
|
||||
std::fprintf(f, ",");
|
||||
first_z = false;
|
||||
|
||||
int z = item.first;
|
||||
const std::set<int> &z_regions = item.second;
|
||||
|
||||
std::fprintf(f, "\"%d\":[", z);
|
||||
|
||||
bool first_x = true;
|
||||
for (int x : z_regions) {
|
||||
if (!first_x)
|
||||
std::fprintf(f, ",");
|
||||
first_x = false;
|
||||
|
||||
|
||||
std::fprintf(f, "%d", x);
|
||||
}
|
||||
|
||||
std::fprintf(f, "]");
|
||||
}
|
||||
|
||||
std::fprintf(f, "}}");
|
||||
}
|
||||
|
||||
std::fprintf(f, "],");
|
||||
std::fprintf(f, "\"spawn\":{");
|
||||
std::fprintf(f, "\"x\":%li,", (long)spawnX);
|
||||
std::fprintf(f, "\"z\":%li", (long)spawnZ);
|
||||
std::fprintf(f, "}");
|
||||
std::fprintf(f, "}");
|
||||
|
||||
std::fclose(f);
|
||||
|
||||
if (std::rename(tmpfile.c_str(), filename) < 0) {
|
||||
std::fprintf(stderr, "Unable to save %s: %s\n", filename, std::strerror(errno));
|
||||
std::remove(tmpfile.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
84
src/Info.hpp
84
src/Info.hpp
|
@ -1,84 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <climits>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
|
||||
class Info {
|
||||
public:
|
||||
typedef std::function<void (int, int)> RegionVisitor;
|
||||
|
||||
struct Level {
|
||||
std::map<int, std::set<int>> regions;
|
||||
std::tuple<int, int, int, int> bounds;
|
||||
};
|
||||
|
||||
private:
|
||||
std::vector<Level> levels;
|
||||
|
||||
int32_t spawnX, spawnZ;
|
||||
|
||||
public:
|
||||
Info() : spawnX(0), spawnZ(0) {
|
||||
addMipmapLevel();
|
||||
}
|
||||
|
||||
std::tuple<int, int, int, int> getBounds(size_t level) const {
|
||||
return levels[level].bounds;
|
||||
}
|
||||
|
||||
void addRegion(int x, int z, size_t level) {
|
||||
auto &the_level = levels[level];
|
||||
auto z_regions = the_level.regions.emplace(
|
||||
std::piecewise_construct,
|
||||
std::make_tuple(z),
|
||||
std::make_tuple()).first;
|
||||
z_regions->second.insert(x);
|
||||
|
||||
std::tuple<int, int, int, int> &b = the_level.bounds;
|
||||
|
||||
if (x < std::get<0>(b)) std::get<0>(b) = x;
|
||||
if (x > std::get<1>(b)) std::get<1>(b) = x;
|
||||
if (z < std::get<2>(b)) std::get<2>(b) = z;
|
||||
if (z > std::get<3>(b)) std::get<3>(b) = z;
|
||||
}
|
||||
|
||||
void addMipmapLevel() {
|
||||
levels.emplace_back(Level {
|
||||
.regions = {},
|
||||
.bounds = {INT_MAX, INT_MIN, INT_MAX, INT_MIN},
|
||||
});
|
||||
}
|
||||
|
||||
void visitRegions(size_t level, const RegionVisitor &visitor) const {
|
||||
for (const auto &item : levels[level].regions) {
|
||||
int z = item.first;
|
||||
for (int x : item.second)
|
||||
visitor(x, z);
|
||||
}
|
||||
}
|
||||
|
||||
void setSpawn(const std::pair<int32_t, int32_t> &v) {
|
||||
std::tie(spawnX, spawnZ) = v;
|
||||
}
|
||||
|
||||
void writeJSON(const char *filename) const;
|
||||
};
|
||||
|
||||
}
|
509
src/MinedMap.cpp
509
src/MinedMap.cpp
|
@ -1,509 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015-2021, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "Info.hpp"
|
||||
#include "PNG.hpp"
|
||||
#include "World/Level.hpp"
|
||||
#include "World/Region.hpp"
|
||||
|
||||
#include <cerrno>
|
||||
#include <cinttypes>
|
||||
#include <climits>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
#include <system_error>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
|
||||
static const int BIOME_SMOOTH = 3;
|
||||
static const uint32_t DIM = World::Region::SIZE*World::Chunk::SIZE;
|
||||
|
||||
|
||||
static void addChunkBiome(uint8_t biomemap[DIM*DIM], chunk_idx_t X, chunk_idx_t Z, const World::ChunkData *data) {
|
||||
World::Chunk chunk(data);
|
||||
World::Chunk::Heightmap layer = chunk.getTopLayer(0);
|
||||
|
||||
for (block_idx_t x = 0; x < World::Chunk::SIZE; x++) {
|
||||
for (block_idx_t z = 0; z < World::Chunk::SIZE; z++) {
|
||||
size_t i = (Z*World::Chunk::SIZE+z)*DIM + X*World::Chunk::SIZE+x;
|
||||
const World::Chunk::Height &height = layer.v[x][z];
|
||||
biomemap[i] = chunk.getBiome(x, height.y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t biomeAt(int16_t x, int16_t z, const std::unique_ptr<uint8_t[]> biomemaps[3][3]) {
|
||||
size_t a = 1, b = 1;
|
||||
|
||||
if (x < 0) {
|
||||
a--;
|
||||
x += DIM;
|
||||
} else if (x >= (int32_t)DIM) {
|
||||
a++;
|
||||
x -= DIM;
|
||||
}
|
||||
if (z < 0) {
|
||||
b--;
|
||||
z += DIM;
|
||||
} else if (z >= (int32_t)DIM) {
|
||||
b++;
|
||||
z -= DIM;
|
||||
}
|
||||
|
||||
return biomemaps[a][b].get()[z*DIM + x];
|
||||
}
|
||||
|
||||
static Resource::Color collectColors(
|
||||
region_block_idx_t x, region_block_idx_t z,
|
||||
const World::Block &block, const std::unique_ptr<uint8_t[]> biomemaps[3][3]
|
||||
) {
|
||||
std::unordered_map<uint8_t, unsigned> biomes;
|
||||
for (int16_t dx = -BIOME_SMOOTH; dx <= BIOME_SMOOTH; dx++) {
|
||||
for (int16_t dz = -BIOME_SMOOTH; dz <= BIOME_SMOOTH; dz++) {
|
||||
if (std::abs(dx) + std::abs(dz) > BIOME_SMOOTH)
|
||||
continue;
|
||||
|
||||
uint8_t biome = biomeAt(x+dx, z+dz, biomemaps);
|
||||
if (biomes.count(biome))
|
||||
biomes[biome]++;
|
||||
else
|
||||
biomes[biome] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
Resource::FloatColor c = {};
|
||||
unsigned total = 0;
|
||||
|
||||
for (const auto &e : biomes) {
|
||||
uint8_t biome = e.first;
|
||||
unsigned count = e.second;
|
||||
|
||||
if (biome == 0xff)
|
||||
continue;
|
||||
|
||||
c = c + count * block.getColor(biome);
|
||||
total += count;
|
||||
}
|
||||
|
||||
if (!total)
|
||||
return block.getColor(0);
|
||||
|
||||
return (1.0f / total) * c;
|
||||
}
|
||||
|
||||
static void addChunk(Resource::Color image[DIM*DIM], uint8_t lightmap[2*DIM*DIM], chunk_idx_t X, chunk_idx_t Z,
|
||||
const World::ChunkData *data, const std::unique_ptr<uint8_t[]> biomemaps[3][3]
|
||||
) {
|
||||
World::Chunk chunk(data);
|
||||
World::Chunk::Heightmap layer = chunk.getTopLayer(World::Chunk::WITH_DEPTH);
|
||||
|
||||
for (block_idx_t x = 0; x < World::Chunk::SIZE; x++) {
|
||||
for (block_idx_t z = 0; z < World::Chunk::SIZE; z++) {
|
||||
size_t i = (Z*World::Chunk::SIZE+z)*DIM + X*World::Chunk::SIZE+x;
|
||||
const World::Chunk::Height &height = layer.v[x][z];
|
||||
World::Block block = chunk.getBlock(x, height, z);
|
||||
|
||||
if (!block.isVisible())
|
||||
continue;
|
||||
|
||||
image[i] = collectColors(X*World::Chunk::SIZE+x, Z*World::Chunk::SIZE+z, block, biomemaps);
|
||||
lightmap[2*i+1] = (1 - block.blockLight/15.f)*192;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int64_t readStamp(const std::string &filename) {
|
||||
int64_t v = INT64_MIN;
|
||||
|
||||
std::FILE *f = std::fopen((filename + ".stamp").c_str(), "r");
|
||||
if (f) {
|
||||
if (std::fscanf(f, "%" SCNd64, &v) != 1) {
|
||||
// Ignore errors
|
||||
}
|
||||
std::fclose(f);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static void writeStamp(const std::string &filename, int64_t v) {
|
||||
std::FILE *f = std::fopen((filename + ".stamp").c_str(), "w");
|
||||
if (f) {
|
||||
std::fprintf(f, "%" PRId64, v);
|
||||
std::fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
static bool writeImage(const std::string &output, const uint8_t *data, PNG::Format format, int64_t t) {
|
||||
const std::string tmpfile = output + ".tmp";
|
||||
|
||||
size_t len = PNG::formatBytes(format)*DIM*DIM;
|
||||
bool changed = true;
|
||||
|
||||
try {
|
||||
std::unique_ptr<uint8_t[]> old(new uint8_t[len]);
|
||||
PNG::read(output.c_str(), old.get(), DIM, DIM, format);
|
||||
|
||||
if (std::memcmp(data, old.get(), len) == 0)
|
||||
changed = false;
|
||||
} catch (const std::exception& ex) {
|
||||
}
|
||||
|
||||
try {
|
||||
if (changed) {
|
||||
PNG::write(tmpfile.c_str(), data, DIM, DIM, format);
|
||||
|
||||
if (std::rename(tmpfile.c_str(), output.c_str()) < 0) {
|
||||
std::fprintf(stderr, "Unable to save %s: %s\n", output.c_str(), std::strerror(errno));
|
||||
std::remove(tmpfile.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
writeStamp(output, t);
|
||||
} catch (const std::exception& ex) {
|
||||
std::remove(tmpfile.c_str());
|
||||
throw;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
static int64_t getModTime(const std::string &file) {
|
||||
struct stat s;
|
||||
if (stat(file.c_str(), &s) < 0) {
|
||||
if (errno != ENOENT)
|
||||
std::fprintf(stderr, "Unable to stat %s: %s\n", file.c_str(), std::strerror(errno));
|
||||
return INT64_MIN;
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
return (int64_t)s.st_mtime * 1000000;
|
||||
#elif defined(__APPLE__)
|
||||
return (int64_t)s.st_mtimespec.tv_sec * 1000000 + s.st_mtimespec.tv_nsec / 1000;
|
||||
#else
|
||||
return (int64_t)s.st_mtim.tv_sec * 1000000 + s.st_mtim.tv_nsec / 1000;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool checkRegion(int64_t changed, const std::string &file) {
|
||||
struct stat s;
|
||||
if (stat(file.c_str(), &s) < 0)
|
||||
return true;
|
||||
|
||||
int64_t outtime = readStamp(file);
|
||||
if (changed <= outtime) {
|
||||
std::printf("%s is up-to-date.\n", file.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static std::string format(const T &v) {
|
||||
std::ostringstream s;
|
||||
|
||||
s << v;
|
||||
return s.str();
|
||||
}
|
||||
|
||||
static std::string formatTileName(int x, int z, const std::string &ext) {
|
||||
std::ostringstream s;
|
||||
|
||||
s << "r." << x << "." << z << "." << ext;
|
||||
return s.str();
|
||||
}
|
||||
|
||||
static bool checkFilename(const char *name, int *x, int *z) {
|
||||
if (std::sscanf(name, "r.%i.%i.mca", x, z) != 2)
|
||||
return false;
|
||||
|
||||
return (std::string(name) == formatTileName(*x, *z, "mca"));
|
||||
}
|
||||
|
||||
static void makeDir(const std::string &name) {
|
||||
if (
|
||||
mkdir(
|
||||
name.c_str()
|
||||
#ifndef _WIN32
|
||||
, 0777
|
||||
#endif
|
||||
) < 0 && errno != EEXIST
|
||||
)
|
||||
throw std::system_error(errno, std::generic_category(), "unable to create directory " + name);
|
||||
}
|
||||
|
||||
static void makeBiome(const std::string ®iondir, const std::string &outputdir, int x, int z) {
|
||||
std::string inname = formatTileName(x, z, "mca");
|
||||
std::string outname = formatTileName(x, z, "png");
|
||||
std::string input = regiondir + "/" + inname, output = outputdir + "/biome/" + outname;
|
||||
|
||||
int64_t intime = getModTime(input);
|
||||
if (intime == INT64_MIN)
|
||||
return;
|
||||
|
||||
if (!checkRegion(intime, output))
|
||||
return;
|
||||
|
||||
std::printf("Generating %s from %s... ", output.c_str(), input.c_str());
|
||||
std::fflush(stdout);
|
||||
|
||||
try {
|
||||
std::unique_ptr<uint8_t[]> biomemap(new uint8_t[DIM*DIM]);
|
||||
std::memset(biomemap.get(), 0xff, DIM*DIM);
|
||||
|
||||
World::Region::visitChunks(input.c_str(), [&] (chunk_idx_t X, chunk_idx_t Z, const World::ChunkData *chunk) {
|
||||
addChunkBiome(biomemap.get(), X, Z, chunk);
|
||||
});
|
||||
|
||||
bool changed = writeImage(output, biomemap.get(), PNG::GRAY, intime);
|
||||
std::printf("%s.\n", changed ? "done" : "unchanged");
|
||||
} catch (const std::exception& ex) {
|
||||
std::fprintf(stderr, "Failed to generate %s: %s\n", output.c_str(), ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
static void makeBiomes(const std::string ®iondir, const std::string &outputdir, const Info *info) {
|
||||
info->visitRegions(0, [&] (int x, int z) {
|
||||
makeBiome(regiondir, outputdir, x, z);
|
||||
});
|
||||
}
|
||||
|
||||
static void makeMap(const std::string ®iondir, const std::string &outputdir, int x, int z) {
|
||||
std::string inname = formatTileName(x, z, "mca");
|
||||
std::string outname = formatTileName(x, z, "png");
|
||||
std::string input = regiondir + "/" + inname;
|
||||
std::string output = outputdir + "/map/0/" + outname, output_light = outputdir + "/light/0/" + outname;
|
||||
std::string biomenames[3][3];
|
||||
|
||||
int64_t intime = getModTime(input);
|
||||
if (intime == INT64_MIN)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
biomenames[i][j] = outputdir + "/biome/" + formatTileName(x + i - 1, z + j - 1, "png");
|
||||
intime = std::max(intime, getModTime(biomenames[i][j]));
|
||||
}
|
||||
}
|
||||
|
||||
if (!checkRegion(intime, output))
|
||||
return;
|
||||
|
||||
std::printf("Generating %s from %s... ", output.c_str(), input.c_str());
|
||||
std::fflush(stdout);
|
||||
|
||||
try {
|
||||
std::unique_ptr<uint8_t[]> biomemaps[3][3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
biomemaps[i][j].reset(new uint8_t[DIM*DIM]);
|
||||
std::memset(biomemaps[i][j].get(), 0, DIM*DIM);
|
||||
|
||||
try {
|
||||
PNG::read(biomenames[i][j].c_str(), biomemaps[i][j].get(), DIM, DIM, PNG::GRAY);
|
||||
} catch (const std::exception& ex) {}
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Resource::Color[]> image(new Resource::Color[DIM*DIM]);
|
||||
|
||||
std::unique_ptr<uint8_t[]> lightmap(new uint8_t[2*DIM*DIM]);
|
||||
std::memset(lightmap.get(), 0, 2*DIM*DIM);
|
||||
|
||||
World::Region::visitChunks(input.c_str(), [&] (chunk_idx_t X, chunk_idx_t Z, const World::ChunkData *chunk) {
|
||||
addChunk(image.get(), lightmap.get(), X, Z, chunk, biomemaps);
|
||||
});
|
||||
|
||||
bool changed = writeImage(output, reinterpret_cast<const uint8_t*>(image.get()), PNG::RGB_ALPHA, intime);
|
||||
changed = writeImage(output_light, lightmap.get(), PNG::GRAY_ALPHA, intime) || changed;
|
||||
std::printf("%s.\n", changed ? "done" : "unchanged");
|
||||
} catch (const std::exception& ex) {
|
||||
std::fprintf(stderr, "Failed to generate %s: %s\n", output.c_str(), ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
static void makeMaps(const std::string ®iondir, const std::string &outputdir, const Info *info) {
|
||||
info->visitRegions(0, [&] (int x, int z) {
|
||||
makeMap(regiondir, outputdir, x, z);
|
||||
});
|
||||
}
|
||||
|
||||
static bool makeMipmap(const std::string &dir, size_t level, int x, int z, PNG::Format imageFormat) {
|
||||
bool ret = false;
|
||||
|
||||
std::string indir = dir + "/" + format(level-1) + "/";
|
||||
std::string outdir = dir + "/" + format(level) + "/";
|
||||
|
||||
const std::string nw_str = indir + formatTileName(x*2, z*2, "png");
|
||||
const std::string ne_str = indir + formatTileName(x*2+1, z*2, "png");
|
||||
const std::string sw_str = indir + formatTileName(x*2, z*2+1, "png");
|
||||
const std::string se_str = indir + formatTileName(x*2+1, z*2+1, "png");
|
||||
|
||||
const char *nw = nw_str.c_str();
|
||||
const char *ne = ne_str.c_str();
|
||||
const char *sw = sw_str.c_str();
|
||||
const char *se = se_str.c_str();
|
||||
|
||||
int64_t t = INT64_MIN;
|
||||
unsigned count = 0;
|
||||
for (auto name : {&nw, &ne, &sw, &se}) {
|
||||
struct stat s;
|
||||
if (stat(*name, &s) < 0) {
|
||||
*name = nullptr;
|
||||
continue;
|
||||
}
|
||||
|
||||
int64_t t_part = readStamp(*name);
|
||||
if (t_part > t)
|
||||
t = t_part;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
std::string output = outdir + formatTileName(x, z, "png");
|
||||
|
||||
{
|
||||
struct stat s;
|
||||
if (stat(output.c_str(), &s) == 0) {
|
||||
ret = true;
|
||||
|
||||
int64_t outtime = readStamp(output);
|
||||
if (t <= outtime)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (!count)
|
||||
return ret;
|
||||
|
||||
const std::string tmpfile = output + ".tmp";
|
||||
|
||||
try {
|
||||
PNG::mipmap(tmpfile.c_str(), DIM, DIM, imageFormat, nw, ne, sw, se);
|
||||
|
||||
if (std::rename(tmpfile.c_str(), output.c_str()) < 0) {
|
||||
std::fprintf(stderr, "Unable to save %s: %s\n", output.c_str(), std::strerror(errno));
|
||||
std::remove(tmpfile.c_str());
|
||||
}
|
||||
|
||||
writeStamp(output, t);
|
||||
} catch (const std::exception& ex) {
|
||||
std::remove(tmpfile.c_str());
|
||||
throw;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int floored_half(int a) {
|
||||
return (a - (a < 0)) / 2;
|
||||
}
|
||||
|
||||
static void makeMipmaps(const std::string &dir, Info *info) {
|
||||
for (size_t level = 0; ; level++) {
|
||||
int minX, maxX, minZ, maxZ;
|
||||
std::tie(minX, maxX, minZ, maxZ) = info->getBounds(level);
|
||||
|
||||
if (minX >= -1 && maxX <= 0 && minZ >= -1 && maxZ <= 0)
|
||||
break;
|
||||
|
||||
info->addMipmapLevel();
|
||||
makeDir(dir + "/map/" + format(level + 1));
|
||||
makeDir(dir + "/light/" + format(level + 1));
|
||||
|
||||
info->visitRegions(level, [&] (int x, int z) {
|
||||
info->addRegion(floored_half(x), floored_half(z), level + 1);
|
||||
});
|
||||
|
||||
info->visitRegions(level + 1, [&] (int x, int z) {
|
||||
if (makeMipmap(dir + "/map", level + 1, x, z, PNG::RGB_ALPHA))
|
||||
info->addRegion(x, z, level + 1);
|
||||
|
||||
makeMipmap(dir + "/light", level + 1, x, z, PNG::GRAY_ALPHA);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static Info collectInfo(const std::string ®iondir) {
|
||||
DIR *dir = opendir(regiondir.c_str());
|
||||
if (!dir)
|
||||
throw std::system_error(errno, std::generic_category(), "Unable to read input directory");
|
||||
|
||||
Info info;
|
||||
|
||||
struct dirent *entry;
|
||||
while ((entry = readdir(dir)) != nullptr) {
|
||||
int x, z;
|
||||
if (!checkFilename(entry->d_name, &x, &z))
|
||||
continue;
|
||||
|
||||
info.addRegion(x, z, 0);
|
||||
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static void doLevel(const std::string &inputdir, const std::string &outputdir) {
|
||||
const std::string regiondir = inputdir + "/region";
|
||||
|
||||
makeDir(outputdir + "/biome");
|
||||
makeDir(outputdir + "/map");
|
||||
makeDir(outputdir + "/map/0");
|
||||
makeDir(outputdir + "/light");
|
||||
makeDir(outputdir + "/light/0");
|
||||
|
||||
Info info = collectInfo(regiondir);
|
||||
|
||||
std::printf("Updating biome data...\n");
|
||||
makeBiomes(regiondir, outputdir, &info);
|
||||
|
||||
std::printf("Updating map data...\n");
|
||||
makeMaps(regiondir, outputdir, &info);
|
||||
|
||||
World::Level level((inputdir + "/level.dat").c_str());
|
||||
info.setSpawn(level.getSpawn());
|
||||
|
||||
std::printf("Updating mipmaps...\n");
|
||||
makeMipmaps(outputdir, &info);
|
||||
|
||||
info.writeJSON((outputdir + "/info.json").c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc < 3) {
|
||||
std::fprintf(stderr, "Usage: %s <data directory> <output directory>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
try {
|
||||
MinedMap::doLevel(argv[1], argv[2]);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
std::fprintf(stderr, "Error: %s\n", ex.what());
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Tag.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace NBT {
|
||||
|
||||
class ByteArrayTag : public Tag {
|
||||
private:
|
||||
uint32_t len;
|
||||
const uint8_t *ptr;
|
||||
|
||||
public:
|
||||
static const MakeType<ByteArrayTag> Type;
|
||||
|
||||
|
||||
ByteArrayTag(Buffer *buffer) {
|
||||
len = buffer->get32();
|
||||
ptr = buffer->get(len);
|
||||
}
|
||||
|
||||
virtual const TagType & getType() const {
|
||||
return Type;
|
||||
}
|
||||
|
||||
virtual void print(std::ostream& os, const std::string &indent) const {
|
||||
os << "(" << len << ") [" << std::endl;
|
||||
|
||||
std::string inner = indent + " ";
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
uint8_t v = ptr[i];
|
||||
|
||||
os << inner
|
||||
<< (unsigned)v << " / "
|
||||
<< (int)(int8_t)v << " / "
|
||||
<< std::hex << "0x" << (unsigned)v << std::dec
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
os << indent << "]";
|
||||
}
|
||||
|
||||
uint32_t getLength() const {
|
||||
return len;
|
||||
}
|
||||
|
||||
const uint8_t * getPointer() const {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
uint8_t getValue(size_t i) const {
|
||||
return ptr[i];
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Tag.hpp"
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace NBT {
|
||||
|
||||
class ByteTag : public Tag {
|
||||
private:
|
||||
uint8_t value;
|
||||
|
||||
public:
|
||||
static const MakeType<ByteTag> Type;
|
||||
|
||||
|
||||
ByteTag(Buffer *buffer) {
|
||||
value = buffer->get8();
|
||||
}
|
||||
|
||||
virtual const TagType & getType() const {
|
||||
return Type;
|
||||
}
|
||||
|
||||
virtual void print(std::ostream& os, const std::string &) const {
|
||||
os << (unsigned)getValue() << " / "
|
||||
<< (int)(int8_t)getValue() << " / "
|
||||
<< std::hex << "0x" << (unsigned)getValue() << std::dec;
|
||||
}
|
||||
|
||||
uint8_t getValue() const {
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "EndTag.hpp"
|
||||
#include "Tag.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace NBT {
|
||||
|
||||
class CompoundTag : public Tag, public std::unordered_map<std::string, std::shared_ptr<const Tag>> {
|
||||
public:
|
||||
static const MakeType<CompoundTag> Type;
|
||||
|
||||
|
||||
CompoundTag(Buffer *buffer) {
|
||||
while (true) {
|
||||
std::pair<std::string, std::shared_ptr<const Tag>> v = Tag::readNamedTag(buffer);
|
||||
if (v.second->getType() == EndTag::Type)
|
||||
break;
|
||||
|
||||
insert(std::move(v));
|
||||
}
|
||||
}
|
||||
|
||||
virtual const TagType & getType() const {
|
||||
return Type;
|
||||
}
|
||||
|
||||
virtual void print(std::ostream& os, const std::string &indent) const {
|
||||
os << "{" << std::endl;
|
||||
|
||||
std::string inner = indent + " ";
|
||||
|
||||
for (const auto &item : *this) {
|
||||
os << inner << item.first << ": " << item.second->getType() << " ";
|
||||
item.second->print(os, inner);
|
||||
os << std::endl;
|
||||
}
|
||||
|
||||
os << indent << "}";
|
||||
}
|
||||
|
||||
template<typename T> std::shared_ptr<const T> get(const std::string &key) const {
|
||||
auto it = find(key);
|
||||
if (it == end())
|
||||
return std::shared_ptr<const T>();
|
||||
|
||||
return std::dynamic_pointer_cast<const T>(it->second);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Tag.hpp"
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace NBT {
|
||||
|
||||
class DoubleTag : public Tag {
|
||||
private:
|
||||
const uint8_t *ptr;
|
||||
|
||||
public:
|
||||
static const MakeType<DoubleTag> Type;
|
||||
|
||||
|
||||
DoubleTag(Buffer *buffer) {
|
||||
ptr = buffer->get(8);
|
||||
}
|
||||
|
||||
virtual const TagType & getType() const {
|
||||
return Type;
|
||||
}
|
||||
|
||||
virtual void print(std::ostream& os, const std::string &) const {
|
||||
union {
|
||||
uint64_t i;
|
||||
double d;
|
||||
};
|
||||
|
||||
i = Buffer::parse64(ptr);
|
||||
os << d;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Tag.hpp"
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace NBT {
|
||||
|
||||
class EndTag : public Tag {
|
||||
public:
|
||||
static const MakeType<EndTag> Type;
|
||||
|
||||
|
||||
EndTag(Buffer *) {}
|
||||
|
||||
virtual const TagType & getType() const {
|
||||
return Type;
|
||||
}
|
||||
|
||||
virtual void print(std::ostream&, const std::string &) const {
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Tag.hpp"
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace NBT {
|
||||
|
||||
class FloatTag : public Tag {
|
||||
const uint8_t *ptr;
|
||||
|
||||
public:
|
||||
static const MakeType<FloatTag> Type;
|
||||
|
||||
|
||||
FloatTag(Buffer *buffer) {
|
||||
ptr = buffer->get(4);
|
||||
}
|
||||
|
||||
virtual const TagType & getType() const {
|
||||
return Type;
|
||||
}
|
||||
|
||||
virtual void print(std::ostream& os, const std::string &) const {
|
||||
union {
|
||||
uint32_t i;
|
||||
float f;
|
||||
};
|
||||
|
||||
i = Buffer::parse32(ptr);
|
||||
os << f;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Tag.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace NBT {
|
||||
|
||||
class IntArrayTag : public Tag {
|
||||
private:
|
||||
uint32_t len;
|
||||
const uint8_t *ptr;
|
||||
|
||||
public:
|
||||
static const MakeType<IntArrayTag> Type;
|
||||
|
||||
|
||||
IntArrayTag(Buffer *buffer) {
|
||||
len = buffer->get32();
|
||||
ptr = buffer->get(4*len);
|
||||
}
|
||||
|
||||
virtual const TagType & getType() const {
|
||||
return Type;
|
||||
}
|
||||
|
||||
virtual void print(std::ostream& os, const std::string &indent) const {
|
||||
os << "(" << len << ") [" << std::endl;
|
||||
|
||||
std::string inner = indent + " ";
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
uint32_t v = getValue(i);
|
||||
|
||||
os << inner
|
||||
<< v << " / "
|
||||
<< (int32_t)v << " / "
|
||||
<< std::hex << "0x" << v << std::dec
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
os << indent << "]";
|
||||
}
|
||||
|
||||
uint32_t getLength() const {
|
||||
return len;
|
||||
}
|
||||
|
||||
const uint8_t * getPointer() const {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
uint32_t getValue(size_t i) const {
|
||||
return Buffer::parse32(&ptr[4*i]);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Tag.hpp"
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace NBT {
|
||||
|
||||
class IntTag : public Tag {
|
||||
private:
|
||||
const uint8_t *ptr;
|
||||
|
||||
public:
|
||||
static const MakeType<IntTag> Type;
|
||||
|
||||
|
||||
IntTag(Buffer *buffer) {
|
||||
ptr = buffer->get(4);
|
||||
}
|
||||
|
||||
virtual const TagType & getType() const {
|
||||
return Type;
|
||||
}
|
||||
|
||||
virtual void print(std::ostream& os, const std::string &) const {
|
||||
os << getValue() << " / "
|
||||
<< (int32_t)getValue() << " / "
|
||||
<< std::hex << "0x" << getValue() << std::dec;
|
||||
}
|
||||
|
||||
uint32_t getValue() const {
|
||||
return Buffer::parse32(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Tag.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace NBT {
|
||||
|
||||
class ListTag : public Tag, public std::vector<std::shared_ptr<const Tag>> {
|
||||
private:
|
||||
const TagType *subtype;
|
||||
|
||||
public:
|
||||
static const MakeType<ListTag> Type;
|
||||
|
||||
|
||||
ListTag(Buffer *buffer) {
|
||||
subtype = &getTypeById(buffer->get8());
|
||||
|
||||
uint32_t len = buffer->get32();
|
||||
|
||||
for (uint32_t i = 0; i < len; i++)
|
||||
push_back(subtype->read(buffer));
|
||||
}
|
||||
|
||||
virtual const TagType & getType() const {
|
||||
return Type;
|
||||
}
|
||||
|
||||
virtual const TagType & getSubtype() const {
|
||||
return *subtype;
|
||||
}
|
||||
|
||||
virtual void print(std::ostream& os, const std::string &indent) const {
|
||||
os << getSubtype() << " [" << std::endl;
|
||||
|
||||
std::string inner = indent + " ";
|
||||
|
||||
for (const auto &item : *this) {
|
||||
os << inner;
|
||||
item->print(os, inner);
|
||||
os << std::endl;
|
||||
}
|
||||
|
||||
os << indent << "]";
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015-2018, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Tag.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace NBT {
|
||||
|
||||
class LongArrayTag : public Tag {
|
||||
private:
|
||||
uint32_t len;
|
||||
const uint8_t *ptr;
|
||||
|
||||
public:
|
||||
static const MakeType<LongArrayTag> Type;
|
||||
|
||||
|
||||
LongArrayTag(Buffer *buffer) {
|
||||
len = buffer->get32();
|
||||
ptr = buffer->get(8*len);
|
||||
}
|
||||
|
||||
virtual const TagType & getType() const {
|
||||
return Type;
|
||||
}
|
||||
|
||||
virtual void print(std::ostream& os, const std::string &indent) const {
|
||||
os << "(" << len << ") [" << std::endl;
|
||||
|
||||
std::string inner = indent + " ";
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
uint64_t v = Buffer::parse64(&ptr[8*i]);
|
||||
|
||||
os << inner
|
||||
<< v << " / "
|
||||
<< (int64_t)v << " / "
|
||||
<< std::hex << "0x" << v << std::dec
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
os << indent << "]";
|
||||
}
|
||||
|
||||
uint32_t getLength() const {
|
||||
return len;
|
||||
}
|
||||
|
||||
const uint8_t * getPointer() const {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
uint64_t getValue(size_t i) const {
|
||||
return Buffer::parse64(&ptr[8*i]);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Tag.hpp"
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace NBT {
|
||||
|
||||
class LongTag : public Tag {
|
||||
private:
|
||||
const uint8_t *ptr;
|
||||
|
||||
public:
|
||||
static const MakeType<LongTag> Type;
|
||||
|
||||
|
||||
LongTag(Buffer *buffer) {
|
||||
ptr = buffer->get(8);
|
||||
}
|
||||
|
||||
virtual const TagType & getType() const {
|
||||
return Type;
|
||||
}
|
||||
|
||||
virtual void print(std::ostream& os, const std::string &) const {
|
||||
os << getValue() << " / "
|
||||
<< (int64_t)getValue() << " / "
|
||||
<< std::hex << "0x" << getValue() << std::dec;
|
||||
}
|
||||
|
||||
uint64_t getValue() const {
|
||||
return Buffer::parse64(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Tag.hpp"
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace NBT {
|
||||
|
||||
class ShortTag : public Tag {
|
||||
private:
|
||||
const uint8_t *ptr;
|
||||
|
||||
public:
|
||||
static const MakeType<ShortTag> Type;
|
||||
|
||||
|
||||
ShortTag(Buffer *buffer) {
|
||||
ptr = buffer->get(2);
|
||||
}
|
||||
|
||||
virtual const TagType & getType() const {
|
||||
return Type;
|
||||
}
|
||||
|
||||
virtual void print(std::ostream& os, const std::string &) const {
|
||||
os << getValue() << " / "
|
||||
<< (int16_t)getValue() << " / "
|
||||
<< std::hex << "0x" << getValue() << std::dec;
|
||||
}
|
||||
|
||||
uint16_t getValue() const {
|
||||
return Buffer::parse16(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Tag.hpp"
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace NBT {
|
||||
|
||||
class StringTag : public Tag {
|
||||
private:
|
||||
uint16_t len;
|
||||
const uint8_t *ptr;
|
||||
|
||||
public:
|
||||
static const MakeType<StringTag> Type;
|
||||
|
||||
|
||||
StringTag(Buffer *buffer) {
|
||||
len = buffer->get16();
|
||||
ptr = buffer->get(len);
|
||||
}
|
||||
|
||||
virtual const TagType & getType() const {
|
||||
return Type;
|
||||
}
|
||||
|
||||
std::string getValue() const {
|
||||
return std::string(reinterpret_cast<const char *>(ptr), len);
|
||||
}
|
||||
|
||||
virtual void print(std::ostream& os, const std::string &) const {
|
||||
os << "\"" << getValue() << "\"";
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "Tag.hpp"
|
||||
|
||||
#include "EndTag.hpp"
|
||||
#include "ByteTag.hpp"
|
||||
#include "ShortTag.hpp"
|
||||
#include "IntTag.hpp"
|
||||
#include "LongTag.hpp"
|
||||
#include "FloatTag.hpp"
|
||||
#include "DoubleTag.hpp"
|
||||
#include "ByteArrayTag.hpp"
|
||||
#include "StringTag.hpp"
|
||||
#include "ListTag.hpp"
|
||||
#include "CompoundTag.hpp"
|
||||
#include "IntArrayTag.hpp"
|
||||
#include "LongArrayTag.hpp"
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace NBT {
|
||||
|
||||
const Tag::MakeType<EndTag> EndTag::Type("End");
|
||||
const Tag::MakeType<ByteTag> ByteTag::Type("Byte");
|
||||
const Tag::MakeType<ShortTag> ShortTag::Type("Short");
|
||||
const Tag::MakeType<IntTag> IntTag::Type("Int");
|
||||
const Tag::MakeType<LongTag> LongTag::Type("Long");
|
||||
const Tag::MakeType<FloatTag> FloatTag::Type("Float");
|
||||
const Tag::MakeType<DoubleTag> DoubleTag::Type("Double");
|
||||
const Tag::MakeType<ByteArrayTag> ByteArrayTag::Type("ByteArray");
|
||||
const Tag::MakeType<StringTag> StringTag::Type("String");
|
||||
const Tag::MakeType<ListTag> ListTag::Type("List");
|
||||
const Tag::MakeType<CompoundTag> CompoundTag::Type("Compound");
|
||||
const Tag::MakeType<IntArrayTag> IntArrayTag::Type("IntArray");
|
||||
const Tag::MakeType<LongArrayTag> LongArrayTag::Type("LongArray");
|
||||
|
||||
|
||||
const std::vector<const TagType *> Tag::types = {
|
||||
&EndTag::Type,
|
||||
&ByteTag::Type,
|
||||
&ShortTag::Type,
|
||||
&IntTag::Type,
|
||||
&LongTag::Type,
|
||||
&FloatTag::Type,
|
||||
&DoubleTag::Type,
|
||||
&ByteArrayTag::Type,
|
||||
&StringTag::Type,
|
||||
&ListTag::Type,
|
||||
&CompoundTag::Type,
|
||||
&IntArrayTag::Type,
|
||||
&LongArrayTag::Type,
|
||||
};
|
||||
|
||||
|
||||
std::pair<std::string, std::shared_ptr<const Tag>> Tag::readNamedTag(Buffer *buffer) {
|
||||
const TagType &type = getTypeById(buffer->get8());
|
||||
if (type == EndTag::Type)
|
||||
return std::make_pair("", std::make_shared<EndTag>(buffer));
|
||||
|
||||
uint16_t len = buffer->get16();
|
||||
std::string name(reinterpret_cast<const char*>(buffer->get(len)), len);
|
||||
|
||||
return std::make_pair(name, type.read(buffer));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
|
||||
#include "../Buffer.hpp"
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace NBT {
|
||||
|
||||
class Tag;
|
||||
|
||||
class TagType {
|
||||
public:
|
||||
TagType() = default;
|
||||
TagType(const TagType&) = delete;
|
||||
TagType & operator=(const TagType&) = delete;
|
||||
|
||||
virtual const char * getName() const = 0;
|
||||
virtual std::shared_ptr<const Tag> read(Buffer *buffer) const = 0;
|
||||
|
||||
bool operator==(const TagType &type) const {
|
||||
return this == &type;
|
||||
}
|
||||
};
|
||||
|
||||
class Tag {
|
||||
private:
|
||||
static const std::vector<const TagType *> types;
|
||||
|
||||
protected:
|
||||
template<typename T>
|
||||
class MakeType : public TagType {
|
||||
private:
|
||||
const char *name;
|
||||
|
||||
public:
|
||||
MakeType(const char *name0) : name(name0) {}
|
||||
|
||||
virtual const char * getName() const {
|
||||
return name;
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<const Tag> read(Buffer *buffer) const {
|
||||
return std::make_shared<T>(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static const TagType & getTypeById(uint8_t id) {
|
||||
return *types.at(id);
|
||||
}
|
||||
|
||||
public:
|
||||
static std::pair<std::string, std::shared_ptr<const Tag>> readNamedTag(Buffer *buffer);
|
||||
|
||||
virtual const TagType & getType() const = 0;
|
||||
virtual void print(std::ostream& os, const std::string &indent) const = 0;
|
||||
|
||||
virtual ~Tag() {}
|
||||
};
|
||||
|
||||
static inline std::ostream& operator<<(std::ostream& os, const TagType &type) {
|
||||
return os << type.getName();
|
||||
}
|
||||
|
||||
static inline std::ostream& operator<<(std::ostream& os, const Tag &tag) {
|
||||
os << tag.getType() << " ";
|
||||
tag.print(os, "");
|
||||
return os;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
143
src/PNG.cpp
143
src/PNG.cpp
|
@ -1,143 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "PNG.hpp"
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <system_error>
|
||||
|
||||
#include <png.h>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace PNG {
|
||||
|
||||
static const int formatColorTypes[] = {
|
||||
[RGB_ALPHA] = PNG_COLOR_TYPE_RGB_ALPHA,
|
||||
[GRAY_ALPHA] = PNG_COLOR_TYPE_GRAY_ALPHA,
|
||||
[GRAY] = PNG_COLOR_TYPE_GRAY,
|
||||
};
|
||||
|
||||
void write(const char *filename, const uint8_t *data, size_t width, size_t height, Format format) {
|
||||
std::FILE *f = std::fopen(filename, "wb");
|
||||
if (!f)
|
||||
throw std::system_error(errno, std::generic_category(), "unable to open PNG file");
|
||||
|
||||
png_structp png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
||||
if (!png_ptr)
|
||||
throw std::runtime_error("unable to create PNG write struct");
|
||||
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr) {
|
||||
png_destroy_write_struct(&png_ptr, nullptr);
|
||||
throw std::runtime_error("unable to create PNG info struct");
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
std::fclose(f);
|
||||
throw std::runtime_error("unable to write PNG file");
|
||||
}
|
||||
|
||||
png_init_io(png_ptr, f);
|
||||
|
||||
png_set_IHDR(png_ptr, info_ptr, width, height, 8, formatColorTypes[format],
|
||||
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||
|
||||
uint8_t *row_pointers[height];
|
||||
for (size_t i = 0; i < height; i++)
|
||||
row_pointers[i] = const_cast<uint8_t*>(&data[formatBytes(format)*i*width]);
|
||||
|
||||
png_set_rows(png_ptr, info_ptr, row_pointers);
|
||||
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, nullptr);
|
||||
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
std::fclose(f);
|
||||
}
|
||||
|
||||
void read(const char *filename, uint8_t *data, size_t width, size_t height, Format format) {
|
||||
std::FILE *f = std::fopen(filename, "rb");
|
||||
if (!f)
|
||||
throw std::system_error(errno, std::generic_category(), "unable to open PNG file");
|
||||
|
||||
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
||||
if (!png_ptr)
|
||||
throw std::runtime_error("unable to create PNG read struct");
|
||||
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr) {
|
||||
png_destroy_read_struct(&png_ptr, nullptr, nullptr);
|
||||
throw std::runtime_error("unable to create PNG info struct");
|
||||
}
|
||||
|
||||
png_infop end_info = png_create_info_struct(png_ptr);
|
||||
if (!end_info) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
|
||||
throw std::runtime_error("unable to create PNG info struct");
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
|
||||
fclose(f);
|
||||
throw std::runtime_error("unable to read PNG file");
|
||||
}
|
||||
|
||||
png_init_io(png_ptr, f);
|
||||
|
||||
png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, nullptr);
|
||||
|
||||
if (png_get_image_width(png_ptr, info_ptr) != width
|
||||
|| png_get_image_height(png_ptr, info_ptr) != height
|
||||
|| png_get_bit_depth(png_ptr, info_ptr) != 8
|
||||
|| png_get_color_type(png_ptr, info_ptr) != formatColorTypes[format])
|
||||
longjmp(png_jmpbuf(png_ptr), 1);
|
||||
|
||||
uint8_t **row_pointers = png_get_rows(png_ptr, info_ptr);
|
||||
for (size_t i = 0; i < height; i++)
|
||||
std::memcpy(&data[formatBytes(format)*i*width], row_pointers[i], formatBytes(format)*width);
|
||||
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
|
||||
std::fclose(f);
|
||||
}
|
||||
|
||||
static void readScaled(uint8_t *data, size_t offset_w, size_t offset_h, const char *file, size_t width, size_t height, Format format) {
|
||||
if (!file)
|
||||
return;
|
||||
|
||||
size_t b = formatBytes(format);
|
||||
|
||||
std::unique_ptr<uint8_t[]> input(new uint8_t[b*width*height]);
|
||||
read(file, input.get(), width, height, format);
|
||||
|
||||
for (size_t h = 0; h < width/2; h++) {
|
||||
for (size_t w = 0; w < width/2; w++) {
|
||||
for (size_t c = 0; c < b; c++) {
|
||||
size_t i = 2*b*(width*h + w) + c;
|
||||
data[b*(width*(offset_h+h) + offset_w+w) + c] = (input[i] + input[i+b] + input[i+b*width] + input[i+b*width+b])/4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mipmap(const char *output, size_t width, size_t height, Format format, const char *nw, const char *ne, const char *sw, const char *se) {
|
||||
size_t size = formatBytes(format)*width*height;
|
||||
std::unique_ptr<uint8_t[]> data(new uint8_t[size]);
|
||||
std::memset(data.get(), 0, size);
|
||||
|
||||
readScaled(data.get(), 0, 0, nw, width, height, format);
|
||||
readScaled(data.get(), width/2, 0, ne, width, height, format);
|
||||
readScaled(data.get(), 0, height/2, sw, width, height, format);
|
||||
readScaled(data.get(), width/2, height/2, se, width, height, format);
|
||||
|
||||
write(output, data.get(), width, height, format);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
38
src/PNG.hpp
38
src/PNG.hpp
|
@ -1,38 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace PNG {
|
||||
|
||||
enum Format {
|
||||
RGB_ALPHA,
|
||||
GRAY_ALPHA,
|
||||
GRAY,
|
||||
};
|
||||
|
||||
static inline size_t formatBytes(Format format) {
|
||||
const size_t data[] = {
|
||||
[RGB_ALPHA] = 4,
|
||||
[GRAY_ALPHA] = 2,
|
||||
[GRAY] = 1,
|
||||
};
|
||||
|
||||
return data[format];
|
||||
}
|
||||
|
||||
void write(const char *filename, const uint8_t *data, size_t width, size_t height, Format format);
|
||||
void read(const char *filename, uint8_t *data, size_t width, size_t height, Format format);
|
||||
void mipmap(const char *output, size_t width, size_t height, Format format, const char *nw, const char *ne, const char *sw, const char *se);
|
||||
|
||||
}
|
||||
}
|
|
@ -1,448 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015-2021, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
Copyright (c) 2019, Roman Shishkin <spark@uwtech.org>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "Biome.hpp"
|
||||
|
||||
#include "BlockType.hpp"
|
||||
|
||||
namespace MinedMap {
|
||||
namespace Resource {
|
||||
|
||||
static FloatColor colorFromParams(float temp, float rain, bool grass) {
|
||||
const FloatColor grassColors[3] = {
|
||||
{0.502f, 0.706f, 0.592f}, // lower right
|
||||
{0.247f, 0.012f, -0.259f}, // lower left - lower right
|
||||
{-0.471f, 0.086f, -0.133f}, // upper left - lower left
|
||||
};
|
||||
const FloatColor foliageColors[3] = {
|
||||
{0.376f, 0.631f, 0.482f}, // lower right
|
||||
{0.306f, 0.012f, -0.317f}, // lower left - lower right
|
||||
{-0.580f, 0.106f, -0.165f}, // upper left - lower left
|
||||
};
|
||||
|
||||
const FloatColor *colors = grass ? grassColors : foliageColors;
|
||||
|
||||
return colors[0] + temp*colors[1] + rain*colors[2];
|
||||
}
|
||||
|
||||
|
||||
FloatColor Biome::getGrassColor(float temp, float rain) const {
|
||||
return colorFromParams(temp, rain, true);
|
||||
}
|
||||
|
||||
FloatColor Biome::getFoliageColor(float temp, float rain) const {
|
||||
return colorFromParams(temp, rain, false);
|
||||
}
|
||||
|
||||
|
||||
FloatColor Biome::getBlockColor(const BlockType *type, y_idx_t height) const {
|
||||
FloatColor c = {
|
||||
float(type->color.r),
|
||||
float(type->color.g),
|
||||
float(type->color.b),
|
||||
};
|
||||
|
||||
float t = clamp(temp - std::max(0.0f, (int(height)-64)/600.0f), 0, 1);
|
||||
float r = clamp(rain, 0, 1) * t;
|
||||
|
||||
if (type->flags & BLOCK_GRASS)
|
||||
c *= getGrassColor(t, r);
|
||||
if (type->flags & BLOCK_FOLIAGE)
|
||||
c *= getFoliageColor(t, r);
|
||||
if (type->flags & BLOCK_BIRCH)
|
||||
c *= FloatColor {0.380f, 0.600f, 0.380f};
|
||||
if (type->flags & BLOCK_SPRUCE)
|
||||
c *= FloatColor {0.502f, 0.655f, 0.333f};
|
||||
if (type->flags & BLOCK_WATER)
|
||||
c *= getWaterColor();
|
||||
|
||||
float h = 0.5f + height * 0.005f;
|
||||
|
||||
c.r = clamp(c.r * h, 0, 255);
|
||||
c.g = clamp(c.g * h, 0, 255);
|
||||
c.b = clamp(c.b * h, 0, 255);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
class SwampBiome : public Biome {
|
||||
protected:
|
||||
virtual FloatColor getGrassColor(float, float) const {
|
||||
return {0.417f, 0.439f, 0.224f};
|
||||
}
|
||||
virtual FloatColor getFoliageColor(float temp, float rain) const {
|
||||
return getGrassColor(temp, rain);
|
||||
}
|
||||
|
||||
public:
|
||||
SwampBiome(float temp0, float rain0, FloatColor water0) :
|
||||
Biome(temp0, rain0, water0) {}
|
||||
};
|
||||
|
||||
class DarkForestBiome : public Biome {
|
||||
private:
|
||||
const FloatColor darkGreen = {0.157f, 0.204f, 0.039f};
|
||||
|
||||
protected:
|
||||
virtual FloatColor getGrassColor(float temp, float rain) const {
|
||||
return 0.5 * (darkGreen + colorFromParams(temp, rain, true));
|
||||
}
|
||||
|
||||
virtual FloatColor getFoliageColor(float temp, float rain) const {
|
||||
return 0.5 * (darkGreen + colorFromParams(temp, rain, false));
|
||||
}
|
||||
|
||||
public:
|
||||
DarkForestBiome(float temp0, float rain0) : Biome(temp0, rain0) {}
|
||||
};
|
||||
|
||||
class BadlandsBiome : public Biome {
|
||||
protected:
|
||||
virtual FloatColor getGrassColor(float, float) const {
|
||||
return {0.565f, 0.506f, 0.302f};
|
||||
}
|
||||
virtual FloatColor getFoliageColor(float, float) const {
|
||||
return {0.620f, 0.506f, 0.302f};
|
||||
}
|
||||
|
||||
public:
|
||||
BadlandsBiome(float temp0, float rain0) : Biome(temp0, rain0) {}
|
||||
};
|
||||
|
||||
|
||||
/* Values from https://github.com/erich666/Mineways/blob/master/Win/biomes.cpp or
|
||||
* extracted from Minecraft code decompiled using https://github.com/Hexeption/MCP-Reborn */
|
||||
|
||||
static const Biome BiomeDefault(0.5f, 0.5f);
|
||||
static const Biome BiomePlains(0.8f, 0.4f);
|
||||
static const Biome BiomeDesert(2.0f, 0.0f);
|
||||
static const Biome BiomeMountains(0.2f, 0.3f);
|
||||
static const Biome BiomeForest(0.7f, 0.8f);
|
||||
static const Biome BiomeTaiga(0.25f, 0.8f);
|
||||
static const SwampBiome BiomeSwamp(0.8f, 0.9f, {0.380f, 0.482f, 0.392f});
|
||||
static const Biome BiomeFrozen(0.0f, 0.5f);
|
||||
static const Biome BiomeMushroomFields(0.9f, 1.0f);
|
||||
static const Biome BiomeJungle(0.95f, 0.9f);
|
||||
static const Biome BiomeJungleEdge(0.95f, 0.8f);
|
||||
static const Biome BiomeSnowyBeach(0.05f, 0.3f);
|
||||
static const Biome BiomeBirchForest(0.6f, 0.6f);
|
||||
static const DarkForestBiome BiomeDarkForest(0.7f, 0.8f);
|
||||
static const Biome BiomeSnowyTaiga(-0.5f, 0.4f);
|
||||
static const Biome BiomeGiantTreeTaiga(0.3f, 0.8f);
|
||||
static const Biome BiomeSavanna(1.2f, 0.0f);
|
||||
static const Biome BiomeSavannaPlateau(1.0f, 0.0f);
|
||||
static const Biome BiomeShatteredSavanna(1.1f, 0.0f);
|
||||
static const BadlandsBiome BiomeBadlands(2.0f, 0.0f);
|
||||
|
||||
static const Biome BiomeFrozenOcean(0.0f, 0.5f, {0.224f, 0.220f, 0.788f});
|
||||
static const Biome BiomeWarmOcean(0.8f, 0.5f, {0.263f, 0.835f, 0.933f});
|
||||
static const Biome BiomeLukewarmOcean(0.8f, 0.5f, {0.271f, 0.678f, 0.949f});
|
||||
static const Biome BiomeColdOcean(0.8f, 0.5f, {0.239f, 0.341f, 0.839f});
|
||||
|
||||
static const Biome BiomeMeadow(0.5f, 0.8f);
|
||||
static const Biome BiomeGrove(-0.2f, 0.8f);
|
||||
static const Biome BiomeJaggedPeaks(-0.7f, 0.9f);
|
||||
static const Biome BiomeStonyPeaks(1.0f, 0.3f);
|
||||
static const Biome BiomeSnowySlopes(-0.3f, 0.9f);
|
||||
static const SwampBiome BiomeMangroveSwamp(0.8f, 0.9f, {0.227f, 0.478f, 0.416f});
|
||||
|
||||
const Biome *const Biome::Default = &BiomeDefault;
|
||||
|
||||
/* Minecraft 1.18 does not use numerical IDs for biomes anymore.
|
||||
* Previously unused biome IDs are assigned to the new biome types of
|
||||
* Minecraft 1.18 for storage in MinedMap's biome data cache. */
|
||||
|
||||
const Biome *const Biome::Biomes[256] = {
|
||||
/* 0 */ &BiomeDefault, /* Ocean */
|
||||
/* 1 */ &BiomePlains,
|
||||
/* 2 */ &BiomeDesert,
|
||||
/* 3 */ &BiomeMountains,
|
||||
/* 4 */ &BiomeForest,
|
||||
/* 5 */ &BiomeTaiga,
|
||||
/* 6 */ &BiomeSwamp,
|
||||
/* 7 */ &BiomeDefault, /* River */
|
||||
/* 8 */ &BiomeDesert, /* Nether */
|
||||
/* 9 */ &BiomeDefault, /* The End */
|
||||
/* 10 */ &BiomeFrozenOcean,
|
||||
/* 11 */ &BiomeFrozenOcean, /* Frozen River */
|
||||
/* 12 */ &BiomeFrozen, /* Snowy Tundra */
|
||||
/* 13 */ &BiomeFrozen, /* Snowy Mountains */
|
||||
/* 14 */ &BiomeMushroomFields,
|
||||
/* 15 */ &BiomeMushroomFields, /* Mushroom Field Shore */
|
||||
/* 16 */ &BiomePlains, /* Beach */
|
||||
/* 17 */ &BiomeDesert, /* Desert Hills */
|
||||
/* 18 */ &BiomeForest, /* Wooded Hiils */
|
||||
/* 19 */ &BiomeTaiga, /* Taiga Hills */
|
||||
/* 20 */ &BiomeMountains, /* Moutain Edge */
|
||||
/* 21 */ &BiomeJungle,
|
||||
/* 22 */ &BiomeJungle, /* Jungle Hills */
|
||||
/* 23 */ &BiomeJungleEdge,
|
||||
/* 24 */ &BiomeDefault, /* Deep Ocean */
|
||||
/* 25 */ &BiomeMountains, /* Stone Shore */
|
||||
/* 26 */ &BiomeSnowyBeach,
|
||||
/* 27 */ &BiomeBirchForest,
|
||||
/* 28 */ &BiomeBirchForest, /* Birch Forest Hills */
|
||||
/* 29 */ &BiomeDarkForest,
|
||||
/* 30 */ &BiomeSnowyTaiga,
|
||||
/* 31 */ &BiomeSnowyTaiga, /* Snowy Taiga Hills */
|
||||
/* 32 */ &BiomeGiantTreeTaiga,
|
||||
/* 33 */ &BiomeGiantTreeTaiga, /* Giant Tree Taiga Hills */
|
||||
/* 34 */ &BiomeMountains, /* Wooded Mountains */
|
||||
/* 35 */ &BiomeSavanna,
|
||||
/* 36 */ &BiomeSavanna, /* Savanna Plateau */
|
||||
/* 37 */ &BiomeBadlands,
|
||||
/* 38 */ &BiomeBadlands, /* Wooded Badlands Plateau */
|
||||
/* 39 */ &BiomeBadlands, /* Badlands Plateau */
|
||||
/* 40 */ &BiomeDefault, /* Small End Islands */
|
||||
/* 41 */ &BiomeDefault, /* End Midlands */
|
||||
/* 42 */ &BiomeDefault, /* End Highlands */
|
||||
/* 43 */ &BiomeDefault, /* End Barrens */
|
||||
/* 44 */ &BiomeWarmOcean,
|
||||
/* 45 */ &BiomeLukewarmOcean,
|
||||
/* 46 */ &BiomeColdOcean,
|
||||
/* 47 */ &BiomeWarmOcean, /* Deep Warm Ocean */
|
||||
/* 48 */ &BiomeLukewarmOcean, /* Deep Lukewarm Ocean */
|
||||
/* 49 */ &BiomeColdOcean, /* Deep Cold Ocean */
|
||||
/* 50 */ &BiomeFrozenOcean, /* Deep Frozen Ocean */
|
||||
/* 51 */ &BiomeMeadow, /* MinedMap assignment */
|
||||
/* 52 */ &BiomeGrove, /* MinedMap assignment */
|
||||
/* 53 */ &BiomeJaggedPeaks, /* MinedMap assignment */
|
||||
/* 54 */ &BiomeStonyPeaks, /* MinedMap assignment */
|
||||
/* 55 */ &BiomeSnowySlopes, /* MinedMap assignment */
|
||||
/* 56 */ &BiomeMangroveSwamp, /* MinedMap assignment */
|
||||
/* 57 */ nullptr,
|
||||
/* 58 */ nullptr,
|
||||
/* 59 */ nullptr,
|
||||
/* 60 */ nullptr,
|
||||
/* 61 */ nullptr,
|
||||
/* 62 */ nullptr,
|
||||
/* 63 */ nullptr,
|
||||
/* 64 */ nullptr,
|
||||
/* 65 */ nullptr,
|
||||
/* 66 */ nullptr,
|
||||
/* 67 */ nullptr,
|
||||
/* 68 */ nullptr,
|
||||
/* 69 */ nullptr,
|
||||
/* 70 */ nullptr,
|
||||
/* 71 */ nullptr,
|
||||
/* 72 */ nullptr,
|
||||
/* 73 */ nullptr,
|
||||
/* 74 */ nullptr,
|
||||
/* 75 */ nullptr,
|
||||
/* 76 */ nullptr,
|
||||
/* 77 */ nullptr,
|
||||
/* 78 */ nullptr,
|
||||
/* 79 */ nullptr,
|
||||
/* 80 */ nullptr,
|
||||
/* 81 */ nullptr,
|
||||
/* 82 */ nullptr,
|
||||
/* 83 */ nullptr,
|
||||
/* 84 */ nullptr,
|
||||
/* 85 */ nullptr,
|
||||
/* 86 */ nullptr,
|
||||
/* 87 */ nullptr,
|
||||
/* 88 */ nullptr,
|
||||
/* 89 */ nullptr,
|
||||
/* 90 */ nullptr,
|
||||
/* 91 */ nullptr,
|
||||
/* 92 */ nullptr,
|
||||
/* 93 */ nullptr,
|
||||
/* 94 */ nullptr,
|
||||
/* 95 */ nullptr,
|
||||
/* 96 */ nullptr,
|
||||
/* 97 */ nullptr,
|
||||
/* 98 */ nullptr,
|
||||
/* 99 */ nullptr,
|
||||
/* 100 */ nullptr,
|
||||
/* 101 */ nullptr,
|
||||
/* 102 */ nullptr,
|
||||
/* 103 */ nullptr,
|
||||
/* 104 */ nullptr,
|
||||
/* 105 */ nullptr,
|
||||
/* 106 */ nullptr,
|
||||
/* 107 */ nullptr,
|
||||
/* 108 */ nullptr,
|
||||
/* 109 */ nullptr,
|
||||
/* 110 */ nullptr,
|
||||
/* 111 */ nullptr,
|
||||
/* 112 */ nullptr,
|
||||
/* 113 */ nullptr,
|
||||
/* 114 */ nullptr,
|
||||
/* 115 */ nullptr,
|
||||
/* 116 */ nullptr,
|
||||
/* 117 */ nullptr,
|
||||
/* 118 */ nullptr,
|
||||
/* 119 */ nullptr,
|
||||
/* 120 */ nullptr,
|
||||
/* 121 */ nullptr,
|
||||
/* 122 */ nullptr,
|
||||
/* 123 */ nullptr,
|
||||
/* 124 */ nullptr,
|
||||
/* 125 */ nullptr,
|
||||
/* 126 */ nullptr,
|
||||
/* 127 */ &BiomeDefault, /* The Void */
|
||||
/* 128 */ nullptr,
|
||||
/* 129 */ &BiomeDefault, /* Sunflower Plains */
|
||||
/* 130 */ &BiomeDesert, /* Desert Lakes */
|
||||
/* 131 */ &BiomeMountains, /* Gravelly Mountains */
|
||||
/* 132 */ &BiomeForest, /* Flower Forest */
|
||||
/* 133 */ &BiomeTaiga, /* Taiga Mountains */
|
||||
/* 134 */ &BiomeSwamp, /* Swamp Hills */
|
||||
/* 135 */ nullptr,
|
||||
/* 136 */ nullptr,
|
||||
/* 137 */ nullptr,
|
||||
/* 138 */ nullptr,
|
||||
/* 139 */ nullptr,
|
||||
/* 140 */ &BiomeFrozen, /* Ice Spikes */
|
||||
/* 141 */ nullptr,
|
||||
/* 142 */ nullptr,
|
||||
/* 143 */ nullptr,
|
||||
/* 144 */ nullptr,
|
||||
/* 145 */ nullptr,
|
||||
/* 146 */ nullptr,
|
||||
/* 147 */ nullptr,
|
||||
/* 148 */ nullptr,
|
||||
/* 149 */ &BiomeJungle, /* Modified Jungle */
|
||||
/* 150 */ nullptr,
|
||||
/* 151 */ &BiomeJungleEdge, /* Modified Jungle Edge */
|
||||
/* 152 */ nullptr,
|
||||
/* 153 */ nullptr,
|
||||
/* 154 */ nullptr,
|
||||
/* 155 */ &BiomeBirchForest, /* Tall Birch Forest */
|
||||
/* 156 */ &BiomeBirchForest, /* Tall Birch Hills */
|
||||
/* 157 */ &BiomeDarkForest, /* Dark Forest Hills */
|
||||
/* 158 */ &BiomeSnowyTaiga, /* Snowy Taiga Mountains */
|
||||
/* 159 */ nullptr,
|
||||
/* 160 */ &BiomeTaiga, /* Giant Spruce Taiga */
|
||||
/* 161 */ &BiomeTaiga, /* Giant Spruce Taiga Hills */
|
||||
/* 162 */ &BiomeMountains, /* Gravelly Mountains+ */
|
||||
/* 163 */ &BiomeShatteredSavanna,
|
||||
/* 164 */ &BiomeSavannaPlateau, /* Shattered Savanna Plateau */
|
||||
/* 165 */ &BiomeBadlands, /* Eroded Badlands */
|
||||
/* 166 */ &BiomeBadlands, /* Modified Wooded Badlands Plateau */
|
||||
/* 167 */ &BiomeBadlands, /* Modified Badlands Plateau */
|
||||
/* 168 */ &BiomeJungle, /* Bamboo Jungle */
|
||||
/* 169 */ &BiomeJungle, /* Bamboo Jungle Hills */
|
||||
/* 170 */ &BiomeDesert, /* Soul Sand Valley */
|
||||
/* 171 */ &BiomeDesert, /* Crimson Forest */
|
||||
/* 172 */ &BiomeDesert, /* Warped Forest */
|
||||
/* 173 */ &BiomeDesert, /* Basalt Deltas */
|
||||
/* 174 */ &BiomePlains, /* Dripstone Caves */
|
||||
/* 175 */ &BiomeDefault, /* Lush Caves */
|
||||
};
|
||||
|
||||
/* It is unclear which of the renamed/merged biome IDs can appear in practice,
|
||||
* but it shouldn't hurt to support them anyways */
|
||||
|
||||
const std::unordered_map<std::string, uint8_t> Biome::Names = {
|
||||
{ "minecraft:badlands", 37 },
|
||||
{ "minecraft:badlands_plateau", 39 }, /* 1.18: Merged into badlands */
|
||||
{ "minecraft:bamboo_jungle", 168 },
|
||||
{ "minecraft:bamboo_jungle_hills", 169 }, /* 1.18: Merged into bamboo_jungle */
|
||||
{ "minecraft:basalt_deltas", 173 },
|
||||
{ "minecraft:beach", 16 },
|
||||
{ "minecraft:birch_forest", 27 },
|
||||
{ "minecraft:birch_forest_hills", 28 }, /* 1.18: Merged into birch_forest */
|
||||
{ "minecraft:cold_ocean", 46 },
|
||||
{ "minecraft:crimson_forest", 171 },
|
||||
{ "minecraft:dark_forest", 29 },
|
||||
{ "minecraft:dark_forest_hills", 157 }, /* 1.18: Merged into dark_forest */
|
||||
{ "minecraft:deep_cold_ocean", 49 },
|
||||
{ "minecraft:deep_dark", 1 },
|
||||
{ "minecraft:deep_frozen_ocean", 50 },
|
||||
{ "minecraft:deep_lukewarm_ocean", 48 },
|
||||
{ "minecraft:deep_ocean", 24 },
|
||||
{ "minecraft:deep_warm_ocean", 47 }, /* 1.18: Merged into warm_ocean */
|
||||
{ "minecraft:desert", 2 },
|
||||
{ "minecraft:desert_hills", 17 }, /* 1.18: Merged into desert */
|
||||
{ "minecraft:desert_lakes", 130 }, /* 1.18: Merged into desert */
|
||||
{ "minecraft:dripstone_caves", 174 },
|
||||
{ "minecraft:end_barrens", 43 },
|
||||
{ "minecraft:end_highlands", 42 },
|
||||
{ "minecraft:end_midlands", 41 },
|
||||
{ "minecraft:eroded_badlands", 165 },
|
||||
{ "minecraft:extreme_hills", 3 }, /* 1.18: Renamed to windswept_hills (after rename from mountains) */
|
||||
{ "minecraft:flower_forest", 132 },
|
||||
{ "minecraft:forest", 4 },
|
||||
{ "minecraft:frozen_ocean", 10 },
|
||||
{ "minecraft:frozen_peaks", 53 }, /* 1.18: New */
|
||||
{ "minecraft:frozen_river", 11 },
|
||||
{ "minecraft:giant_spruce_taiga", 160 }, /* 1.18: Renamed to old_growth_spruce_taiga */
|
||||
{ "minecraft:giant_spruce_taiga_hills", 161 }, /* 1.18: Merged into giant_spruce_taiga */
|
||||
{ "minecraft:giant_tree_taiga", 32 }, /* 1.18: Renamed to old_growth_pine_taiga */
|
||||
{ "minecraft:giant_tree_taiga_hills", 33 }, /* 1.18: Merged into giant_tree_taiga */
|
||||
{ "minecraft:gravelly_mountains", 131 }, /* 1.18: Renamed to windswept_gravelly_hills */
|
||||
{ "minecraft:grove", 52 }, /* 1.18: New */
|
||||
{ "minecraft:ice_spikes", 140 },
|
||||
{ "minecraft:jagged_peaks", 53 }, /* 1.18: New */
|
||||
{ "minecraft:jungle", 21 },
|
||||
{ "minecraft:jungle_edge", 23 }, /* 1.18: Renamed to sparse_jungle */
|
||||
{ "minecraft:jungle_hills", 22 }, /* 1.18: Merged into jungle */
|
||||
{ "minecraft:lukewarm_ocean", 45 },
|
||||
{ "minecraft:lush_caves", 175 },
|
||||
{ "minecraft:mangrove_swamp", 56 },
|
||||
{ "minecraft:meadow", 51 }, /* 1.18: New */
|
||||
{ "minecraft:modified_badlands_plateau", 167 }, /* 1.18: Merged into badlands */
|
||||
{ "minecraft:modified_gravelly_mountains", 162 }, /* 1.18: Merged into gravelly_mountains */
|
||||
{ "minecraft:modified_jungle", 149 }, /* 1.18: Merged into jungle */
|
||||
{ "minecraft:modified_jungle_edge", 151 }, /* 1.18: Merged into jungle_edge */
|
||||
{ "minecraft:modified_wooded_badlands_plateau", 166 }, /* 1.18: Merged into wooded_badlands */
|
||||
{ "minecraft:mountain_edge", 20 }, /* 1.18: Merged into mountains */
|
||||
{ "minecraft:mountains", 3 }, /* 1.18: Renamed to windswept_hills */
|
||||
{ "minecraft:mushroom_field_shore", 15 }, /* 1.18: Merged into mushroom_fields */
|
||||
{ "minecraft:mushroom_fields", 14 },
|
||||
{ "minecraft:nether_wastes", 8 },
|
||||
{ "minecraft:ocean", 0 },
|
||||
{ "minecraft:old_growth_birch_forest", 155 },
|
||||
{ "minecraft:old_growth_pine_taiga", 32 },
|
||||
{ "minecraft:old_growth_spruce_taiga", 160 },
|
||||
{ "minecraft:plains", 1 },
|
||||
{ "minecraft:river", 7 },
|
||||
{ "minecraft:savanna", 35 },
|
||||
{ "minecraft:savanna_plateau", 36 },
|
||||
{ "minecraft:shattered_savanna", 163 },
|
||||
{ "minecraft:shattered_savanna_plateau", 164 }, /* 1.18: Merged into shattered_savanna */
|
||||
{ "minecraft:small_end_islands", 40 },
|
||||
{ "minecraft:snowy_beach", 26 },
|
||||
{ "minecraft:snowy_mountains", 13 }, /* 1.18: Merged into snowy_tundra */
|
||||
{ "minecraft:snowy_plains", 12 },
|
||||
{ "minecraft:snowy_slopes", 55 },
|
||||
{ "minecraft:snowy_taiga", 30 },
|
||||
{ "minecraft:snowy_taiga_hills", 31 }, /* 1.18: Merged into snowy_taiga */
|
||||
{ "minecraft:snowy_taiga_mountains", 158 }, /* 1.18: Merged into snowy_taiga */
|
||||
{ "minecraft:snowy_tundra", 12 },
|
||||
{ "minecraft:soul_sand_valley", 170 },
|
||||
{ "minecraft:sparse_jungle", 23 },
|
||||
{ "minecraft:stone_shore", 25 },
|
||||
{ "minecraft:stony_peaks", 54 }, /* 1.18: New */
|
||||
{ "minecraft:stony_shore", 25 },
|
||||
{ "minecraft:sunflower_plains", 129 },
|
||||
{ "minecraft:swamp", 6 },
|
||||
{ "minecraft:swamp_hills", 134 }, /* 1.18: Merged into swamp */
|
||||
{ "minecraft:taiga", 5 },
|
||||
{ "minecraft:taiga_hills", 19 }, /* 1.18: Merged into taiga */
|
||||
{ "minecraft:taiga_mountains", 133 }, /* 1.18: Merged into taiga */
|
||||
{ "minecraft:tall_birch_forest", 155 }, /* 1.18: Renamed to old_growth_birch_forest */
|
||||
{ "minecraft:tall_birch_hills", 156 }, /* 1.18: Merged into tall_birch_forest */
|
||||
{ "minecraft:the_end", 9 },
|
||||
{ "minecraft:the_void", 127 },
|
||||
{ "minecraft:warm_ocean", 44 },
|
||||
{ "minecraft:warped_forest", 172 },
|
||||
{ "minecraft:windswept_forest", 34 },
|
||||
{ "minecraft:windswept_gravelly_hills", 131 },
|
||||
{ "minecraft:windswept_hills", 3 },
|
||||
{ "minecraft:windswept_savanna", 163 },
|
||||
{ "minecraft:wooded_badlands", 38 },
|
||||
{ "minecraft:wooded_badlands_plateau", 38 }, /* 1.18: Renamed to wooded_badlands */
|
||||
{ "minecraft:wooded_hills", 18 }, /* 1.18: Merged into forest */
|
||||
{ "minecraft:wooded_mountains", 34 /* 1.18: Renamed to windswept_forest */},
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015-2021, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Color.hpp"
|
||||
#include "../Util.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace MinedMap {
|
||||
namespace Resource {
|
||||
|
||||
class BlockType;
|
||||
|
||||
class Biome {
|
||||
private:
|
||||
float temp, rain;
|
||||
FloatColor water;
|
||||
|
||||
protected:
|
||||
virtual FloatColor getGrassColor(float temp, float rain) const;
|
||||
virtual FloatColor getFoliageColor(float temp, float rain) const;
|
||||
|
||||
FloatColor getWaterColor() const { return water; };
|
||||
|
||||
public:
|
||||
static const Biome *const Default;
|
||||
static const Biome *const Biomes[256];
|
||||
static const std::unordered_map<std::string, uint8_t> Names;
|
||||
|
||||
Biome(float temp0, float rain0, FloatColor water0 = {0.247f, 0.463f, 0.894f})
|
||||
: temp(temp0), rain(rain0), water(water0) {}
|
||||
|
||||
FloatColor getBlockColor(const BlockType *type, y_idx_t height) const;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015-2018, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "BlockType.hpp"
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace Resource {
|
||||
|
||||
const std::unordered_map<std::string, BlockType> BlockType::Types = {
|
||||
|
||||
#include "BlockType.inc.cpp"
|
||||
|
||||
};
|
||||
|
||||
struct LegacyBlockType {
|
||||
const char *data[16];
|
||||
};
|
||||
|
||||
static constexpr LegacyBlockType simple(const char *t) {
|
||||
return {
|
||||
t, t, t, t,
|
||||
t, t, t, t,
|
||||
t, t, t, t,
|
||||
t, t, t, t,
|
||||
};
|
||||
}
|
||||
|
||||
static const LegacyBlockType LEGACY_BLOCK_TYPE_DATA[256] = {
|
||||
|
||||
#include "LegacyBlockType.inc.cpp"
|
||||
|
||||
};
|
||||
|
||||
|
||||
const BlockType * BlockType::lookup(const std::string &name) {
|
||||
auto it = Types.find(name);
|
||||
if (it == Types.end())
|
||||
return nullptr;
|
||||
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
static LegacyPalette makeLegacyPalette() {
|
||||
const std::string name_prefix("minecraft:");
|
||||
|
||||
LegacyPalette palette = {};
|
||||
for (size_t type = 0; type < 256; type++) {
|
||||
for (size_t data = 0; data < 16; data++) {
|
||||
const char *name = LEGACY_BLOCK_TYPE_DATA[type].data[data];
|
||||
if (!name)
|
||||
continue;
|
||||
|
||||
palette.types[type][data] = BlockType::lookup(name_prefix + name);
|
||||
}
|
||||
}
|
||||
|
||||
return palette;
|
||||
}
|
||||
|
||||
const LegacyPalette LEGACY_BLOCK_TYPES = makeLegacyPalette();
|
||||
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace MinedMap {
|
||||
namespace Resource {
|
||||
|
||||
#define BLOCK_OPAQUE (1u << 0)
|
||||
#define BLOCK_GRASS (1u << 1)
|
||||
#define BLOCK_FOLIAGE (1u << 2)
|
||||
#define BLOCK_BIRCH (1u << 3)
|
||||
#define BLOCK_SPRUCE (1u << 4)
|
||||
#define BLOCK_WATER (1u << 5)
|
||||
|
||||
class BlockType {
|
||||
private:
|
||||
static const std::unordered_map<std::string, BlockType> Types;
|
||||
|
||||
public:
|
||||
static const BlockType * lookup(const std::string &name);
|
||||
|
||||
uint8_t flags;
|
||||
struct {
|
||||
uint8_t r, g, b;
|
||||
} color;
|
||||
};
|
||||
|
||||
|
||||
struct LegacyPalette {
|
||||
const BlockType *types[256][16];
|
||||
};
|
||||
|
||||
extern const LegacyPalette LEGACY_BLOCK_TYPES;
|
||||
|
||||
}
|
||||
}
|
|
@ -1,938 +0,0 @@
|
|||
{"minecraft:acacia_button", {0, {0, 0, 0}}},
|
||||
{"minecraft:acacia_door", {BLOCK_OPAQUE, {167, 95, 60}}},
|
||||
{"minecraft:acacia_fence", {BLOCK_OPAQUE, {168, 90, 50}}},
|
||||
{"minecraft:acacia_fence_gate", {BLOCK_OPAQUE, {168, 90, 50}}},
|
||||
{"minecraft:acacia_leaves", {BLOCK_OPAQUE|BLOCK_FOLIAGE, {149, 148, 148}}},
|
||||
{"minecraft:acacia_log", {BLOCK_OPAQUE, {150, 88, 55}}},
|
||||
{"minecraft:acacia_planks", {BLOCK_OPAQUE, {168, 90, 50}}},
|
||||
{"minecraft:acacia_pressure_plate", {BLOCK_OPAQUE, {168, 90, 50}}},
|
||||
{"minecraft:acacia_sapling", {BLOCK_OPAQUE, {118, 117, 23}}},
|
||||
{"minecraft:acacia_sign", {BLOCK_OPAQUE, {168, 90, 50}}},
|
||||
{"minecraft:acacia_slab", {BLOCK_OPAQUE, {168, 90, 50}}},
|
||||
{"minecraft:acacia_stairs", {BLOCK_OPAQUE, {168, 90, 50}}},
|
||||
{"minecraft:acacia_trapdoor", {BLOCK_OPAQUE, {156, 87, 51}}},
|
||||
{"minecraft:acacia_wall_sign", {0, {0, 0, 0}}},
|
||||
{"minecraft:acacia_wood", {BLOCK_OPAQUE, {103, 96, 86}}},
|
||||
{"minecraft:activator_rail", {BLOCK_OPAQUE, {115, 87, 74}}},
|
||||
{"minecraft:air", {0, {0, 0, 0}}},
|
||||
{"minecraft:allium", {0, {0, 0, 0}}},
|
||||
{"minecraft:amethyst_block", {BLOCK_OPAQUE, {133, 97, 191}}},
|
||||
{"minecraft:amethyst_cluster", {BLOCK_OPAQUE, {163, 126, 207}}},
|
||||
{"minecraft:ancient_debris", {BLOCK_OPAQUE, {94, 66, 58}}},
|
||||
{"minecraft:andesite", {BLOCK_OPAQUE, {136, 136, 136}}},
|
||||
{"minecraft:andesite_slab", {BLOCK_OPAQUE, {136, 136, 136}}},
|
||||
{"minecraft:andesite_stairs", {BLOCK_OPAQUE, {136, 136, 136}}},
|
||||
{"minecraft:andesite_wall", {BLOCK_OPAQUE, {136, 136, 136}}},
|
||||
{"minecraft:anvil", {BLOCK_OPAQUE, {72, 72, 72}}},
|
||||
{"minecraft:attached_melon_stem", {BLOCK_OPAQUE|BLOCK_GRASS, {141, 142, 141}}},
|
||||
{"minecraft:attached_pumpkin_stem", {BLOCK_OPAQUE|BLOCK_GRASS, {139, 139, 139}}},
|
||||
{"minecraft:azalea", {BLOCK_OPAQUE, {101, 124, 47}}},
|
||||
{"minecraft:azalea_leaves", {BLOCK_OPAQUE, {90, 114, 44}}},
|
||||
{"minecraft:azure_bluet", {0, {0, 0, 0}}},
|
||||
{"minecraft:bamboo", {BLOCK_OPAQUE, {93, 144, 19}}},
|
||||
{"minecraft:bamboo_sapling", {0, {0, 0, 0}}},
|
||||
{"minecraft:barrel", {BLOCK_OPAQUE, {134, 100, 58}}},
|
||||
{"minecraft:barrier", {0, {0, 0, 0}}},
|
||||
{"minecraft:basalt", {BLOCK_OPAQUE, {80, 81, 86}}},
|
||||
{"minecraft:beacon", {BLOCK_OPAQUE, {117, 220, 215}}},
|
||||
{"minecraft:bedrock", {BLOCK_OPAQUE, {85, 85, 85}}},
|
||||
{"minecraft:bee_nest", {BLOCK_OPAQUE, {202, 160, 74}}},
|
||||
{"minecraft:beehive", {BLOCK_OPAQUE, {180, 146, 90}}},
|
||||
{"minecraft:beetroots", {BLOCK_OPAQUE, {93, 91, 30}}},
|
||||
{"minecraft:bell", {BLOCK_OPAQUE, {253, 235, 110}}},
|
||||
{"minecraft:big_dripleaf", {BLOCK_OPAQUE, {111, 141, 51}}},
|
||||
{"minecraft:big_dripleaf_stem", {0, {0, 0, 0}}},
|
||||
{"minecraft:birch_button", {0, {0, 0, 0}}},
|
||||
{"minecraft:birch_door", {BLOCK_OPAQUE, {220, 209, 176}}},
|
||||
{"minecraft:birch_fence", {BLOCK_OPAQUE, {192, 175, 121}}},
|
||||
{"minecraft:birch_fence_gate", {BLOCK_OPAQUE, {192, 175, 121}}},
|
||||
{"minecraft:birch_leaves", {BLOCK_OPAQUE|BLOCK_BIRCH, {130, 129, 130}}},
|
||||
{"minecraft:birch_log", {BLOCK_OPAQUE, {193, 179, 135}}},
|
||||
{"minecraft:birch_planks", {BLOCK_OPAQUE, {192, 175, 121}}},
|
||||
{"minecraft:birch_pressure_plate", {BLOCK_OPAQUE, {192, 175, 121}}},
|
||||
{"minecraft:birch_sapling", {BLOCK_OPAQUE, {127, 160, 79}}},
|
||||
{"minecraft:birch_sign", {BLOCK_OPAQUE, {192, 175, 121}}},
|
||||
{"minecraft:birch_slab", {BLOCK_OPAQUE, {192, 175, 121}}},
|
||||
{"minecraft:birch_stairs", {BLOCK_OPAQUE, {192, 175, 121}}},
|
||||
{"minecraft:birch_trapdoor", {BLOCK_OPAQUE, {207, 194, 157}}},
|
||||
{"minecraft:birch_wall_sign", {0, {0, 0, 0}}},
|
||||
{"minecraft:birch_wood", {BLOCK_OPAQUE, {216, 215, 210}}},
|
||||
{"minecraft:black_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:black_bed", {0, {0, 0, 0}}},
|
||||
{"minecraft:black_candle", {0, {0, 0, 0}}},
|
||||
{"minecraft:black_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}},
|
||||
{"minecraft:black_carpet", {BLOCK_OPAQUE, {20, 21, 25}}},
|
||||
{"minecraft:black_concrete", {BLOCK_OPAQUE, {8, 10, 15}}},
|
||||
{"minecraft:black_concrete_powder", {BLOCK_OPAQUE, {25, 26, 31}}},
|
||||
{"minecraft:black_glazed_terracotta", {BLOCK_OPAQUE, {67, 30, 32}}},
|
||||
{"minecraft:black_shulker_box", {BLOCK_OPAQUE, {25, 25, 29}}},
|
||||
{"minecraft:black_stained_glass", {BLOCK_OPAQUE, {25, 25, 25}}},
|
||||
{"minecraft:black_stained_glass_pane", {BLOCK_OPAQUE, {24, 24, 24}}},
|
||||
{"minecraft:black_terracotta", {BLOCK_OPAQUE, {37, 22, 16}}},
|
||||
{"minecraft:black_wall_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:black_wool", {BLOCK_OPAQUE, {20, 21, 25}}},
|
||||
{"minecraft:blackstone", {BLOCK_OPAQUE, {42, 36, 41}}},
|
||||
{"minecraft:blackstone_slab", {BLOCK_OPAQUE, {42, 36, 41}}},
|
||||
{"minecraft:blackstone_stairs", {BLOCK_OPAQUE, {42, 36, 41}}},
|
||||
{"minecraft:blackstone_wall", {BLOCK_OPAQUE, {42, 36, 41}}},
|
||||
{"minecraft:blast_furnace", {BLOCK_OPAQUE, {80, 80, 81}}},
|
||||
{"minecraft:blue_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:blue_bed", {0, {0, 0, 0}}},
|
||||
{"minecraft:blue_candle", {0, {0, 0, 0}}},
|
||||
{"minecraft:blue_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}},
|
||||
{"minecraft:blue_carpet", {BLOCK_OPAQUE, {53, 57, 157}}},
|
||||
{"minecraft:blue_concrete", {BLOCK_OPAQUE, {44, 46, 143}}},
|
||||
{"minecraft:blue_concrete_powder", {BLOCK_OPAQUE, {70, 73, 166}}},
|
||||
{"minecraft:blue_glazed_terracotta", {BLOCK_OPAQUE, {47, 64, 139}}},
|
||||
{"minecraft:blue_ice", {BLOCK_OPAQUE, {116, 167, 253}}},
|
||||
{"minecraft:blue_orchid", {0, {0, 0, 0}}},
|
||||
{"minecraft:blue_shulker_box", {BLOCK_OPAQUE, {43, 45, 140}}},
|
||||
{"minecraft:blue_stained_glass", {BLOCK_OPAQUE, {51, 76, 178}}},
|
||||
{"minecraft:blue_stained_glass_pane", {BLOCK_OPAQUE, {48, 73, 171}}},
|
||||
{"minecraft:blue_terracotta", {BLOCK_OPAQUE, {74, 59, 91}}},
|
||||
{"minecraft:blue_wall_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:blue_wool", {BLOCK_OPAQUE, {53, 57, 157}}},
|
||||
{"minecraft:bone_block", {BLOCK_OPAQUE, {209, 206, 179}}},
|
||||
{"minecraft:bookshelf", {BLOCK_OPAQUE, {162, 130, 78}}},
|
||||
{"minecraft:brain_coral", {0, {0, 0, 0}}},
|
||||
{"minecraft:brain_coral_block", {BLOCK_OPAQUE, {207, 91, 159}}},
|
||||
{"minecraft:brain_coral_fan", {0, {0, 0, 0}}},
|
||||
{"minecraft:brain_coral_wall_fan", {0, {0, 0, 0}}},
|
||||
{"minecraft:brewing_stand", {BLOCK_OPAQUE, {122, 100, 80}}},
|
||||
{"minecraft:brick_slab", {BLOCK_OPAQUE, {150, 97, 83}}},
|
||||
{"minecraft:brick_stairs", {BLOCK_OPAQUE, {150, 97, 83}}},
|
||||
{"minecraft:brick_wall", {BLOCK_OPAQUE, {150, 97, 83}}},
|
||||
{"minecraft:bricks", {BLOCK_OPAQUE, {150, 97, 83}}},
|
||||
{"minecraft:brown_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:brown_bed", {0, {0, 0, 0}}},
|
||||
{"minecraft:brown_candle", {0, {0, 0, 0}}},
|
||||
{"minecraft:brown_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}},
|
||||
{"minecraft:brown_carpet", {BLOCK_OPAQUE, {114, 71, 40}}},
|
||||
{"minecraft:brown_concrete", {BLOCK_OPAQUE, {96, 59, 31}}},
|
||||
{"minecraft:brown_concrete_powder", {BLOCK_OPAQUE, {125, 84, 53}}},
|
||||
{"minecraft:brown_glazed_terracotta", {BLOCK_OPAQUE, {119, 106, 85}}},
|
||||
{"minecraft:brown_mushroom", {0, {0, 0, 0}}},
|
||||
{"minecraft:brown_mushroom_block", {BLOCK_OPAQUE, {149, 111, 81}}},
|
||||
{"minecraft:brown_shulker_box", {BLOCK_OPAQUE, {106, 66, 35}}},
|
||||
{"minecraft:brown_stained_glass", {BLOCK_OPAQUE, {102, 76, 51}}},
|
||||
{"minecraft:brown_stained_glass_pane", {BLOCK_OPAQUE, {97, 73, 48}}},
|
||||
{"minecraft:brown_terracotta", {BLOCK_OPAQUE, {77, 51, 35}}},
|
||||
{"minecraft:brown_wall_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:brown_wool", {BLOCK_OPAQUE, {114, 71, 40}}},
|
||||
{"minecraft:bubble_column", {BLOCK_OPAQUE|BLOCK_WATER, {177, 177, 177}}},
|
||||
{"minecraft:bubble_coral", {0, {0, 0, 0}}},
|
||||
{"minecraft:bubble_coral_block", {BLOCK_OPAQUE, {165, 26, 162}}},
|
||||
{"minecraft:bubble_coral_fan", {0, {0, 0, 0}}},
|
||||
{"minecraft:bubble_coral_wall_fan", {0, {0, 0, 0}}},
|
||||
{"minecraft:budding_amethyst", {BLOCK_OPAQUE, {132, 96, 186}}},
|
||||
{"minecraft:cactus", {BLOCK_OPAQUE, {85, 127, 43}}},
|
||||
{"minecraft:cake", {BLOCK_OPAQUE, {248, 222, 214}}},
|
||||
{"minecraft:calcite", {BLOCK_OPAQUE, {223, 224, 220}}},
|
||||
{"minecraft:campfire", {BLOCK_OPAQUE, {110, 88, 54}}},
|
||||
{"minecraft:candle", {0, {0, 0, 0}}},
|
||||
{"minecraft:candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}},
|
||||
{"minecraft:carrots", {BLOCK_OPAQUE, {81, 124, 37}}},
|
||||
{"minecraft:cartography_table", {BLOCK_OPAQUE, {103, 87, 67}}},
|
||||
{"minecraft:carved_pumpkin", {BLOCK_OPAQUE, {198, 118, 24}}},
|
||||
{"minecraft:cauldron", {BLOCK_OPAQUE, {73, 72, 74}}},
|
||||
{"minecraft:cave_air", {0, {0, 0, 0}}},
|
||||
{"minecraft:cave_vines", {BLOCK_OPAQUE, {90, 109, 40}}},
|
||||
{"minecraft:cave_vines_plant", {BLOCK_OPAQUE, {88, 101, 38}}},
|
||||
{"minecraft:chain", {0, {0, 0, 0}}},
|
||||
{"minecraft:chain_command_block", {BLOCK_OPAQUE, {131, 161, 147}}},
|
||||
{"minecraft:chest", {BLOCK_OPAQUE, {162, 130, 78}}},
|
||||
{"minecraft:chipped_anvil", {BLOCK_OPAQUE, {72, 72, 72}}},
|
||||
{"minecraft:chiseled_deepslate", {BLOCK_OPAQUE, {54, 54, 54}}},
|
||||
{"minecraft:chiseled_nether_bricks", {BLOCK_OPAQUE, {47, 23, 28}}},
|
||||
{"minecraft:chiseled_polished_blackstone", {BLOCK_OPAQUE, {53, 48, 56}}},
|
||||
{"minecraft:chiseled_quartz_block", {BLOCK_OPAQUE, {231, 226, 218}}},
|
||||
{"minecraft:chiseled_red_sandstone", {BLOCK_OPAQUE, {181, 97, 31}}},
|
||||
{"minecraft:chiseled_sandstone", {BLOCK_OPAQUE, {223, 214, 170}}},
|
||||
{"minecraft:chiseled_stone_bricks", {BLOCK_OPAQUE, {119, 118, 119}}},
|
||||
{"minecraft:chorus_flower", {BLOCK_OPAQUE, {151, 120, 151}}},
|
||||
{"minecraft:chorus_plant", {BLOCK_OPAQUE, {93, 57, 93}}},
|
||||
{"minecraft:clay", {BLOCK_OPAQUE, {160, 166, 179}}},
|
||||
{"minecraft:coal_block", {BLOCK_OPAQUE, {16, 15, 15}}},
|
||||
{"minecraft:coal_ore", {BLOCK_OPAQUE, {105, 105, 105}}},
|
||||
{"minecraft:coarse_dirt", {BLOCK_OPAQUE, {119, 85, 59}}},
|
||||
{"minecraft:cobbled_deepslate", {BLOCK_OPAQUE, {77, 77, 80}}},
|
||||
{"minecraft:cobbled_deepslate_slab", {BLOCK_OPAQUE, {77, 77, 80}}},
|
||||
{"minecraft:cobbled_deepslate_stairs", {BLOCK_OPAQUE, {77, 77, 80}}},
|
||||
{"minecraft:cobbled_deepslate_wall", {BLOCK_OPAQUE, {77, 77, 80}}},
|
||||
{"minecraft:cobblestone", {BLOCK_OPAQUE, {127, 127, 127}}},
|
||||
{"minecraft:cobblestone_slab", {BLOCK_OPAQUE, {127, 127, 127}}},
|
||||
{"minecraft:cobblestone_stairs", {BLOCK_OPAQUE, {127, 127, 127}}},
|
||||
{"minecraft:cobblestone_wall", {BLOCK_OPAQUE, {127, 127, 127}}},
|
||||
{"minecraft:cobweb", {BLOCK_OPAQUE, {228, 233, 234}}},
|
||||
{"minecraft:cocoa", {BLOCK_OPAQUE, {154, 91, 40}}},
|
||||
{"minecraft:command_block", {BLOCK_OPAQUE, {181, 136, 108}}},
|
||||
{"minecraft:comparator", {BLOCK_OPAQUE, {166, 161, 159}}},
|
||||
{"minecraft:composter", {BLOCK_OPAQUE, {88, 61, 23}}},
|
||||
{"minecraft:conduit", {BLOCK_OPAQUE, {159, 139, 113}}},
|
||||
{"minecraft:copper_block", {BLOCK_OPAQUE, {192, 107, 79}}},
|
||||
{"minecraft:copper_ore", {BLOCK_OPAQUE, {124, 125, 120}}},
|
||||
{"minecraft:cornflower", {0, {0, 0, 0}}},
|
||||
{"minecraft:cracked_deepslate_bricks", {BLOCK_OPAQUE, {64, 64, 65}}},
|
||||
{"minecraft:cracked_deepslate_tiles", {BLOCK_OPAQUE, {52, 52, 52}}},
|
||||
{"minecraft:cracked_nether_bricks", {BLOCK_OPAQUE, {40, 20, 23}}},
|
||||
{"minecraft:cracked_polished_blackstone_bricks", {BLOCK_OPAQUE, {44, 37, 43}}},
|
||||
{"minecraft:cracked_stone_bricks", {BLOCK_OPAQUE, {118, 117, 118}}},
|
||||
{"minecraft:crafting_table", {BLOCK_OPAQUE, {119, 73, 42}}},
|
||||
{"minecraft:creeper_head", {0, {0, 0, 0}}},
|
||||
{"minecraft:creeper_wall_head", {0, {0, 0, 0}}},
|
||||
{"minecraft:crimson_button", {0, {0, 0, 0}}},
|
||||
{"minecraft:crimson_door", {BLOCK_OPAQUE, {114, 54, 79}}},
|
||||
{"minecraft:crimson_fence", {BLOCK_OPAQUE, {101, 48, 70}}},
|
||||
{"minecraft:crimson_fence_gate", {BLOCK_OPAQUE, {101, 48, 70}}},
|
||||
{"minecraft:crimson_fungus", {0, {0, 0, 0}}},
|
||||
{"minecraft:crimson_hyphae", {BLOCK_OPAQUE, {92, 25, 29}}},
|
||||
{"minecraft:crimson_nylium", {BLOCK_OPAQUE, {130, 31, 31}}},
|
||||
{"minecraft:crimson_planks", {BLOCK_OPAQUE, {101, 48, 70}}},
|
||||
{"minecraft:crimson_pressure_plate", {BLOCK_OPAQUE, {101, 48, 70}}},
|
||||
{"minecraft:crimson_roots", {BLOCK_OPAQUE, {126, 8, 41}}},
|
||||
{"minecraft:crimson_sign", {BLOCK_OPAQUE, {101, 48, 70}}},
|
||||
{"minecraft:crimson_slab", {BLOCK_OPAQUE, {101, 48, 70}}},
|
||||
{"minecraft:crimson_stairs", {BLOCK_OPAQUE, {101, 48, 70}}},
|
||||
{"minecraft:crimson_stem", {BLOCK_OPAQUE, {112, 49, 70}}},
|
||||
{"minecraft:crimson_trapdoor", {BLOCK_OPAQUE, {103, 50, 72}}},
|
||||
{"minecraft:crimson_wall_sign", {0, {0, 0, 0}}},
|
||||
{"minecraft:crying_obsidian", {BLOCK_OPAQUE, {32, 10, 60}}},
|
||||
{"minecraft:cut_copper", {BLOCK_OPAQUE, {191, 106, 80}}},
|
||||
{"minecraft:cut_copper_slab", {BLOCK_OPAQUE, {191, 106, 80}}},
|
||||
{"minecraft:cut_copper_stairs", {BLOCK_OPAQUE, {191, 106, 80}}},
|
||||
{"minecraft:cut_red_sandstone", {BLOCK_OPAQUE, {181, 97, 31}}},
|
||||
{"minecraft:cut_red_sandstone_slab", {BLOCK_OPAQUE, {181, 97, 31}}},
|
||||
{"minecraft:cut_sandstone", {BLOCK_OPAQUE, {223, 214, 170}}},
|
||||
{"minecraft:cut_sandstone_slab", {BLOCK_OPAQUE, {223, 214, 170}}},
|
||||
{"minecraft:cyan_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:cyan_bed", {0, {0, 0, 0}}},
|
||||
{"minecraft:cyan_candle", {0, {0, 0, 0}}},
|
||||
{"minecraft:cyan_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}},
|
||||
{"minecraft:cyan_carpet", {BLOCK_OPAQUE, {21, 137, 145}}},
|
||||
{"minecraft:cyan_concrete", {BLOCK_OPAQUE, {21, 119, 136}}},
|
||||
{"minecraft:cyan_concrete_powder", {BLOCK_OPAQUE, {36, 147, 157}}},
|
||||
{"minecraft:cyan_glazed_terracotta", {BLOCK_OPAQUE, {52, 118, 125}}},
|
||||
{"minecraft:cyan_shulker_box", {BLOCK_OPAQUE, {20, 121, 135}}},
|
||||
{"minecraft:cyan_stained_glass", {BLOCK_OPAQUE, {76, 127, 153}}},
|
||||
{"minecraft:cyan_stained_glass_pane", {BLOCK_OPAQUE, {73, 122, 147}}},
|
||||
{"minecraft:cyan_terracotta", {BLOCK_OPAQUE, {86, 91, 91}}},
|
||||
{"minecraft:cyan_wall_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:cyan_wool", {BLOCK_OPAQUE, {21, 137, 145}}},
|
||||
{"minecraft:damaged_anvil", {BLOCK_OPAQUE, {72, 72, 72}}},
|
||||
{"minecraft:dandelion", {0, {0, 0, 0}}},
|
||||
{"minecraft:dark_oak_button", {0, {0, 0, 0}}},
|
||||
{"minecraft:dark_oak_door", {BLOCK_OPAQUE, {76, 51, 25}}},
|
||||
{"minecraft:dark_oak_fence", {BLOCK_OPAQUE, {66, 43, 20}}},
|
||||
{"minecraft:dark_oak_fence_gate", {BLOCK_OPAQUE, {66, 43, 20}}},
|
||||
{"minecraft:dark_oak_leaves", {BLOCK_OPAQUE|BLOCK_FOLIAGE, {150, 150, 150}}},
|
||||
{"minecraft:dark_oak_log", {BLOCK_OPAQUE, {67, 45, 22}}},
|
||||
{"minecraft:dark_oak_planks", {BLOCK_OPAQUE, {66, 43, 20}}},
|
||||
{"minecraft:dark_oak_pressure_plate", {BLOCK_OPAQUE, {66, 43, 20}}},
|
||||
{"minecraft:dark_oak_sapling", {BLOCK_OPAQUE, {61, 90, 30}}},
|
||||
{"minecraft:dark_oak_sign", {BLOCK_OPAQUE, {66, 43, 20}}},
|
||||
{"minecraft:dark_oak_slab", {BLOCK_OPAQUE, {66, 43, 20}}},
|
||||
{"minecraft:dark_oak_stairs", {BLOCK_OPAQUE, {66, 43, 20}}},
|
||||
{"minecraft:dark_oak_trapdoor", {BLOCK_OPAQUE, {75, 49, 23}}},
|
||||
{"minecraft:dark_oak_wall_sign", {0, {0, 0, 0}}},
|
||||
{"minecraft:dark_oak_wood", {BLOCK_OPAQUE, {60, 46, 26}}},
|
||||
{"minecraft:dark_prismarine", {BLOCK_OPAQUE, {51, 91, 75}}},
|
||||
{"minecraft:dark_prismarine_slab", {BLOCK_OPAQUE, {51, 91, 75}}},
|
||||
{"minecraft:dark_prismarine_stairs", {BLOCK_OPAQUE, {51, 91, 75}}},
|
||||
{"minecraft:daylight_detector", {BLOCK_OPAQUE, {130, 116, 94}}},
|
||||
{"minecraft:dead_brain_coral", {0, {0, 0, 0}}},
|
||||
{"minecraft:dead_brain_coral_block", {BLOCK_OPAQUE, {124, 117, 114}}},
|
||||
{"minecraft:dead_brain_coral_fan", {0, {0, 0, 0}}},
|
||||
{"minecraft:dead_brain_coral_wall_fan", {0, {0, 0, 0}}},
|
||||
{"minecraft:dead_bubble_coral", {0, {0, 0, 0}}},
|
||||
{"minecraft:dead_bubble_coral_block", {BLOCK_OPAQUE, {131, 123, 119}}},
|
||||
{"minecraft:dead_bubble_coral_fan", {0, {0, 0, 0}}},
|
||||
{"minecraft:dead_bubble_coral_wall_fan", {0, {0, 0, 0}}},
|
||||
{"minecraft:dead_bush", {BLOCK_OPAQUE, {107, 78, 40}}},
|
||||
{"minecraft:dead_fire_coral", {0, {0, 0, 0}}},
|
||||
{"minecraft:dead_fire_coral_block", {BLOCK_OPAQUE, {131, 123, 119}}},
|
||||
{"minecraft:dead_fire_coral_fan", {0, {0, 0, 0}}},
|
||||
{"minecraft:dead_fire_coral_wall_fan", {0, {0, 0, 0}}},
|
||||
{"minecraft:dead_horn_coral", {0, {0, 0, 0}}},
|
||||
{"minecraft:dead_horn_coral_block", {BLOCK_OPAQUE, {133, 126, 122}}},
|
||||
{"minecraft:dead_horn_coral_fan", {0, {0, 0, 0}}},
|
||||
{"minecraft:dead_horn_coral_wall_fan", {0, {0, 0, 0}}},
|
||||
{"minecraft:dead_tube_coral", {0, {0, 0, 0}}},
|
||||
{"minecraft:dead_tube_coral_block", {BLOCK_OPAQUE, {130, 123, 119}}},
|
||||
{"minecraft:dead_tube_coral_fan", {0, {0, 0, 0}}},
|
||||
{"minecraft:dead_tube_coral_wall_fan", {0, {0, 0, 0}}},
|
||||
{"minecraft:deepslate", {BLOCK_OPAQUE, {80, 80, 82}}},
|
||||
{"minecraft:deepslate_brick_slab", {BLOCK_OPAQUE, {70, 70, 71}}},
|
||||
{"minecraft:deepslate_brick_stairs", {BLOCK_OPAQUE, {70, 70, 71}}},
|
||||
{"minecraft:deepslate_brick_wall", {BLOCK_OPAQUE, {70, 70, 71}}},
|
||||
{"minecraft:deepslate_bricks", {BLOCK_OPAQUE, {70, 70, 71}}},
|
||||
{"minecraft:deepslate_coal_ore", {BLOCK_OPAQUE, {74, 74, 76}}},
|
||||
{"minecraft:deepslate_copper_ore", {BLOCK_OPAQUE, {92, 93, 89}}},
|
||||
{"minecraft:deepslate_diamond_ore", {BLOCK_OPAQUE, {83, 106, 106}}},
|
||||
{"minecraft:deepslate_emerald_ore", {BLOCK_OPAQUE, {78, 104, 87}}},
|
||||
{"minecraft:deepslate_gold_ore", {BLOCK_OPAQUE, {115, 102, 78}}},
|
||||
{"minecraft:deepslate_iron_ore", {BLOCK_OPAQUE, {106, 99, 94}}},
|
||||
{"minecraft:deepslate_lapis_ore", {BLOCK_OPAQUE, {79, 90, 115}}},
|
||||
{"minecraft:deepslate_redstone_ore", {BLOCK_OPAQUE, {104, 73, 74}}},
|
||||
{"minecraft:deepslate_tile_slab", {BLOCK_OPAQUE, {54, 54, 55}}},
|
||||
{"minecraft:deepslate_tile_stairs", {BLOCK_OPAQUE, {54, 54, 55}}},
|
||||
{"minecraft:deepslate_tile_wall", {BLOCK_OPAQUE, {54, 54, 55}}},
|
||||
{"minecraft:deepslate_tiles", {BLOCK_OPAQUE, {54, 54, 55}}},
|
||||
{"minecraft:detector_rail", {BLOCK_OPAQUE, {123, 104, 90}}},
|
||||
{"minecraft:diamond_block", {BLOCK_OPAQUE, {98, 237, 228}}},
|
||||
{"minecraft:diamond_ore", {BLOCK_OPAQUE, {121, 141, 140}}},
|
||||
{"minecraft:diorite", {BLOCK_OPAQUE, {188, 188, 188}}},
|
||||
{"minecraft:diorite_slab", {BLOCK_OPAQUE, {188, 188, 188}}},
|
||||
{"minecraft:diorite_stairs", {BLOCK_OPAQUE, {188, 188, 188}}},
|
||||
{"minecraft:diorite_wall", {BLOCK_OPAQUE, {188, 188, 188}}},
|
||||
{"minecraft:dirt", {BLOCK_OPAQUE, {134, 96, 67}}},
|
||||
{"minecraft:dirt_path", {BLOCK_OPAQUE, {148, 121, 65}}},
|
||||
{"minecraft:dispenser", {BLOCK_OPAQUE, {110, 109, 109}}},
|
||||
{"minecraft:dragon_egg", {BLOCK_OPAQUE, {12, 9, 15}}},
|
||||
{"minecraft:dragon_head", {0, {0, 0, 0}}},
|
||||
{"minecraft:dragon_wall_head", {0, {0, 0, 0}}},
|
||||
{"minecraft:dried_kelp_block", {BLOCK_OPAQUE, {50, 58, 38}}},
|
||||
{"minecraft:dripstone_block", {BLOCK_OPAQUE, {134, 107, 92}}},
|
||||
{"minecraft:dropper", {BLOCK_OPAQUE, {110, 109, 109}}},
|
||||
{"minecraft:emerald_block", {BLOCK_OPAQUE, {42, 203, 87}}},
|
||||
{"minecraft:emerald_ore", {BLOCK_OPAQUE, {108, 136, 115}}},
|
||||
{"minecraft:enchanting_table", {BLOCK_OPAQUE, {128, 75, 85}}},
|
||||
{"minecraft:end_gateway", {BLOCK_OPAQUE, {15, 10, 24}}},
|
||||
{"minecraft:end_portal", {BLOCK_OPAQUE, {15, 10, 24}}},
|
||||
{"minecraft:end_portal_frame", {BLOCK_OPAQUE, {91, 120, 97}}},
|
||||
{"minecraft:end_rod", {0, {0, 0, 0}}},
|
||||
{"minecraft:end_stone", {BLOCK_OPAQUE, {219, 222, 158}}},
|
||||
{"minecraft:end_stone_brick_slab", {BLOCK_OPAQUE, {218, 224, 162}}},
|
||||
{"minecraft:end_stone_brick_stairs", {BLOCK_OPAQUE, {218, 224, 162}}},
|
||||
{"minecraft:end_stone_brick_wall", {BLOCK_OPAQUE, {218, 224, 162}}},
|
||||
{"minecraft:end_stone_bricks", {BLOCK_OPAQUE, {218, 224, 162}}},
|
||||
{"minecraft:ender_chest", {BLOCK_OPAQUE, {15, 10, 24}}},
|
||||
{"minecraft:exposed_copper", {BLOCK_OPAQUE, {161, 125, 103}}},
|
||||
{"minecraft:exposed_cut_copper", {BLOCK_OPAQUE, {154, 121, 101}}},
|
||||
{"minecraft:exposed_cut_copper_slab", {BLOCK_OPAQUE, {154, 121, 101}}},
|
||||
{"minecraft:exposed_cut_copper_stairs", {BLOCK_OPAQUE, {154, 121, 101}}},
|
||||
{"minecraft:farmland", {BLOCK_OPAQUE, {81, 44, 15}}},
|
||||
{"minecraft:fern", {0, {0, 0, 0}}},
|
||||
{"minecraft:fire", {BLOCK_OPAQUE, {211, 140, 53}}},
|
||||
{"minecraft:fire_coral", {0, {0, 0, 0}}},
|
||||
{"minecraft:fire_coral_block", {BLOCK_OPAQUE, {163, 35, 46}}},
|
||||
{"minecraft:fire_coral_fan", {0, {0, 0, 0}}},
|
||||
{"minecraft:fire_coral_wall_fan", {0, {0, 0, 0}}},
|
||||
{"minecraft:fletching_table", {BLOCK_OPAQUE, {197, 180, 133}}},
|
||||
{"minecraft:flower_pot", {BLOCK_OPAQUE, {124, 68, 53}}},
|
||||
{"minecraft:flowering_azalea", {BLOCK_OPAQUE, {112, 121, 64}}},
|
||||
{"minecraft:flowering_azalea_leaves", {BLOCK_OPAQUE, {99, 111, 60}}},
|
||||
{"minecraft:frogspawn", {BLOCK_OPAQUE, {105, 90, 82}}},
|
||||
{"minecraft:frosted_ice", {BLOCK_OPAQUE, {140, 181, 252}}},
|
||||
{"minecraft:furnace", {BLOCK_OPAQUE, {110, 109, 109}}},
|
||||
{"minecraft:gilded_blackstone", {BLOCK_OPAQUE, {55, 42, 38}}},
|
||||
{"minecraft:glass", {BLOCK_OPAQUE, {175, 213, 219}}},
|
||||
{"minecraft:glass_pane", {BLOCK_OPAQUE, {170, 210, 217}}},
|
||||
{"minecraft:glow_item_frame", {0, {0, 0, 0}}},
|
||||
{"minecraft:glow_lichen", {0, {0, 0, 0}}},
|
||||
{"minecraft:glowstone", {BLOCK_OPAQUE, {171, 131, 84}}},
|
||||
{"minecraft:gold_block", {BLOCK_OPAQUE, {246, 208, 61}}},
|
||||
{"minecraft:gold_ore", {BLOCK_OPAQUE, {145, 133, 106}}},
|
||||
{"minecraft:granite", {BLOCK_OPAQUE, {149, 103, 85}}},
|
||||
{"minecraft:granite_slab", {BLOCK_OPAQUE, {149, 103, 85}}},
|
||||
{"minecraft:granite_stairs", {BLOCK_OPAQUE, {149, 103, 85}}},
|
||||
{"minecraft:granite_wall", {BLOCK_OPAQUE, {149, 103, 85}}},
|
||||
{"minecraft:grass", {0, {0, 0, 0}}},
|
||||
{"minecraft:grass_block", {BLOCK_OPAQUE|BLOCK_GRASS, {147, 147, 147}}},
|
||||
{"minecraft:grass_path", {BLOCK_OPAQUE, {148, 121, 65}}},
|
||||
{"minecraft:gravel", {BLOCK_OPAQUE, {131, 127, 126}}},
|
||||
{"minecraft:gray_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:gray_bed", {0, {0, 0, 0}}},
|
||||
{"minecraft:gray_candle", {0, {0, 0, 0}}},
|
||||
{"minecraft:gray_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}},
|
||||
{"minecraft:gray_carpet", {BLOCK_OPAQUE, {62, 68, 71}}},
|
||||
{"minecraft:gray_concrete", {BLOCK_OPAQUE, {54, 57, 61}}},
|
||||
{"minecraft:gray_concrete_powder", {BLOCK_OPAQUE, {76, 81, 84}}},
|
||||
{"minecraft:gray_glazed_terracotta", {BLOCK_OPAQUE, {83, 90, 93}}},
|
||||
{"minecraft:gray_shulker_box", {BLOCK_OPAQUE, {55, 58, 62}}},
|
||||
{"minecraft:gray_stained_glass", {BLOCK_OPAQUE, {76, 76, 76}}},
|
||||
{"minecraft:gray_stained_glass_pane", {BLOCK_OPAQUE, {73, 73, 73}}},
|
||||
{"minecraft:gray_terracotta", {BLOCK_OPAQUE, {57, 42, 35}}},
|
||||
{"minecraft:gray_wall_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:gray_wool", {BLOCK_OPAQUE, {62, 68, 71}}},
|
||||
{"minecraft:green_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:green_bed", {0, {0, 0, 0}}},
|
||||
{"minecraft:green_candle", {0, {0, 0, 0}}},
|
||||
{"minecraft:green_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}},
|
||||
{"minecraft:green_carpet", {BLOCK_OPAQUE, {84, 109, 27}}},
|
||||
{"minecraft:green_concrete", {BLOCK_OPAQUE, {73, 91, 36}}},
|
||||
{"minecraft:green_concrete_powder", {BLOCK_OPAQUE, {97, 119, 44}}},
|
||||
{"minecraft:green_glazed_terracotta", {BLOCK_OPAQUE, {117, 142, 67}}},
|
||||
{"minecraft:green_shulker_box", {BLOCK_OPAQUE, {79, 100, 31}}},
|
||||
{"minecraft:green_stained_glass", {BLOCK_OPAQUE, {102, 127, 51}}},
|
||||
{"minecraft:green_stained_glass_pane", {BLOCK_OPAQUE, {97, 122, 48}}},
|
||||
{"minecraft:green_terracotta", {BLOCK_OPAQUE, {76, 83, 42}}},
|
||||
{"minecraft:green_wall_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:green_wool", {BLOCK_OPAQUE, {84, 109, 27}}},
|
||||
{"minecraft:grindstone", {BLOCK_OPAQUE, {142, 142, 142}}},
|
||||
{"minecraft:hanging_roots", {BLOCK_OPAQUE, {161, 115, 91}}},
|
||||
{"minecraft:hay_block", {BLOCK_OPAQUE, {165, 139, 12}}},
|
||||
{"minecraft:heavy_weighted_pressure_plate", {BLOCK_OPAQUE, {220, 220, 220}}},
|
||||
{"minecraft:honey_block", {BLOCK_OPAQUE, {251, 185, 52}}},
|
||||
{"minecraft:honeycomb_block", {BLOCK_OPAQUE, {229, 148, 29}}},
|
||||
{"minecraft:hopper", {BLOCK_OPAQUE, {75, 74, 75}}},
|
||||
{"minecraft:horn_coral", {0, {0, 0, 0}}},
|
||||
{"minecraft:horn_coral_block", {BLOCK_OPAQUE, {216, 199, 66}}},
|
||||
{"minecraft:horn_coral_fan", {0, {0, 0, 0}}},
|
||||
{"minecraft:horn_coral_wall_fan", {0, {0, 0, 0}}},
|
||||
{"minecraft:ice", {BLOCK_OPAQUE, {145, 183, 253}}},
|
||||
{"minecraft:infested_chiseled_stone_bricks", {BLOCK_OPAQUE, {119, 118, 119}}},
|
||||
{"minecraft:infested_cobblestone", {BLOCK_OPAQUE, {127, 127, 127}}},
|
||||
{"minecraft:infested_cracked_stone_bricks", {BLOCK_OPAQUE, {118, 117, 118}}},
|
||||
{"minecraft:infested_deepslate", {BLOCK_OPAQUE, {80, 80, 82}}},
|
||||
{"minecraft:infested_mossy_stone_bricks", {BLOCK_OPAQUE, {115, 121, 105}}},
|
||||
{"minecraft:infested_stone", {BLOCK_OPAQUE, {125, 125, 125}}},
|
||||
{"minecraft:infested_stone_bricks", {BLOCK_OPAQUE, {122, 121, 122}}},
|
||||
{"minecraft:iron_bars", {BLOCK_OPAQUE, {136, 139, 135}}},
|
||||
{"minecraft:iron_block", {BLOCK_OPAQUE, {220, 220, 220}}},
|
||||
{"minecraft:iron_door", {BLOCK_OPAQUE, {194, 193, 193}}},
|
||||
{"minecraft:iron_ore", {BLOCK_OPAQUE, {136, 129, 122}}},
|
||||
{"minecraft:iron_trapdoor", {BLOCK_OPAQUE, {202, 202, 202}}},
|
||||
{"minecraft:item_frame", {0, {0, 0, 0}}},
|
||||
{"minecraft:jack_o_lantern", {BLOCK_OPAQUE, {214, 152, 52}}},
|
||||
{"minecraft:jigsaw", {BLOCK_OPAQUE, {80, 69, 81}}},
|
||||
{"minecraft:jukebox", {BLOCK_OPAQUE, {93, 64, 47}}},
|
||||
{"minecraft:jungle_button", {0, {0, 0, 0}}},
|
||||
{"minecraft:jungle_door", {BLOCK_OPAQUE, {163, 119, 84}}},
|
||||
{"minecraft:jungle_fence", {BLOCK_OPAQUE, {160, 115, 80}}},
|
||||
{"minecraft:jungle_fence_gate", {BLOCK_OPAQUE, {160, 115, 80}}},
|
||||
{"minecraft:jungle_leaves", {BLOCK_OPAQUE|BLOCK_FOLIAGE, {156, 154, 143}}},
|
||||
{"minecraft:jungle_log", {BLOCK_OPAQUE, {149, 109, 70}}},
|
||||
{"minecraft:jungle_planks", {BLOCK_OPAQUE, {160, 115, 80}}},
|
||||
{"minecraft:jungle_pressure_plate", {BLOCK_OPAQUE, {160, 115, 80}}},
|
||||
{"minecraft:jungle_sapling", {BLOCK_OPAQUE, {47, 81, 16}}},
|
||||
{"minecraft:jungle_sign", {BLOCK_OPAQUE, {160, 115, 80}}},
|
||||
{"minecraft:jungle_slab", {BLOCK_OPAQUE, {160, 115, 80}}},
|
||||
{"minecraft:jungle_stairs", {BLOCK_OPAQUE, {160, 115, 80}}},
|
||||
{"minecraft:jungle_trapdoor", {BLOCK_OPAQUE, {152, 110, 77}}},
|
||||
{"minecraft:jungle_wall_sign", {0, {0, 0, 0}}},
|
||||
{"minecraft:jungle_wood", {BLOCK_OPAQUE, {85, 67, 25}}},
|
||||
{"minecraft:kelp", {0, {0, 0, 0}}},
|
||||
{"minecraft:kelp_plant", {BLOCK_OPAQUE, {86, 130, 42}}},
|
||||
{"minecraft:ladder", {0, {0, 0, 0}}},
|
||||
{"minecraft:lantern", {BLOCK_OPAQUE, {106, 91, 83}}},
|
||||
{"minecraft:lapis_block", {BLOCK_OPAQUE, {30, 67, 140}}},
|
||||
{"minecraft:lapis_ore", {BLOCK_OPAQUE, {107, 117, 141}}},
|
||||
{"minecraft:large_amethyst_bud", {0, {0, 0, 0}}},
|
||||
{"minecraft:large_fern", {BLOCK_OPAQUE|BLOCK_GRASS, {125, 125, 125}}},
|
||||
{"minecraft:lava", {BLOCK_OPAQUE, {212, 90, 18}}},
|
||||
{"minecraft:lava_cauldron", {BLOCK_OPAQUE, {73, 72, 74}}},
|
||||
{"minecraft:lectern", {BLOCK_OPAQUE, {173, 137, 83}}},
|
||||
{"minecraft:lever", {0, {0, 0, 0}}},
|
||||
{"minecraft:light", {0, {0, 0, 0}}},
|
||||
{"minecraft:light_blue_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:light_blue_bed", {0, {0, 0, 0}}},
|
||||
{"minecraft:light_blue_candle", {0, {0, 0, 0}}},
|
||||
{"minecraft:light_blue_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}},
|
||||
{"minecraft:light_blue_carpet", {BLOCK_OPAQUE, {58, 175, 217}}},
|
||||
{"minecraft:light_blue_concrete", {BLOCK_OPAQUE, {35, 137, 198}}},
|
||||
{"minecraft:light_blue_concrete_powder", {BLOCK_OPAQUE, {74, 180, 213}}},
|
||||
{"minecraft:light_blue_glazed_terracotta", {BLOCK_OPAQUE, {94, 164, 208}}},
|
||||
{"minecraft:light_blue_shulker_box", {BLOCK_OPAQUE, {49, 163, 212}}},
|
||||
{"minecraft:light_blue_stained_glass", {BLOCK_OPAQUE, {102, 153, 216}}},
|
||||
{"minecraft:light_blue_stained_glass_pane", {BLOCK_OPAQUE, {97, 147, 208}}},
|
||||
{"minecraft:light_blue_terracotta", {BLOCK_OPAQUE, {113, 108, 137}}},
|
||||
{"minecraft:light_blue_wall_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:light_blue_wool", {BLOCK_OPAQUE, {58, 175, 217}}},
|
||||
{"minecraft:light_gray_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:light_gray_bed", {0, {0, 0, 0}}},
|
||||
{"minecraft:light_gray_candle", {0, {0, 0, 0}}},
|
||||
{"minecraft:light_gray_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}},
|
||||
{"minecraft:light_gray_carpet", {BLOCK_OPAQUE, {142, 142, 134}}},
|
||||
{"minecraft:light_gray_concrete", {BLOCK_OPAQUE, {125, 125, 115}}},
|
||||
{"minecraft:light_gray_concrete_powder", {BLOCK_OPAQUE, {154, 154, 148}}},
|
||||
{"minecraft:light_gray_glazed_terracotta", {BLOCK_OPAQUE, {144, 166, 167}}},
|
||||
{"minecraft:light_gray_shulker_box", {BLOCK_OPAQUE, {124, 124, 115}}},
|
||||
{"minecraft:light_gray_stained_glass", {BLOCK_OPAQUE, {153, 153, 153}}},
|
||||
{"minecraft:light_gray_stained_glass_pane", {BLOCK_OPAQUE, {147, 147, 147}}},
|
||||
{"minecraft:light_gray_terracotta", {BLOCK_OPAQUE, {135, 106, 97}}},
|
||||
{"minecraft:light_gray_wall_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:light_gray_wool", {BLOCK_OPAQUE, {142, 142, 134}}},
|
||||
{"minecraft:light_weighted_pressure_plate", {BLOCK_OPAQUE, {246, 208, 61}}},
|
||||
{"minecraft:lightning_rod", {0, {0, 0, 0}}},
|
||||
{"minecraft:lilac", {BLOCK_OPAQUE, {154, 125, 147}}},
|
||||
{"minecraft:lily_of_the_valley", {0, {0, 0, 0}}},
|
||||
{"minecraft:lily_pad", {BLOCK_OPAQUE|BLOCK_GRASS, {133, 133, 133}}},
|
||||
{"minecraft:lime_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:lime_bed", {0, {0, 0, 0}}},
|
||||
{"minecraft:lime_candle", {0, {0, 0, 0}}},
|
||||
{"minecraft:lime_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}},
|
||||
{"minecraft:lime_carpet", {BLOCK_OPAQUE, {112, 185, 25}}},
|
||||
{"minecraft:lime_concrete", {BLOCK_OPAQUE, {94, 168, 24}}},
|
||||
{"minecraft:lime_concrete_powder", {BLOCK_OPAQUE, {125, 189, 41}}},
|
||||
{"minecraft:lime_glazed_terracotta", {BLOCK_OPAQUE, {162, 197, 55}}},
|
||||
{"minecraft:lime_shulker_box", {BLOCK_OPAQUE, {99, 172, 23}}},
|
||||
{"minecraft:lime_stained_glass", {BLOCK_OPAQUE, {127, 204, 25}}},
|
||||
{"minecraft:lime_stained_glass_pane", {BLOCK_OPAQUE, {122, 196, 24}}},
|
||||
{"minecraft:lime_terracotta", {BLOCK_OPAQUE, {103, 117, 52}}},
|
||||
{"minecraft:lime_wall_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:lime_wool", {BLOCK_OPAQUE, {112, 185, 25}}},
|
||||
{"minecraft:lodestone", {BLOCK_OPAQUE, {147, 149, 152}}},
|
||||
{"minecraft:loom", {BLOCK_OPAQUE, {142, 119, 91}}},
|
||||
{"minecraft:magenta_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:magenta_bed", {0, {0, 0, 0}}},
|
||||
{"minecraft:magenta_candle", {0, {0, 0, 0}}},
|
||||
{"minecraft:magenta_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}},
|
||||
{"minecraft:magenta_carpet", {BLOCK_OPAQUE, {189, 68, 179}}},
|
||||
{"minecraft:magenta_concrete", {BLOCK_OPAQUE, {169, 48, 159}}},
|
||||
{"minecraft:magenta_concrete_powder", {BLOCK_OPAQUE, {192, 83, 184}}},
|
||||
{"minecraft:magenta_glazed_terracotta", {BLOCK_OPAQUE, {208, 100, 191}}},
|
||||
{"minecraft:magenta_shulker_box", {BLOCK_OPAQUE, {173, 54, 163}}},
|
||||
{"minecraft:magenta_stained_glass", {BLOCK_OPAQUE, {178, 76, 216}}},
|
||||
{"minecraft:magenta_stained_glass_pane", {BLOCK_OPAQUE, {171, 73, 208}}},
|
||||
{"minecraft:magenta_terracotta", {BLOCK_OPAQUE, {149, 88, 108}}},
|
||||
{"minecraft:magenta_wall_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:magenta_wool", {BLOCK_OPAQUE, {189, 68, 179}}},
|
||||
{"minecraft:magma_block", {BLOCK_OPAQUE, {142, 63, 31}}},
|
||||
{"minecraft:mangrove_button", {0, {0, 0, 0}}},
|
||||
{"minecraft:mangrove_door", {BLOCK_OPAQUE, {112, 48, 46}}},
|
||||
{"minecraft:mangrove_fence", {BLOCK_OPAQUE, {117, 54, 48}}},
|
||||
{"minecraft:mangrove_fence_gate", {BLOCK_OPAQUE, {117, 54, 48}}},
|
||||
{"minecraft:mangrove_leaves", {BLOCK_OPAQUE|BLOCK_FOLIAGE, {129, 128, 128}}},
|
||||
{"minecraft:mangrove_log", {BLOCK_OPAQUE, {102, 48, 42}}},
|
||||
{"minecraft:mangrove_planks", {BLOCK_OPAQUE, {117, 54, 48}}},
|
||||
{"minecraft:mangrove_pressure_plate", {BLOCK_OPAQUE, {117, 54, 48}}},
|
||||
{"minecraft:mangrove_propagule", {BLOCK_OPAQUE, {96, 174, 83}}},
|
||||
{"minecraft:mangrove_roots", {BLOCK_OPAQUE, {74, 59, 38}}},
|
||||
{"minecraft:mangrove_sign", {BLOCK_OPAQUE, {117, 54, 48}}},
|
||||
{"minecraft:mangrove_slab", {BLOCK_OPAQUE, {117, 54, 48}}},
|
||||
{"minecraft:mangrove_stairs", {BLOCK_OPAQUE, {117, 54, 48}}},
|
||||
{"minecraft:mangrove_trapdoor", {BLOCK_OPAQUE, {110, 46, 42}}},
|
||||
{"minecraft:mangrove_wall_sign", {0, {0, 0, 0}}},
|
||||
{"minecraft:mangrove_wood", {BLOCK_OPAQUE, {83, 66, 41}}},
|
||||
{"minecraft:medium_amethyst_bud", {0, {0, 0, 0}}},
|
||||
{"minecraft:melon", {BLOCK_OPAQUE, {111, 144, 30}}},
|
||||
{"minecraft:melon_stem", {BLOCK_OPAQUE|BLOCK_GRASS, {153, 153, 153}}},
|
||||
{"minecraft:moss_block", {BLOCK_OPAQUE, {89, 109, 45}}},
|
||||
{"minecraft:moss_carpet", {BLOCK_OPAQUE, {89, 109, 45}}},
|
||||
{"minecraft:mossy_cobblestone", {BLOCK_OPAQUE, {110, 118, 94}}},
|
||||
{"minecraft:mossy_cobblestone_slab", {BLOCK_OPAQUE, {110, 118, 94}}},
|
||||
{"minecraft:mossy_cobblestone_stairs", {BLOCK_OPAQUE, {110, 118, 94}}},
|
||||
{"minecraft:mossy_cobblestone_wall", {BLOCK_OPAQUE, {110, 118, 94}}},
|
||||
{"minecraft:mossy_stone_brick_slab", {BLOCK_OPAQUE, {115, 121, 105}}},
|
||||
{"minecraft:mossy_stone_brick_stairs", {BLOCK_OPAQUE, {115, 121, 105}}},
|
||||
{"minecraft:mossy_stone_brick_wall", {BLOCK_OPAQUE, {115, 121, 105}}},
|
||||
{"minecraft:mossy_stone_bricks", {BLOCK_OPAQUE, {115, 121, 105}}},
|
||||
{"minecraft:moving_piston", {0, {0, 0, 0}}},
|
||||
{"minecraft:mud", {BLOCK_OPAQUE, {60, 57, 60}}},
|
||||
{"minecraft:mud_brick_slab", {BLOCK_OPAQUE, {137, 103, 79}}},
|
||||
{"minecraft:mud_brick_stairs", {BLOCK_OPAQUE, {137, 103, 79}}},
|
||||
{"minecraft:mud_brick_wall", {BLOCK_OPAQUE, {137, 103, 79}}},
|
||||
{"minecraft:mud_bricks", {BLOCK_OPAQUE, {137, 103, 79}}},
|
||||
{"minecraft:muddy_mangrove_roots", {BLOCK_OPAQUE, {70, 58, 45}}},
|
||||
{"minecraft:mushroom_stem", {BLOCK_OPAQUE, {203, 196, 185}}},
|
||||
{"minecraft:mycelium", {BLOCK_OPAQUE, {111, 98, 101}}},
|
||||
{"minecraft:nether_brick_fence", {BLOCK_OPAQUE, {44, 21, 26}}},
|
||||
{"minecraft:nether_brick_slab", {BLOCK_OPAQUE, {44, 21, 26}}},
|
||||
{"minecraft:nether_brick_stairs", {BLOCK_OPAQUE, {44, 21, 26}}},
|
||||
{"minecraft:nether_brick_wall", {BLOCK_OPAQUE, {44, 21, 26}}},
|
||||
{"minecraft:nether_bricks", {BLOCK_OPAQUE, {44, 21, 26}}},
|
||||
{"minecraft:nether_gold_ore", {BLOCK_OPAQUE, {115, 54, 42}}},
|
||||
{"minecraft:nether_portal", {BLOCK_OPAQUE, {89, 11, 192}}},
|
||||
{"minecraft:nether_quartz_ore", {BLOCK_OPAQUE, {117, 65, 62}}},
|
||||
{"minecraft:nether_sprouts", {BLOCK_OPAQUE, {19, 151, 133}}},
|
||||
{"minecraft:nether_wart", {BLOCK_OPAQUE, {111, 18, 19}}},
|
||||
{"minecraft:nether_wart_block", {BLOCK_OPAQUE, {114, 2, 2}}},
|
||||
{"minecraft:netherite_block", {BLOCK_OPAQUE, {66, 61, 63}}},
|
||||
{"minecraft:netherrack", {BLOCK_OPAQUE, {97, 38, 38}}},
|
||||
{"minecraft:note_block", {BLOCK_OPAQUE, {88, 58, 40}}},
|
||||
{"minecraft:oak_button", {0, {0, 0, 0}}},
|
||||
{"minecraft:oak_door", {BLOCK_OPAQUE, {140, 110, 66}}},
|
||||
{"minecraft:oak_fence", {BLOCK_OPAQUE, {162, 130, 78}}},
|
||||
{"minecraft:oak_fence_gate", {BLOCK_OPAQUE, {162, 130, 78}}},
|
||||
{"minecraft:oak_leaves", {BLOCK_OPAQUE|BLOCK_FOLIAGE, {144, 144, 144}}},
|
||||
{"minecraft:oak_log", {BLOCK_OPAQUE, {151, 121, 73}}},
|
||||
{"minecraft:oak_planks", {BLOCK_OPAQUE, {162, 130, 78}}},
|
||||
{"minecraft:oak_pressure_plate", {BLOCK_OPAQUE, {162, 130, 78}}},
|
||||
{"minecraft:oak_sapling", {BLOCK_OPAQUE, {77, 106, 40}}},
|
||||
{"minecraft:oak_sign", {BLOCK_OPAQUE, {162, 130, 78}}},
|
||||
{"minecraft:oak_slab", {BLOCK_OPAQUE, {162, 130, 78}}},
|
||||
{"minecraft:oak_stairs", {BLOCK_OPAQUE, {162, 130, 78}}},
|
||||
{"minecraft:oak_trapdoor", {BLOCK_OPAQUE, {124, 99, 56}}},
|
||||
{"minecraft:oak_wall_sign", {0, {0, 0, 0}}},
|
||||
{"minecraft:oak_wood", {BLOCK_OPAQUE, {109, 85, 50}}},
|
||||
{"minecraft:observer", {BLOCK_OPAQUE, {98, 98, 98}}},
|
||||
{"minecraft:obsidian", {BLOCK_OPAQUE, {15, 10, 24}}},
|
||||
{"minecraft:ochre_froglight", {BLOCK_OPAQUE, {250, 245, 206}}},
|
||||
{"minecraft:orange_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:orange_bed", {0, {0, 0, 0}}},
|
||||
{"minecraft:orange_candle", {0, {0, 0, 0}}},
|
||||
{"minecraft:orange_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}},
|
||||
{"minecraft:orange_carpet", {BLOCK_OPAQUE, {240, 118, 19}}},
|
||||
{"minecraft:orange_concrete", {BLOCK_OPAQUE, {224, 97, 0}}},
|
||||
{"minecraft:orange_concrete_powder", {BLOCK_OPAQUE, {227, 131, 31}}},
|
||||
{"minecraft:orange_glazed_terracotta", {BLOCK_OPAQUE, {154, 147, 91}}},
|
||||
{"minecraft:orange_shulker_box", {BLOCK_OPAQUE, {234, 106, 8}}},
|
||||
{"minecraft:orange_stained_glass", {BLOCK_OPAQUE, {216, 127, 51}}},
|
||||
{"minecraft:orange_stained_glass_pane", {BLOCK_OPAQUE, {208, 122, 48}}},
|
||||
{"minecraft:orange_terracotta", {BLOCK_OPAQUE, {161, 83, 37}}},
|
||||
{"minecraft:orange_tulip", {0, {0, 0, 0}}},
|
||||
{"minecraft:orange_wall_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:orange_wool", {BLOCK_OPAQUE, {240, 118, 19}}},
|
||||
{"minecraft:oxeye_daisy", {0, {0, 0, 0}}},
|
||||
{"minecraft:oxidized_copper", {BLOCK_OPAQUE, {82, 162, 132}}},
|
||||
{"minecraft:oxidized_cut_copper", {BLOCK_OPAQUE, {79, 153, 126}}},
|
||||
{"minecraft:oxidized_cut_copper_slab", {BLOCK_OPAQUE, {79, 153, 126}}},
|
||||
{"minecraft:oxidized_cut_copper_stairs", {BLOCK_OPAQUE, {79, 153, 126}}},
|
||||
{"minecraft:packed_ice", {BLOCK_OPAQUE, {141, 180, 250}}},
|
||||
{"minecraft:packed_mud", {BLOCK_OPAQUE, {142, 106, 79}}},
|
||||
{"minecraft:pearlescent_froglight", {BLOCK_OPAQUE, {245, 240, 239}}},
|
||||
{"minecraft:peony", {BLOCK_OPAQUE, {129, 126, 139}}},
|
||||
{"minecraft:petrified_oak_slab", {BLOCK_OPAQUE, {162, 130, 78}}},
|
||||
{"minecraft:pink_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:pink_bed", {0, {0, 0, 0}}},
|
||||
{"minecraft:pink_candle", {0, {0, 0, 0}}},
|
||||
{"minecraft:pink_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}},
|
||||
{"minecraft:pink_carpet", {BLOCK_OPAQUE, {237, 141, 172}}},
|
||||
{"minecraft:pink_concrete", {BLOCK_OPAQUE, {213, 101, 142}}},
|
||||
{"minecraft:pink_concrete_powder", {BLOCK_OPAQUE, {228, 153, 181}}},
|
||||
{"minecraft:pink_glazed_terracotta", {BLOCK_OPAQUE, {235, 154, 181}}},
|
||||
{"minecraft:pink_shulker_box", {BLOCK_OPAQUE, {230, 121, 157}}},
|
||||
{"minecraft:pink_stained_glass", {BLOCK_OPAQUE, {242, 127, 165}}},
|
||||
{"minecraft:pink_stained_glass_pane", {BLOCK_OPAQUE, {233, 122, 159}}},
|
||||
{"minecraft:pink_terracotta", {BLOCK_OPAQUE, {161, 78, 78}}},
|
||||
{"minecraft:pink_tulip", {0, {0, 0, 0}}},
|
||||
{"minecraft:pink_wall_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:pink_wool", {BLOCK_OPAQUE, {237, 141, 172}}},
|
||||
{"minecraft:piston", {BLOCK_OPAQUE, {109, 104, 96}}},
|
||||
{"minecraft:piston_head", {BLOCK_OPAQUE, {153, 127, 85}}},
|
||||
{"minecraft:player_head", {0, {0, 0, 0}}},
|
||||
{"minecraft:player_wall_head", {0, {0, 0, 0}}},
|
||||
{"minecraft:podzol", {BLOCK_OPAQUE, {91, 63, 24}}},
|
||||
{"minecraft:pointed_dripstone", {BLOCK_OPAQUE, {129, 102, 89}}},
|
||||
{"minecraft:polished_andesite", {BLOCK_OPAQUE, {132, 134, 133}}},
|
||||
{"minecraft:polished_andesite_slab", {BLOCK_OPAQUE, {132, 134, 133}}},
|
||||
{"minecraft:polished_andesite_stairs", {BLOCK_OPAQUE, {132, 134, 133}}},
|
||||
{"minecraft:polished_basalt", {BLOCK_OPAQUE, {99, 98, 100}}},
|
||||
{"minecraft:polished_blackstone", {BLOCK_OPAQUE, {53, 48, 56}}},
|
||||
{"minecraft:polished_blackstone_brick_slab", {BLOCK_OPAQUE, {48, 42, 49}}},
|
||||
{"minecraft:polished_blackstone_brick_stairs", {BLOCK_OPAQUE, {48, 42, 49}}},
|
||||
{"minecraft:polished_blackstone_brick_wall", {BLOCK_OPAQUE, {48, 42, 49}}},
|
||||
{"minecraft:polished_blackstone_bricks", {BLOCK_OPAQUE, {48, 42, 49}}},
|
||||
{"minecraft:polished_blackstone_button", {0, {0, 0, 0}}},
|
||||
{"minecraft:polished_blackstone_pressure_plate", {BLOCK_OPAQUE, {53, 48, 56}}},
|
||||
{"minecraft:polished_blackstone_slab", {BLOCK_OPAQUE, {53, 48, 56}}},
|
||||
{"minecraft:polished_blackstone_stairs", {BLOCK_OPAQUE, {53, 48, 56}}},
|
||||
{"minecraft:polished_blackstone_wall", {BLOCK_OPAQUE, {53, 48, 56}}},
|
||||
{"minecraft:polished_deepslate", {BLOCK_OPAQUE, {72, 72, 73}}},
|
||||
{"minecraft:polished_deepslate_slab", {BLOCK_OPAQUE, {72, 72, 73}}},
|
||||
{"minecraft:polished_deepslate_stairs", {BLOCK_OPAQUE, {72, 72, 73}}},
|
||||
{"minecraft:polished_deepslate_wall", {BLOCK_OPAQUE, {72, 72, 73}}},
|
||||
{"minecraft:polished_diorite", {BLOCK_OPAQUE, {192, 193, 194}}},
|
||||
{"minecraft:polished_diorite_slab", {BLOCK_OPAQUE, {192, 193, 194}}},
|
||||
{"minecraft:polished_diorite_stairs", {BLOCK_OPAQUE, {192, 193, 194}}},
|
||||
{"minecraft:polished_granite", {BLOCK_OPAQUE, {154, 106, 89}}},
|
||||
{"minecraft:polished_granite_slab", {BLOCK_OPAQUE, {154, 106, 89}}},
|
||||
{"minecraft:polished_granite_stairs", {BLOCK_OPAQUE, {154, 106, 89}}},
|
||||
{"minecraft:poppy", {0, {0, 0, 0}}},
|
||||
{"minecraft:potatoes", {BLOCK_OPAQUE, {84, 135, 47}}},
|
||||
{"minecraft:potted_acacia_sapling", {BLOCK_OPAQUE, {118, 117, 23}}},
|
||||
{"minecraft:potted_allium", {BLOCK_OPAQUE, {158, 137, 183}}},
|
||||
{"minecraft:potted_azalea_bush", {BLOCK_OPAQUE, {101, 124, 47}}},
|
||||
{"minecraft:potted_azure_bluet", {BLOCK_OPAQUE, {169, 204, 127}}},
|
||||
{"minecraft:potted_bamboo", {BLOCK_OPAQUE, {93, 144, 19}}},
|
||||
{"minecraft:potted_birch_sapling", {BLOCK_OPAQUE, {127, 160, 79}}},
|
||||
{"minecraft:potted_blue_orchid", {BLOCK_OPAQUE, {47, 162, 168}}},
|
||||
{"minecraft:potted_brown_mushroom", {BLOCK_OPAQUE, {153, 116, 92}}},
|
||||
{"minecraft:potted_cactus", {BLOCK_OPAQUE, {85, 127, 43}}},
|
||||
{"minecraft:potted_cornflower", {BLOCK_OPAQUE, {79, 121, 146}}},
|
||||
{"minecraft:potted_crimson_fungus", {BLOCK_OPAQUE, {141, 44, 29}}},
|
||||
{"minecraft:potted_crimson_roots", {BLOCK_OPAQUE, {127, 8, 41}}},
|
||||
{"minecraft:potted_dandelion", {BLOCK_OPAQUE, {147, 172, 43}}},
|
||||
{"minecraft:potted_dark_oak_sapling", {BLOCK_OPAQUE, {61, 90, 30}}},
|
||||
{"minecraft:potted_dead_bush", {BLOCK_OPAQUE, {107, 78, 40}}},
|
||||
{"minecraft:potted_fern", {BLOCK_OPAQUE|BLOCK_GRASS, {124, 124, 124}}},
|
||||
{"minecraft:potted_flowering_azalea_bush", {BLOCK_OPAQUE, {112, 121, 64}}},
|
||||
{"minecraft:potted_jungle_sapling", {BLOCK_OPAQUE, {47, 81, 16}}},
|
||||
{"minecraft:potted_lily_of_the_valley", {BLOCK_OPAQUE, {123, 174, 95}}},
|
||||
{"minecraft:potted_mangrove_propagule", {BLOCK_OPAQUE, {96, 174, 83}}},
|
||||
{"minecraft:potted_oak_sapling", {BLOCK_OPAQUE, {77, 106, 40}}},
|
||||
{"minecraft:potted_orange_tulip", {BLOCK_OPAQUE, {93, 142, 30}}},
|
||||
{"minecraft:potted_oxeye_daisy", {BLOCK_OPAQUE, {179, 202, 143}}},
|
||||
{"minecraft:potted_pink_tulip", {BLOCK_OPAQUE, {99, 157, 78}}},
|
||||
{"minecraft:potted_poppy", {BLOCK_OPAQUE, {128, 64, 37}}},
|
||||
{"minecraft:potted_red_mushroom", {BLOCK_OPAQUE, {216, 75, 67}}},
|
||||
{"minecraft:potted_red_tulip", {BLOCK_OPAQUE, {89, 128, 32}}},
|
||||
{"minecraft:potted_spruce_sapling", {BLOCK_OPAQUE, {44, 60, 36}}},
|
||||
{"minecraft:potted_warped_fungus", {BLOCK_OPAQUE, {74, 109, 87}}},
|
||||
{"minecraft:potted_warped_roots", {BLOCK_OPAQUE, {20, 136, 123}}},
|
||||
{"minecraft:potted_white_tulip", {BLOCK_OPAQUE, {93, 164, 71}}},
|
||||
{"minecraft:potted_wither_rose", {BLOCK_OPAQUE, {41, 44, 23}}},
|
||||
{"minecraft:powder_snow", {BLOCK_OPAQUE, {248, 253, 253}}},
|
||||
{"minecraft:powder_snow_cauldron", {BLOCK_OPAQUE, {73, 72, 74}}},
|
||||
{"minecraft:powered_rail", {BLOCK_OPAQUE, {137, 109, 74}}},
|
||||
{"minecraft:prismarine", {BLOCK_OPAQUE, {99, 156, 151}}},
|
||||
{"minecraft:prismarine_brick_slab", {BLOCK_OPAQUE, {99, 171, 158}}},
|
||||
{"minecraft:prismarine_brick_stairs", {BLOCK_OPAQUE, {99, 171, 158}}},
|
||||
{"minecraft:prismarine_bricks", {BLOCK_OPAQUE, {99, 171, 158}}},
|
||||
{"minecraft:prismarine_slab", {BLOCK_OPAQUE, {99, 156, 151}}},
|
||||
{"minecraft:prismarine_stairs", {BLOCK_OPAQUE, {99, 156, 151}}},
|
||||
{"minecraft:prismarine_wall", {BLOCK_OPAQUE, {99, 156, 151}}},
|
||||
{"minecraft:pumpkin", {BLOCK_OPAQUE, {198, 118, 24}}},
|
||||
{"minecraft:pumpkin_stem", {BLOCK_OPAQUE|BLOCK_GRASS, {154, 154, 154}}},
|
||||
{"minecraft:purple_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:purple_bed", {0, {0, 0, 0}}},
|
||||
{"minecraft:purple_candle", {0, {0, 0, 0}}},
|
||||
{"minecraft:purple_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}},
|
||||
{"minecraft:purple_carpet", {BLOCK_OPAQUE, {121, 42, 172}}},
|
||||
{"minecraft:purple_concrete", {BLOCK_OPAQUE, {100, 31, 156}}},
|
||||
{"minecraft:purple_concrete_powder", {BLOCK_OPAQUE, {131, 55, 177}}},
|
||||
{"minecraft:purple_glazed_terracotta", {BLOCK_OPAQUE, {109, 48, 152}}},
|
||||
{"minecraft:purple_shulker_box", {BLOCK_OPAQUE, {103, 32, 156}}},
|
||||
{"minecraft:purple_stained_glass", {BLOCK_OPAQUE, {127, 63, 178}}},
|
||||
{"minecraft:purple_stained_glass_pane", {BLOCK_OPAQUE, {122, 61, 171}}},
|
||||
{"minecraft:purple_terracotta", {BLOCK_OPAQUE, {118, 70, 86}}},
|
||||
{"minecraft:purple_wall_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:purple_wool", {BLOCK_OPAQUE, {121, 42, 172}}},
|
||||
{"minecraft:purpur_block", {BLOCK_OPAQUE, {169, 125, 169}}},
|
||||
{"minecraft:purpur_pillar", {BLOCK_OPAQUE, {171, 129, 171}}},
|
||||
{"minecraft:purpur_slab", {BLOCK_OPAQUE, {169, 125, 169}}},
|
||||
{"minecraft:purpur_stairs", {BLOCK_OPAQUE, {169, 125, 169}}},
|
||||
{"minecraft:quartz_block", {BLOCK_OPAQUE, {235, 229, 222}}},
|
||||
{"minecraft:quartz_bricks", {BLOCK_OPAQUE, {234, 229, 221}}},
|
||||
{"minecraft:quartz_pillar", {BLOCK_OPAQUE, {235, 230, 224}}},
|
||||
{"minecraft:quartz_slab", {BLOCK_OPAQUE, {235, 229, 222}}},
|
||||
{"minecraft:quartz_stairs", {BLOCK_OPAQUE, {235, 229, 222}}},
|
||||
{"minecraft:rail", {BLOCK_OPAQUE, {125, 111, 88}}},
|
||||
{"minecraft:raw_copper_block", {BLOCK_OPAQUE, {154, 105, 79}}},
|
||||
{"minecraft:raw_gold_block", {BLOCK_OPAQUE, {221, 169, 46}}},
|
||||
{"minecraft:raw_iron_block", {BLOCK_OPAQUE, {166, 135, 107}}},
|
||||
{"minecraft:red_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:red_bed", {0, {0, 0, 0}}},
|
||||
{"minecraft:red_candle", {0, {0, 0, 0}}},
|
||||
{"minecraft:red_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}},
|
||||
{"minecraft:red_carpet", {BLOCK_OPAQUE, {160, 39, 34}}},
|
||||
{"minecraft:red_concrete", {BLOCK_OPAQUE, {142, 32, 32}}},
|
||||
{"minecraft:red_concrete_powder", {BLOCK_OPAQUE, {168, 54, 50}}},
|
||||
{"minecraft:red_glazed_terracotta", {BLOCK_OPAQUE, {181, 59, 53}}},
|
||||
{"minecraft:red_mushroom", {0, {0, 0, 0}}},
|
||||
{"minecraft:red_mushroom_block", {BLOCK_OPAQUE, {200, 46, 45}}},
|
||||
{"minecraft:red_nether_brick_slab", {BLOCK_OPAQUE, {69, 7, 9}}},
|
||||
{"minecraft:red_nether_brick_stairs", {BLOCK_OPAQUE, {69, 7, 9}}},
|
||||
{"minecraft:red_nether_brick_wall", {BLOCK_OPAQUE, {69, 7, 9}}},
|
||||
{"minecraft:red_nether_bricks", {BLOCK_OPAQUE, {69, 7, 9}}},
|
||||
{"minecraft:red_sand", {BLOCK_OPAQUE, {190, 102, 33}}},
|
||||
{"minecraft:red_sandstone", {BLOCK_OPAQUE, {181, 97, 31}}},
|
||||
{"minecraft:red_sandstone_slab", {BLOCK_OPAQUE, {181, 97, 31}}},
|
||||
{"minecraft:red_sandstone_stairs", {BLOCK_OPAQUE, {181, 97, 31}}},
|
||||
{"minecraft:red_sandstone_wall", {BLOCK_OPAQUE, {181, 97, 31}}},
|
||||
{"minecraft:red_shulker_box", {BLOCK_OPAQUE, {140, 31, 30}}},
|
||||
{"minecraft:red_stained_glass", {BLOCK_OPAQUE, {153, 51, 51}}},
|
||||
{"minecraft:red_stained_glass_pane", {BLOCK_OPAQUE, {147, 48, 48}}},
|
||||
{"minecraft:red_terracotta", {BLOCK_OPAQUE, {143, 61, 46}}},
|
||||
{"minecraft:red_tulip", {0, {0, 0, 0}}},
|
||||
{"minecraft:red_wall_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:red_wool", {BLOCK_OPAQUE, {160, 39, 34}}},
|
||||
{"minecraft:redstone_block", {BLOCK_OPAQUE, {175, 24, 5}}},
|
||||
{"minecraft:redstone_lamp", {BLOCK_OPAQUE, {95, 54, 30}}},
|
||||
{"minecraft:redstone_ore", {BLOCK_OPAQUE, {140, 109, 109}}},
|
||||
{"minecraft:redstone_torch", {0, {0, 0, 0}}},
|
||||
{"minecraft:redstone_wall_torch", {0, {0, 0, 0}}},
|
||||
{"minecraft:redstone_wire", {BLOCK_OPAQUE, {175, 24, 5}}},
|
||||
{"minecraft:reinforced_deepslate", {BLOCK_OPAQUE, {80, 82, 78}}},
|
||||
{"minecraft:repeater", {BLOCK_OPAQUE, {160, 157, 156}}},
|
||||
{"minecraft:repeating_command_block", {BLOCK_OPAQUE, {129, 111, 176}}},
|
||||
{"minecraft:respawn_anchor", {BLOCK_OPAQUE, {75, 26, 144}}},
|
||||
{"minecraft:rooted_dirt", {BLOCK_OPAQUE, {144, 103, 76}}},
|
||||
{"minecraft:rose_bush", {BLOCK_OPAQUE, {131, 66, 37}}},
|
||||
{"minecraft:sand", {BLOCK_OPAQUE, {219, 207, 163}}},
|
||||
{"minecraft:sandstone", {BLOCK_OPAQUE, {223, 214, 170}}},
|
||||
{"minecraft:sandstone_slab", {BLOCK_OPAQUE, {223, 214, 170}}},
|
||||
{"minecraft:sandstone_stairs", {BLOCK_OPAQUE, {223, 214, 170}}},
|
||||
{"minecraft:sandstone_wall", {BLOCK_OPAQUE, {223, 214, 170}}},
|
||||
{"minecraft:scaffolding", {BLOCK_OPAQUE, {174, 134, 80}}},
|
||||
{"minecraft:sculk", {BLOCK_OPAQUE, {12, 29, 36}}},
|
||||
{"minecraft:sculk_catalyst", {BLOCK_OPAQUE, {15, 31, 38}}},
|
||||
{"minecraft:sculk_sensor", {BLOCK_OPAQUE, {7, 70, 84}}},
|
||||
{"minecraft:sculk_shrieker", {BLOCK_OPAQUE, {198, 205, 169}}},
|
||||
{"minecraft:sculk_vein", {BLOCK_OPAQUE, {7, 48, 57}}},
|
||||
{"minecraft:sea_lantern", {BLOCK_OPAQUE, {172, 199, 190}}},
|
||||
{"minecraft:sea_pickle", {BLOCK_OPAQUE, {90, 97, 39}}},
|
||||
{"minecraft:seagrass", {0, {0, 0, 0}}},
|
||||
{"minecraft:shroomlight", {BLOCK_OPAQUE, {240, 146, 70}}},
|
||||
{"minecraft:shulker_box", {BLOCK_OPAQUE, {139, 96, 139}}},
|
||||
{"minecraft:sign", {BLOCK_OPAQUE, {162, 130, 78}}},
|
||||
{"minecraft:skeleton_skull", {0, {0, 0, 0}}},
|
||||
{"minecraft:skeleton_wall_skull", {0, {0, 0, 0}}},
|
||||
{"minecraft:slime_block", {BLOCK_OPAQUE, {111, 192, 91}}},
|
||||
{"minecraft:small_amethyst_bud", {0, {0, 0, 0}}},
|
||||
{"minecraft:small_dripleaf", {0, {0, 0, 0}}},
|
||||
{"minecraft:smithing_table", {BLOCK_OPAQUE, {57, 58, 70}}},
|
||||
{"minecraft:smoker", {BLOCK_OPAQUE, {85, 83, 81}}},
|
||||
{"minecraft:smooth_basalt", {BLOCK_OPAQUE, {72, 72, 78}}},
|
||||
{"minecraft:smooth_quartz", {BLOCK_OPAQUE, {235, 229, 222}}},
|
||||
{"minecraft:smooth_quartz_slab", {BLOCK_OPAQUE, {235, 229, 222}}},
|
||||
{"minecraft:smooth_quartz_stairs", {BLOCK_OPAQUE, {235, 229, 222}}},
|
||||
{"minecraft:smooth_red_sandstone", {BLOCK_OPAQUE, {181, 97, 31}}},
|
||||
{"minecraft:smooth_red_sandstone_slab", {BLOCK_OPAQUE, {181, 97, 31}}},
|
||||
{"minecraft:smooth_red_sandstone_stairs", {BLOCK_OPAQUE, {181, 97, 31}}},
|
||||
{"minecraft:smooth_sandstone", {BLOCK_OPAQUE, {223, 214, 170}}},
|
||||
{"minecraft:smooth_sandstone_slab", {BLOCK_OPAQUE, {223, 214, 170}}},
|
||||
{"minecraft:smooth_sandstone_stairs", {BLOCK_OPAQUE, {223, 214, 170}}},
|
||||
{"minecraft:smooth_stone", {BLOCK_OPAQUE, {158, 158, 158}}},
|
||||
{"minecraft:smooth_stone_slab", {BLOCK_OPAQUE, {158, 158, 158}}},
|
||||
{"minecraft:snow", {BLOCK_OPAQUE, {249, 254, 254}}},
|
||||
{"minecraft:snow_block", {BLOCK_OPAQUE, {249, 254, 254}}},
|
||||
{"minecraft:soul_campfire", {BLOCK_OPAQUE, {80, 204, 208}}},
|
||||
{"minecraft:soul_fire", {BLOCK_OPAQUE, {51, 192, 197}}},
|
||||
{"minecraft:soul_lantern", {BLOCK_OPAQUE, {71, 99, 114}}},
|
||||
{"minecraft:soul_sand", {BLOCK_OPAQUE, {81, 62, 50}}},
|
||||
{"minecraft:soul_soil", {BLOCK_OPAQUE, {75, 57, 46}}},
|
||||
{"minecraft:soul_torch", {0, {0, 0, 0}}},
|
||||
{"minecraft:soul_wall_torch", {0, {0, 0, 0}}},
|
||||
{"minecraft:spawner", {BLOCK_OPAQUE, {36, 46, 62}}},
|
||||
{"minecraft:sponge", {BLOCK_OPAQUE, {195, 192, 74}}},
|
||||
{"minecraft:spore_blossom", {BLOCK_OPAQUE, {206, 96, 158}}},
|
||||
{"minecraft:spruce_button", {0, {0, 0, 0}}},
|
||||
{"minecraft:spruce_door", {BLOCK_OPAQUE, {106, 80, 48}}},
|
||||
{"minecraft:spruce_fence", {BLOCK_OPAQUE, {114, 84, 48}}},
|
||||
{"minecraft:spruce_fence_gate", {BLOCK_OPAQUE, {114, 84, 48}}},
|
||||
{"minecraft:spruce_leaves", {BLOCK_OPAQUE|BLOCK_SPRUCE, {126, 126, 126}}},
|
||||
{"minecraft:spruce_log", {BLOCK_OPAQUE, {108, 80, 46}}},
|
||||
{"minecraft:spruce_planks", {BLOCK_OPAQUE, {114, 84, 48}}},
|
||||
{"minecraft:spruce_pressure_plate", {BLOCK_OPAQUE, {114, 84, 48}}},
|
||||
{"minecraft:spruce_sapling", {BLOCK_OPAQUE, {44, 60, 36}}},
|
||||
{"minecraft:spruce_sign", {BLOCK_OPAQUE, {114, 84, 48}}},
|
||||
{"minecraft:spruce_slab", {BLOCK_OPAQUE, {114, 84, 48}}},
|
||||
{"minecraft:spruce_stairs", {BLOCK_OPAQUE, {114, 84, 48}}},
|
||||
{"minecraft:spruce_trapdoor", {BLOCK_OPAQUE, {103, 79, 47}}},
|
||||
{"minecraft:spruce_wall_sign", {0, {0, 0, 0}}},
|
||||
{"minecraft:spruce_wood", {BLOCK_OPAQUE, {58, 37, 16}}},
|
||||
{"minecraft:sticky_piston", {BLOCK_OPAQUE, {109, 104, 96}}},
|
||||
{"minecraft:stone", {BLOCK_OPAQUE, {125, 125, 125}}},
|
||||
{"minecraft:stone_brick_slab", {BLOCK_OPAQUE, {122, 121, 122}}},
|
||||
{"minecraft:stone_brick_stairs", {BLOCK_OPAQUE, {122, 121, 122}}},
|
||||
{"minecraft:stone_brick_wall", {BLOCK_OPAQUE, {122, 121, 122}}},
|
||||
{"minecraft:stone_bricks", {BLOCK_OPAQUE, {122, 121, 122}}},
|
||||
{"minecraft:stone_button", {0, {0, 0, 0}}},
|
||||
{"minecraft:stone_pressure_plate", {BLOCK_OPAQUE, {125, 125, 125}}},
|
||||
{"minecraft:stone_slab", {BLOCK_OPAQUE, {125, 125, 125}}},
|
||||
{"minecraft:stone_stairs", {BLOCK_OPAQUE, {125, 125, 125}}},
|
||||
{"minecraft:stonecutter", {BLOCK_OPAQUE, {123, 118, 111}}},
|
||||
{"minecraft:stripped_acacia_log", {BLOCK_OPAQUE, {166, 91, 51}}},
|
||||
{"minecraft:stripped_acacia_wood", {BLOCK_OPAQUE, {174, 92, 59}}},
|
||||
{"minecraft:stripped_birch_log", {BLOCK_OPAQUE, {191, 171, 116}}},
|
||||
{"minecraft:stripped_birch_wood", {BLOCK_OPAQUE, {196, 176, 118}}},
|
||||
{"minecraft:stripped_crimson_hyphae", {BLOCK_OPAQUE, {137, 57, 90}}},
|
||||
{"minecraft:stripped_crimson_stem", {BLOCK_OPAQUE, {121, 56, 82}}},
|
||||
{"minecraft:stripped_dark_oak_log", {BLOCK_OPAQUE, {65, 44, 22}}},
|
||||
{"minecraft:stripped_dark_oak_wood", {BLOCK_OPAQUE, {72, 56, 36}}},
|
||||
{"minecraft:stripped_jungle_log", {BLOCK_OPAQUE, {165, 122, 81}}},
|
||||
{"minecraft:stripped_jungle_wood", {BLOCK_OPAQUE, {171, 132, 84}}},
|
||||
{"minecraft:stripped_mangrove_log", {BLOCK_OPAQUE, {109, 43, 43}}},
|
||||
{"minecraft:stripped_mangrove_wood", {BLOCK_OPAQUE, {119, 54, 47}}},
|
||||
{"minecraft:stripped_oak_log", {BLOCK_OPAQUE, {160, 129, 77}}},
|
||||
{"minecraft:stripped_oak_wood", {BLOCK_OPAQUE, {177, 144, 86}}},
|
||||
{"minecraft:stripped_spruce_log", {BLOCK_OPAQUE, {105, 80, 46}}},
|
||||
{"minecraft:stripped_spruce_wood", {BLOCK_OPAQUE, {115, 89, 52}}},
|
||||
{"minecraft:stripped_warped_hyphae", {BLOCK_OPAQUE, {57, 150, 147}}},
|
||||
{"minecraft:stripped_warped_stem", {BLOCK_OPAQUE, {52, 128, 124}}},
|
||||
{"minecraft:structure_block", {BLOCK_OPAQUE, {88, 74, 90}}},
|
||||
{"minecraft:structure_void", {0, {0, 0, 0}}},
|
||||
{"minecraft:sugar_cane", {BLOCK_OPAQUE, {148, 192, 101}}},
|
||||
{"minecraft:sunflower", {BLOCK_OPAQUE, {246, 196, 54}}},
|
||||
{"minecraft:sweet_berry_bush", {BLOCK_OPAQUE, {68, 77, 50}}},
|
||||
{"minecraft:tall_grass", {BLOCK_OPAQUE|BLOCK_GRASS, {151, 149, 151}}},
|
||||
{"minecraft:tall_seagrass", {BLOCK_OPAQUE, {59, 139, 14}}},
|
||||
{"minecraft:target", {BLOCK_OPAQUE, {226, 170, 157}}},
|
||||
{"minecraft:terracotta", {BLOCK_OPAQUE, {152, 94, 67}}},
|
||||
{"minecraft:tinted_glass", {BLOCK_OPAQUE, {44, 38, 46}}},
|
||||
{"minecraft:tnt", {BLOCK_OPAQUE, {142, 62, 53}}},
|
||||
{"minecraft:torch", {0, {0, 0, 0}}},
|
||||
{"minecraft:trapped_chest", {BLOCK_OPAQUE, {162, 130, 78}}},
|
||||
{"minecraft:tripwire", {0, {0, 0, 0}}},
|
||||
{"minecraft:tripwire_hook", {0, {0, 0, 0}}},
|
||||
{"minecraft:tube_coral", {0, {0, 0, 0}}},
|
||||
{"minecraft:tube_coral_block", {BLOCK_OPAQUE, {49, 87, 206}}},
|
||||
{"minecraft:tube_coral_fan", {0, {0, 0, 0}}},
|
||||
{"minecraft:tube_coral_wall_fan", {0, {0, 0, 0}}},
|
||||
{"minecraft:tuff", {BLOCK_OPAQUE, {108, 109, 102}}},
|
||||
{"minecraft:turtle_egg", {BLOCK_OPAQUE, {228, 226, 191}}},
|
||||
{"minecraft:twisting_vines", {BLOCK_OPAQUE, {20, 143, 124}}},
|
||||
{"minecraft:twisting_vines_plant", {BLOCK_OPAQUE, {20, 135, 122}}},
|
||||
{"minecraft:verdant_froglight", {BLOCK_OPAQUE, {229, 244, 228}}},
|
||||
{"minecraft:vine", {BLOCK_OPAQUE|BLOCK_GRASS, {116, 116, 116}}},
|
||||
{"minecraft:void_air", {0, {0, 0, 0}}},
|
||||
{"minecraft:wall_sign", {0, {0, 0, 0}}},
|
||||
{"minecraft:wall_torch", {0, {0, 0, 0}}},
|
||||
{"minecraft:warped_button", {0, {0, 0, 0}}},
|
||||
{"minecraft:warped_door", {BLOCK_OPAQUE, {44, 126, 120}}},
|
||||
{"minecraft:warped_fence", {BLOCK_OPAQUE, {43, 104, 99}}},
|
||||
{"minecraft:warped_fence_gate", {BLOCK_OPAQUE, {43, 104, 99}}},
|
||||
{"minecraft:warped_fungus", {0, {0, 0, 0}}},
|
||||
{"minecraft:warped_hyphae", {BLOCK_OPAQUE, {58, 58, 77}}},
|
||||
{"minecraft:warped_nylium", {BLOCK_OPAQUE, {43, 114, 101}}},
|
||||
{"minecraft:warped_planks", {BLOCK_OPAQUE, {43, 104, 99}}},
|
||||
{"minecraft:warped_pressure_plate", {BLOCK_OPAQUE, {43, 104, 99}}},
|
||||
{"minecraft:warped_roots", {BLOCK_OPAQUE, {20, 138, 124}}},
|
||||
{"minecraft:warped_sign", {BLOCK_OPAQUE, {43, 104, 99}}},
|
||||
{"minecraft:warped_slab", {BLOCK_OPAQUE, {43, 104, 99}}},
|
||||
{"minecraft:warped_stairs", {BLOCK_OPAQUE, {43, 104, 99}}},
|
||||
{"minecraft:warped_stem", {BLOCK_OPAQUE, {53, 109, 110}}},
|
||||
{"minecraft:warped_trapdoor", {BLOCK_OPAQUE, {47, 119, 111}}},
|
||||
{"minecraft:warped_wall_sign", {0, {0, 0, 0}}},
|
||||
{"minecraft:warped_wart_block", {BLOCK_OPAQUE, {22, 119, 121}}},
|
||||
{"minecraft:water", {BLOCK_OPAQUE|BLOCK_WATER, {177, 177, 177}}},
|
||||
{"minecraft:water_cauldron", {BLOCK_OPAQUE, {73, 72, 74}}},
|
||||
{"minecraft:waxed_copper_block", {BLOCK_OPAQUE, {192, 107, 79}}},
|
||||
{"minecraft:waxed_cut_copper", {BLOCK_OPAQUE, {191, 106, 80}}},
|
||||
{"minecraft:waxed_cut_copper_slab", {BLOCK_OPAQUE, {191, 106, 80}}},
|
||||
{"minecraft:waxed_cut_copper_stairs", {BLOCK_OPAQUE, {191, 106, 80}}},
|
||||
{"minecraft:waxed_exposed_copper", {BLOCK_OPAQUE, {161, 125, 103}}},
|
||||
{"minecraft:waxed_exposed_cut_copper", {BLOCK_OPAQUE, {154, 121, 101}}},
|
||||
{"minecraft:waxed_exposed_cut_copper_slab", {BLOCK_OPAQUE, {154, 121, 101}}},
|
||||
{"minecraft:waxed_exposed_cut_copper_stairs", {BLOCK_OPAQUE, {154, 121, 101}}},
|
||||
{"minecraft:waxed_oxidized_copper", {BLOCK_OPAQUE, {82, 162, 132}}},
|
||||
{"minecraft:waxed_oxidized_cut_copper", {BLOCK_OPAQUE, {79, 153, 126}}},
|
||||
{"minecraft:waxed_oxidized_cut_copper_slab", {BLOCK_OPAQUE, {79, 153, 126}}},
|
||||
{"minecraft:waxed_oxidized_cut_copper_stairs", {BLOCK_OPAQUE, {79, 153, 126}}},
|
||||
{"minecraft:waxed_weathered_copper", {BLOCK_OPAQUE, {108, 153, 110}}},
|
||||
{"minecraft:waxed_weathered_cut_copper", {BLOCK_OPAQUE, {109, 145, 107}}},
|
||||
{"minecraft:waxed_weathered_cut_copper_slab", {BLOCK_OPAQUE, {109, 145, 107}}},
|
||||
{"minecraft:waxed_weathered_cut_copper_stairs", {BLOCK_OPAQUE, {109, 145, 107}}},
|
||||
{"minecraft:weathered_copper", {BLOCK_OPAQUE, {108, 153, 110}}},
|
||||
{"minecraft:weathered_cut_copper", {BLOCK_OPAQUE, {109, 145, 107}}},
|
||||
{"minecraft:weathered_cut_copper_slab", {BLOCK_OPAQUE, {109, 145, 107}}},
|
||||
{"minecraft:weathered_cut_copper_stairs", {BLOCK_OPAQUE, {109, 145, 107}}},
|
||||
{"minecraft:weeping_vines", {BLOCK_OPAQUE, {104, 1, 0}}},
|
||||
{"minecraft:weeping_vines_plant", {BLOCK_OPAQUE, {132, 16, 12}}},
|
||||
{"minecraft:wet_sponge", {BLOCK_OPAQUE, {171, 181, 70}}},
|
||||
{"minecraft:wheat", {BLOCK_OPAQUE, {166, 151, 73}}},
|
||||
{"minecraft:white_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:white_bed", {0, {0, 0, 0}}},
|
||||
{"minecraft:white_candle", {0, {0, 0, 0}}},
|
||||
{"minecraft:white_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}},
|
||||
{"minecraft:white_carpet", {BLOCK_OPAQUE, {233, 236, 236}}},
|
||||
{"minecraft:white_concrete", {BLOCK_OPAQUE, {207, 213, 214}}},
|
||||
{"minecraft:white_concrete_powder", {BLOCK_OPAQUE, {225, 227, 227}}},
|
||||
{"minecraft:white_glazed_terracotta", {BLOCK_OPAQUE, {188, 212, 202}}},
|
||||
{"minecraft:white_shulker_box", {BLOCK_OPAQUE, {215, 220, 221}}},
|
||||
{"minecraft:white_stained_glass", {BLOCK_OPAQUE, {255, 255, 255}}},
|
||||
{"minecraft:white_stained_glass_pane", {BLOCK_OPAQUE, {246, 246, 246}}},
|
||||
{"minecraft:white_terracotta", {BLOCK_OPAQUE, {209, 178, 161}}},
|
||||
{"minecraft:white_tulip", {0, {0, 0, 0}}},
|
||||
{"minecraft:white_wall_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:white_wool", {BLOCK_OPAQUE, {233, 236, 236}}},
|
||||
{"minecraft:wither_rose", {0, {0, 0, 0}}},
|
||||
{"minecraft:wither_skeleton_skull", {0, {0, 0, 0}}},
|
||||
{"minecraft:wither_skeleton_wall_skull", {0, {0, 0, 0}}},
|
||||
{"minecraft:yellow_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:yellow_bed", {0, {0, 0, 0}}},
|
||||
{"minecraft:yellow_candle", {0, {0, 0, 0}}},
|
||||
{"minecraft:yellow_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}},
|
||||
{"minecraft:yellow_carpet", {BLOCK_OPAQUE, {248, 197, 39}}},
|
||||
{"minecraft:yellow_concrete", {BLOCK_OPAQUE, {240, 175, 21}}},
|
||||
{"minecraft:yellow_concrete_powder", {BLOCK_OPAQUE, {232, 199, 54}}},
|
||||
{"minecraft:yellow_glazed_terracotta", {BLOCK_OPAQUE, {234, 192, 88}}},
|
||||
{"minecraft:yellow_shulker_box", {BLOCK_OPAQUE, {248, 188, 29}}},
|
||||
{"minecraft:yellow_stained_glass", {BLOCK_OPAQUE, {229, 229, 51}}},
|
||||
{"minecraft:yellow_stained_glass_pane", {BLOCK_OPAQUE, {221, 221, 48}}},
|
||||
{"minecraft:yellow_terracotta", {BLOCK_OPAQUE, {186, 133, 35}}},
|
||||
{"minecraft:yellow_wall_banner", {0, {0, 0, 0}}},
|
||||
{"minecraft:yellow_wool", {BLOCK_OPAQUE, {248, 197, 39}}},
|
||||
{"minecraft:zombie_head", {0, {0, 0, 0}}},
|
||||
{"minecraft:zombie_wall_head", {0, {0, 0, 0}}},
|
|
@ -1,52 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2018, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace Resource {
|
||||
|
||||
struct FloatColor {
|
||||
float r, g, b;
|
||||
};
|
||||
|
||||
static inline FloatColor operator+(const FloatColor &a, const FloatColor &b){
|
||||
return FloatColor {
|
||||
a.r+b.r,
|
||||
a.g+b.g,
|
||||
a.b+b.b,
|
||||
};
|
||||
}
|
||||
|
||||
static inline FloatColor & operator*=(FloatColor &a, const FloatColor &b) {
|
||||
a.r *= b.r;
|
||||
a.g *= b.g;
|
||||
a.b *= b.b;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline FloatColor operator*(float s, const FloatColor &c) {
|
||||
return FloatColor {
|
||||
s*c.r,
|
||||
s*c.g,
|
||||
s*c.b,
|
||||
};
|
||||
}
|
||||
|
||||
struct Color {
|
||||
uint8_t r, g, b, a;
|
||||
|
||||
Color() : r(0), g(0), b(0), a(0) {}
|
||||
Color(FloatColor c) : r(c.r), g(c.g), b(c.b), a(0xff) {}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,597 +0,0 @@
|
|||
/* 0 */ simple("air"),
|
||||
/* 1 */ {
|
||||
"stone",
|
||||
"granite",
|
||||
"polished_granite",
|
||||
"diorite",
|
||||
"polished_diorite",
|
||||
"andesite",
|
||||
"polished_andesite",
|
||||
},
|
||||
/* 2 */ simple("grass_block"),
|
||||
/* 3 */ {
|
||||
"dirt",
|
||||
"coarse_dirt",
|
||||
"podzol",
|
||||
},
|
||||
/* 4 */ simple("cobblestone"),
|
||||
/* 5 */ {
|
||||
"oak_planks",
|
||||
"spruce_planks",
|
||||
"birch_planks",
|
||||
"jungle_planks",
|
||||
"acacia_planks",
|
||||
"dark_oak_planks",
|
||||
},
|
||||
/* 6 */ {
|
||||
"oak_sapling",
|
||||
"spruce_sapling",
|
||||
"birch_sapling",
|
||||
"jungle_sapling",
|
||||
"acacia_sapling",
|
||||
"dark_oak_sapling",
|
||||
nullptr,
|
||||
nullptr,
|
||||
"oak_sapling",
|
||||
"spruce_sapling",
|
||||
"birch_sapling",
|
||||
"jungle_sapling",
|
||||
"acacia_sapling",
|
||||
"dark_oak_sapling",
|
||||
},
|
||||
/* 7 */ simple("bedrock"),
|
||||
/* 8 */ simple("water"),
|
||||
/* 9 */ simple("water"),
|
||||
/* 10 */ simple("lava"),
|
||||
/* 11 */ simple("lava"),
|
||||
/* 12 */ {
|
||||
"sand",
|
||||
"red_sand",
|
||||
},
|
||||
/* 13 */ simple("gravel"),
|
||||
/* 14 */ simple("gold_ore"),
|
||||
/* 15 */ simple("iron_ore"),
|
||||
/* 16 */ simple("coal_ore"),
|
||||
/* 17 */ {
|
||||
"oak_log",
|
||||
"spruce_log",
|
||||
"birch_log",
|
||||
"jungle_log",
|
||||
"oak_log",
|
||||
"spruce_log",
|
||||
"birch_log",
|
||||
"jungle_log",
|
||||
"oak_log",
|
||||
"spruce_log",
|
||||
"birch_log",
|
||||
"jungle_log",
|
||||
"oak_log",
|
||||
"spruce_log",
|
||||
"birch_log",
|
||||
"jungle_log",
|
||||
},
|
||||
/* 18 */ {
|
||||
"oak_leaves",
|
||||
"spruce_leaves",
|
||||
"birch_leaves",
|
||||
"jungle_leaves",
|
||||
"oak_leaves",
|
||||
"spruce_leaves",
|
||||
"birch_leaves",
|
||||
"jungle_leaves",
|
||||
"oak_leaves",
|
||||
"spruce_leaves",
|
||||
"birch_leaves",
|
||||
"jungle_leaves",
|
||||
"oak_leaves",
|
||||
"spruce_leaves",
|
||||
"birch_leaves",
|
||||
"jungle_leaves",
|
||||
},
|
||||
/* 19 */ simple("sponge"),
|
||||
/* 20 */ simple("glass"),
|
||||
/* 21 */ simple("lapis_ore"),
|
||||
/* 22 */ simple("lapis_block"),
|
||||
/* 23 */ simple("dispenser"),
|
||||
/* 24 */ simple("sandstone"),
|
||||
/* 25 */ simple("note_block"),
|
||||
/* 26 */ {/* bed */},
|
||||
/* 27 */ simple("powered_rail"),
|
||||
/* 28 */ simple("detector_rail"),
|
||||
/* 29 */ simple("sticky_piston"),
|
||||
/* 30 */ simple("cobweb"),
|
||||
/* 31 */ {
|
||||
"grass",
|
||||
"fern",
|
||||
},
|
||||
/* 32 */ simple("dead_bush"),
|
||||
/* 33 */ simple("piston"),
|
||||
/* 34 */ simple("piston_head"),
|
||||
/* 35 */ {
|
||||
"white_wool",
|
||||
"orange_wool",
|
||||
"magenta_wool",
|
||||
"light_blue_wool",
|
||||
"yellow_wool",
|
||||
"lime_wool",
|
||||
"pink_wool",
|
||||
"gray_wool",
|
||||
"light_gray_wool",
|
||||
"cyan_wool",
|
||||
"purple_wool",
|
||||
"blue_wool",
|
||||
"brown_wool",
|
||||
"green_wool",
|
||||
"red_wool",
|
||||
"black_wool",
|
||||
},
|
||||
/* 36 */ simple("moving_piston"),
|
||||
/* 37 */ simple("dandelion"),
|
||||
/* 38 */ {
|
||||
"poppy",
|
||||
"blue_orchid",
|
||||
"allium",
|
||||
"azure_bluet",
|
||||
"red_tulip",
|
||||
"orange_tulip",
|
||||
"white_tulip",
|
||||
"pink_tulip",
|
||||
"oxeye_daisy",
|
||||
},
|
||||
/* 39 */ simple("brown_mushroom"),
|
||||
/* 40 */ simple("red_mushroom"),
|
||||
/* 41 */ simple("gold_block"),
|
||||
/* 42 */ simple("iron_block"),
|
||||
/* 43 */ {
|
||||
"smooth_stone_slab",
|
||||
"sandstone_slab",
|
||||
"oak_slab",
|
||||
"cobblestone_slab",
|
||||
"brick_slab",
|
||||
"stone_brick_slab",
|
||||
"nether_brick_slab",
|
||||
"quartz_slab",
|
||||
},
|
||||
/* 44 */ {
|
||||
"smooth_stone_slab",
|
||||
"sandstone_slab",
|
||||
"oak_slab",
|
||||
"cobblestone_slab",
|
||||
"brick_slab",
|
||||
"stone_brick_slab",
|
||||
"nether_brick_slab",
|
||||
"quartz_slab",
|
||||
"stone_slab",
|
||||
"sandstone_slab",
|
||||
"oak_slab",
|
||||
"cobblestone_slab",
|
||||
"brick_slab",
|
||||
"stone_brick_slab",
|
||||
"nether_brick_slab",
|
||||
"quartz_slab",
|
||||
},
|
||||
/* 45 */ simple("bricks"),
|
||||
/* 46 */ simple("tnt"),
|
||||
/* 47 */ simple("bookshelf"),
|
||||
/* 48 */ simple("mossy_cobblestone"),
|
||||
/* 49 */ simple("obsidian"),
|
||||
/* 50 */ {
|
||||
nullptr,
|
||||
"wall_torch",
|
||||
"wall_torch",
|
||||
"wall_torch",
|
||||
"wall_torch",
|
||||
"torch",
|
||||
},
|
||||
/* 51 */ simple("fire"),
|
||||
/* 52 */ simple("spawner"),
|
||||
/* 53 */ simple("oak_stairs"),
|
||||
/* 54 */ simple("chest"),
|
||||
/* 55 */ simple("redstone_wire"),
|
||||
/* 56 */ simple("diamond_ore"),
|
||||
/* 57 */ simple("diamond_block"),
|
||||
/* 58 */ simple("crafting_table"),
|
||||
/* 59 */ simple("wheat"),
|
||||
/* 60 */ simple("farmland"),
|
||||
/* 61 */ simple("furnace"),
|
||||
/* 62 */ simple("furnace"),
|
||||
/* 63 */ simple("sign"),
|
||||
/* 64 */ simple("oak_door"),
|
||||
/* 65 */ simple("ladder"),
|
||||
/* 66 */ simple("rail"),
|
||||
/* 67 */ simple("cobblestone_stairs"),
|
||||
/* 68 */ simple("wall_sign"),
|
||||
/* 69 */ simple("lever"),
|
||||
/* 70 */ simple("stone_pressure_plate"),
|
||||
/* 71 */ simple("iron_door"),
|
||||
/* 72 */ simple("oak_pressure_plate"),
|
||||
/* 73 */ simple("redstone_ore"),
|
||||
/* 74 */ simple("redstone_ore"),
|
||||
/* 75 */ {
|
||||
nullptr,
|
||||
"redstone_wall_torch",
|
||||
"redstone_wall_torch",
|
||||
"redstone_wall_torch",
|
||||
"redstone_wall_torch",
|
||||
"redstone_torch",
|
||||
},
|
||||
/* 76 */ {
|
||||
nullptr,
|
||||
"redstone_wall_torch",
|
||||
"redstone_wall_torch",
|
||||
"redstone_wall_torch",
|
||||
"redstone_wall_torch",
|
||||
"redstone_torch",
|
||||
},
|
||||
/* 77 */ simple("stone_button"),
|
||||
/* 78 */ simple("snow"),
|
||||
/* 79 */ simple("ice"),
|
||||
/* 80 */ simple("snow_block"),
|
||||
/* 81 */ simple("cactus"),
|
||||
/* 82 */ simple("clay"),
|
||||
/* 83 */ simple("sugar_cane"),
|
||||
/* 84 */ simple("jukebox"),
|
||||
/* 85 */ simple("oak_fence"),
|
||||
/* 86 */ simple("pumpkin"),
|
||||
/* 87 */ simple("netherrack"),
|
||||
/* 88 */ simple("soul_sand"),
|
||||
/* 89 */ simple("glowstone"),
|
||||
/* 90 */ simple("nether_portal"),
|
||||
/* 91 */ simple("pumpkin"),
|
||||
/* 92 */ simple("cake"),
|
||||
/* 93 */ simple("repeater"),
|
||||
/* 94 */ simple("repeater"),
|
||||
/* 95 */ {
|
||||
"white_stained_glass",
|
||||
"orange_stained_glass",
|
||||
"magenta_stained_glass",
|
||||
"light_blue_stained_glass",
|
||||
"yellow_stained_glass",
|
||||
"lime_stained_glass",
|
||||
"pink_stained_glass",
|
||||
"gray_stained_glass",
|
||||
"light_gray_stained_glass",
|
||||
"cyan_stained_glass",
|
||||
"purple_stained_glass",
|
||||
"blue_stained_glass",
|
||||
"brown_stained_glass",
|
||||
"green_stained_glass",
|
||||
"red_stained_glass",
|
||||
"black_stained_glass",
|
||||
},
|
||||
/* 96 */ simple("oak_trapdoor"),
|
||||
/* 97 */ {
|
||||
"infested_stone",
|
||||
"infested_cobblestone",
|
||||
"infested_stone_bricks",
|
||||
"infested_mossy_stone_bricks",
|
||||
"infested_cracked_stone_bricks",
|
||||
"infested_chiseled_stone_bricks",
|
||||
},
|
||||
/* 98 */ {
|
||||
"stone_bricks",
|
||||
"mossy_stone_bricks",
|
||||
"cracked_stone_bricks",
|
||||
"chiseled_stone_bricks",
|
||||
},
|
||||
/* 99 */ simple("brown_mushroom_block"),
|
||||
/* 100 */ simple("red_mushroom_block"),
|
||||
/* 101 */ simple("iron_bars"),
|
||||
/* 102 */ simple("glass_pane"),
|
||||
/* 103 */ simple("melon"),
|
||||
/* 104 */ simple("pumpkin_stem"),
|
||||
/* 105 */ simple("melon_stem"),
|
||||
/* 106 */ simple("vine"),
|
||||
/* 107 */ simple("oak_fence_gate"),
|
||||
/* 108 */ simple("brick_stairs"),
|
||||
/* 109 */ simple("stone_brick_stairs"),
|
||||
/* 110 */ simple("mycelium"),
|
||||
/* 111 */ simple("lily_pad"),
|
||||
/* 112 */ simple("nether_bricks"),
|
||||
/* 113 */ simple("nether_brick_fence"),
|
||||
/* 114 */ simple("nether_brick_stairs"),
|
||||
/* 115 */ simple("nether_wart"),
|
||||
/* 116 */ simple("enchanting_table"),
|
||||
/* 117 */ simple("brewing_stand"),
|
||||
/* 118 */ simple("cauldron"),
|
||||
/* 119 */ simple("end_portal"),
|
||||
/* 120 */ simple("end_portal_frame"),
|
||||
/* 121 */ simple("end_stone"),
|
||||
/* 122 */ simple("dragon_egg"),
|
||||
/* 123 */ simple("redstone_lamp"),
|
||||
/* 124 */ simple("redstone_lamp"),
|
||||
/* 125 */ {
|
||||
"oak_slab",
|
||||
"spruce_slab",
|
||||
"birch_slab",
|
||||
"jungle_slab",
|
||||
"acacia_slab",
|
||||
"dark_oak_slab",
|
||||
},
|
||||
/* 126 */ {
|
||||
"oak_slab",
|
||||
"spruce_slab",
|
||||
"birch_slab",
|
||||
"jungle_slab",
|
||||
"acacia_slab",
|
||||
"dark_oak_slab",
|
||||
nullptr,
|
||||
nullptr,
|
||||
"oak_slab",
|
||||
"spruce_slab",
|
||||
"birch_slab",
|
||||
"jungle_slab",
|
||||
"acacia_slab",
|
||||
"dark_oak_slab",
|
||||
},
|
||||
/* 127 */ simple("cocoa"),
|
||||
/* 128 */ simple("sandstone_stairs"),
|
||||
/* 129 */ simple("emerald_ore"),
|
||||
/* 130 */ simple("ender_chest"),
|
||||
/* 131 */ simple("tripwire_hook"),
|
||||
/* 132 */ simple("tripwire"),
|
||||
/* 133 */ simple("emerald_block"),
|
||||
/* 134 */ simple("spruce_stairs"),
|
||||
/* 135 */ simple("birch_stairs"),
|
||||
/* 136 */ simple("jungle_stairs"),
|
||||
/* 137 */ simple("command_block"),
|
||||
/* 138 */ simple("beacon"),
|
||||
/* 139 */ {
|
||||
"cobblestone_wall",
|
||||
"mossy_cobblestone_wall",
|
||||
},
|
||||
/* 140 */ simple("flower_pot"),
|
||||
/* 141 */ simple("carrots"),
|
||||
/* 142 */ simple("potatoes"),
|
||||
/* 143 */ {},
|
||||
/* 144 */ {},
|
||||
/* 145 */ {
|
||||
"anvil",
|
||||
"anvil",
|
||||
"anvil",
|
||||
"anvil",
|
||||
"chipped_anvil",
|
||||
"chipped_anvil",
|
||||
"chipped_anvil",
|
||||
"chipped_anvil",
|
||||
"damaged_anvil",
|
||||
"damaged_anvil",
|
||||
"damaged_anvil",
|
||||
"damaged_anvil",
|
||||
},
|
||||
/* 146 */ simple("trapped_chest"),
|
||||
/* 147 */ simple("light_weighted_pressure_plate"),
|
||||
/* 148 */ simple("heavy_weighted_pressure_plate"),
|
||||
/* 149 */ simple("comparator"),
|
||||
/* 150 */ simple("comparator"),
|
||||
/* 151 */ simple("daylight_detector"),
|
||||
/* 152 */ simple("redstone_block"),
|
||||
/* 153 */ simple("nether_quartz_ore"),
|
||||
/* 154 */ simple("hopper"),
|
||||
/* 155 */ simple("quartz_block"),
|
||||
/* 156 */ simple("quartz_stairs"),
|
||||
/* 157 */ simple("activator_rail"),
|
||||
/* 158 */ simple("dropper"),
|
||||
/* 159 */ {
|
||||
"white_terracotta",
|
||||
"orange_terracotta",
|
||||
"magenta_terracotta",
|
||||
"light_blue_terracotta",
|
||||
"yellow_terracotta",
|
||||
"lime_terracotta",
|
||||
"pink_terracotta",
|
||||
"gray_terracotta",
|
||||
"light_gray_terracotta",
|
||||
"cyan_terracotta",
|
||||
"purple_terracotta",
|
||||
"blue_terracotta",
|
||||
"brown_terracotta",
|
||||
"green_terracotta",
|
||||
"red_terracotta",
|
||||
"black_terracotta",
|
||||
},
|
||||
/* 160 */ {
|
||||
"white_stained_glass_pane",
|
||||
"orange_stained_glass_pane",
|
||||
"magenta_stained_glass_pane",
|
||||
"light_blue_stained_glass_pane",
|
||||
"yellow_stained_glass_pane",
|
||||
"lime_stained_glass_pane",
|
||||
"pink_stained_glass_pane",
|
||||
"gray_stained_glass_pane",
|
||||
"light_gray_stained_glass_pane",
|
||||
"cyan_stained_glass_pane",
|
||||
"purple_stained_glass_pane",
|
||||
"blue_stained_glass_pane",
|
||||
"brown_stained_glass_pane",
|
||||
"green_stained_glass_pane",
|
||||
"red_stained_glass_pane",
|
||||
"black_stained_glass_pane",
|
||||
},
|
||||
/* 161 */ {
|
||||
"acacia_leaves",
|
||||
"dark_oak_leaves",
|
||||
nullptr,
|
||||
nullptr,
|
||||
"acacia_leaves",
|
||||
"dark_oak_leaves",
|
||||
nullptr,
|
||||
nullptr,
|
||||
"acacia_leaves",
|
||||
"dark_oak_leaves",
|
||||
nullptr,
|
||||
nullptr,
|
||||
"acacia_leaves",
|
||||
"dark_oak_leaves",
|
||||
},
|
||||
/* 162 */ {
|
||||
"acacia_log",
|
||||
"dark_oak_log",
|
||||
nullptr,
|
||||
nullptr,
|
||||
"acacia_log",
|
||||
"dark_oak_log",
|
||||
nullptr,
|
||||
nullptr,
|
||||
"acacia_log",
|
||||
"dark_oak_log",
|
||||
nullptr,
|
||||
nullptr,
|
||||
"acacia_log",
|
||||
"dark_oak_log",
|
||||
},
|
||||
/* 163 */ simple("acacia_stairs"),
|
||||
/* 164 */ simple("dark_oak_stairs"),
|
||||
/* 165 */ simple("slime_block"),
|
||||
/* 166 */ simple("barrier"),
|
||||
/* 167 */ simple("iron_trapdoor"),
|
||||
/* 168 */ {
|
||||
"prismarine",
|
||||
"prismarine_bricks",
|
||||
"dark_prismarine",
|
||||
},
|
||||
/* 169 */ simple("sea_lantern"),
|
||||
/* 170 */ simple("hay_block"),
|
||||
/* 171 */ {
|
||||
"white_carpet",
|
||||
"orange_carpet",
|
||||
"magenta_carpet",
|
||||
"light_blue_carpet",
|
||||
"yellow_carpet",
|
||||
"lime_carpet",
|
||||
"pink_carpet",
|
||||
"gray_carpet",
|
||||
"light_gray_carpet",
|
||||
"cyan_carpet",
|
||||
"purple_carpet",
|
||||
"blue_carpet",
|
||||
"brown_carpet",
|
||||
"green_carpet",
|
||||
"red_carpet",
|
||||
"black_carpet",
|
||||
},
|
||||
/* 172 */ simple("terracotta"),
|
||||
/* 173 */ simple("coal_block"),
|
||||
/* 174 */ simple("packed_ice"),
|
||||
/* 175 */ {
|
||||
"sunflower",
|
||||
"lilac",
|
||||
"tall_grass",
|
||||
"large_fern",
|
||||
"rose_bush",
|
||||
"peony",
|
||||
},
|
||||
/* 176 */ {/* banner */},
|
||||
/* 177 */ {/* wall banner */},
|
||||
/* 178 */ simple("daylight_detector"),
|
||||
/* 179 */ simple("red_sandstone"),
|
||||
/* 180 */ simple("red_sandstone_stairs"),
|
||||
/* 181 */ simple("red_sandstone_slab"),
|
||||
/* 182 */ simple("red_sandstone_slab"),
|
||||
/* 183 */ simple("spruce_fence_gate"),
|
||||
/* 184 */ simple("birch_fence_gate"),
|
||||
/* 185 */ simple("jungle_fence_gate"),
|
||||
/* 186 */ simple("dark_oak_fence_gate"),
|
||||
/* 187 */ simple("acacia_fence_gate"),
|
||||
/* 188 */ simple("spruce_fence"),
|
||||
/* 189 */ simple("birch_fence"),
|
||||
/* 190 */ simple("jungle_fence"),
|
||||
/* 191 */ simple("dark_oak_fence"),
|
||||
/* 192 */ simple("acacia_fence"),
|
||||
/* 193 */ simple("spruce_door"),
|
||||
/* 194 */ simple("birch_door"),
|
||||
/* 195 */ simple("jungle_door"),
|
||||
/* 196 */ simple("acacia_door"),
|
||||
/* 197 */ simple("dark_oak_door"),
|
||||
/* 198 */ simple("end_rod"),
|
||||
/* 199 */ simple("chorus_plant"),
|
||||
/* 200 */ simple("chorus_flower"),
|
||||
/* 201 */ simple("purpur_block"),
|
||||
/* 202 */ simple("purpur_pillar"),
|
||||
/* 203 */ simple("purpur_stairs"),
|
||||
/* 204 */ simple("purpur_slab"),
|
||||
/* 205 */ simple("purpur_slab"),
|
||||
/* 206 */ simple("end_stone_bricks"),
|
||||
/* 207 */ simple("beetroots"),
|
||||
/* 208 */ simple("grass_path"),
|
||||
/* 209 */ simple("end_gateway"),
|
||||
/* 210 */ simple("repeating_command_block"),
|
||||
/* 211 */ simple("chain_command_block"),
|
||||
/* 212 */ simple("frosted_ice"),
|
||||
/* 213 */ simple("magma_block"),
|
||||
/* 214 */ simple("nether_wart_block"),
|
||||
/* 215 */ simple("red_nether_bricks"),
|
||||
/* 216 */ simple("bone_block"),
|
||||
/* 217 */ simple("structure_void"),
|
||||
/* 218 */ simple("observer"),
|
||||
/* 219 */ simple("white_shulker_box"),
|
||||
/* 220 */ simple("orange_shulker_box"),
|
||||
/* 221 */ simple("magenta_shulker_box"),
|
||||
/* 222 */ simple("light_blue_shulker_box"),
|
||||
/* 223 */ simple("yellow_shulker_box"),
|
||||
/* 224 */ simple("lime_shulker_box"),
|
||||
/* 225 */ simple("pink_shulker_box"),
|
||||
/* 226 */ simple("gray_shulker_box"),
|
||||
/* 227 */ simple("light_gray_shulker_box"),
|
||||
/* 228 */ simple("cyan_shulker_box"),
|
||||
/* 229 */ simple("purple_shulker_box"),
|
||||
/* 230 */ simple("blue_shulker_box"),
|
||||
/* 231 */ simple("brown_shulker_box"),
|
||||
/* 232 */ simple("green_shulker_box"),
|
||||
/* 233 */ simple("red_shulker_box"),
|
||||
/* 234 */ simple("black_shulker_box"),
|
||||
/* 235 */ simple("white_glazed_terracotta"),
|
||||
/* 236 */ simple("orange_glazed_terracotta"),
|
||||
/* 237 */ simple("magenta_glazed_terracotta"),
|
||||
/* 238 */ simple("light_blue_glazed_terracotta"),
|
||||
/* 239 */ simple("yellow_glazed_terracotta"),
|
||||
/* 240 */ simple("lime_glazed_terracotta"),
|
||||
/* 241 */ simple("pink_glazed_terracotta"),
|
||||
/* 242 */ simple("gray_glazed_terracotta"),
|
||||
/* 243 */ simple("light_gray_glazed_terracotta"),
|
||||
/* 244 */ simple("cyan_glazed_terracotta"),
|
||||
/* 245 */ simple("purple_glazed_terracotta"),
|
||||
/* 246 */ simple("blue_glazed_terracotta"),
|
||||
/* 247 */ simple("brown_glazed_terracotta"),
|
||||
/* 248 */ simple("green_glazed_terracotta"),
|
||||
/* 249 */ simple("red_glazed_terracotta"),
|
||||
/* 250 */ simple("black_glazed_terracotta"),
|
||||
/* 251 */ {
|
||||
"white_concrete",
|
||||
"orange_concrete",
|
||||
"magenta_concrete",
|
||||
"light_blue_concrete",
|
||||
"yellow_concrete",
|
||||
"lime_concrete",
|
||||
"pink_concrete",
|
||||
"gray_concrete",
|
||||
"light_gray_concrete",
|
||||
"cyan_concrete",
|
||||
"purple_concrete",
|
||||
"blue_concrete",
|
||||
"brown_concrete",
|
||||
"green_concrete",
|
||||
"red_concrete",
|
||||
"black_concrete",
|
||||
},
|
||||
/* 252 */ {
|
||||
"white_concrete_powder",
|
||||
"orange_concrete_powder",
|
||||
"magenta_concrete_powder",
|
||||
"light_blue_concrete_powder",
|
||||
"yellow_concrete_powder",
|
||||
"lime_concrete_powder",
|
||||
"pink_concrete_powder",
|
||||
"gray_concrete_powder",
|
||||
"light_gray_concrete_powder",
|
||||
"cyan_concrete_powder",
|
||||
"purple_concrete_powder",
|
||||
"blue_concrete_powder",
|
||||
"brown_concrete_powder",
|
||||
"green_concrete_powder",
|
||||
"red_concrete_powder",
|
||||
"black_concrete_powder",
|
||||
},
|
||||
/* 253 */ {},
|
||||
/* 254 */ {},
|
||||
/* 255 */ simple("structure_block"),
|
|
@ -1,20 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
|
||||
// UniqueCPtr is a wrapper around std::unique_ptr using std::free as its deallocator
|
||||
//
|
||||
// This allows to use it to manage memory allocated by C APIs (malloc, realloc, ...)
|
||||
template<typename T> class UniqueCPtr : public std::unique_ptr<T, void (*)(void *)> {
|
||||
public:
|
||||
UniqueCPtr() : std::unique_ptr<T, void (*)(void *)>(nullptr, std::free) {}
|
||||
template<typename T2> UniqueCPtr(T2 ptr) : std::unique_ptr<T, void (*)(void *)>(ptr, std::free) {}
|
||||
};
|
44
src/Util.hpp
44
src/Util.hpp
|
@ -1,44 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015-2021, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
|
||||
template <typename T> static inline T assertValue(T&& val) {
|
||||
if (!val)
|
||||
throw std::invalid_argument("assertValue failed");
|
||||
|
||||
return std::forward<T>(val);
|
||||
}
|
||||
|
||||
static inline float clamp(float v, float min, float max) {
|
||||
return std::max(std::min(v, max), min);
|
||||
}
|
||||
|
||||
// A block coordinate relative to a chunk/section (X/Y/Z)
|
||||
typedef uint8_t block_idx_t;
|
||||
// A section index in a chunk (Y)
|
||||
typedef int8_t section_idx_t;
|
||||
// A chunk coordinate relative to a region (X/Z)
|
||||
typedef uint8_t chunk_idx_t;
|
||||
|
||||
// A block coordinate relative to a region (X/Z)
|
||||
typedef uint16_t region_block_idx_t;
|
||||
// A block coordinate (Y)
|
||||
typedef int16_t y_idx_t;
|
||||
|
||||
const y_idx_t y_idx_min = std::numeric_limits<y_idx_t>::min();
|
||||
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015-2021, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../NBT/CompoundTag.hpp"
|
||||
#include "../Resource/Biome.hpp"
|
||||
#include "../Resource/BlockType.hpp"
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace World {
|
||||
|
||||
struct Block {
|
||||
const Resource::BlockType *type;
|
||||
y_idx_t depth;
|
||||
uint8_t blockLight;
|
||||
|
||||
bool isVisible() const {
|
||||
return type && (type->flags & BLOCK_OPAQUE);
|
||||
}
|
||||
|
||||
Resource::FloatColor getColor(uint8_t biome) const {
|
||||
if (!isVisible())
|
||||
return Resource::FloatColor {};
|
||||
|
||||
return (Resource::Biome::Biomes[biome] ?: Resource::Biome::Default)->getBlockColor(type, depth);
|
||||
}
|
||||
|
||||
operator bool() const {
|
||||
return type;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,201 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015-2021, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "Chunk.hpp"
|
||||
#include "../NBT/IntTag.hpp"
|
||||
#include "../NBT/ListTag.hpp"
|
||||
#include "../NBT/StringTag.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace World {
|
||||
|
||||
Chunk::Chunk(const ChunkData *data) {
|
||||
std::shared_ptr<const NBT::ListTag> sectionsTag;
|
||||
|
||||
auto level = data->getRoot()->get<NBT::CompoundTag>("Level");
|
||||
if (level) {
|
||||
sectionsTag = level->get<NBT::ListTag>("Sections");
|
||||
if (!sectionsTag || sectionsTag->empty())
|
||||
return;
|
||||
|
||||
auto biomesIntArray = level->get<NBT::IntArrayTag>("Biomes");
|
||||
auto biomesByteArray = level->get<NBT::ByteArrayTag>("Biomes");
|
||||
|
||||
if (biomesIntArray && biomesIntArray->getLength() == BSIZE*BSIZE*BMAXY) {
|
||||
biomeInts = std::move(biomesIntArray);
|
||||
biomeFormat = INT_ARRAY;
|
||||
} else if (biomesIntArray && biomesIntArray->getLength() == SIZE*SIZE) {
|
||||
biomeInts = std::move(biomesIntArray);
|
||||
biomeFormat = INT_ARRAY_PRE1_15;
|
||||
} else if (biomesByteArray && biomesByteArray->getLength() == SIZE*SIZE) {
|
||||
biomeBytes = std::move(biomesByteArray);
|
||||
biomeFormat = BYTE_ARRAY;
|
||||
} else {
|
||||
throw std::invalid_argument("corrupt biome data");
|
||||
}
|
||||
} else {
|
||||
sectionsTag = data->getRoot()->get<NBT::ListTag>("sections");
|
||||
if (!sectionsTag || sectionsTag->empty())
|
||||
return;
|
||||
|
||||
biomeFormat = SECTION;
|
||||
}
|
||||
|
||||
auto dataVersionTag = data->getRoot()->get<NBT::IntTag>("DataVersion");
|
||||
uint32_t dataVersion = dataVersionTag ? dataVersionTag->getValue() : 0;
|
||||
|
||||
std::vector<std::unique_ptr<Section>> tmpSections;
|
||||
section_idx_t minY = std::numeric_limits<section_idx_t>::max();
|
||||
section_idx_t maxY = std::numeric_limits<section_idx_t>::min();
|
||||
|
||||
for (auto &sTag : *sectionsTag) {
|
||||
auto s = std::dynamic_pointer_cast<const NBT::CompoundTag>(sTag);
|
||||
std::unique_ptr<Section> section = Section::makeSection(s, dataVersion);
|
||||
section_idx_t Y = section->getY();
|
||||
if (Y < minY)
|
||||
minY = Y;
|
||||
if (Y > maxY)
|
||||
maxY = Y;
|
||||
|
||||
tmpSections.push_back(std::move(section));
|
||||
}
|
||||
|
||||
if (tmpSections.empty())
|
||||
return;
|
||||
|
||||
assertValue(minY <= maxY);
|
||||
sectionOffset = minY;
|
||||
sections.resize(maxY - minY + 1);
|
||||
|
||||
for (auto §ion : tmpSections) {
|
||||
section_idx_t Y = section->getY();
|
||||
Y -= sectionOffset;
|
||||
assertValue(Y >= 0 && size_t(Y) < sections.size());
|
||||
assertValue(!sections[Y]);
|
||||
sections[Y] = std::move(section);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t Chunk::getBiome(block_idx_t x, y_idx_t y, block_idx_t z) const {
|
||||
if (x >= SIZE || z >= SIZE)
|
||||
throw std::invalid_argument("getBiome: invalid block coordinate");
|
||||
|
||||
switch (biomeFormat) {
|
||||
case INT_ARRAY:
|
||||
if (y < 0 || y >= MAXY)
|
||||
break;
|
||||
return biomeInts->getValue((y>>BSHIFT)*BSIZE*BSIZE + (z>>BSHIFT)*BSIZE + (x>>BSHIFT));
|
||||
case INT_ARRAY_PRE1_15:
|
||||
return biomeInts->getValue(z*SIZE + x);
|
||||
case BYTE_ARRAY:
|
||||
return biomeBytes->getValue(z*SIZE + x);
|
||||
case SECTION: {
|
||||
section_idx_t Y = (y >> HSHIFT) - sectionOffset;
|
||||
|
||||
if (Y < 0 || size_t(Y) >= sections.size() || !sections[Y])
|
||||
break;
|
||||
|
||||
return sections[Y]->getBiomeAt(x, y & HMASK, z);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
Block Chunk::getBlock(block_idx_t x, Chunk::Height height, block_idx_t z) const {
|
||||
Block block = {};
|
||||
|
||||
block.depth = height.depth;
|
||||
|
||||
if (height.y == y_idx_min)
|
||||
return block;
|
||||
|
||||
section_idx_t Y = (height.y >> HSHIFT) - sectionOffset;
|
||||
block_idx_t y = height.y & HMASK;
|
||||
|
||||
if (Y >= 0 && size_t(Y) < sections.size() && sections[Y])
|
||||
block.type = sections[Y]->getBlockStateAt(x, y, z);
|
||||
|
||||
section_idx_t Yt = ((height.y + 1) >> HSHIFT) - sectionOffset;
|
||||
block_idx_t yt = (height.y + 1) & HMASK;
|
||||
|
||||
if (Yt >= 0 && size_t(Yt) < sections.size() && sections[Yt])
|
||||
block.blockLight = sections[Yt]->getBlockLightAt(x, yt, z);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
bool Chunk::getHeight(
|
||||
Chunk::Height *height, const Section *section,
|
||||
block_idx_t x, block_idx_t y, block_idx_t z, int flags
|
||||
) const {
|
||||
if (height->depth > y_idx_min)
|
||||
return false;
|
||||
|
||||
if (!(flags & WITH_DEPTH) && height->y > y_idx_min)
|
||||
return false;
|
||||
|
||||
const Resource::BlockType *type = section->getBlockStateAt(x, y, z);
|
||||
if (!type || !(type->flags & BLOCK_OPAQUE))
|
||||
return false;
|
||||
|
||||
if (height->y == y_idx_min)
|
||||
height->y = (section->getY() << HSHIFT) + y;
|
||||
|
||||
if (!(flags & WITH_DEPTH))
|
||||
return true;
|
||||
|
||||
if (type->flags & BLOCK_WATER)
|
||||
return false;
|
||||
|
||||
height->depth = (section->getY() << HSHIFT) + y;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Chunk::Heightmap Chunk::getTopLayer(int flags) const {
|
||||
uint32_t done = 0;
|
||||
Heightmap ret;
|
||||
|
||||
for (block_idx_t z = 0; z < SIZE; z++) {
|
||||
for (block_idx_t x = 0; x < SIZE; x++)
|
||||
ret.v[x][z] = Height { .y = y_idx_min, .depth = y_idx_min };
|
||||
}
|
||||
|
||||
for (section_idx_t Y = sections.size() - 1; Y >= 0; Y--) {
|
||||
if (done == SIZE*SIZE)
|
||||
break;
|
||||
|
||||
if (!sections[Y])
|
||||
continue;
|
||||
|
||||
const Section *section = sections[Y].get();
|
||||
|
||||
for (int8_t y = SIZE-1; y >= 0; y--) {
|
||||
if (done == SIZE*SIZE)
|
||||
break;
|
||||
|
||||
for (block_idx_t z = 0; z < SIZE; z++) {
|
||||
for (block_idx_t x = 0; x < SIZE; x++) {
|
||||
if (getHeight(&ret.v[x][z], section, x, y, z, flags))
|
||||
done++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015-2021, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "Block.hpp"
|
||||
#include "ChunkData.hpp"
|
||||
#include "Section.hpp"
|
||||
#include "../NBT/ByteArrayTag.hpp"
|
||||
#include "../NBT/IntArrayTag.hpp"
|
||||
#include "../Resource/BlockType.hpp"
|
||||
#include "../Util.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace World {
|
||||
|
||||
class Chunk {
|
||||
public:
|
||||
// Number of blocks in a chunk in x/z dimensions
|
||||
static const uint32_t SIZE = Section::SIZE;
|
||||
// Maximum Y value for pre-1.18 chunks
|
||||
static const y_idx_t MAXY = 256;
|
||||
|
||||
// Shift to get from height to section index
|
||||
static const unsigned HSHIFT = 4;
|
||||
// Mask to get from height to y index inside section
|
||||
static const block_idx_t HMASK = 0xf;
|
||||
|
||||
// Since Minecraft 1.15, biome information is stored for
|
||||
// 4x4x4 block groups
|
||||
static const unsigned BSHIFT = Section::BSHIFT;
|
||||
// Number of biome values in a chunk in x/z dimensions
|
||||
static const uint32_t BSIZE = Section::BSIZE;
|
||||
// Number of biome values in a chunk in y dimension
|
||||
static const uint32_t BMAXY = MAXY >> BSHIFT;
|
||||
|
||||
// Flags
|
||||
static const int WITH_DEPTH = (1 << 0);
|
||||
|
||||
struct Height {
|
||||
y_idx_t y;
|
||||
y_idx_t depth;
|
||||
};
|
||||
|
||||
struct Heightmap {
|
||||
Height v[SIZE][SIZE];
|
||||
};
|
||||
|
||||
private:
|
||||
section_idx_t sectionOffset;
|
||||
std::vector<std::unique_ptr<Section>> sections;
|
||||
|
||||
enum BiomeFormat {
|
||||
UNKNOWN = 0,
|
||||
BYTE_ARRAY,
|
||||
INT_ARRAY_PRE1_15,
|
||||
INT_ARRAY,
|
||||
SECTION,
|
||||
} biomeFormat = UNKNOWN;
|
||||
|
||||
std::shared_ptr<const NBT::ByteArrayTag> biomeBytes;
|
||||
std::shared_ptr<const NBT::IntArrayTag> biomeInts;
|
||||
|
||||
bool getHeight(
|
||||
Height *height, const Section *section,
|
||||
block_idx_t x, block_idx_t y, block_idx_t z, int flags
|
||||
) const;
|
||||
|
||||
const Resource::BlockType * getBlockStateAt(block_idx_t x, y_idx_t y, block_idx_t z) const {
|
||||
section_idx_t Y = (y >> HSHIFT) - sectionOffset;
|
||||
|
||||
if (Y < 0 || size_t(Y) >= sections.size() || !sections[Y])
|
||||
return nullptr;
|
||||
|
||||
return sections[Y]->getBlockStateAt(x, y & HMASK, z);
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
Chunk(const ChunkData *data);
|
||||
|
||||
uint8_t getBiome(block_idx_t x, y_idx_t y, block_idx_t z) const;
|
||||
Block getBlock(block_idx_t x, Height y, block_idx_t z) const;
|
||||
|
||||
Heightmap getTopLayer(int flags) const;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015-2018, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "ChunkData.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace World {
|
||||
|
||||
ChunkData::ChunkData(Buffer buffer) {
|
||||
size_t size = buffer.get32();
|
||||
|
||||
Buffer buffer2(buffer.get(size), size);
|
||||
|
||||
uint8_t format = buffer2.get8();
|
||||
if (format != 2)
|
||||
throw std::invalid_argument("unknown chunk format");
|
||||
|
||||
inflateChunk(buffer2);
|
||||
parseChunk();
|
||||
}
|
||||
|
||||
void ChunkData::inflateChunk(Buffer buffer) {
|
||||
size_t outlen = 0;
|
||||
uint8_t *output = nullptr;
|
||||
|
||||
z_stream stream = {};
|
||||
int ret = inflateInit(&stream);
|
||||
if (ret != Z_OK)
|
||||
throw std::runtime_error("inflateInit() failed");
|
||||
|
||||
stream.avail_in = buffer.getRemaining();
|
||||
stream.next_in = const_cast<uint8_t *>(buffer.get(stream.avail_in));
|
||||
|
||||
while (stream.avail_in) {
|
||||
outlen += 65536;
|
||||
output = static_cast<uint8_t *>(std::realloc(output, outlen));
|
||||
|
||||
stream.next_out = output + stream.total_out;
|
||||
stream.avail_out = outlen - stream.total_out;
|
||||
|
||||
ret = inflate(&stream, Z_NO_FLUSH);
|
||||
switch (ret) {
|
||||
case Z_NEED_DICT:
|
||||
case Z_DATA_ERROR:
|
||||
case Z_MEM_ERROR:
|
||||
inflateEnd(&stream);
|
||||
throw std::runtime_error("inflate() failed");
|
||||
}
|
||||
}
|
||||
|
||||
inflateEnd(&stream);
|
||||
|
||||
len = stream.total_out;
|
||||
data = UniqueCPtr<uint8_t[]>(output);
|
||||
}
|
||||
|
||||
void ChunkData::parseChunk() {
|
||||
Buffer nbt(data.get(), len);
|
||||
std::pair<std::string, std::shared_ptr<const NBT::Tag>> tag = NBT::Tag::readNamedTag(&nbt);
|
||||
if (!tag.first.empty())
|
||||
throw std::invalid_argument("invalid root tag");
|
||||
|
||||
root = assertValue(std::dynamic_pointer_cast<const NBT::CompoundTag>(tag.second));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015-2018, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "../Buffer.hpp"
|
||||
#include "../UniqueCPtr.hpp"
|
||||
#include "../Util.hpp"
|
||||
#include "../NBT/CompoundTag.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace World {
|
||||
|
||||
class ChunkData {
|
||||
private:
|
||||
size_t len;
|
||||
UniqueCPtr<uint8_t[]> data;
|
||||
|
||||
std::shared_ptr<const NBT::CompoundTag> root;
|
||||
|
||||
void inflateChunk(Buffer buffer);
|
||||
void parseChunk();
|
||||
|
||||
public:
|
||||
ChunkData(Buffer buffer);
|
||||
|
||||
const std::shared_ptr<const NBT::CompoundTag> & getRoot() const {
|
||||
return root;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "Level.hpp"
|
||||
#include "../GZip.hpp"
|
||||
#include "../Util.hpp"
|
||||
#include "../NBT/IntTag.hpp"
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace World {
|
||||
|
||||
Level::Level(const char *filename) {
|
||||
buffer = readGZip(filename);
|
||||
|
||||
Buffer nbt(buffer.data(), buffer.size());
|
||||
std::pair<std::string, std::shared_ptr<const NBT::Tag>> tag = NBT::Tag::readNamedTag(&nbt);
|
||||
if (tag.first != "")
|
||||
throw std::invalid_argument("invalid root tag");
|
||||
|
||||
root = assertValue(std::dynamic_pointer_cast<const NBT::CompoundTag>(tag.second));
|
||||
data = assertValue(root->get<NBT::CompoundTag>("Data"));
|
||||
}
|
||||
|
||||
std::pair<int32_t, int32_t> Level::getSpawn() const {
|
||||
int32_t x = assertValue(data->get<NBT::IntTag>("SpawnX"))->getValue();
|
||||
int32_t z = assertValue(data->get<NBT::IntTag>("SpawnZ"))->getValue();
|
||||
|
||||
return std::make_pair(x, z);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../NBT/CompoundTag.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace World {
|
||||
|
||||
class Level {
|
||||
private:
|
||||
std::vector<uint8_t> buffer;
|
||||
|
||||
std::shared_ptr<const NBT::CompoundTag> root;
|
||||
std::shared_ptr<const NBT::CompoundTag> data;
|
||||
|
||||
public:
|
||||
Level(const char *filename);
|
||||
|
||||
std::pair<int32_t, int32_t> getSpawn() const;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015-2021, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "Region.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace World {
|
||||
|
||||
Region::ChunkMap Region::processHeader(const uint8_t header[4096]) {
|
||||
ChunkMap map;
|
||||
|
||||
for (chunk_idx_t z = 0; z < 32; z++) {
|
||||
for (chunk_idx_t x = 0; x < 32; x++) {
|
||||
const uint8_t *p = &header[128*z + x*4];
|
||||
|
||||
uint32_t offset = (p[0] << 16) | (p[1] << 8) | p[2];
|
||||
|
||||
if (!offset)
|
||||
continue;
|
||||
|
||||
uint8_t len = p[3];
|
||||
|
||||
map.emplace(offset, ChunkDesc(x, z, len));
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
void Region::visitChunks(const char *filename, const ChunkVisitor &visitor) {
|
||||
std::ifstream file;
|
||||
file.exceptions(std::ios::badbit);
|
||||
file.open(filename, std::ios::in | std::ios::binary);
|
||||
|
||||
ChunkMap chunkMap;
|
||||
|
||||
{
|
||||
uint8_t header[4096];
|
||||
file.read((char *)header, sizeof(header));
|
||||
|
||||
chunkMap = processHeader(header);
|
||||
}
|
||||
|
||||
bool seen[SIZE][SIZE] = {};
|
||||
|
||||
size_t i = 1, c = 0;
|
||||
while (!file.eof() && !file.fail()) {
|
||||
auto it = chunkMap.find(i);
|
||||
if (it == chunkMap.end()) {
|
||||
file.ignore(4096);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
chunk_idx_t x = std::get<0>(it->second);
|
||||
chunk_idx_t z = std::get<1>(it->second);
|
||||
size_t len = std::get<2>(it->second);
|
||||
|
||||
if (seen[x][z])
|
||||
throw std::invalid_argument("duplicate chunk");
|
||||
|
||||
seen[x][z] = true;
|
||||
c++;
|
||||
|
||||
uint8_t buffer[len * 4096];
|
||||
std::memset(buffer, 0, sizeof(buffer));
|
||||
file.read((char *)buffer, len * 4096);
|
||||
|
||||
ChunkData chunk(Buffer(buffer, len * 4096));
|
||||
visitor(x, z, &chunk);
|
||||
|
||||
i += len;
|
||||
}
|
||||
|
||||
if (c != chunkMap.size())
|
||||
throw std::invalid_argument("region incomplete");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015-2021, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Chunk.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace World {
|
||||
|
||||
class Region {
|
||||
public:
|
||||
// Number of chunks in a region in each dimension
|
||||
static const uint32_t SIZE = 32;
|
||||
|
||||
typedef std::function<void (chunk_idx_t, chunk_idx_t, const ChunkData *)> ChunkVisitor;
|
||||
|
||||
Region() = delete;
|
||||
|
||||
private:
|
||||
typedef std::tuple<chunk_idx_t, chunk_idx_t, uint8_t> ChunkDesc;
|
||||
typedef std::unordered_map<uint32_t, ChunkDesc> ChunkMap;
|
||||
|
||||
static ChunkMap processHeader(const uint8_t header[4096]);
|
||||
|
||||
public:
|
||||
static void visitChunks(const char *filename, const ChunkVisitor &visitor);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,230 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015-2021, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "Section.hpp"
|
||||
#include "../Resource/Biome.hpp"
|
||||
#include "../NBT/ByteTag.hpp"
|
||||
#include "../NBT/IntTag.hpp"
|
||||
#include "../NBT/StringTag.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace World {
|
||||
|
||||
Section::Section(const std::shared_ptr<const NBT::CompoundTag> §ion) {
|
||||
const std::shared_ptr<const NBT::ByteTag> YByteTag = section->get<NBT::ByteTag>("Y");
|
||||
if (YByteTag) {
|
||||
Y = int8_t(YByteTag->getValue());
|
||||
} else {
|
||||
const std::shared_ptr<const NBT::IntTag> YIntTag = assertValue(section->get<NBT::IntTag>("Y"));
|
||||
int32_t value = YIntTag->getValue();
|
||||
if (int8_t(value) != value)
|
||||
throw std::invalid_argument("unsupported section Y coordinate");
|
||||
Y = value;
|
||||
}
|
||||
blockLight = section->get<NBT::ByteArrayTag>("BlockLight");
|
||||
}
|
||||
|
||||
const Resource::BlockType * Section::getBlockStateAt(block_idx_t, block_idx_t, block_idx_t) const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint8_t Section::getBiomeAt(block_idx_t x, block_idx_t y, block_idx_t z) const {
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
std::unique_ptr<Section> Section::makeSection(const std::shared_ptr<const NBT::CompoundTag> §ion, uint32_t dataVersion) {
|
||||
{
|
||||
const std::shared_ptr<const NBT::CompoundTag> blockStates = section->get<NBT::CompoundTag>("block_states");
|
||||
if (blockStates) {
|
||||
const std::shared_ptr<const NBT::ListTag> palette = assertValue(blockStates->get<NBT::ListTag>("palette"));
|
||||
std::shared_ptr<const NBT::LongArrayTag> data = blockStates->get<NBT::LongArrayTag>("data");
|
||||
|
||||
const std::shared_ptr<const NBT::CompoundTag> biomes = assertValue(section->get<NBT::CompoundTag>("biomes"));
|
||||
const std::shared_ptr<const NBT::ListTag> biomePalette = assertValue(biomes->get<NBT::ListTag>("palette"));
|
||||
std::shared_ptr<const NBT::LongArrayTag> biomeData = biomes->get<NBT::LongArrayTag>("data");
|
||||
|
||||
return std::unique_ptr<Section>(new PaletteSection(
|
||||
section, std::move(data), palette, std::move(biomeData), biomePalette, dataVersion
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::shared_ptr<const NBT::LongArrayTag> blockStates = section->get<NBT::LongArrayTag>("BlockStates");
|
||||
if (blockStates) {
|
||||
const std::shared_ptr<const NBT::ListTag> palette = assertValue(section->get<NBT::ListTag>("Palette"));
|
||||
|
||||
return std::unique_ptr<Section>(new PaletteSection(
|
||||
section, std::move(blockStates), palette,
|
||||
std::shared_ptr<const NBT::LongArrayTag>(), std::shared_ptr<const NBT::ListTag>(), dataVersion
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::shared_ptr<const NBT::ByteArrayTag> blocks = section->get<NBT::ByteArrayTag>("Blocks");
|
||||
if (blocks) {
|
||||
std::shared_ptr<const NBT::ByteArrayTag> data = assertValue(section->get<NBT::ByteArrayTag>("Data"));
|
||||
|
||||
return std::unique_ptr<Section>(new LegacySection(section, std::move(blocks), std::move(data)));
|
||||
}
|
||||
}
|
||||
|
||||
return std::unique_ptr<Section>(new Section(section));
|
||||
}
|
||||
|
||||
|
||||
const Resource::BlockType * LegacySection::getBlockStateAt(block_idx_t x, block_idx_t y, block_idx_t z) const {
|
||||
uint8_t type = getBlockAt(x, y, z);
|
||||
uint8_t data = getDataAt(x, y, z);
|
||||
|
||||
return Resource::LEGACY_BLOCK_TYPES.types[type][data];
|
||||
}
|
||||
|
||||
|
||||
const Resource::BlockType * PaletteSection::lookup(const std::string &name, uint32_t dataVersion) {
|
||||
if (dataVersion < 1900 && name == "minecraft:stone_slab")
|
||||
return Resource::BlockType::lookup("minecraft:smooth_stone_slab");
|
||||
|
||||
return Resource::BlockType::lookup(name);
|
||||
}
|
||||
|
||||
PaletteSection::PaletteSection(
|
||||
const std::shared_ptr<const NBT::CompoundTag> §ion,
|
||||
std::shared_ptr<const NBT::LongArrayTag> &&blockStates0,
|
||||
const std::shared_ptr<const NBT::ListTag> &paletteData,
|
||||
std::shared_ptr<const NBT::LongArrayTag> &&biomes0,
|
||||
const std::shared_ptr<const NBT::ListTag> &biomePaletteData,
|
||||
uint32_t dataVersion0
|
||||
) : Section(section), blockStates(blockStates0), biomes(biomes0), dataVersion(dataVersion0) {
|
||||
bits = 4;
|
||||
while ((1u << bits) < paletteData->size()) {
|
||||
bits++;
|
||||
|
||||
if (bits > 12)
|
||||
throw std::invalid_argument("unsupported block palette size");
|
||||
}
|
||||
|
||||
biomeBits = 1;
|
||||
if (biomePaletteData) {
|
||||
while ((1u << biomeBits) < biomePaletteData->size()) {
|
||||
biomeBits++;
|
||||
|
||||
if (biomeBits > 6)
|
||||
throw std::invalid_argument("unsupported biome palette size");
|
||||
}
|
||||
}
|
||||
|
||||
unsigned expectedLength;
|
||||
|
||||
if (dataVersion < 2529) {
|
||||
expectedLength = 64 * bits;
|
||||
} else {
|
||||
unsigned blocksPerWord = (64 / bits);
|
||||
expectedLength = (4096 + blocksPerWord - 1) / blocksPerWord;
|
||||
}
|
||||
|
||||
if (blockStates && blockStates->getLength() != expectedLength)
|
||||
throw std::invalid_argument("corrupt section block data");
|
||||
|
||||
unsigned biomesPerWord = (64 / biomeBits);
|
||||
unsigned expectedBiomeLength = (64 + biomesPerWord - 1) / biomesPerWord;
|
||||
|
||||
if (biomes && biomes->getLength() != expectedBiomeLength)
|
||||
throw std::invalid_argument("corrupt section biome data");
|
||||
|
||||
for (const auto &entry : *paletteData) {
|
||||
const NBT::CompoundTag &paletteEntry = *assertValue(dynamic_cast<const NBT::CompoundTag *>(entry.get()));
|
||||
std::string name = assertValue(paletteEntry.get<NBT::StringTag>("Name"))->getValue();
|
||||
|
||||
const Resource::BlockType *type = lookup(name, dataVersion);
|
||||
if (!type)
|
||||
std::fprintf(stderr, "Warning: unknown block type: %s\n", name.c_str());
|
||||
|
||||
palette.push_back(type);
|
||||
}
|
||||
|
||||
if (biomePaletteData) {
|
||||
for (const auto &entry : *biomePaletteData) {
|
||||
const NBT::StringTag &paletteEntry =
|
||||
*assertValue(dynamic_cast<const NBT::StringTag *>(entry.get()));
|
||||
std::string name = paletteEntry.getValue();
|
||||
|
||||
auto it = Resource::Biome::Names.find(name);
|
||||
uint8_t biome;
|
||||
if (it != Resource::Biome::Names.end()) {
|
||||
biome = it->second;
|
||||
} else {
|
||||
std::fprintf(stderr, "Warning: unknown biome: %s\n", name.c_str());
|
||||
biome = 0xff;
|
||||
}
|
||||
|
||||
biomePalette.push_back(biome);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Resource::BlockType * PaletteSection::getBlockStateAt(block_idx_t x, block_idx_t y, block_idx_t z) const {
|
||||
if (!blockStates)
|
||||
return palette.at(0);
|
||||
|
||||
size_t index = getIndex(x, y, z);
|
||||
size_t bitIndex;
|
||||
|
||||
if (dataVersion < 2529) {
|
||||
bitIndex = bits * index;
|
||||
} else {
|
||||
unsigned blocksPerWord = (64 / bits);
|
||||
size_t word = index / blocksPerWord;
|
||||
bitIndex = 64 * word + bits * (index % blocksPerWord);
|
||||
}
|
||||
|
||||
size_t pos = bitIndex >> 3;
|
||||
unsigned shift = bitIndex & 7;
|
||||
uint16_t mask = (1u << bits) - 1;
|
||||
|
||||
uint32_t v = blockStates->getPointer()[mangleByteIndex(pos)];
|
||||
|
||||
if (shift + bits > 8)
|
||||
v |= blockStates->getPointer()[mangleByteIndex(pos + 1)] << 8;
|
||||
if (shift + bits > 16)
|
||||
v |= blockStates->getPointer()[mangleByteIndex(pos + 2)] << 16;
|
||||
/* We do not need to check for shift+bits > 24: bits should never
|
||||
be greater than 12, so our value will never span more than 3 bytes */
|
||||
|
||||
return palette.at((v >> shift) & mask);
|
||||
}
|
||||
|
||||
uint8_t PaletteSection::getBiomeAt(block_idx_t x, block_idx_t y, block_idx_t z) const {
|
||||
if (!biomes)
|
||||
return biomePalette.at(0);
|
||||
|
||||
size_t index = getBiomeIndex(x, y, z);
|
||||
|
||||
unsigned biomesPerWord = (64 / biomeBits);
|
||||
size_t word = index / biomesPerWord;
|
||||
size_t bitIndex = 64 * word + biomeBits * (index % biomesPerWord);
|
||||
|
||||
size_t pos = bitIndex >> 3;
|
||||
unsigned shift = bitIndex & 7;
|
||||
uint16_t mask = (1u << biomeBits) - 1;
|
||||
|
||||
uint32_t v = biomes->getPointer()[mangleByteIndex(pos)];
|
||||
|
||||
if (shift + biomeBits > 8)
|
||||
v |= biomes->getPointer()[mangleByteIndex(pos + 1)] << 8;
|
||||
/* We do not need to check for shift+bits > 16: biomeBits should never
|
||||
be greater than 6, so our value will never span more than 2 bytes */
|
||||
|
||||
return biomePalette.at((v >> shift) & mask);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,142 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2015-2021, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "../NBT/ByteArrayTag.hpp"
|
||||
#include "../NBT/CompoundTag.hpp"
|
||||
#include "../NBT/ListTag.hpp"
|
||||
#include "../NBT/LongArrayTag.hpp"
|
||||
#include "../Resource/BlockType.hpp"
|
||||
#include "../Util.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
namespace MinedMap {
|
||||
namespace World {
|
||||
|
||||
class Section {
|
||||
public:
|
||||
// Number of blocks in a section in each dimension
|
||||
static const uint32_t SIZE = 16;
|
||||
|
||||
// Since Minecraft 1.15, biome information is stored for
|
||||
// 4x4x4 block groups
|
||||
static const unsigned BSHIFT = 2;
|
||||
// Number of biome values in a chunk in x/z dimensions
|
||||
static const uint32_t BSIZE = SIZE >> BSHIFT;
|
||||
|
||||
|
||||
private:
|
||||
section_idx_t Y;
|
||||
std::shared_ptr<const NBT::ByteArrayTag> blockLight;
|
||||
|
||||
protected:
|
||||
static size_t getIndex(block_idx_t x, block_idx_t y, block_idx_t z) {
|
||||
if (x >= SIZE || y >= SIZE || z >= SIZE)
|
||||
throw std::range_error("Section::getIndex(): bad coordinates");
|
||||
|
||||
return SIZE*SIZE*y + SIZE*z + x;
|
||||
}
|
||||
|
||||
static size_t getBiomeIndex(block_idx_t x, block_idx_t y, block_idx_t z) {
|
||||
if (x >= SIZE || y >= SIZE || z >= SIZE)
|
||||
throw std::range_error("Section::getBiomeIndex(): bad coordinates");
|
||||
|
||||
return BSIZE*BSIZE*(y>>BSHIFT) + BSIZE*(z>>BSHIFT) + (x>>BSHIFT);
|
||||
}
|
||||
|
||||
static uint8_t getHalf(const uint8_t *v, block_idx_t x, block_idx_t y, block_idx_t z) {
|
||||
size_t i = getIndex(x, y, z);
|
||||
|
||||
if (i % 2)
|
||||
return (v[i/2] >> 4);
|
||||
else
|
||||
return (v[i/2] & 0xf);
|
||||
}
|
||||
|
||||
Section(const std::shared_ptr<const NBT::CompoundTag> §ion);
|
||||
|
||||
public:
|
||||
virtual ~Section() {}
|
||||
|
||||
section_idx_t getY() const { return Y; };
|
||||
|
||||
virtual const Resource::BlockType * getBlockStateAt(block_idx_t x, block_idx_t y, block_idx_t z) const;
|
||||
virtual uint8_t getBiomeAt(block_idx_t x, block_idx_t y, block_idx_t z) const;
|
||||
|
||||
uint8_t getBlockLightAt(block_idx_t x, block_idx_t y, block_idx_t z) const {
|
||||
if (!blockLight)
|
||||
return 0;
|
||||
|
||||
return getHalf(blockLight->getPointer(), x, y, z);
|
||||
}
|
||||
|
||||
static std::unique_ptr<Section> makeSection(const std::shared_ptr<const NBT::CompoundTag> §ion, uint32_t dataVersion);
|
||||
};
|
||||
|
||||
class LegacySection : public Section {
|
||||
private:
|
||||
std::shared_ptr<const NBT::ByteArrayTag> blocks;
|
||||
std::shared_ptr<const NBT::ByteArrayTag> data;
|
||||
|
||||
|
||||
uint8_t getBlockAt(block_idx_t x, block_idx_t y, block_idx_t z) const {
|
||||
return blocks->getValue(getIndex(x, y, z));
|
||||
}
|
||||
|
||||
uint8_t getDataAt(block_idx_t x, block_idx_t y, block_idx_t z) const {
|
||||
return getHalf(data->getPointer(), x, y, z);
|
||||
}
|
||||
|
||||
public:
|
||||
LegacySection(
|
||||
const std::shared_ptr<const NBT::CompoundTag> §ion,
|
||||
std::shared_ptr<const NBT::ByteArrayTag> &&blocks0,
|
||||
std::shared_ptr<const NBT::ByteArrayTag> &&data0
|
||||
) : Section(section), blocks(blocks0), data(data0) {}
|
||||
|
||||
virtual const Resource::BlockType * getBlockStateAt(block_idx_t x, block_idx_t y, block_idx_t z) const;
|
||||
};
|
||||
|
||||
class PaletteSection : public Section {
|
||||
private:
|
||||
std::shared_ptr<const NBT::LongArrayTag> blockStates;
|
||||
std::vector<const Resource::BlockType *> palette;
|
||||
unsigned bits;
|
||||
|
||||
std::shared_ptr<const NBT::LongArrayTag> biomes;
|
||||
std::vector<uint8_t> biomePalette;
|
||||
unsigned biomeBits;
|
||||
|
||||
uint32_t dataVersion;
|
||||
|
||||
static const Resource::BlockType * lookup(const std::string &name, uint32_t dataVersion);
|
||||
|
||||
static size_t mangleByteIndex(size_t index) {
|
||||
return (index & ~(size_t)7) + 7 - (index & 7);
|
||||
}
|
||||
|
||||
public:
|
||||
PaletteSection(
|
||||
const std::shared_ptr<const NBT::CompoundTag> §ion,
|
||||
std::shared_ptr<const NBT::LongArrayTag> &&blockStates0,
|
||||
const std::shared_ptr<const NBT::ListTag> &paletteData,
|
||||
std::shared_ptr<const NBT::LongArrayTag> &&biomes0,
|
||||
const std::shared_ptr<const NBT::ListTag> &biomePaletteData,
|
||||
uint32_t dataVersion0
|
||||
);
|
||||
|
||||
virtual const Resource::BlockType * getBlockStateAt(block_idx_t x, block_idx_t y, block_idx_t z) const;
|
||||
virtual uint8_t getBiomeAt(block_idx_t x, block_idx_t y, block_idx_t z) const;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2018, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "Buffer.hpp"
|
||||
#include "GZip.hpp"
|
||||
#include "Util.hpp"
|
||||
#include "NBT/Tag.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
using namespace MinedMap;
|
||||
|
||||
if (argc != 2) {
|
||||
std::fprintf(stderr, "Usage: %s <nbtfile>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> buffer = readGZip(argv[1]);
|
||||
|
||||
Buffer nbt(buffer.data(), buffer.size());
|
||||
std::pair<std::string, std::shared_ptr<const NBT::Tag>> tag = NBT::Tag::readNamedTag(&nbt);
|
||||
if (tag.first != "")
|
||||
throw std::invalid_argument("invalid root tag");
|
||||
|
||||
std::cout << *tag.second << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
Copyright (c) 2018-2021, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "Buffer.hpp"
|
||||
#include "GZip.hpp"
|
||||
#include "Util.hpp"
|
||||
#include "NBT/Tag.hpp"
|
||||
#include "World/Region.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
using namespace MinedMap;
|
||||
|
||||
if (argc != 2) {
|
||||
std::fprintf(stderr, "Usage: %s <regionfile>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
World::Region::visitChunks(argv[1], [&] (chunk_idx_t X, chunk_idx_t Z, const World::ChunkData *chunk) {
|
||||
std::cout << "Chunk(" << unsigned(X) << ", " << unsigned(Z) << "): "
|
||||
<< *chunk->getRoot() << std::endl;
|
||||
});
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue