package com.tiedup.remake.v2.client; import com.tiedup.remake.blocks.entity.ModBlockEntities; import com.tiedup.remake.client.model.CellCoreBakedModel; import com.tiedup.remake.client.renderer.CellCoreRenderer; import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.v2.V2BlockEntities; import java.util.Map; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.event.EntityRenderersEvent; import net.minecraftforge.client.event.ModelEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; /** * V2 Client-side setup. * Registers block entity renderers, model replacements, and icon model overrides. * *

The icon override system allows data-driven bondage items and furniture placers * to display per-variant inventory sprites. Each JSON definition can specify an * optional {@code icon} field pointing to a model ResourceLocation. The model * is resolved at render time from the baked model registry.

* *

Icon models that correspond to existing registered items (e.g., "tiedup:item/armbinder") * are automatically available. For custom icon models that don't correspond to a registered * item, place the model JSON under {@code assets//models/item/icons/} and it * will be registered for baking via {@link ModelEvent.RegisterAdditional}.

*/ @Mod.EventBusSubscriber( modid = TiedUpMod.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT ) public class V2ClientSetup { @SubscribeEvent public static void registerRenderers( EntityRenderersEvent.RegisterRenderers event ) { // Register OBJ block renderers event.registerBlockEntityRenderer( V2BlockEntities.PET_BOWL.get(), ObjBlockRenderer::new ); event.registerBlockEntityRenderer( V2BlockEntities.PET_BED.get(), ObjBlockRenderer::new ); event.registerBlockEntityRenderer( V2BlockEntities.PET_CAGE.get(), ObjBlockRenderer::new ); // Register Cell Core pulsing indicator renderer event.registerBlockEntityRenderer( ModBlockEntities.CELL_CORE.get(), CellCoreRenderer::new ); TiedUpMod.LOGGER.info( "[V2ClientSetup] Registered block entity renderers" ); } @SubscribeEvent public static void onModifyBakingResult( ModelEvent.ModifyBakingResult event ) { // Block model path key (used in model JSON references) ResourceLocation blockModelLoc = ResourceLocation.fromNamespaceAndPath( TiedUpMod.MOD_ID, "block/cell_core" ); // Blockstate variant key (used by the block renderer to look up models) ModelResourceLocation stateModelLoc = new ModelResourceLocation( ResourceLocation.fromNamespaceAndPath( TiedUpMod.MOD_ID, "cell_core" ), "" ); // Find the original model from either key BakedModel original = event.getModels().get(stateModelLoc); if (original == null) { original = event.getModels().get(blockModelLoc); } if (original != null) { CellCoreBakedModel wrapper = new CellCoreBakedModel(original); event.getModels().put(blockModelLoc, wrapper); event.getModels().put(stateModelLoc, wrapper); TiedUpMod.LOGGER.info( "[V2ClientSetup] Replaced cell_core BakedModel at both model keys" ); } // ===== Data-driven item icon overrides ===== wrapItemModelWithIconOverrides( event.getModels(), "data_driven_item", DataDrivenIconOverrides.Mode.BONDAGE_ITEM ); wrapItemModelWithIconOverrides( event.getModels(), "furniture_placer", DataDrivenIconOverrides.Mode.FURNITURE_PLACER ); } /** * Wrap an item's baked model with a {@link DataDrivenIconBakedModel} that * switches the rendered model based on NBT icon definitions. * * @param models the mutable model registry from {@link ModelEvent.ModifyBakingResult} * @param itemName the item registry name (e.g., "data_driven_item") * @param mode the icon override mode (determines which NBT key to read) */ private static void wrapItemModelWithIconOverrides( Map models, String itemName, DataDrivenIconOverrides.Mode mode ) { ModelResourceLocation itemModelLoc = new ModelResourceLocation( ResourceLocation.fromNamespaceAndPath(TiedUpMod.MOD_ID, itemName), "inventory" ); BakedModel originalItemModel = models.get(itemModelLoc); if (originalItemModel == null) { TiedUpMod.LOGGER.warn( "[V2ClientSetup] Could not find baked model for {} — icon overrides not applied", itemModelLoc ); return; } DataDrivenIconOverrides overrides = new DataDrivenIconOverrides(mode); DataDrivenIconBakedModel wrapped = new DataDrivenIconBakedModel( originalItemModel, overrides ); models.put(itemModelLoc, wrapped); TiedUpMod.LOGGER.info( "[V2ClientSetup] Wrapped {} model with icon overrides (mode={})", itemName, mode ); } }