From 30b4db4adc085f88b5a3d8954ac76bb475e71637 Mon Sep 17 00:00:00 2001 From: Paula Date: Sat, 1 Jun 2024 11:56:31 +0200 Subject: [PATCH] additionToBackup --- .../java/modchest/transform/MaterialMap.java | 9 + .../modchest/transform/MaterialMapLoader.java | 216 +++++++++++++++++- 2 files changed, 224 insertions(+), 1 deletion(-) diff --git a/src/client/java/modchest/transform/MaterialMap.java b/src/client/java/modchest/transform/MaterialMap.java index 58f9e0f..e0c79a2 100644 --- a/src/client/java/modchest/transform/MaterialMap.java +++ b/src/client/java/modchest/transform/MaterialMap.java @@ -1,5 +1,14 @@ package modchest.transform; +import org.jetbrains.annotations.Nullable; + +import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; +import net.minecraft.block.BlockState; +import net.minecraft.client.texture.Sprite; +import net.minecraft.fluid.FluidState; +import net.minecraft.item.ItemStack; +import net.minecraft.particle.ParticleType; + public interface MaterialMap { /** * Used by renderer to avoid overhead of sprite reverse lookup when not needed. diff --git a/src/client/java/modchest/transform/MaterialMapLoader.java b/src/client/java/modchest/transform/MaterialMapLoader.java index c1d1f13..483706b 100644 --- a/src/client/java/modchest/transform/MaterialMapLoader.java +++ b/src/client/java/modchest/transform/MaterialMapLoader.java @@ -1,5 +1,219 @@ package modchest.transform; -public class MaterialMapLoader { +import org.jetbrains.annotations.ApiStatus.Internal; +import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.entity.EntityType; +import net.minecraft.fluid.FluidState; +import net.minecraft.item.ItemStack; +import net.minecraft.particle.ParticleType; +import net.minecraft.resource.ResourceManager; +import net.minecraft.util.Identifier; + +@Internal +public class MaterialMapLoader implements SimpleSynchronousResourceReloadListener { + private MaterialMapLoader() { } + + public MaterialMap get(BlockState state) { + return BLOCK_MAP.getOrDefault(state, DEFAULT_MAP); + } + + public MaterialMap get(FluidState fluidState) { + return FLUID_MAP.getOrDefault(fluidState, DEFAULT_MAP); + } + + public MaterialMap get(ItemStack itemStack) { + return ITEM_MAP.getOrDefault(itemStack.getItem(), DEFAULT_MAP); + } + + public MaterialMap get(ParticleType particleType) { + return PARTICLE_MAP.getOrDefault(particleType, DEFAULT_MAP); + } + + public BlockEntityMaterialMap get(BlockEntityType blockEntityType) { + return BLOCK_ENTITY_MAP.getOrDefault(blockEntityType, BlockEntityMaterialMap.IDENTITY); + } + + public EntityMaterialMap get(EntityType entityType) { + return ENTITY_MAP.getOrDefault(entityType, EntityMaterialMap.IDENTITY); + } + + @Override + public Identifier getFabricId() { + return id; + } + + @Override + public Collection getFabricDependencies() { + return DEPS; + } + + @Override + public void reload(ResourceManager manager) { + MaterialLoaderImpl.reset(); + + BLOCK_MAP.clear(); + final Iterator blocks = Registry.BLOCK.iterator(); + + while (blocks.hasNext()) { + loadBlock(manager, blocks.next()); + } + + FLUID_MAP.clear(); + final Iterator fluids = Registry.FLUID.iterator(); + + while (fluids.hasNext()) { + loadFluid(manager, fluids.next()); + } + + // NB: must come after block because uses block maps for block items + ITEM_MAP.clear(); + final Iterator items = Registry.ITEM.iterator(); + + while (items.hasNext()) { + loadItem(manager, items.next()); + } + + PARTICLE_MAP.clear(); + final Iterator> particles = Registry.PARTICLE_TYPE.iterator(); + + while (particles.hasNext()) { + loadParticle(manager, particles.next()); + } + + BLOCK_ENTITY_MAP.clear(); + final Iterator> blockEntities = Registry.BLOCK_ENTITY_TYPE.iterator(); + + while (blockEntities.hasNext()) { + loadBlockEntity(manager, blockEntities.next()); + } + + ENTITY_MAP.clear(); + final Iterator> entities = Registry.ENTITY_TYPE.iterator(); + + while (entities.hasNext()) { + loadEntity(manager, entities.next()); + } + } + + private void loadBlock(ResourceManager manager, Block block) { + final Identifier blockId = Registry.BLOCK.getId(block); + + final Identifier id = new Identifier(blockId.getNamespace(), "materialmaps/block/" + blockId.getPath() + ".json"); + + try (Resource res = manager.getResource(id)) { + MaterialMapDeserializer.deserialize(block.getStateManager().getStates(), id, new InputStreamReader(res.getInputStream(), StandardCharsets.UTF_8), BLOCK_MAP); + } catch (final FileNotFoundException e) { + // eat these, material maps are not required + } catch (final Exception e) { + Frex.LOG.info("Unable to load block material map " + id.toString() + " due to exception " + e.toString()); + } + } + + private void loadFluid(ResourceManager manager, Fluid fluid) { + final Identifier blockId = Registry.FLUID.getId(fluid); + + final Identifier id = new Identifier(blockId.getNamespace(), "materialmaps/fluid/" + blockId.getPath() + ".json"); + + try (Resource res = manager.getResource(id)) { + MaterialMapDeserializer.deserialize(fluid.getStateManager().getStates(), id, new InputStreamReader(res.getInputStream(), StandardCharsets.UTF_8), FLUID_MAP); + } catch (final FileNotFoundException e) { + // eat these, material maps are not required + } catch (final Exception e) { + Frex.LOG.info("Unable to load fluid material map " + id.toString() + " due to exception " + e.toString()); + } + } + + private void loadItem(ResourceManager manager, Item item) { + final Identifier itemId = Registry.ITEM.getId(item); + + final Identifier id = new Identifier(itemId.getNamespace(), "materialmaps/item/" + itemId.getPath() + ".json"); + + try (Resource res = manager.getResource(id)) { + ItemMaterialMapDeserializer.deserialize(item, id, new InputStreamReader(res.getInputStream(), StandardCharsets.UTF_8), ITEM_MAP); + } catch (final FileNotFoundException e) { + // fall back to block map for block items + // otherwise eat these, material maps are not required + + if (item instanceof BlockItem) { + final MaterialMap map = BLOCK_MAP.get(((BlockItem) item).getBlock().getDefaultState()); + + if (map != null) { + ITEM_MAP.put(item, map); + } + } + } catch (final Exception e) { + Frex.LOG.info("Unable to load block material map " + id.toString() + " due to exception " + e.toString()); + } + } + + private void loadParticle(ResourceManager manager, ParticleType particleType) { + final Identifier particleId = Registry.PARTICLE_TYPE.getId(particleType); + + final Identifier id = new Identifier(particleId.getNamespace(), "materialmaps/particle/" + particleId.getPath() + ".json"); + + try (Resource res = manager.getResource(id)) { + ParticleMaterialMapDeserializer.deserialize(particleType, id, new InputStreamReader(res.getInputStream(), StandardCharsets.UTF_8), PARTICLE_MAP); + } catch (final FileNotFoundException e) { + // eat these, material maps are not required + } catch (final Exception e) { + Frex.LOG.info("Unable to load particle material map " + id.toString() + " due to exception " + e.toString()); + } + } + + private void loadBlockEntity(ResourceManager manager, BlockEntityType blockEntityType) { + final Identifier blockEntityId = Registry.BLOCK_ENTITY_TYPE.getId(blockEntityType); + final Identifier id = new Identifier(blockEntityId.getNamespace(), "materialmaps/block_entity/" + blockEntityId.getPath() + ".json"); + + try { + List resources = manager.getAllResources(id); + + if (resources.size() > 0) { + BlockEntityMaterialMapDeserializer.deserialize(blockEntityType, id, resources, BLOCK_ENTITY_MAP); + } + } catch (final FileNotFoundException e) { + // eat these, material maps are not required + } catch (final Exception e) { + Frex.LOG.info("Unable to load block entity material map " + id.toString() + " due to exception " + e.toString()); + } + } + + private void loadEntity(ResourceManager manager, EntityType entityType) { + final Identifier entityId = Registry.ENTITY_TYPE.getId(entityType); + final Identifier id = new Identifier(entityId.getNamespace(), "materialmaps/entity/" + entityId.getPath() + ".json"); + + try { + List resources = manager.getAllResources(id); + + if (resources.size() > 0) { + EntityMaterialMapDeserializer.deserialize(entityType, id, resources, ENTITY_MAP); + } + } catch (final FileNotFoundException e) { + // eat these, material maps are not required + } catch (final Exception e) { + Frex.LOG.info("Unable to load block entity material map " + id.toString() + " due to exception " + e.toString()); + } + } + + public static final MaterialMap DEFAULT_MAP = new SingleMaterialMap(null); + + private static final IdentityHashMap BLOCK_MAP = new IdentityHashMap<>(); + private static final IdentityHashMap FLUID_MAP = new IdentityHashMap<>(); + private static final IdentityHashMap ITEM_MAP = new IdentityHashMap<>(); + private static final IdentityHashMap, MaterialMap> PARTICLE_MAP = new IdentityHashMap<>(); + private static final IdentityHashMap, BlockEntityMaterialMap> BLOCK_ENTITY_MAP = new IdentityHashMap<>(); + private static final IdentityHashMap, EntityMaterialMap> ENTITY_MAP = new IdentityHashMap<>(); + + private static List DEPS = ImmutableList.of(ResourceReloadListenerKeys.MODELS, ResourceReloadListenerKeys.TEXTURES); + private static final Identifier id = new Identifier("frex:material_map"); + + public static final MaterialMapLoader INSTANCE = new MaterialMapLoader(); + + @Override + public void reload(ResourceManager manager) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'reload'"); + } }