Jump to content

[1.16.5] Liquid BlockState rendering issues


Ginger_Plays

Recommended Posts

Hello, I'm trying to make a block that looks like a fluid but is solid. To that end, I've copied a bunch of code for making blocks with dynamic textures and stuck that in my mod. But when I give it a Fluid BlockState, it doesn't render anything. (I'm using just water for testing)

BoundFluidBlock:

package io.github.gingerindustries.cursedadditions.blocks;

import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.material.Material;
import net.minecraft.fluid.Fluids;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockDisplayReader;

public class BoundFluidBlock extends Block {
	public BoundFluidBlock() {
		super(Block.Properties.of(Material.WATER));
	}

	public static BlockState getTargetFluid(IBlockDisplayReader world, BlockPos pos) {
		return Fluids.WATER.getSource(true).createLegacyBlock();
	}

}

BoundFluidBakedModel:

package io.github.gingerindustries.cursedadditions.client.blocks.model;

import java.util.List;
import java.util.Random;


import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import org.apache.logging.log4j.Logger;

import io.github.gingerindustries.cursedadditions.CursedAdditions;
import io.github.gingerindustries.cursedadditions.blocks.BoundFluidBlock;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockRendererDispatcher;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.model.ItemOverrideList;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockDisplayReader;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.data.ModelDataMap;
import net.minecraftforge.client.model.data.ModelProperty;


public class BoundFluidBakedModel implements IBakedModel {
	private static final Logger LOGGER = CursedAdditions.LOGGER;
	private static boolean loggedError = false; // no console spam

	public BoundFluidBakedModel(IBakedModel unCamouflagedModel) {
		defaultModel = unCamouflagedModel;
	}

	public static ModelProperty<BlockState> COPIED_BLOCK = new ModelProperty<>();

	public static ModelDataMap getEmptyIModelData() {
		ModelDataMap.Builder builder = new ModelDataMap.Builder();
		builder.withProperty(COPIED_BLOCK);
		ModelDataMap modelDataMap = builder.build();
		return modelDataMap;
	}

	/**
	 * Forge's extension in place of IBakedModel::getQuads It allows us to pass in
	 * some extra information which we can use to choose the appropriate quads to
	 * render
	 * 
	 * @param state
	 * @param side
	 * @param rand
	 * @param extraData
	 * @return
	 */
	@Override
	@Nonnull
	public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand,
			@Nonnull IModelData extraData) {
		return getActualBakedModelFromIModelData(extraData).getQuads(state, side, rand, extraData);
	}

	@Override
	@Nonnull
	public IModelData getModelData(@Nonnull IBlockDisplayReader world, @Nonnull BlockPos pos, @Nonnull BlockState state,
			@Nonnull IModelData tileData) {
		BlockState fluid = BoundFluidBlock.getTargetFluid(world, pos);
		ModelDataMap modelDataMap = getEmptyIModelData();
		modelDataMap.setData(COPIED_BLOCK, fluid);
		return modelDataMap;
	}

	@Override
	public TextureAtlasSprite getParticleTexture(@Nonnull IModelData data) {
		return getActualBakedModelFromIModelData(data).getParticleTexture(data);
	}

	private IBakedModel getActualBakedModelFromIModelData(@Nonnull IModelData data) {
		IBakedModel retval = defaultModel; // default
		if (!data.hasProperty(COPIED_BLOCK)) {
			if (!loggedError) {
				LOGGER.error("IModelData did not have expected property COPIED_BLOCK, falling back to default");
				loggedError = true;
			}
			return retval;
		}
		BlockState copiedBlock = data.getData(COPIED_BLOCK);
		Minecraft mc = Minecraft.getInstance();
		BlockRendererDispatcher blockRendererDispatcher = mc.getBlockRenderer();
		retval = blockRendererDispatcher.getBlockModel(copiedBlock);
		return retval;
	}

	private IBakedModel defaultModel;

	// ---- All these methods are required by the interface but we don't do anything
	// special with them.

	@Override
	public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, Random rand) {
		throw new AssertionError("IBakedModel::getQuads should never be called, only IForgeBakedModel::getQuads");
	}

	@Override
	public boolean useAmbientOcclusion() {
		// TODO Auto-generated method stub
		return defaultModel.useAmbientOcclusion();
	}

	@Override
	public boolean isGui3d() {
		return defaultModel.isGui3d();
	}

	@Override
	public boolean usesBlockLight() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean isCustomRenderer() {
		// TODO Auto-generated method stub
		return defaultModel.isCustomRenderer();
	}

	@Override
	public TextureAtlasSprite getParticleIcon() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public ItemOverrideList getOverrides() {
		// TODO Auto-generated method stub
		return null;
	}
}

Registry code in BlockSetup: 

public static void onModelBakeEvent(ModelBakeEvent event) {
    	CursedAdditions.LOGGER.debug("Setting up BoundFluid...");
		for (BlockState blockState : BlockSetup.BOUND_FLUID.get().getStateDefinition().getPossibleStates()) {
			ModelResourceLocation variantMRL = BlockModelShapes.stateToModelLocation(blockState);
			IBakedModel existingModel = event.getModelRegistry().get(variantMRL);
			if (existingModel == null) {
				CursedAdditions.LOGGER
						.warn("Did not find the expected vanilla baked model(s) for BoundFluid in registry");
			} else if (existingModel instanceof BoundFluidBakedModel) {
				CursedAdditions.LOGGER.warn("Tried to replace BoundFluidBakedModel twice");
			} else {
				BoundFluidBakedModel customModel = new BoundFluidBakedModel(existingModel);
				event.getModelRegistry().put(variantMRL, customModel);
			}
		}
	}

 

Edited by Ginger_Plays
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • I'm unable to join my local forge servers. When running my forge servers of seemingly any version (tested 1.18 to 1.21.1) I get an error message [Forge Version Check/WARN] [ne.mi.fm.VersionChecker/]: Failed to process update information The server continues to start up and run, however I'm unable to join. Looking for solutions? Full error message: (note last "thead warning" error seems to be unrelated and only happened once for 1.20.1) Forge version check warning has happened for every version. [09:52:31] [Forge Version Check/WARN] [ne.mi.fm.VersionChecker/]: Failed to process update information java.net.http.HttpConnectTimeoutException: HTTP connect timed out         at jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:950) ~[java.net.http:?] {}         at jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:133) ~[java.net.http:?] {}         at net.minecraftforge.fml.VersionChecker$1.openUrlString(VersionChecker.java:142) ~[fmlcore-1.20.1-47.3.10.jar%23102!/:?] {}         at net.minecraftforge.fml.VersionChecker$1.process(VersionChecker.java:180) ~[fmlcore-1.20.1-47.3.10.jar%23102!/:?] {}         at java.lang.Iterable.forEach(Iterable.java:75) ~[?:?] {}         at net.minecraftforge.fml.VersionChecker$1.run(VersionChecker.java:117) ~[fmlcore-1.20.1-47.3.10.jar%23102!/:?] {} Caused by: java.net.http.HttpConnectTimeoutException: HTTP connect timed out         at jdk.internal.net.http.ResponseTimerEvent.handle(ResponseTimerEvent.java:68) ~[java.net.http:?] {}         at jdk.internal.net.http.HttpClientImpl.purgeTimeoutsAndReturnNextDeadline(HttpClientImpl.java:1788) ~[java.net.http:?] {}         at jdk.internal.net.http.HttpClientImpl$SelectorManager.run(HttpClientImpl.java:1385) ~[java.net.http:?] {} Caused by: java.net.ConnectException: HTTP connect timed out         at jdk.internal.net.http.ResponseTimerEvent.handle(ResponseTimerEvent.java:69) ~[java.net.http:?] {}         at jdk.internal.net.http.HttpClientImpl.purgeTimeoutsAndReturnNextDeadline(HttpClientImpl.java:1788) ~[java.net.http:?] {}         at jdk.internal.net.http.HttpClientImpl$SelectorManager.run(HttpClientImpl.java:1385) ~[java.net.http:?] {} [09:52:31] [Yggdrasil Key Fetcher/ERROR] [mojang/YggdrasilServicesKeyInfo]: Failed to request yggdrasil public key com.mojang.authlib.exceptions.AuthenticationUnavailableException: Cannot contact authentication server         at com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService.makeRequest(YggdrasilAuthenticationService.java:119) ~[authlib-4.0.43.jar%2375!/:?] {}         at com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService.makeRequest(YggdrasilAuthenticationService.java:91) ~[authlib-4.0.43.jar%2375!/:?] {}         at com.mojang.authlib.yggdrasil.YggdrasilServicesKeyInfo.fetch(YggdrasilServicesKeyInfo.java:94) ~[authlib-4.0.43.jar%2375!/:?] {}         at com.mojang.authlib.yggdrasil.YggdrasilServicesKeyInfo.lambda$get$1(YggdrasilServicesKeyInfo.java:81) ~[authlib-4.0.43.jar%2375!/:?] {}         at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572) ~[?:?] {}         at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:358) ~[?:?] {}         at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) ~[?:?] {}         at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[?:?] {}         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[?:?] {}         at java.lang.Thread.run(Thread.java:1575) ~[?:?] {} Caused by: java.net.SocketTimeoutException: Connect timed out         at sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:546) ~[?:?] {}         at sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:592) ~[?:?] {}         at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[?:?] {}         at java.net.Socket.connect(Socket.java:760) ~[?:?] {}         at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:304) ~[?:?] {}         at sun.net.NetworkClient.doConnect(NetworkClient.java:178) ~[?:?] {}         at sun.net.www.http.HttpClient.openServer(HttpClient.java:531) ~[?:?] {}         at sun.net.www.http.HttpClient.openServer(HttpClient.java:636) ~[?:?] {}         at sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:264) ~[?:?] {}         at sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:377) ~[?:?] {}         at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:193) ~[?:?] {}         at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1273) ~[?:?] {}         at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1114) ~[?:?] {}         at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:179) ~[?:?] {}         at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1676) ~[?:?] {}         at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1600) ~[?:?] {}         at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:223) ~[?:?] {}         at com.mojang.authlib.HttpAuthenticationService.performGetRequest(HttpAuthenticationService.java:140) ~[authlib-4.0.43.jar%2375!/:?] {}         at com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService.makeRequest(YggdrasilAuthenticationService.java:96) ~[authlib-4.0.43.jar%2375!/:?] {}         ... 9 more [09:52:31] [Server thread/WARN] [minecraft/MinecraftServer]: Can't keep up! Is the server overloaded? Running 5985ms or 119 ticks behind
    • Remove the mod tempad from the mods-folder
    • Hi, deleting the config folder did not appear to work, what mod are you referring to I could try to delete to fix the problem?
    • A friend found this code, but I don't know where. It seems to be very outdated, maybe from 1.12? and so uses TextureManager$loadTexture and TextureManager$deleteTexture which both don't seem to exist anymore. It also uses Minecraft.getMinecraft().mcDataDir.getCanonicalPath() which I replaced with the resource location of my texture .getPath()? Not sure if thats entirely correct. String textureName = "entitytest.png"; File textureFile = null; try { textureFile = new File(Minecraft.getMinecraft().mcDataDir.getCanonicalPath(), textureName); } catch (Exception ex) { } if (textureFile != null && textureFile.exists()) { ResourceLocation MODEL_TEXTURE = Resources.OTHER_TESTMODEL_CUSTOM; TextureManager texturemanager = Minecraft.getMinecraft().getTextureManager(); texturemanager.deleteTexture(MODEL_TEXTURE); Object object = new ThreadDownloadImageData(textureFile, null, MODEL_TEXTURE, new ImageBufferDownload()); texturemanager.loadTexture(MODEL_TEXTURE, (ITextureObject)object); return true; } else { return false; }   Then I've been trying to go through the source code of the reload resource packs from minecraft, to see if I can "cache" some data and simply reload some textures and swap them out, but I can't seem to figure out where exactly its "loading" the texture files and such. Minecraft$reloadResourcePacks(bool) seems to be mainly controlling the loading screen, and using this.resourcePackRepository.reload(); which is PackRepository$reload(), but that function seems to be using this absolute confusion of a line List<String> list = this.selected.stream().map(Pack::getId).collect(ImmutableList.toImmutableList()); and then this.discoverAvailable() and this.rebuildSelected. The rebuild selected seemed promising, but it seems to just be going through each pack and doing this to them? pack.getDefaultPosition().insert(list, pack, Functions.identity(), false); e.g. putting them into a list of packs and returning that into this.selected? Where do the textures actually get baked/loaded/whatever? Any info on how Minecraft reloads resource packs or how the texture manager works would be appreciated!
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.