From bfdf7fa7ce024d28130c8db53dc8f0d3dcf07255 Mon Sep 17 00:00:00 2001 From: "Blue (Lukas Rieger)" Date: Sun, 5 Jan 2020 18:52:30 +0100 Subject: [PATCH] Add bluemap:missing block and basic unit tests. The bluemap:missing block will be used as fallback if bluemap cant render another block for some reason. The unit tests are just the setup, they will need to catch up over time ^^ --- .github/workflows/gradle.yml | 2 + .../bluecolored/bluemap/cli/BlueMapCLI.java | 3 +- .../bluecolored/bluemap/cli/RenderTask.java | 4 +- BlueMapCore/build.gradle | 2 + .../bluemap/core/config/BlockIdConfig.java | 2 +- .../core/config/BlockPropertiesConfig.java | 45 +++++++-- .../bluemap/core/mca/ChunkAnvil113.java | 2 +- .../bluemap/core/mca/MCAWorld.java | 2 +- .../core/render/hires/HiresModelRenderer.java | 14 ++- .../core/resourcepack/BlockModelResource.java | 58 +++++++++++- .../bluemap/core/world/BlockProperties.java | 2 +- .../bluemap/core/world/BlockState.java | 23 +---- .../assets/bluemap/blockstates/missing.json | 5 + .../assets/bluemap/models/block/missing.json | 6 ++ .../assets/bluemap/textures/block/missing.png | Bin 0 -> 2826 bytes .../src/main/resources/resourceExtensions.zip | Bin 1552 -> 5752 bytes .../bluemap/core/world/BlockStateTest.java | 86 ++++++++++++++++++ .../bluemap/sponge/SpongePlugin.java | 2 + 18 files changed, 220 insertions(+), 38 deletions(-) create mode 100644 BlueMapCore/src/main/resourceExtensions/assets/bluemap/blockstates/missing.json create mode 100644 BlueMapCore/src/main/resourceExtensions/assets/bluemap/models/block/missing.json create mode 100644 BlueMapCore/src/main/resourceExtensions/assets/bluemap/textures/block/missing.png create mode 100644 BlueMapCore/src/test/java/de/bluecolored/bluemap/core/world/BlockStateTest.java diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 8600fe13..555de4f0 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -11,6 +11,8 @@ jobs: uses: actions/setup-java@v1 with: java-version: 1.8 + - name: Test with Gradle + run: ./gradlew test - name: Build with Gradle run: ./gradlew shadowJar - uses: actions/upload-artifact@v1 diff --git a/BlueMapCLI/src/main/java/de/bluecolored/bluemap/cli/BlueMapCLI.java b/BlueMapCLI/src/main/java/de/bluecolored/bluemap/cli/BlueMapCLI.java index 510af72b..3690787e 100644 --- a/BlueMapCLI/src/main/java/de/bluecolored/bluemap/cli/BlueMapCLI.java +++ b/BlueMapCLI/src/main/java/de/bluecolored/bluemap/cli/BlueMapCLI.java @@ -90,7 +90,8 @@ public void renderMaps() throws IOException { config.getWebDataPath().toFile().mkdirs(); Map maps = new HashMap<>(); - + + configManager.getBlockPropertiesConfig().setResourcePack(resourcePack); for (MapConfig mapConfig : config.getMapConfigs()) { File mapPath = new File(mapConfig.getWorldPath()); if (!mapPath.exists() || !mapPath.isDirectory()) { diff --git a/BlueMapCLI/src/main/java/de/bluecolored/bluemap/cli/RenderTask.java b/BlueMapCLI/src/main/java/de/bluecolored/bluemap/cli/RenderTask.java index e1e9fac3..782eb20b 100644 --- a/BlueMapCLI/src/main/java/de/bluecolored/bluemap/cli/RenderTask.java +++ b/BlueMapCLI/src/main/java/de/bluecolored/bluemap/cli/RenderTask.java @@ -134,7 +134,9 @@ public void render() { long ert = (long)((time / pct) * (1d - pct)); String ertDurationString = DurationFormatUtils.formatDurationWords(ert, true, true); - Logger.global.logInfo("Rendered " + renderedTiles + " of " + tileCount + " tiles in " + durationString); + double tps = renderedTiles / (time / 1000.0); + + Logger.global.logInfo("Rendered " + renderedTiles + " of " + tileCount + " tiles in " + durationString + " | " + GenericMath.round(tps, 3) + " tiles/s"); Logger.global.logInfo(GenericMath.round(pct * 100, 3) + "% | Estimated remaining time: " + ertDurationString); } diff --git a/BlueMapCore/build.gradle b/BlueMapCore/build.gradle index 9b5bc5a9..660a351f 100644 --- a/BlueMapCore/build.gradle +++ b/BlueMapCore/build.gradle @@ -8,6 +8,8 @@ dependencies { compile 'ninja.leaping.configurate:configurate-gson:3.3' compile 'ninja.leaping.configurate:configurate-yaml:3.3' compile 'com.github.Querz:NBT:4.0' + + testCompile 'junit:junit:4.12' } task zipWebroot(type: Zip) { diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BlockIdConfig.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BlockIdConfig.java index 4fe6f648..4a9dd2ab 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BlockIdConfig.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BlockIdConfig.java @@ -84,7 +84,7 @@ public BlockState get(int id, int meta) { BlockState state = mappings.get(idmeta); if (state == null) { - state = mappings.getOrDefault(new BlockIDMeta(id, 0), BlockState.AIR); //meta-fallback + state = mappings.getOrDefault(new BlockIDMeta(id, 0), BlockState.MISSING); //meta-fallback if (autopoulationConfigLoader != null) { mappings.put(idmeta, state); diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BlockPropertiesConfig.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BlockPropertiesConfig.java index 86125a81..269602be 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BlockPropertiesConfig.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BlockPropertiesConfig.java @@ -31,11 +31,14 @@ import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; -import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; +import com.google.common.collect.MultimapBuilder; import de.bluecolored.bluemap.core.logger.Logger; import de.bluecolored.bluemap.core.mca.mapping.BlockPropertiesMapper; +import de.bluecolored.bluemap.core.resourcepack.NoSuchResourceException; +import de.bluecolored.bluemap.core.resourcepack.ResourcePack; +import de.bluecolored.bluemap.core.resourcepack.TransformedBlockModelResource; import de.bluecolored.bluemap.core.world.BlockProperties; import de.bluecolored.bluemap.core.world.BlockState; import ninja.leaping.configurate.ConfigurationNode; @@ -48,6 +51,8 @@ public class BlockPropertiesConfig implements BlockPropertiesMapper { private Multimap> mappings; private LoadingCache mappingCache; + private ResourcePack resourcePack = null; + public BlockPropertiesConfig(ConfigurationNode node) throws IOException { this(node, null); } @@ -55,7 +60,7 @@ public BlockPropertiesConfig(ConfigurationNode node) throws IOException { public BlockPropertiesConfig(ConfigurationNode node, ConfigurationLoader autopoulationConfigLoader) throws IOException { this.autopoulationConfigLoader = autopoulationConfigLoader; - mappings = HashMultimap.create(); + mappings = MultimapBuilder.hashKeys().arrayListValues().build(); for (Entry e : node.getChildrenMap().entrySet()){ String key = e.getKey().toString(); @@ -81,6 +86,14 @@ public BlockPropertiesConfig(ConfigurationNode node, ConfigurationLoader(new BlockState(bs.getFullId()), generated)); if (autopoulationConfigLoader != null) { - mappings.put(bs.getFullId(), new BlockStateMapping(new BlockState(bs.getFullId()), BlockProperties.DEFAULT)); - synchronized (autopoulationConfigLoader) { try { ConfigurationNode node = autopoulationConfigLoader.load(); ConfigurationNode bpNode = node.getNode(bs.getFullId()); - bpNode.getNode("culling").setValue(false); - bpNode.getNode("occluding").setValue(false); - bpNode.getNode("flammable").setValue(false); + bpNode.getNode("culling").setValue(generated.isCulling()); + bpNode.getNode("occluding").setValue(generated.isOccluding()); + bpNode.getNode("flammable").setValue(generated.isFlammable()); autopoulationConfigLoader.save(node); } catch (IOException ex) { Logger.global.noFloodError("blockpropsconf-autopopulate-ioex", "Failed to auto-populate BlockPropertiesConfig!", ex); @@ -115,7 +144,7 @@ private BlockProperties mapNoCache(BlockState bs){ } } - return BlockProperties.DEFAULT; + return generated; } } diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/ChunkAnvil113.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/ChunkAnvil113.java index 765d5465..a8bebeba 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/ChunkAnvil113.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/ChunkAnvil113.java @@ -188,7 +188,7 @@ public BlockState getBlockState(Vector3i pos) { if (value >= palette.length) { Logger.global.noFloodWarning("palettewarning", "Got palette value " + value + " but palette has size of " + palette.length + " (Future occasions of this error will not be logged)"); - return BlockState.AIR; + return BlockState.MISSING; } return palette[(int) value]; diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/MCAWorld.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/MCAWorld.java index 931334ea..cc910d0b 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/MCAWorld.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/MCAWorld.java @@ -139,7 +139,7 @@ public BlockState getBlockState(Vector3i pos) { return chunk.getBlockState(pos); } catch (Exception ex) { - return BlockState.AIR; + return BlockState.MISSING; } } diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/render/hires/HiresModelRenderer.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/render/hires/HiresModelRenderer.java index 3e8aaab2..5d6c13ad 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/render/hires/HiresModelRenderer.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/render/hires/HiresModelRenderer.java @@ -31,6 +31,7 @@ import de.bluecolored.bluemap.core.logger.Logger; import de.bluecolored.bluemap.core.render.RenderSettings; import de.bluecolored.bluemap.core.render.WorldTile; +import de.bluecolored.bluemap.core.render.context.ExtendedBlockContext; import de.bluecolored.bluemap.core.render.context.SlicedWorldChunkBlockContext; import de.bluecolored.bluemap.core.render.hires.blockmodel.BlockStateModel; import de.bluecolored.bluemap.core.render.hires.blockmodel.BlockStateModelFactory; @@ -39,6 +40,7 @@ import de.bluecolored.bluemap.core.util.AABB; import de.bluecolored.bluemap.core.util.MathUtils; import de.bluecolored.bluemap.core.world.Block; +import de.bluecolored.bluemap.core.world.BlockState; import de.bluecolored.bluemap.core.world.ChunkNotGeneratedException; import de.bluecolored.bluemap.core.world.WorldChunk; @@ -79,11 +81,19 @@ public HiresModel render(WorldTile tile, AABB region, RenderSettings renderSetti maxHeight = y; + ExtendedBlockContext context = new SlicedWorldChunkBlockContext(chunk, new Vector3i(x, y, z), renderSettings.getSliceY()); + BlockStateModel blockModel; try { - blockModel = modelFactory.createFrom(block.getBlock(), new SlicedWorldChunkBlockContext(chunk, new Vector3i(x, y, z), renderSettings.getSliceY()), renderSettings); + blockModel = modelFactory.createFrom(block.getBlock(), context, renderSettings); } catch (NoSuchResourceException e) { - blockModel = new BlockStateModel(); + try { + blockModel = modelFactory.createFrom(BlockState.MISSING, context, renderSettings); + } catch (NoSuchResourceException e2) { + e.addSuppressed(e2); + blockModel = new BlockStateModel(); + } + Logger.global.noFloodDebug(block.getBlock().getFullId() + "-hiresModelRenderer-blockmodelerr", "Failed to create BlockModel for BlockState: " + block.getBlock() + " (" + e.toString() + ")"); } diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/resourcepack/BlockModelResource.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/resourcepack/BlockModelResource.java index 5e7cbfee..3b6ce9ca 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/resourcepack/BlockModelResource.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/resourcepack/BlockModelResource.java @@ -54,6 +54,9 @@ public class BlockModelResource { private ModelType modelType = ModelType.NORMAL; + private boolean culling = false; + private boolean occluding = false; + private boolean ambientOcclusion = true; private Collection elements = new ArrayList<>(); private Map textures = new HashMap<>(); @@ -67,6 +70,14 @@ public ModelType getType() { public boolean isAmbientOcclusion() { return ambientOcclusion; } + + public boolean isCulling() { + return culling; + } + + public boolean isOccluding() { + return occluding; + } public Collection getElements() { return elements; @@ -82,7 +93,8 @@ public class Element { private Rotation rotation = new Rotation(); private boolean shade = true; private EnumMap faces = new EnumMap<>(Direction.class); - + private boolean fullCube = false; + private Element() {} public Vector4f getDefaultUV(Direction face) { @@ -137,6 +149,10 @@ public Rotation getRotation() { public boolean isShade() { return shade; } + + public boolean isFullCube() { + return fullCube; + } public EnumMap getFaces() { return faces; @@ -216,6 +232,8 @@ public static Builder builder(FileAccess sourcesAccess, ResourcePack resourcePac public static class Builder { private static final String JSON_COMMENT = "__comment"; + private static final Vector3f FULL_CUBE_FROM = Vector3f.ZERO; + private static final Vector3f FULL_CUBE_TO = new Vector3f(16f, 16f, 16f); private FileAccess sourcesAccess; private ResourcePack resourcePack; @@ -288,6 +306,35 @@ private BlockModelResource buildNoReset(String modelPath, boolean renderElements } } + //check block properties + for (Element element : blockModel.elements) { + if (element.isFullCube()) { + blockModel.occluding = true; + + blockModel.culling = true; + for (Direction dir : Direction.values()) { + Face face = element.faces.get(dir); + if (face == null) { + blockModel.culling = false; + break; + } + + Texture texture = face.getTexture(); + if (texture == null) { + blockModel.culling = false; + break; + } + + if (texture.getColor().getW() < 1) { + blockModel.culling = false; + break; + } + } + + break; + } + } + return blockModel; } @@ -297,7 +344,9 @@ private Element buildElement(BlockModelResource model, ConfigurationNode node, S element.from = readVector3f(node.getNode("from")); element.to = readVector3f(node.getNode("to")); - element.shade = node.getNode("shade").getBoolean(false); + element.shade = node.getNode("shade").getBoolean(true); + + boolean fullElement = element.from.equals(FULL_CUBE_FROM) && element.to.equals(FULL_CUBE_TO); if (!node.getNode("rotation").isVirtual()) { element.rotation.angle = node.getNode("rotation", "angle").getFloat(0); @@ -306,6 +355,7 @@ private Element buildElement(BlockModelResource model, ConfigurationNode node, S element.rotation.rescale = node.getNode("rotation", "rescale").getBoolean(false); } + boolean allDirs = true; for (Direction direction : Direction.values()) { ConfigurationNode faceNode = node.getNode("faces", direction.name().toLowerCase()); if (!faceNode.isVirtual()) { @@ -315,9 +365,13 @@ private Element buildElement(BlockModelResource model, ConfigurationNode node, S } catch (ParseResourceException | IOException ex) { Logger.global.logDebug("Failed to parse an " + direction + " face for the model " + topModelPath + "! " + ex); } + } else { + allDirs = false; } } + if (fullElement && allDirs) element.fullCube = true; + return element; } diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/world/BlockProperties.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/world/BlockProperties.java index c5bbb748..0ed1459e 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/world/BlockProperties.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/world/BlockProperties.java @@ -26,7 +26,7 @@ public class BlockProperties { - public static final BlockProperties DEFAULT = new BlockProperties(false, false, false); + public static final BlockProperties DEFAULT = new BlockProperties(true, true, false); private final boolean culling, occluding, flammable; diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/world/BlockState.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/world/BlockState.java index 2dcde1e2..b7f9e9a8 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/world/BlockState.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/world/BlockState.java @@ -42,9 +42,10 @@ */ public class BlockState { - private static Pattern BLOCKSTATE_SERIALIZATION_PATTERN = Pattern.compile("^(.+?)(?:\\[(.+)\\])?$"); + private static Pattern BLOCKSTATE_SERIALIZATION_PATTERN = Pattern.compile("^(.+?)(?:\\[(.*)\\])?$"); public static final BlockState AIR = new BlockState("minecraft:air", Collections.emptyMap()); + public static final BlockState MISSING = new BlockState("bluemap:missing", Collections.emptyMap()); private boolean hashed; private int hash; @@ -133,24 +134,6 @@ public BlockState with(String property, String value) { return new BlockState(this, property, value); } - public final boolean checkVariantCondition(String condition){ - if (condition.isEmpty() || condition.equals("normal")) return true; - - Map blockProperties = getProperties(); - String[] conditions = condition.split(","); - for (String c : conditions){ - String[] kv = c.split("=", 2); - String key = kv[0]; - String value = kv[1]; - - if (!value.equals(blockProperties.get(key))){ - return false; - } - } - - return true; - } - @Override public boolean equals(Object obj) { if (!(obj instanceof BlockState)) return false; @@ -187,7 +170,7 @@ public static BlockState fromString(String serializedBlockState) throws IllegalA Map pt = new HashMap<>(); String g2 = m.group(2); - if (g2 != null){ + if (g2 != null && !g2.isEmpty()){ String[] propertyStrings = g2.trim().split(","); for (String s : propertyStrings){ String[] kv = s.split("=", 2); diff --git a/BlueMapCore/src/main/resourceExtensions/assets/bluemap/blockstates/missing.json b/BlueMapCore/src/main/resourceExtensions/assets/bluemap/blockstates/missing.json new file mode 100644 index 00000000..d917d257 --- /dev/null +++ b/BlueMapCore/src/main/resourceExtensions/assets/bluemap/blockstates/missing.json @@ -0,0 +1,5 @@ +{ + "variants": { + "": { "model": "bluemap:block/missing" } + } +} \ No newline at end of file diff --git a/BlueMapCore/src/main/resourceExtensions/assets/bluemap/models/block/missing.json b/BlueMapCore/src/main/resourceExtensions/assets/bluemap/models/block/missing.json new file mode 100644 index 00000000..5995c0c0 --- /dev/null +++ b/BlueMapCore/src/main/resourceExtensions/assets/bluemap/models/block/missing.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "bluemap:block/missing" + } +} \ No newline at end of file diff --git a/BlueMapCore/src/main/resourceExtensions/assets/bluemap/textures/block/missing.png b/BlueMapCore/src/main/resourceExtensions/assets/bluemap/textures/block/missing.png new file mode 100644 index 0000000000000000000000000000000000000000..bbfd3944cfa4f8ecf201c7fb575dab9b75b9b23c GIT binary patch literal 2826 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 R22g;1ddC5P`tXed_&@$MR=@xN delta 166 zcmeyNGl7RMz?+$ci-CcIgCRS4w*N#v<;@>?4VYO#oXM(!hLbNA<}C zd?J$#MYI?rfGmZ{H9*!>AWL)d1raSKe#Xg#eDaf}MNOEx87Bvdx-cCEQBso^2(V4w pE~>@E$OPy9<>#EtBc{c)3MM2V7U0dw2C|702$wQ3FoZILcmVF#C!7EP diff --git a/BlueMapCore/src/test/java/de/bluecolored/bluemap/core/world/BlockStateTest.java b/BlueMapCore/src/test/java/de/bluecolored/bluemap/core/world/BlockStateTest.java new file mode 100644 index 00000000..e1232223 --- /dev/null +++ b/BlueMapCore/src/test/java/de/bluecolored/bluemap/core/world/BlockStateTest.java @@ -0,0 +1,86 @@ +/* + * This file is part of BlueMap, licensed under the MIT License (MIT). + * + * Copyright (c) Blue (Lukas Rieger) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package de.bluecolored.bluemap.core.world; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class BlockStateTest { + + @Test + public void testIdNamespace() { + BlockState blockState = new BlockState("someblock"); + assertEquals("minecraft:someblock", blockState.getFullId()); + assertEquals("minecraft", blockState.getNamespace()); + assertEquals("someblock", blockState.getId()); + + blockState = new BlockState("somemod:someblock"); + assertEquals("somemod:someblock", blockState.getFullId()); + assertEquals("somemod", blockState.getNamespace()); + assertEquals("someblock", blockState.getId()); + } + + @Test + public void testToString() { + BlockState blockState = new BlockState("someblock"); + assertEquals("minecraft:someblock[]", blockState.toString()); + + blockState = blockState.with("testProp", "testVal"); + assertEquals("minecraft:someblock[testProp=testVal]", blockState.toString()); + + blockState = blockState.with("testProp2", "testVal2"); + String toString = blockState.toString(); + assertTrue( + toString.equals("minecraft:someblock[testProp=testVal,testProp2=testVal2]") || + toString.equals("minecraft:someblock[testProp2=testVal2,testProp=testVal]") + ); + } + + + @Test + public void testFromString() { + BlockState blockState = BlockState.fromString("somemod:someblock"); + assertEquals("somemod:someblock", blockState.getFullId()); + assertEquals("somemod", blockState.getNamespace()); + assertEquals("someblock", blockState.getId()); + assertTrue(blockState.getProperties().isEmpty()); + + blockState = BlockState.fromString("somemod:someblock[]"); + assertEquals("somemod:someblock", blockState.getFullId()); + assertEquals("somemod", blockState.getNamespace()); + assertEquals("someblock", blockState.getId()); + assertTrue(blockState.getProperties().isEmpty()); + + blockState = BlockState.fromString("somemod:someblock[testProp=testVal,testProp2=testVal2]"); + assertEquals("somemod:someblock", blockState.getFullId()); + assertEquals("somemod", blockState.getNamespace()); + assertEquals("someblock", blockState.getId()); + assertEquals("testVal", blockState.getProperties().get("testProp")); + assertEquals("testVal2", blockState.getProperties().get("testProp2")); + } + +} diff --git a/BlueMapSponge/src/main/java/de/bluecolored/bluemap/sponge/SpongePlugin.java b/BlueMapSponge/src/main/java/de/bluecolored/bluemap/sponge/SpongePlugin.java index 428e7a82..c54c90bf 100644 --- a/BlueMapSponge/src/main/java/de/bluecolored/bluemap/sponge/SpongePlugin.java +++ b/BlueMapSponge/src/main/java/de/bluecolored/bluemap/sponge/SpongePlugin.java @@ -179,6 +179,8 @@ public synchronized void load() throws ExecutionException, IOException, Interrup resourcePack.loadBlockColorConfig(blockColorsConfigFile); resourcePack.saveTextureFile(textureExportFile); + configManager.getBlockPropertiesConfig().setResourcePack(resourcePack); + //load maps for (MapConfig mapConfig : config.getMapConfigs()) { String id = mapConfig.getId();