BlueMap/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/resourcepack/BlockStateResource.java

155 lines
5.2 KiB
Java

/*
* This file is part of BlueMap, licensed under the MIT License (MIT).
*
* Copyright (c) Blue (Lukas Rieger) <https://bluecolored.de>
* 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.resourcepack;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Vector;
import com.google.common.base.Preconditions;
import de.bluecolored.bluemap.core.util.WeighedArrayList;
import de.bluecolored.bluemap.core.world.BlockState;
import ninja.leaping.configurate.ConfigurationNode;
import ninja.leaping.configurate.gson.GsonConfigurationLoader;
public class BlockStateResource {
private BlockState block;
private Collection<WeighedArrayList<BlockModelResource>> modelResources;
protected BlockStateResource(BlockState block, ResourcePack resources) throws NoSuchResourceException, InvalidResourceDeclarationException {
this.block = Preconditions.checkNotNull(block);
this.modelResources = new Vector<>();
try {
ConfigurationNode data = GsonConfigurationLoader.builder()
.setSource(() -> new BufferedReader(new InputStreamReader(resources.getResource(getResourcePath()), StandardCharsets.UTF_8)))
.build()
.load();
load(data, resources);
} catch (IOException e) {
throw new NoSuchResourceException("There is no definition for resource-id: " + block.getId(), e);
} catch (NullPointerException e){
throw new InvalidResourceDeclarationException(e);
}
this.modelResources = Collections.unmodifiableCollection(this.modelResources);
}
private void load(ConfigurationNode data, ResourcePack resources) throws InvalidResourceDeclarationException {
//load variants
ConfigurationNode variants = data.getNode("variants");
for (Entry<Object, ? extends ConfigurationNode> e : variants.getChildrenMap().entrySet()){
if (getBlock().checkVariantCondition(e.getKey().toString())){
addModelResource(e.getValue(), resources);
break;
}
}
//load multipart
ConfigurationNode multipart = data.getNode("multipart");
for (ConfigurationNode part : multipart.getChildrenList()){
ConfigurationNode when = part.getNode("when");
if (when.isVirtual() || checkMultipartCondition(when)){
addModelResource(part.getNode("apply"), resources);
}
}
}
private void addModelResource(ConfigurationNode n, ResourcePack resources) throws InvalidResourceDeclarationException {
WeighedArrayList<BlockModelResource> models = new WeighedArrayList<>();
if (n.hasListChildren()){
//if it is a weighted list of alternative models, select one by random and weight
List<? extends ConfigurationNode> cList = n.getChildrenList();
for (ConfigurationNode c : cList){
int weight = c.getNode("weight").getInt(1);
models.add(new BlockModelResource(this, c, resources), weight);
}
} else {
models.add(new BlockModelResource(this, n, resources));
}
modelResources.add(models);
}
private boolean checkMultipartCondition(ConfigurationNode when){
ConfigurationNode or = when.getNode("OR");
if (!or.isVirtual()){
for (ConfigurationNode condition : or.getChildrenList()){
if (checkMultipartCondition(condition)) return true;
}
return false;
}
Map<String, String> blockProperties = getBlock().getProperties();
for (Entry<Object, ? extends ConfigurationNode> e : when.getChildrenMap().entrySet()){
String key = e.getKey().toString();
String[] values = e.getValue().getString().split("\\|");
boolean found = false;
for (String value : values){
if (value.equals(blockProperties.get(key))){
found = true;
break;
}
}
if (!found) return false;
}
return true;
}
public BlockState getBlock() {
return block;
}
public Collection<WeighedArrayList<BlockModelResource>> getModelResources(){
return modelResources;
}
private Path getResourcePath(){
return Paths.get("assets", block.getNamespace(), "blockstates", block.getId() + ".json");
}
}