Skip to content

Commit e613b59

Browse files
authored
[1.21.4] Expose vanilla model generators for modded usages (#1725)
1 parent 17ebc64 commit e613b59

File tree

217 files changed

+2323
-6423
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

217 files changed

+2323
-6423
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--- a/net/minecraft/client/data/models/BlockModelGenerators.java
2+
+++ b/net/minecraft/client/data/models/BlockModelGenerators.java
3+
@@ -5819,4 +_,16 @@
4+
return this;
5+
}
6+
}
7+
+
8+
+ /**
9+
+ * Neo: create a {@link BlockModelGenerators.BlockFamilyProvider} which re-uses the existing model of the given full
10+
+ * block instead of creating a model and blockstate file for it. Intended for use cases where the full block is
11+
+ * separately generated or otherwise exists such as when a dummy {@link BlockFamily} is used to create additional
12+
+ * variants for existing vanilla block families
13+
+ */
14+
+ public BlockModelGenerators.BlockFamilyProvider familyWithExistingFullBlock(Block fullBlock) {
15+
+ var provider = new BlockModelGenerators.BlockFamilyProvider(TextureMapping.cube(fullBlock));
16+
+ provider.fullBlock = ModelLocationUtils.getModelLocation(fullBlock);
17+
+ return provider;
18+
+ }
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--- a/net/minecraft/client/data/models/EquipmentAssetProvider.java
2+
+++ b/net/minecraft/client/data/models/EquipmentAssetProvider.java
3+
@@ -26,6 +_,10 @@
4+
this.pathProvider = p_387559_.createPathProvider(PackOutput.Target.RESOURCE_PACK, "equipment");
5+
}
6+
7+
+ protected void registerModels(BiConsumer<ResourceKey<EquipmentAsset>, EquipmentClientInfo> output) {
8+
+ bootstrap(output);
9+
+ }
10+
+
11+
private static void bootstrap(BiConsumer<ResourceKey<EquipmentAsset>, EquipmentClientInfo> p_387865_) {
12+
p_387865_.accept(
13+
EquipmentAssets.LEATHER,
14+
@@ -106,7 +_,7 @@
15+
@Override
16+
public CompletableFuture<?> run(CachedOutput p_387304_) {
17+
Map<ResourceKey<EquipmentAsset>, EquipmentClientInfo> map = new HashMap<>();
18+
- bootstrap((p_386976_, p_388942_) -> {
19+
+ registerModels((p_386976_, p_388942_) -> {
20+
if (map.putIfAbsent(p_386976_, p_388942_) != null) {
21+
throw new IllegalStateException("Tried to register equipment asset twice for id: " + p_386976_);
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--- a/net/minecraft/client/data/models/ItemModelOutput.java
2+
+++ b/net/minecraft/client/data/models/ItemModelOutput.java
3+
@@ -10,4 +_,10 @@
4+
void accept(Item p_387543_, ItemModel.Unbaked p_386880_);
5+
6+
void copy(Item p_387316_, Item p_387995_);
7+
+
8+
+ /**
9+
+ * Neo: Pulled up from {@link ModelProvider.ItemInfoCollector} to give modders full control over the {@link net.minecraft.client.renderer.item.ClientItem} instead of just the {@link ItemModel.Unbaked} in {@link #accept(Item, ItemModel.Unbaked)
10+
+ */
11+
+ default void register(Item item, net.minecraft.client.renderer.item.ClientItem clientItem) {
12+
+ }
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
--- a/net/minecraft/client/data/models/ModelProvider.java
2+
+++ b/net/minecraft/client/data/models/ModelProvider.java
3+
@@ -34,20 +_,58 @@
4+
private final PackOutput.PathProvider blockStatePathProvider;
5+
private final PackOutput.PathProvider itemInfoPathProvider;
6+
private final PackOutput.PathProvider modelPathProvider;
7+
+ public final String modId;
8+
9+
+ // Neo: Use the constructor which accepts a mod ID.
10+
+ @Deprecated
11+
public ModelProvider(PackOutput p_388260_) {
12+
+ this(p_388260_, ResourceLocation.DEFAULT_NAMESPACE);
13+
+ }
14+
+
15+
+ public ModelProvider(PackOutput p_388260_, String modId) {
16+
this.blockStatePathProvider = p_388260_.createPathProvider(PackOutput.Target.RESOURCE_PACK, "blockstates");
17+
this.itemInfoPathProvider = p_388260_.createPathProvider(PackOutput.Target.RESOURCE_PACK, "items");
18+
this.modelPathProvider = p_388260_.createPathProvider(PackOutput.Target.RESOURCE_PACK, "models");
19+
+ this.modId = modId;
20+
+ }
21+
+
22+
+ protected void registerModels(BlockModelGenerators blockModels, ItemModelGenerators itemModels) {
23+
+ blockModels.run();
24+
+ itemModels.run();
25+
+ }
26+
+
27+
+ /**
28+
+ * Returns a {@link Stream stream} containing all {@link Block blocks} which must have their models/block states generated or {@link Stream#empty() empty} if none are desired.
29+
+ * <p>
30+
+ * When using providers for specific {@link Block block} usages, it is best to override this method returning the exact {@link Block blocks} which must be generated,
31+
+ * or {@link Stream#empty() empty} if generating only {@link Item item} models.
32+
+ * <p>
33+
+ * Default implementation generates models for {@link Block blocks} matching the given {@code modId}.
34+
+ * @see #getKnownItems()
35+
+ */
36+
+ protected Stream<? extends Holder<Block>> getKnownBlocks() {
37+
+ return BuiltInRegistries.BLOCK.listElements().filter(holder -> holder.getKey().location().getNamespace().equals(modId));
38+
+ }
39+
+
40+
+ /**
41+
+ * Returns a {@link Stream stream} containing all {@link Item items} which must have their models/client items generated or {@link Stream#empty() empty} if none are desired.
42+
+ * <p>
43+
+ * When using providers for specific {@link Item item} usages, it is best to override this method returning the exact {@link Item items} which must be generated,
44+
+ * or {@link Stream#empty() empty} if generating only {@link Block block} models (which have no respective {@link Item item}).
45+
+ * <p>
46+
+ * Default implementation generates models for {@link Item items} matching the given {@code modId}.
47+
+ * @see #getKnownBlocks()
48+
+ */
49+
+ protected Stream<? extends Holder<Item>> getKnownItems() {
50+
+ return BuiltInRegistries.ITEM.listElements().filter(holder -> holder.getKey().location().getNamespace().equals(modId));
51+
}
52+
53+
@Override
54+
public CompletableFuture<?> run(CachedOutput p_387857_) {
55+
- ModelProvider.ItemInfoCollector modelprovider$iteminfocollector = new ModelProvider.ItemInfoCollector();
56+
- ModelProvider.BlockStateGeneratorCollector modelprovider$blockstategeneratorcollector = new ModelProvider.BlockStateGeneratorCollector();
57+
+ ModelProvider.ItemInfoCollector modelprovider$iteminfocollector = new ModelProvider.ItemInfoCollector(this::getKnownItems);
58+
+ ModelProvider.BlockStateGeneratorCollector modelprovider$blockstategeneratorcollector = new ModelProvider.BlockStateGeneratorCollector(this::getKnownBlocks);
59+
ModelProvider.SimpleModelCollector modelprovider$simplemodelcollector = new ModelProvider.SimpleModelCollector();
60+
- new BlockModelGenerators(modelprovider$blockstategeneratorcollector, modelprovider$iteminfocollector, modelprovider$simplemodelcollector).run();
61+
- new ItemModelGenerators(modelprovider$iteminfocollector, modelprovider$simplemodelcollector).run();
62+
+ registerModels(new BlockModelGenerators(modelprovider$blockstategeneratorcollector, modelprovider$iteminfocollector, modelprovider$simplemodelcollector), new ItemModelGenerators(modelprovider$iteminfocollector, modelprovider$simplemodelcollector));
63+
modelprovider$blockstategeneratorcollector.validate();
64+
modelprovider$iteminfocollector.finalizeAndValidate();
65+
return CompletableFuture.allOf(
66+
@@ -63,12 +_,22 @@
67+
68+
@Override
69+
public String getName() {
70+
- return "Model Definitions";
71+
+ return "Model Definitions - " + modId;
72+
}
73+
74+
@OnlyIn(Dist.CLIENT)
75+
static class BlockStateGeneratorCollector implements Consumer<BlockStateGenerator> {
76+
private final Map<Block, BlockStateGenerator> generators = new HashMap<>();
77+
+ private final Supplier<Stream<? extends Holder<Block>>> knownBlocks;
78+
+
79+
+ public BlockStateGeneratorCollector(Supplier<Stream<? extends Holder<Block>>> knownBlocks) {
80+
+ this.knownBlocks = knownBlocks;
81+
+ }
82+
+
83+
+ @Deprecated // Neo: Provided for vanilla/multi-loader compatibility. Use constructor with Supplier parameter.
84+
+ public BlockStateGeneratorCollector() {
85+
+ this(BuiltInRegistries.BLOCK::listElements);
86+
+ }
87+
88+
public void accept(BlockStateGenerator p_388748_) {
89+
Block block = p_388748_.getBlock();
90+
@@ -79,9 +_,9 @@
91+
}
92+
93+
public void validate() {
94+
- Stream<Holder.Reference<Block>> stream = BuiltInRegistries.BLOCK.listElements().filter(p_388333_ -> true);
95+
+ Stream<? extends Holder<Block>> stream = knownBlocks.get();
96+
List<ResourceLocation> list = stream.filter(p_386843_ -> !this.generators.containsKey(p_386843_.value()))
97+
- .map(p_386823_ -> p_386823_.key().location())
98+
+ .map(p_386823_ -> p_386823_.unwrapKey().orElseThrow().location())
99+
.toList();
100+
if (!list.isEmpty()) {
101+
throw new IllegalStateException("Missing blockstate definitions for: " + list);
102+
@@ -97,6 +_,16 @@
103+
static class ItemInfoCollector implements ItemModelOutput {
104+
private final Map<Item, ClientItem> itemInfos = new HashMap<>();
105+
private final Map<Item, Item> copies = new HashMap<>();
106+
+ private final Supplier<Stream<? extends Holder<Item>>> knownItems;
107+
+
108+
+ public ItemInfoCollector(Supplier<Stream<? extends Holder<Item>>> knownItems) {
109+
+ this.knownItems = knownItems;
110+
+ }
111+
+
112+
+ @Deprecated // Neo: Provided for vanilla/multi-loader compatibility. Use constructor with Supplier parameter.
113+
+ public ItemInfoCollector() {
114+
+ this(BuiltInRegistries.ITEM::listElements);
115+
+ }
116+
117+
@Override
118+
public void accept(Item p_387063_, ItemModel.Unbaked p_388578_) {
119+
@@ -116,7 +_,7 @@
120+
}
121+
122+
public void finalizeAndValidate() {
123+
- BuiltInRegistries.ITEM.forEach(p_388426_ -> {
124+
+ knownItems.get().map(Holder::value).forEach(p_388426_ -> {
125+
if (!this.copies.containsKey(p_388426_)) {
126+
if (p_388426_ instanceof BlockItem blockitem && !this.itemInfos.containsKey(blockitem)) {
127+
ResourceLocation resourcelocation = ModelLocationUtils.getModelLocation(blockitem.getBlock());
128+
@@ -132,10 +_,9 @@
129+
this.register(p_386494_, clientitem);
130+
}
131+
});
132+
- List<ResourceLocation> list = BuiltInRegistries.ITEM
133+
- .listElements()
134+
+ List<ResourceLocation> list = knownItems.get()
135+
.filter(p_388636_ -> !this.itemInfos.containsKey(p_388636_.value()))
136+
- .map(p_388278_ -> p_388278_.key().location())
137+
+ .map(p_388278_ -> p_388278_.unwrapKey().orElseThrow().location())
138+
.toList();
139+
if (!list.isEmpty()) {
140+
throw new IllegalStateException("Missing item model definitions for: " + list);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--- a/net/minecraft/client/data/models/model/ModelLocationUtils.java
2+
+++ b/net/minecraft/client/data/models/model/ModelLocationUtils.java
3+
@@ -11,11 +_,13 @@
4+
public class ModelLocationUtils {
5+
@Deprecated
6+
public static ResourceLocation decorateBlockModelLocation(String p_388520_) {
7+
- return ResourceLocation.withDefaultNamespace("block/" + p_388520_);
8+
+ // Neo: Use ResourceLocation.parse to support modded paths
9+
+ return ResourceLocation.parse(p_388520_).withPrefix("block/");
10+
}
11+
12+
public static ResourceLocation decorateItemModelLocation(String p_387226_) {
13+
- return ResourceLocation.withDefaultNamespace("item/" + p_387226_);
14+
+ // Neo: Use ResourceLocation.parse to support modded paths
15+
+ return ResourceLocation.parse(p_387226_).withPrefix("item/");
16+
}
17+
18+
public static ResourceLocation getModelLocation(Block p_387758_, String p_388221_) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--- a/net/minecraft/client/data/models/model/ModelTemplate.java
2+
+++ b/net/minecraft/client/data/models/model/ModelTemplate.java
3+
@@ -52,6 +_,13 @@
4+
public ResourceLocation create(ResourceLocation p_388380_, TextureMapping p_387099_, BiConsumer<ResourceLocation, ModelInstance> p_387748_) {
5+
Map<TextureSlot, ResourceLocation> map = this.createMap(p_387099_);
6+
p_387748_.accept(p_388380_, () -> {
7+
+ return createBaseTemplate(p_388380_, map);
8+
+ });
9+
+ return p_388380_;
10+
+ }
11+
+
12+
+ // Neo: Reintroduced to allow subclasses to customize the serialization logic, many implementations just delegating
13+
+ public JsonObject createBaseTemplate(ResourceLocation p_388380_, Map<TextureSlot, ResourceLocation> map) {
14+
JsonObject jsonobject = new JsonObject();
15+
this.model.ifPresent(p_388657_ -> jsonobject.addProperty("parent", p_388657_.toString()));
16+
if (!map.isEmpty()) {
17+
@@ -61,11 +_,14 @@
18+
}
19+
20+
return jsonobject;
21+
- });
22+
- return p_388380_;
23+
}
24+
25+
private Map<TextureSlot, ResourceLocation> createMap(TextureMapping p_387972_) {
26+
return Streams.concat(this.requiredSlots.stream(), p_387972_.getForced()).collect(ImmutableMap.toImmutableMap(Function.identity(), p_387972_::get));
27+
+ }
28+
+
29+
+ // Neo: Allows modders to modify this template by adding new elements, custom loader, render types and other modifiers
30+
+ public net.neoforged.neoforge.client.model.generators.template.ExtendedModelTemplateBuilder extend() {
31+
+ return net.neoforged.neoforge.client.model.generators.template.ExtendedModelTemplateBuilder.of(this);
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--- a/net/minecraft/client/data/models/model/ModelTemplates.java
2+
+++ b/net/minecraft/client/data/models/model/ModelTemplates.java
3+
@@ -203,18 +_,18 @@
4+
}
5+
6+
public static ModelTemplate create(String p_386521_, TextureSlot... p_388561_) {
7+
- return new ModelTemplate(Optional.of(ResourceLocation.withDefaultNamespace("block/" + p_386521_)), Optional.empty(), p_388561_);
8+
+ return new ModelTemplate(Optional.of(ModelLocationUtils.decorateBlockModelLocation(p_386521_)), Optional.empty(), p_388561_);
9+
}
10+
11+
public static ModelTemplate createItem(String p_388248_, TextureSlot... p_386756_) {
12+
- return new ModelTemplate(Optional.of(ResourceLocation.withDefaultNamespace("item/" + p_388248_)), Optional.empty(), p_386756_);
13+
+ return new ModelTemplate(Optional.of(ModelLocationUtils.decorateItemModelLocation(p_388248_)), Optional.empty(), p_386756_);
14+
}
15+
16+
public static ModelTemplate createItem(String p_386727_, String p_387707_, TextureSlot... p_387856_) {
17+
- return new ModelTemplate(Optional.of(ResourceLocation.withDefaultNamespace("item/" + p_386727_)), Optional.of(p_387707_), p_387856_);
18+
+ return new ModelTemplate(Optional.of(ModelLocationUtils.decorateItemModelLocation(p_386727_)), Optional.of(p_387707_), p_387856_);
19+
}
20+
21+
public static ModelTemplate create(String p_386833_, String p_386662_, TextureSlot... p_387086_) {
22+
- return new ModelTemplate(Optional.of(ResourceLocation.withDefaultNamespace("block/" + p_386833_)), Optional.of(p_386662_), p_387086_);
23+
+ return new ModelTemplate(Optional.of(ModelLocationUtils.decorateBlockModelLocation(p_386833_)), Optional.of(p_386662_), p_387086_);
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--- a/net/minecraft/client/data/models/model/TextureMapping.java
2+
+++ b/net/minecraft/client/data/models/model/TextureMapping.java
3+
@@ -412,4 +_,12 @@
4+
ResourceLocation resourcelocation = BuiltInRegistries.ITEM.getKey(p_386842_);
5+
return resourcelocation.withPath(p_387396_ -> "item/" + p_387396_ + p_386898_);
6+
}
7+
+
8+
+ // Neo: Added to allow easier texture map copying
9+
+ public TextureMapping copy() {
10+
+ TextureMapping texturemapping = new TextureMapping();
11+
+ texturemapping.slots.putAll(this.slots);
12+
+ texturemapping.forcedSlots.addAll(this.forcedSlots);
13+
+ return texturemapping;
14+
+ }
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) NeoForged and contributors
3+
* SPDX-License-Identifier: LGPL-2.1-only
4+
*/
5+
6+
package net.neoforged.neoforge.client.extensions;
7+
8+
import java.util.function.UnaryOperator;
9+
import net.minecraft.client.data.models.model.ModelTemplate;
10+
import net.minecraft.client.data.models.model.TexturedModel;
11+
12+
public interface ITexturedModelExtension {
13+
/**
14+
* Returns a new textured model holding the modified {@link ModelTemplate}
15+
*/
16+
default TexturedModel updateTemplate(UnaryOperator<ModelTemplate> modifier) {
17+
return new TexturedModel(self().getMapping(), modifier.apply(self().getTemplate()));
18+
}
19+
20+
private TexturedModel self() {
21+
return (TexturedModel) this;
22+
}
23+
24+
interface Provider {
25+
/**
26+
* Returns a new provider which mutates the backing {@link ModelTemplate}
27+
*/
28+
default TexturedModel.Provider updateTemplate(UnaryOperator<ModelTemplate> modifier) {
29+
return block -> self().get(block).updateTemplate(modifier);
30+
}
31+
32+
private TexturedModel.Provider self() {
33+
return (TexturedModel.Provider) this;
34+
}
35+
}
36+
}

src/main/java/net/neoforged/neoforge/client/model/generators/BlockModelBuilder.java

-29
This file was deleted.

src/main/java/net/neoforged/neoforge/client/model/generators/BlockModelProvider.java

-24
This file was deleted.

0 commit comments

Comments
 (0)