Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

How to set texture for dynamically registered blocks from already existing blocks [1.18.2]


X-Lomir
 Share

Recommended Posts

  • Replies 117
  • Created
  • Last Reply

Top Posters In This Topic

Posted (edited)

I managed to solve the overlay texture problem by doing this:

public class FMLClientSetupEventHandler {
  /**
   * Sets the correct {@link RenderType} for {@link crystalspider.justverticalslabs.blocks.VerticalSlabBlock VerticalSlabBlocks}.
   * 
   * @param event
   */
  @SubscribeEvent
  public void setup(FMLClientSetupEvent event) {
    event.enqueueWork(() -> {
      // TODO: Check if it works also for translucent blocks.
      ItemBlockRenderTypes.setRenderLayer(JustVerticalSlabsLoader.VERTICAL_SLAB_BLOCK.get(), RenderType.cutoutMipped());
    });
  }
}

I also tried to solve the color problem by doing this:

public class ColorHandlerEventHandler {
  @SubscribeEvent
  public void onColorHandlerEventBlock(ColorHandlerEvent.Block event) {
    event.getBlockColors().register(new BlockColor() {
      public int getColor(BlockState state, @Nullable BlockAndTintGetter getter, @Nullable BlockPos pos, int tintIndex) {
        if (getter != null && pos != null) {
          BlockState referredSlabState = VerticalSlabUtils.getReferredSlabState(getter, pos);
          if (referredSlabState != null) {
            Block slab = referredSlabState.getBlock();
            if (slab instanceof GrassBlock || slab instanceof LeavesBlock) {
              return event.getBlockColors().getColor(Block.byItem(VerticalSlabUtils.slabMap.get(slab.asItem())).defaultBlockState(), getter, pos, tintIndex);
            }
          }
        }
        return -1;
      }
    }, JustVerticalSlabsLoader.VERTICAL_SLAB_BLOCK.get());
  }

  @SubscribeEvent
  public void onColorHandlerEventItem(ColorHandlerEvent.Item event) {
    event.getItemColors().register(new ItemColor() {
      public int getColor(ItemStack itemStack, int tintIndex) {
        BlockState referredSlabState = VerticalSlabUtils.getReferredSlabState(itemStack);
        if (referredSlabState != null) {
          Block slab = referredSlabState.getBlock();
          if (slab instanceof GrassBlock || slab instanceof LeavesBlock) {
            return event.getItemColors().getColor(VerticalSlabUtils.slabMap.get(slab.asItem()).getDefaultInstance(), tintIndex);
          }
        }
        return -1;
      }
    }, JustVerticalSlabsLoader.VERTICAL_SLAB_ITEM.get());
  }
}

And I tried registering this class first with

FMLJavaModLoadingContext.get().getModEventBus().register(new ColorHandlerEventHandler());

and after with 

MinecraftForge.EVENT_BUS.register(new ColorHandlerEventHandler());

however either way I get this (and no errors):

https://imgur.com/a/M9sfwVw

EDIT: I forgot to add that I moved the code in this new branch.

Edited by X-Lomir
Added extra info.
Link to comment
Share on other sites

In the end it was just me being stupid. What you said I had already did by using the tint index of the referred sprite rather than of my model JSON.

The real problem was that I was checking instanceof on the slab, but I needed to check on the block.

I changed my code to this and it works:

public class ColorHandlerEventHandler {
  @SubscribeEvent
  public void onColorHandlerEventBlock(ColorHandlerEvent.Block event) {
    event.getBlockColors().register(new BlockColor() {
      public int getColor(BlockState state, @Nullable BlockAndTintGetter getter, @Nullable BlockPos pos, int tintIndex) {
        if (getter != null && pos != null) {
          BlockState referredSlabState = VerticalSlabUtils.getReferredSlabState(getter, pos);
          if (referredSlabState != null) {
            // Edited here
            Block block = Block.byItem(VerticalSlabUtils.slabMap.get(referredSlabState.getBlock().asItem()));
            if (block instanceof GrassBlock || block instanceof LeavesBlock) {
              return event.getBlockColors().getColor(block.defaultBlockState(), getter, pos, tintIndex);
            }
          }
        }
        return -1;
      }
    }, JustVerticalSlabsLoader.VERTICAL_SLAB_BLOCK.get());
  }

  @SubscribeEvent
  public void onColorHandlerEventItem(ColorHandlerEvent.Item event) {
    event.getItemColors().register(new ItemColor() {
      public int getColor(ItemStack itemStack, int tintIndex) {
        BlockState referredSlabState = VerticalSlabUtils.getReferredSlabState(itemStack);
        if (referredSlabState != null) {
          // Edited here
          Block block = Block.byItem(VerticalSlabUtils.slabMap.get(referredSlabState.getBlock().asItem()));
          if (block instanceof GrassBlock || block instanceof LeavesBlock) {
            return event.getItemColors().getColor(block.asItem().getDefaultInstance(), tintIndex);
          }
        }
        return -1;
      }
    }, JustVerticalSlabsLoader.VERTICAL_SLAB_ITEM.get());
  }
}

The correct bus seems to be FMLJavaModLoadingContext.get().getModEventBus().

Link to comment
Share on other sites

38 minutes ago, diesieben07 said:

Why do you even have that instanceof check? You can just call BlockColors / ItemColors#getColor directly for all blocks. Not just grass and leaves can be colored.

Yeah you're right. I thought I would break colors of normal blocks if I did that, I don't know why.

Link to comment
Share on other sites

I noticed that some mods can add slabs for blocks that are not full height, like soulsand and dirt path. That caused a couple of problems with my vertical slabs, however I managed to make so that vertical slabs can also be not full height and their textures adapt too.

There is one problem that arose which is that vertical slabs not full height still make other blocks cull their faces: https://imgur.com/a/ZBUpszZ

I don't know why this is happening nor how to solve this. You can see the textures and the shape of the vertical slab being correct, however it's as if it's considered as a full height block.

Code is here.

Link to comment
Share on other sites

Okay, thanks, it works.

I'm testing my mod with transparent slabs, like glass, and, as I expected given I set the render layer as cutout mipped, transparent blocks don't work well at all.

Is there a way to set the render layer depending on the block entity? Or what else could I do to make so that only vertical slabs referring transparent blocks are rendered in translucent render layer?

Link to comment
Share on other sites

No, RenderType can only be set on the Block level (not even BlockState). You'll have to make multiple blocks, one for each RenderType you want to support.

However then you still need a hardcoded map that stores which Block maps to which RenderType, because this information is normally not available server side.

Link to comment
Share on other sites

2 hours ago, diesieben07 said:

No, RenderType can only be set on the Block level (not even BlockState). You'll have to make multiple blocks, one for each RenderType you want to support.

However then you still need a hardcoded map that stores which Block maps to which RenderType, because this information is normally not available server side.

Okay, I figured out as much. I guess I will make another kind of block and use it for certain blocks on a best-effort base, like checking if the ID of the mimicked block contains "glass", "leaf", "leaves", or something like that. Maybe add a config option to add another keyword to use to render a specific kind of block with the translucent layer.

Link to comment
Share on other sites

I added a class for transparent vertical slabs. Everything works fine so far except one thing that is transparent vertical slabs still cull their faces and the faces of their neighboring blocks.

Is there some method or property I can override in my new class or do I necessarily have to duplicate my JSON models and remove the cullfaces?

EDIT: I found getOcclusionShape and it looks like it's working.

Edited by X-Lomir
Added found solution.
Link to comment
Share on other sites

It was pointed out to me a bug my mod has when using shaders other than Minecraft defaults, for example with Optifine internal shaders and BSL Shaders.

The bug consists in all textures, apart from the oak planks, for my vertical slabs to be completely messed up. I guess this has to do with how I'm forcefully writing in the vertexes of my model.

Is there a way to test and debug my mod with Optifine and, optionally, an external shader pack?

Do you have any suggestions or insights about what may be causing the problem and how to fix it? I'm also trying to ask for some help on Minecraft Shaders Discord, I'll update here if I find a solution.

Link to comment
Share on other sites

I managed to solve the issue. The fix was actually quite simple, and I'm also not exactly sure why it works, but it does and I'm satisfied with it 🤣

I think it works because the BLOCK VertexFormat has, in order, a position element, a color element and the 2 UVs elements. A position elements uses 3 vertex elements (x, y and z), a color element takes 1 vertex element, U and V elements take 1 vertex element each. So the index for U is 3 + 1 + vertexIndex, where vertexIndex is the index of the current vertex, which increases every iteration by the size each vertex takes in the vertices array. Similarly, the index for V is 3 + 1 + vertexIndex + 1, accounting for the previous U vertex element.

However I'm not sure this is the correct explanation, but I'll leave here my intuition and the fixed method to update vertices:

private int[] updateVertices(int[] vertices, int[] referredVertices, TextureAtlasSprite oldSprite, TextureAtlasSprite newSprite, boolean faceUp) {
  int[] updatedVertices = vertices.clone();
  for (int vertexIndex = 0; vertexIndex < DefaultVertexFormat.BLOCK.getVertexSize(); vertexIndex += DefaultVertexFormat.BLOCK.getIntegerSize()) {
    float y = Float.intBitsToFloat(referredVertices[vertexIndex + 1]);
    // Lower only top face since RenderType CutoutMipped will remove extra transparent texture bits that go out of the shape. 
    if (faceUp && y > 0 && y < 0.5) {
      updatedVertices[vertexIndex + 1] = Float.floatToRawIntBits(y + 0.5F);
    }
    updatedVertices[vertexIndex + 4] = changeUVertexSprite(oldSprite, newSprite, updatedVertices[vertexIndex + 4]);
    updatedVertices[vertexIndex + 5] = changeVVertexSprite(oldSprite, newSprite, updatedVertices[vertexIndex + 5]);
  }
  return updatedVertices;
}

 

Link to comment
Share on other sites

I'm wondering... Couldn't I put a property into my BlockState that will hold the referredBlockState?

Basically in VerticalSlabBlock#getStateForPlacement I could read the NBT tag from the itemstack and save it in my BlockState, the same way I do for light. This way I could get rid of BEs altogether and make better use of BlockState chaching system. Also it would allow my blocks to be pushed by pistons and to mimic properties I currently cannot mimic because their getter only takes a BlockState as input.

The only problem I can see would be how to handle VerticalSlabBakedModel#getQuads because of that thing with the breaking progress animation.

Link to comment
Share on other sites

No, you can't do that.

BlockStates need to have a finite set of values, they are all precomputed. If you have more than a couple block states for your block, the system breaks. Apart from that, you'd break worlds as soon as other mods are added or removed (or the amount of slabs changes), because your block state changed.

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
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.

 Share




  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • server failed to start and gives me "Failed to load data packs, can't proceed with server load. You can either fix your data packs or reset to vanilla with --safeMode" error when i look in my logs. its updated to the latest version of forge(40.1.0), and I don't have any data packs installed as far as I know. And I will upload the full logs if asked as i dont know how to attach a document to this post.  
    • Pioneer Craft [modded] {1.18.2} {SMP} {Community} {Light Roleplay} We are Pioneer Craft and we seek you !!! We are building a community of passionate players to build, trade, and share some laughs with. Are you tired of playing alone? Or are you here seeking a server with dedicated members; a server where you are not overlooked and can voice your opinions? If you are interested in these things too, then come join us in Pioneer Craft! Our server is player built and driven. We have a custom mod pack with mods chosen by our community to suit our needs. We have designed our server for player driven roleplay! There will be four communities which will each be self-sufficient. We encourage and seek builders who want to create a beautiful world to live in. This is a whitelist server and we are looking for dedicated applicants and experienced builders. Applications are located on our website which can be accessed through the discord. Other than the application questions, we are requesting photos of your prior builds which will be taken into consideration. Please show photos of your builds in the share-your-work section of the discord. The server uses CurseForge to run. This server is for mature members (16+) . Discord (must join): https://discord.gg/c4uJvb29CN
    • Pioneer Craft [modded] {1.18.2} {SMP} {Community} {Light Roleplay} We are Pioneer Craft and we seek you !!! We are building a community of passionate players to build, trade, and share some laughs with. Are you tired of playing alone? Or are you here seeking a server with dedicated members; a server where you are not overlooked and can voice your opinions? If you are interested in these things too, then come join us in Pioneer Craft! Our server is player built and driven. We have a custom mod pack with mods chosen by our community to suit our needs. We have designed our server for player driven roleplay! There will be four communities which will each be self-sufficient. We encourage and seek builders who want to create a beautiful world to live in. This is a whitelist server and we are looking for dedicated applicants and experienced builders. Applications are located on our website which can be accessed through the discord. Other than the application questions, we are requesting photos of your prior builds which will be taken into consideration. Please show photos of your builds in the share-your-work section of the discord. The server uses CurseForge to run. This server is for mature members (16+) . Discord (must join): https://discord.gg/c4uJvb29CN 
    • Update: I didn't need capabilities. In fact, I didn't need to override applyEffectTick at all. But it seems like I need reflections. The increased hitbox size now works for both entity and block collision--with a little drawback. This is what it looks like so far: // this event handler checks every tick if the living entity has the "big" effect @SubscribeEvent public static void entitySizeChange(LivingEvent.LivingUpdateEvent event) { LivingEntity livingEntity = event.getEntityLiving(); if (livingEntity.getActiveEffectsMap() != null && livingEntity.hasEffect(ModEffects.BIG.get())) { EntityDimensions newDims = livingEntity.getDimensions(livingEntity.getPose()).scale(8.0F, 2.0F); try { // using reflection Field field = Entity.class.getDeclaredField("dimensions"); field.setAccessible(true); field.set(livingEntity, newDims); // setting the living entity's EntityDimensions EntityDimensions newEntityDimensions = (EntityDimensions) field.get(livingEntity); livingEntity.setBoundingBox(newEntityDimensions.makeBoundingBox( // setting the living entity's AABB livingEntity.getX(), livingEntity.getY(), livingEntity.getZ() )); } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); } } }   The aforementioned drawback is that, when the effect wears off, the living entity's still keeps its bigger hitbox until it changes pose (i.e. my player crouching). Given that the EntityEvent.Size event fires whenever an entity changes pose, should I manually fire it with EVENT_BUS::post when that entity's effect wears off? If so, where? I tried manually firing EntityEvent.Size on my overridden removeAttributeModifiers(), but to no avail. 
    • I'm working with very limited recourses on my PC so I wish this graph worked properly I allowed 3gbs when I created the server and now decided to bump it up to 6G's I'm having the same issue as OP there is no update on the GUI itself that says so, it gets to 1% free and seems to stop at 2800ish MB's of space and the entire server starts to lag. This is extremely frustrating I've looked around the internet and can't seem to find ANY fix about this. My user_jvm_args file looks as so. # Xmx and Xms set the maximum and minimum RAM usage, respectively. # They can take any number, followed by an M or a G. # M means Megabyte, G means Gigabyte. # For example, to set the maximum to 3GB: -Xmx3G # To set the minimum to 2.5GB: -Xms2500M # A good default for a modded server is 4GB. # Uncomment the next line to set it. -Xmx4G -Xms2G I read on reddit that adding an Xms command at the end fixed it for someone but it didn't for me at all.
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.