package joshie.harvest.mining.render; import joshie.harvest.core.base.render.BakedHF; import joshie.harvest.core.util.annotations.HFEvents; import joshie.harvest.mining.HFMining; import joshie.harvest.mining.block.BlockDirt; import joshie.harvest.mining.block.BlockDirt.TextureStyle; import net.minecraft.block.Block; import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.BakedQuadRetextured; import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.client.renderer.block.statemap.DefaultStateMapper; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.WeightedRandom; import net.minecraft.util.registry.IRegistry; import net.minecraftforge.client.event.ModelBakeEvent; import net.minecraftforge.client.event.TextureStitchEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Map; import static joshie.harvest.core.lib.HFModInfo.MODID; public class BakedDirt extends BakedHF { private final IBakedModel overlay; protected final List<WeightedTexture> textures; private final int totalWeight; public BakedDirt(IBakedModel parent, IBakedModel overlay, List<WeightedTexture> overlays) { super(parent); this.overlay = overlay; this.textures = overlays; this.totalWeight = WeightedRandom.getTotalWeight(textures); } private TextureAtlasSprite getRandomTexture(long rand) { return (WeightedRandom.getRandomItem(textures, Math.abs((int)rand >> 16) % totalWeight)).sprite; } @Override public List<BakedQuad> getQuads(final @Nullable IBlockState state, final @Nullable EnumFacing side, final long rand) { List<BakedQuad> quads = new ArrayList<>(BakedDirt.super.getQuads(state, side, rand)); overlay.getQuads(state, side, rand).stream().map(quad -> new BakedQuadRetextured(quad, getRandomTexture(rand))).forEachOrdered(quads::add); return quads; } @HFEvents public static class StateMapper extends DefaultStateMapper { private static final String[] VALID_STATES = new String[] { "ne=blank,nw=blank,se=blank,sw=blank", "ne=blank,nw=blank,se=blank,sw=inner", "ne=blank,nw=blank,se=horizontal,sw=horizontal", "ne=blank,nw=blank,se=inner,sw=blank", "ne=blank,nw=blank,se=inner,sw=inner", "ne=blank,nw=inner,se=blank,sw=blank", "ne=blank,nw=inner,se=blank,sw=inner", "ne=blank,nw=inner,se=horizontal,sw=horizontal", "ne=blank,nw=inner,se=inner,sw=blank", "ne=blank,nw=inner,se=inner,sw=inner", "ne=blank,nw=vertical,se=blank,sw=vertical", "ne=blank,nw=vertical,se=horizontal,sw=outer", "ne=blank,nw=vertical,se=inner,sw=vertical", "ne=horizontal,nw=horizontal,se=blank,sw=blank", "ne=horizontal,nw=horizontal,se=blank,sw=inner", "ne=horizontal,nw=horizontal,se=horizontal,sw=horizontal", "ne=horizontal,nw=horizontal,se=inner,sw=blank", "ne=horizontal,nw=horizontal,se=inner,sw=inner", "ne=horizontal,nw=outer,se=blank,sw=vertical", "ne=horizontal,nw=outer,se=horizontal,sw=outer", "ne=horizontal,nw=outer,se=inner,sw=vertical", "ne=inner,nw=blank,se=blank,sw=blank", "ne=inner,nw=blank,se=blank,sw=inner", "ne=inner,nw=blank,se=horizontal,sw=horizontal", "ne=inner,nw=blank,se=inner,sw=blank", "ne=inner,nw=blank,se=inner,sw=inner", "ne=inner,nw=inner,se=blank,sw=blank", "ne=inner,nw=inner,se=blank,sw=inner", "ne=inner,nw=inner,se=horizontal,sw=horizontal", "ne=inner,nw=inner,se=inner,sw=blank", "ne=inner,nw=inner,se=inner,sw=inner", "ne=inner,nw=vertical,se=blank,sw=vertical", "ne=inner,nw=vertical,se=horizontal,sw=outer", "ne=inner,nw=vertical,se=inner,sw=vertical", "ne=outer,nw=horizontal,se=outer,sw=horizontal", "ne=outer,nw=horizontal,se=vertical,sw=blank", "ne=outer,nw=horizontal,se=vertical,sw=inner", "ne=outer,nw=outer,se=outer,sw=outer", "ne=outer,nw=outer,se=vertical,sw=vertical", "ne=vertical,nw=blank,se=outer,sw=horizontal", "ne=vertical,nw=blank,se=vertical,sw=blank", "ne=vertical,nw=blank,se=vertical,sw=inner", "ne=vertical,nw=inner,se=outer,sw=horizontal", "ne=vertical,nw=inner,se=vertical,sw=blank", "ne=vertical,nw=inner,se=vertical,sw=inner", "ne=vertical,nw=vertical,se=outer,sw=outer", "ne=vertical,nw=vertical,se=vertical,sw=vertical" }; private boolean isValidState(String state) { for (String s: VALID_STATES) { if (state.equalsIgnoreCase(s)) { return true; } } return false; } @Override public Map<IBlockState, ModelResourceLocation> putStateModelLocations(Block block) { if (block == HFMining.DIRT) { mapStateModelLocations.put(new BlockStateContainer(block).getBaseState(), new ModelResourceLocation(block.getRegistryName(), "overlay")); } //State > Resource for (IBlockState iblockstate : block.getBlockState().getValidStates()) { ModelResourceLocation model = getModelResourceLocation(iblockstate); if (model != null) { mapStateModelLocations.put(iblockstate, model); } } return mapStateModelLocations; } @Override protected ModelResourceLocation getModelResourceLocation(IBlockState state) { String properties = this.getPropertyString(state.getProperties()); if (!isValidState(properties)) return null; return new ModelResourceLocation("harvestfestival:dirt", properties); } @SubscribeEvent public void onStitch(TextureStitchEvent event) { for (TextureType type: TextureType.values()) { event.getMap().registerSprite(new ResourceLocation(MODID, "blocks/mine/overlays/" + type.name().toLowerCase(Locale.ENGLISH))); } } @SubscribeEvent public void onBaking(ModelBakeEvent event) { IRegistry<ModelResourceLocation, IBakedModel> registry = event.getModelRegistry(); IBakedModel overlay = registry.getObject(new ModelResourceLocation("harvestfestival:dirt", "overlay")); List<WeightedTexture> overlays = new ArrayList<>(); for (TextureType type : TextureType.values()) { TextureAtlasSprite sprite = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite("harvestfestival:blocks/mine/overlays/" + type.name().toLowerCase(Locale.ENGLISH)); overlays.add(new WeightedTexture(sprite, type.weight)); } //Change the models for (BlockDirt.TextureStyle ne : TextureStyle.values()) { for (BlockDirt.TextureStyle nw : TextureStyle.values()) { for (BlockDirt.TextureStyle se : TextureStyle.values()) { for (BlockDirt.TextureStyle sw : TextureStyle.values()) { String state = String.format("ne=%s,nw=%s,se=%s,sw=%s", ne.getName(), nw.getName(), se.getName(), sw.getName()); IBakedModel original = registry.getObject(new ModelResourceLocation("harvestfestival:dirt", state)); registry.putObject(new ModelResourceLocation("harvestfestival:dirt", state), new BakedDirt(original, overlay, overlays)); } } } } } } public enum TextureType { BLANK(200), BONES1(1), BONES2(1), BONES3(1), BONES4(1), LEAVES1(1), LEAVES2(1), LEAVES3(1), LEAVES4(1), PEBBLE1(1), PEBBLE2(1), PEBBLE3(1), PEBBLE4(1), PEBBLE5(1), PEBBLE6(1), ROCK1(1), ROCK2(1); private final int weight; TextureType(int weight) { this.weight = weight; } } private static class WeightedTexture extends WeightedRandom.Item { public final TextureAtlasSprite sprite; public WeightedTexture(TextureAtlasSprite sprite, int weight) { super(weight); this.sprite = sprite; } } }