Created
August 7, 2022 05:19
-
-
Save ThatGravyBoat/3205b86119d3692c4b324da2d148cfef to your computer and use it in GitHub Desktop.
Block State Item Models
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Mixin(ItemModelShaper.class) | |
public class MixinItemModelShaper { | |
@Shadow @Final private ModelManager modelManager; | |
@Unique | |
private static final Int2ObjectMap<ModelResourceLocation> blockstatemodels$cache = new Int2ObjectOpenHashMap<>(); | |
@Inject(method = "getItemModel(Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/client/resources/model/BakedModel;", at = @At("HEAD"), cancellable = true) | |
public void onGetModel(ItemStack stack, CallbackInfoReturnable<BakedModel> cir) { | |
final Item item = stack.getItem(); | |
if (item instanceof BlockItem blockItem && blockstatemodels$canShowBlockStateModel(item)) { | |
if (stack.hasTag() && stack.getTag().contains("BlockStateTag", Tag.TAG_COMPOUND)) { | |
final CompoundTag tag = stack.getTag().getCompound("BlockStateTag"); | |
final int hash = tag.hashCode(); | |
if (!blockstatemodels$cache.containsKey(hash)) { | |
final Block block = blockItem.getBlock(); | |
final Map<String, String> states = new HashMap<>(); | |
final BlockState state = block.defaultBlockState(); | |
//noinspection rawtypes | |
for (Property property : state.getProperties()) states.put(property.getName(), blockstatemodels$getPropertyValue(property, state)); | |
for (String key : tag.getAllKeys()) states.put(key, tag.getString(key)); | |
final String[] stringStates = states.entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).toArray(String[]::new); | |
Arrays.sort(stringStates); | |
final ResourceLocation id = blockstatemodels$hasValue(block); | |
if (id != null) { | |
blockstatemodels$cache.put(hash, new ModelResourceLocation(id, String.join(",", stringStates))); | |
} | |
} | |
if (blockstatemodels$cache.containsKey(hash)) { | |
final ModelResourceLocation location = blockstatemodels$cache.get(hash); | |
if (location != null) { | |
final BakedModel model = this.modelManager.getModel(location); | |
if (model != this.modelManager.getMissingModel()) { | |
cir.setReturnValue(model); | |
} else { | |
blockstatemodels$cache.put(hash, null); | |
} | |
} | |
} | |
} | |
} | |
} | |
@Unique | |
@SuppressWarnings({"rawtypes", "unchecked"}) | |
private static String blockstatemodels$getPropertyValue(Property property, BlockState state) { | |
return property.getName(state.getValue(property)); | |
} | |
@Unique | |
private static boolean blockstatemodels$canShowBlockStateModel(Item item) { | |
if (item instanceof BlockItem blockItem) { | |
if (item instanceof ModelItemExtension extension && extension.canShowBlockStateModel()) { | |
return true; | |
} | |
return blockItem.getBlock() instanceof ModelItemExtension extension && extension.canShowBlockStateModel(); | |
} | |
return false; | |
} | |
@Unique | |
private static ResourceLocation blockstatemodels$hasValue(Block block) { | |
ResourceLocation key = Registry.BLOCK.getKey(block); | |
if (key == Registry.BLOCK.getDefaultKey() && Registry.BLOCK.get(key) != block) return null; | |
return key; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment