Skip to content

Commit 048a4f3

Browse files
committed
Load render type from model JSON like neoforge.
Signed-off-by: 秋雨落 <i@rain.cx>
1 parent e437901 commit 048a4f3

4 files changed

Lines changed: 143 additions & 0 deletions

File tree

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package games.moegirl.sinocraft.sinocore.fabric.client;
2+
3+
import games.moegirl.sinocraft.sinocore.fabric.client.resource.RenderTypeLoader;
4+
import net.fabricmc.api.ClientModInitializer;
5+
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
6+
import net.minecraft.server.packs.PackType;
7+
8+
public class SinoCoreFabricClient implements ClientModInitializer {
9+
@Override
10+
public void onInitializeClient() {
11+
ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(RenderTypeLoader.INSTANCE);
12+
}
13+
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
package games.moegirl.sinocraft.sinocore.fabric.client.resource;
2+
3+
import com.google.gson.Gson;
4+
import com.google.gson.JsonElement;
5+
import com.google.gson.JsonObject;
6+
import games.moegirl.sinocraft.sinocore.SinoCore;
7+
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
8+
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
9+
import net.minecraft.client.renderer.ItemBlockRenderTypes;
10+
import net.minecraft.client.renderer.RenderType;
11+
import net.minecraft.core.registries.BuiltInRegistries;
12+
import net.minecraft.resources.ResourceLocation;
13+
import net.minecraft.server.packs.resources.ResourceManager;
14+
import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener;
15+
import net.minecraft.util.profiling.ProfilerFiller;
16+
import net.minecraft.world.level.block.Block;
17+
import org.jetbrains.annotations.Nullable;
18+
19+
import java.util.HashMap;
20+
import java.util.Map;
21+
22+
/**
23+
* Load render type from model JSON like neoforge.
24+
* <p>
25+
* It is <b>not really same</b> as neoforge one:
26+
* In neoforge, it applies to model. Here it applies to block/item directly. <br/>
27+
* It assumes model {@code example:block/some_block} is for block {@code example:some_block}. <br/>
28+
* And items are always use translucent render type in fabric. See {@link BlockRenderLayerMap}.
29+
*
30+
* @author qyl27
31+
* @see <a href="https://docs.neoforged.net/docs/1.21.1/resources/client/models/#render-types">Neoforge Docs - Render Types</a>
32+
*/
33+
public class RenderTypeLoader extends SimpleJsonResourceReloadListener implements IdentifiableResourceReloadListener {
34+
35+
private static final Map<Block, RenderType> MODIFIED_BLOCK_RENDER_TYPES = new HashMap<>();
36+
37+
private RenderTypeLoader() {
38+
super(new Gson(), "models");
39+
}
40+
41+
@Override
42+
protected void apply(Map<ResourceLocation, JsonElement> map, ResourceManager resourceManager, ProfilerFiller profiler) {
43+
profiler.push("sinocore_render_type_loader");
44+
45+
for (var entry : map.entrySet()) {
46+
var key = entry.getKey();
47+
var value = entry.getValue();
48+
49+
if (key.getPath().startsWith("block/")) {
50+
var id = ResourceLocation.fromNamespaceAndPath(key.getNamespace(), key.getPath().substring("block/".length()));
51+
applyForBlock(id, value);
52+
}
53+
}
54+
55+
profiler.pop();
56+
}
57+
58+
private void applyForBlock(ResourceLocation id, JsonElement value) {
59+
var blockOptional = BuiltInRegistries.BLOCK.getOptional(id);
60+
if (blockOptional.isEmpty()) {
61+
// Has no block with id, pass.
62+
return;
63+
}
64+
65+
var block = blockOptional.get();
66+
var existing = ItemBlockRenderTypes.TYPE_BY_BLOCK.get(block);
67+
var modified = MODIFIED_BLOCK_RENDER_TYPES.get(block);
68+
if (value instanceof JsonObject model) {
69+
if (model.has("render_type")) {
70+
var typeId = ResourceLocation.parse(model.get("render_type").getAsString());
71+
RenderType renderType = getVanillaBlockRenderType(typeId);
72+
if (renderType != null) {
73+
// It has a valid render type in model.
74+
if (renderType != existing) {
75+
// Apply our modify.
76+
BlockRenderLayerMap.INSTANCE.putBlock(block, renderType);
77+
MODIFIED_BLOCK_RENDER_TYPES.put(block, renderType);
78+
return;
79+
}
80+
}
81+
}
82+
}
83+
84+
if (modified != null) {
85+
// It has a render type previously, but now not, remove it.
86+
if (modified == existing) {
87+
ItemBlockRenderTypes.TYPE_BY_BLOCK.remove(block);
88+
}
89+
MODIFIED_BLOCK_RENDER_TYPES.remove(block);
90+
}
91+
}
92+
93+
private static final ResourceLocation SOLID = ResourceLocation.withDefaultNamespace("solid");
94+
private static final ResourceLocation CUTOUT = ResourceLocation.withDefaultNamespace("cutout");
95+
private static final ResourceLocation CUTOUT_MIPPED = ResourceLocation.withDefaultNamespace("cutout_mipped");
96+
private static final ResourceLocation CUTOUT_MIPPED_ALL = ResourceLocation.withDefaultNamespace("cutout_mipped_all");
97+
private static final ResourceLocation TRANSLUCENT = ResourceLocation.withDefaultNamespace("translucent");
98+
private static final ResourceLocation TRIPWIRE = ResourceLocation.withDefaultNamespace("tripwire");
99+
100+
private static @Nullable RenderType getVanillaBlockRenderType(ResourceLocation id) {
101+
if (SOLID.equals(id)) {
102+
return RenderType.solid();
103+
} else if (CUTOUT.equals(id)) {
104+
return RenderType.cutout();
105+
} else if (CUTOUT_MIPPED.equals(id) || CUTOUT_MIPPED_ALL.equals(id)) {
106+
return RenderType.cutoutMipped();
107+
} else if (TRANSLUCENT.equals(id)) {
108+
return RenderType.translucent();
109+
} else if (TRIPWIRE.equals(id)) {
110+
return RenderType.tripwire();
111+
}
112+
113+
return null;
114+
}
115+
116+
public static final RenderTypeLoader INSTANCE = new RenderTypeLoader();
117+
118+
private static final ResourceLocation ID = ResourceLocation.fromNamespaceAndPath(SinoCore.MODID, "render_type_loader");
119+
120+
@Override
121+
public ResourceLocation getFabricId() {
122+
return ID;
123+
}
124+
}

fabric/src/main/templates/fabric.mod.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
"entrypoints": {
2121
"main": [
2222
"games.moegirl.sinocraft.sinocore.fabric.SinoCoreFabric"
23+
],
24+
"client": [
25+
"games.moegirl.sinocraft.sinocore.fabric.client.SinoCoreFabricClient"
2326
]
2427
},
2528
"mixins": [

src/main/resources/sinocore.accesswidener

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@ accessible method net/minecraft/world/inventory/AbstractContainerMenu addSlot (L
44
accessible method net/minecraft/advancements/CriteriaTriggers register (Ljava/lang/String;Lnet/minecraft/advancements/CriterionTrigger;)Lnet/minecraft/advancements/CriterionTrigger;
55
accessible field net/minecraft/server/network/ServerCommonPacketListenerImpl connection Lnet/minecraft/network/Connection;
66
accessible method net/minecraft/client/gui/components/ImageWidget <init> (IIII)V
7+
8+
# For RenderTypeLoader in Fabric
9+
accessible field net/minecraft/client/renderer/ItemBlockRenderTypes TYPE_BY_BLOCK Ljava/util/Map;

0 commit comments

Comments
 (0)