SimpleMultipart/src/main/java/net/shadowfacts/simplemultipart/client/MultipartModelProvider.java

127 lines
4.5 KiB
Java
Raw Normal View History

2018-12-24 16:29:06 +00:00
package net.shadowfacts.simplemultipart.client;
import net.fabricmc.fabric.api.client.model.ModelProvider;
import net.fabricmc.fabric.api.client.model.ModelProviderException;
2018-12-24 20:43:12 +00:00
import net.minecraft.class_816;
2018-12-24 16:29:06 +00:00
import net.minecraft.client.MinecraftClient;
2018-12-24 16:36:59 +00:00
import net.minecraft.client.render.block.BlockModels;
2018-12-24 16:29:06 +00:00
import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.render.model.json.ModelVariantMap;
import net.minecraft.client.render.model.json.WeightedUnbakedModel;
import net.minecraft.client.util.ModelIdentifier;
import net.minecraft.resource.Resource;
2018-12-24 16:36:59 +00:00
import net.minecraft.resource.ResourceManager;
2018-12-24 16:29:06 +00:00
import net.minecraft.util.Identifier;
2018-12-24 16:36:59 +00:00
import net.shadowfacts.simplemultipart.SimpleMultipart;
import net.shadowfacts.simplemultipart.multipart.Multipart;
import net.shadowfacts.simplemultipart.multipart.MultipartState;
2018-12-24 16:29:06 +00:00
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.HashMap;
2018-12-24 16:36:59 +00:00
import java.util.HashSet;
2018-12-24 16:29:06 +00:00
import java.util.Map;
2018-12-24 16:36:59 +00:00
import java.util.Set;
import java.util.function.Consumer;
2018-12-24 16:29:06 +00:00
/**
* @author shadowfacts
*/
public class MultipartModelProvider implements ModelProvider {
2018-12-24 16:36:59 +00:00
private static final Set<ModelIdentifier> multipartModels = new HashSet<>();
2018-12-24 16:29:06 +00:00
private final Map<ModelIdentifier, UnbakedModel> unbakedModels = new HashMap<>();
2018-12-24 16:36:59 +00:00
static void registerMultipartModels(ResourceManager resourceManager, Consumer<ModelIdentifier> adder) {
for (Multipart part : SimpleMultipart.MULTIPART) {
Identifier partId = SimpleMultipart.MULTIPART.getId(part);
for (MultipartState state : part.getStateFactory().getStates()) {
String variant = BlockModels.propertyMapToString(state.getEntries());
ModelIdentifier id = new ModelIdentifier(partId, variant);
multipartModels.add(id);
adder.accept(id);
}
2018-12-24 16:47:50 +00:00
// TODO: should multiparts be able to control this?
multipartModels.add(new ModelIdentifier(partId, "inventory"));
2018-12-24 16:36:59 +00:00
}
}
2018-12-24 16:29:06 +00:00
@Override
public UnbakedModel load(Identifier id, Context context) throws ModelProviderException {
if (!(id instanceof ModelIdentifier)) {
return null;
}
ModelIdentifier modelId = (ModelIdentifier)id;
2018-12-24 16:36:59 +00:00
if (!multipartModels.contains(modelId)) {
2018-12-24 16:29:06 +00:00
return null;
}
try {
return getOrLoadPartModel(modelId);
} catch (IOException e) {
throw new ModelProviderException("Exception encountered while loading model " + id, e);
}
}
2018-12-24 20:43:12 +00:00
private UnbakedModel getOrLoadPartModel(ModelIdentifier modelId) throws ModelProviderException, IOException {
UnbakedModel existing = unbakedModels.get(modelId);
2018-12-24 16:29:06 +00:00
if (existing != null) {
return existing;
}
2018-12-24 20:43:12 +00:00
return loadPartModel(modelId);
2018-12-24 16:29:06 +00:00
}
2018-12-24 20:43:12 +00:00
private UnbakedModel loadPartModel(ModelIdentifier modelId) throws ModelProviderException, IOException {
Identifier partId = new Identifier(modelId.getNamespace(), modelId.getPath());
Identifier partStateDefId = new Identifier(partId.getNamespace(), "multipartstates/" + partId.getPath() + ".json");
Multipart part = SimpleMultipart.MULTIPART.get(partId);
MultipartFakeBlock blockAdapter = new MultipartFakeBlock(part);
ModelVariantMap variantMap = loadPartVariantMap(blockAdapter, partStateDefId);
if (variantMap.method_3422()) {
class_816 multipartUnbakedModel = variantMap.method_3421();
part.getStateFactory().getStates().forEach(state -> {
ModelIdentifier stateModelId = new ModelIdentifier(partId, BlockModels.propertyMapToString(state.getEntries()));
unbakedModels.put(stateModelId, multipartUnbakedModel);
});
} else {
Map<String, WeightedUnbakedModel> variants = variantMap.method_3423();
variants.forEach((variant, model) -> {
unbakedModels.put(new ModelIdentifier(partId, variant), model);
});
}
2018-12-24 16:29:06 +00:00
2018-12-24 20:43:12 +00:00
UnbakedModel model = unbakedModels.get(modelId);
2018-12-24 16:29:06 +00:00
if (model == null) {
2018-12-24 20:43:12 +00:00
throw new ModelProviderException("Loaded multipart state " + partStateDefId + " for model " + modelId + " but still missing model");
2018-12-24 16:29:06 +00:00
}
return model;
}
2018-12-24 20:43:12 +00:00
private ModelVariantMap loadPartVariantMap(MultipartFakeBlock blockAdapter, Identifier partStateDefId) throws IOException {
2018-12-24 16:29:06 +00:00
Resource resource = null;
Reader reader = null;
try {
2018-12-24 20:43:12 +00:00
resource = MinecraftClient.getInstance().getResourceManager().getResource(partStateDefId);
2018-12-24 16:29:06 +00:00
reader = new InputStreamReader(resource.getInputStream());
ModelVariantMap.class_791 context = new ModelVariantMap.class_791();
2018-12-24 20:43:12 +00:00
context.method_3426(blockAdapter.getStateFactory());
2018-12-24 16:29:06 +00:00
return ModelVariantMap.method_3424(context, reader);
} finally {
IOUtils.closeQuietly(reader);
IOUtils.closeQuietly(resource);
}
}
}