Only provide each mod its own model list in ModelBakeEvent
This commit is contained in:
parent
1b6880ed9f
commit
16d317af97
|
|
@ -1,22 +1,37 @@
|
||||||
package org.embeddedt.modernfix.forge.dynresources;
|
package org.embeddedt.modernfix.forge.dynresources;
|
||||||
|
|
||||||
import com.google.common.collect.ForwardingMap;
|
import com.google.common.collect.ForwardingMap;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.google.common.graph.GraphBuilder;
|
||||||
|
import com.google.common.graph.MutableGraph;
|
||||||
import net.minecraft.client.resources.model.BakedModel;
|
import net.minecraft.client.resources.model.BakedModel;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraftforge.fml.ModContainer;
|
||||||
|
import net.minecraftforge.fml.ModList;
|
||||||
|
import net.minecraftforge.forgespi.language.IModInfo;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
import org.embeddedt.modernfix.dynamicresources.ModelLocationCache;
|
import org.embeddedt.modernfix.dynamicresources.ModelLocationCache;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores a list of all known default block/item models in the game, and provides a namespaced version
|
||||||
|
* of the model registry that emulates vanilla keySet behavior.
|
||||||
|
*/
|
||||||
public class ModelBakeEventHelper {
|
public class ModelBakeEventHelper {
|
||||||
public static Map<ResourceLocation, BakedModel> wrapRegistry(Map<ResourceLocation, BakedModel> modelRegistry) {
|
private final Map<ResourceLocation, BakedModel> modelRegistry;
|
||||||
Set<ResourceLocation> topLevelModelLocations = new HashSet<>(modelRegistry.keySet());
|
private final Set<ResourceLocation> topLevelModelLocations;
|
||||||
|
private final MutableGraph<String> dependencyGraph;
|
||||||
|
public ModelBakeEventHelper(Map<ResourceLocation, BakedModel> modelRegistry) {
|
||||||
|
this.modelRegistry = modelRegistry;
|
||||||
|
this.topLevelModelLocations = new HashSet<>(modelRegistry.keySet());
|
||||||
for(Block block : ForgeRegistries.BLOCKS) {
|
for(Block block : ForgeRegistries.BLOCKS) {
|
||||||
for(BlockState state : block.getStateDefinition().getPossibleStates()) {
|
for(BlockState state : block.getStateDefinition().getPossibleStates()) {
|
||||||
topLevelModelLocations.add(ModelLocationCache.get(state));
|
topLevelModelLocations.add(ModelLocationCache.get(state));
|
||||||
|
|
@ -25,6 +40,28 @@ public class ModelBakeEventHelper {
|
||||||
for(Item item : ForgeRegistries.ITEMS) {
|
for(Item item : ForgeRegistries.ITEMS) {
|
||||||
topLevelModelLocations.add(ModelLocationCache.get(item));
|
topLevelModelLocations.add(ModelLocationCache.get(item));
|
||||||
}
|
}
|
||||||
|
this.dependencyGraph = GraphBuilder.undirected().build();
|
||||||
|
ModList.get().forEachModContainer((id, mc) -> {
|
||||||
|
this.dependencyGraph.addNode(id);
|
||||||
|
});
|
||||||
|
for(String id : this.dependencyGraph.nodes()) {
|
||||||
|
Optional<? extends ModContainer> mContainer = ModList.get().getModContainerById(id);
|
||||||
|
if(mContainer.isPresent()) {
|
||||||
|
for(IModInfo.ModVersion version : mContainer.get().getModInfo().getDependencies()) {
|
||||||
|
this.dependencyGraph.putEdge(id, version.getModId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<ResourceLocation, BakedModel> wrapRegistry(String modId) {
|
||||||
|
final Set<String> modIdsToInclude = new HashSet<>();
|
||||||
|
modIdsToInclude.add(modId);
|
||||||
|
try {
|
||||||
|
modIdsToInclude.addAll(this.dependencyGraph.adjacentNodes(modId));
|
||||||
|
} catch(IllegalArgumentException ignored) { /* sanity check */ }
|
||||||
|
modIdsToInclude.remove("minecraft");
|
||||||
|
Set<ResourceLocation> ourModelLocations = Sets.filter(this.topLevelModelLocations, loc -> modIdsToInclude.contains(loc.getNamespace()));
|
||||||
return new ForwardingMap<ResourceLocation, BakedModel>() {
|
return new ForwardingMap<ResourceLocation, BakedModel>() {
|
||||||
@Override
|
@Override
|
||||||
protected Map<ResourceLocation, BakedModel> delegate() {
|
protected Map<ResourceLocation, BakedModel> delegate() {
|
||||||
|
|
@ -33,18 +70,12 @@ public class ModelBakeEventHelper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<ResourceLocation> keySet() {
|
public Set<ResourceLocation> keySet() {
|
||||||
return topLevelModelLocations;
|
return ourModelLocations;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean containsKey(@Nullable Object key) {
|
public boolean containsKey(@Nullable Object key) {
|
||||||
return topLevelModelLocations.contains(key) || super.containsKey(key);
|
return ourModelLocations.contains(key) || super.containsKey(key);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BakedModel put(ResourceLocation key, BakedModel value) {
|
|
||||||
topLevelModelLocations.add(key);
|
|
||||||
return super.put(key, value);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,18 @@ package org.embeddedt.modernfix.forge.mixin.perf.dynamic_resources;
|
||||||
import net.minecraft.client.resources.model.BakedModel;
|
import net.minecraft.client.resources.model.BakedModel;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraftforge.client.ForgeHooksClient;
|
import net.minecraftforge.client.ForgeHooksClient;
|
||||||
|
import net.minecraftforge.client.event.ModelBakeEvent;
|
||||||
|
import net.minecraftforge.eventbus.api.Event;
|
||||||
|
import net.minecraftforge.fml.ModContainer;
|
||||||
|
import net.minecraftforge.fml.ModList;
|
||||||
|
import net.minecraftforge.fml.ModLoader;
|
||||||
|
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
|
||||||
import org.embeddedt.modernfix.forge.dynresources.ModelBakeEventHelper;
|
import org.embeddedt.modernfix.forge.dynresources.ModelBakeEventHelper;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@Mixin(ForgeHooksClient.class)
|
@Mixin(ForgeHooksClient.class)
|
||||||
|
|
@ -15,8 +22,21 @@ public class ForgeHooksClientMixin {
|
||||||
/**
|
/**
|
||||||
* Generate a more realistic keySet that contains every item and block model location, to help with mod compat.
|
* Generate a more realistic keySet that contains every item and block model location, to help with mod compat.
|
||||||
*/
|
*/
|
||||||
@ModifyVariable(method = "onModelBake", at = @At("HEAD"), ordinal = 0, argsOnly = true)
|
@Redirect(method = "onModelBake", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/ModLoader;postEvent(Lnet/minecraftforge/eventbus/api/Event;)V"))
|
||||||
private static Map<ResourceLocation, BakedModel> generateModelKeySet(Map<ResourceLocation, BakedModel> modelRegistry) {
|
private static void postNamespacedKeySetEvent(ModLoader loader, Event event) {
|
||||||
return ModelBakeEventHelper.wrapRegistry(modelRegistry);
|
if(!ModLoader.isLoadingStateValid())
|
||||||
|
return;
|
||||||
|
ModelBakeEvent bakeEvent = ((ModelBakeEvent)event);
|
||||||
|
ModelBakeEventHelper helper = new ModelBakeEventHelper(bakeEvent.getModelRegistry());
|
||||||
|
Method acceptEv = ObfuscationReflectionHelper.findMethod(ModContainer.class, "acceptEvent", Event.class);
|
||||||
|
ModList.get().forEachModContainer((id, mc) -> {
|
||||||
|
Map<ResourceLocation, BakedModel> newRegistry = helper.wrapRegistry(id);
|
||||||
|
ModelBakeEvent postedEvent = new ModelBakeEvent(bakeEvent.getModelManager(), newRegistry, bakeEvent.getModelLoader());
|
||||||
|
try {
|
||||||
|
acceptEv.invoke(mc, postedEvent);
|
||||||
|
} catch(ReflectiveOperationException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user