Jump to content

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


X-Lomir

Recommended Posts

2 hours ago, X-Lomir said:

That register method takes as first parameter a instance of BlockColor, you are passing it an int (FoliageColor#getDefaultColor returns an int).

A BlockColor instance is quite easy as BlockColor is just an interface with a single method:

public interface BlockColor {
   int getColor(BlockState p_92567_, @Nullable BlockAndTintGetter p_92568_, @Nullable BlockPos p_92569_, int p_92570_);
}

Since you basically want to copy the coloring foliage gets, you can do something similar to me:

@SubscribeEvent
public static void onColorHandlerEventBlock(ColorHandlerEvent.Block event) {
  event.getBlockColors().register(
    new BlockColor() {
      public int getColor(BlockState state, @Nullable BlockAndTintGetter getter, @Nullable BlockPos pos, int tintIndex) {
        return getter != null && pos != null ? event.getBlockColors().getColor(Blocks.OAK_LEAVES.defaultBlockState(), getter, pos, tintIndex) : -1;
      }
    },
    ModBuildingBlocks.CONNECTABLE_OAK_LEAF_WALL
  );
}

Where you basically create a new BlockColor instance that returns the same coloring for oak leaves.

Alternatively you can also create a separate class implementing BlockColor:

public class ConnectableOakLeafWallBlockColor implements BlockColor {
  public int getColor(BlockState state, @Nullable BlockAndTintGetter getter, @Nullable BlockPos pos, int tintIndex) {
    return getter != null && pos != null ? Minecraft.getInstance().getBlockColors().getColor(Blocks.OAK_LEAVES.defaultBlockState(), getter, pos, tintIndex) : -1;
  }
}

And just pass it to register:

@SubscribeEvent
public static void onColorHandlerEventBlock(ColorHandlerEvent.Block event) {
  event.getBlockColors().register(new ConnectableOakLeafWallBlockColor(), ModBuildingBlocks.CONNECTABLE_OAK_LEAF_WALL);
}

The choice is yours.

 

Also be careful because you need to avoid having this part of the code when your mod runs only server-side or it will just crash being unable to find BlockColor (which indeed exists only client-side). I fixed this problem by having a separate class handling my color registering annotated like so (be careful to make your methods static if you do the same):

@EventBusSubscriber(value = Dist.CLIENT, bus = Bus.MOD)
public class ColorHandlerEventHandler {

  @SubscribeEvent
  public static void onColorHandlerEventBlock(ColorHandlerEvent.Block event) {
    // do stuff
  }

  @SubscribeEvent
  public static void onColorHandlerEventItem(ColorHandlerEvent.Item event) {
    // do stuff
  }
}

I speak from experience 🤣

I hope I was of help, if you need to look more at my code the most updated branch is this one.

First of all, thank you so much for your quick and detailed reply!!!

A lot of things got a lot clearer to me but my blocks still are rendered in gray. I don't get why and when I wanted to look into your code I realized there are no tinted blocks in your mod.

At least I couldn't find any leaves slabs or grass slabs so I'm still a little lost but your answer was by far the best I got in the last 2 weeks I spent trying to find a solution to this problem

 

p.s.: I just realised I'm stupid and I forgot to call it in the Main Constructor ..... sigh

Edited by Brainterminator
Link to comment
Share on other sites

  • Replies 92
  • Created
  • Last Reply

Top Posters In This Topic

2 hours ago, Brainterminator said:

I don't get why and when I wanted to look into your code I realized there are no tinted blocks in your mod.

Yeah I know, this is because Minecraft Vanilla doesn't have slabs of such materials, so in Vanilla no vertical slabs will have a need for coloring. However if you try my mod in combination with another mod that adds horizontal slabs of grass or foliage or whatever other block that needs coloring you will see that the vertical slabs will appear and will be tinted correctly :)

I'm glad you could figure out the other problem anyway

Link to comment
Share on other sites

56 minutes ago, X-Lomir said:

Yeah I know, this is because Minecraft Vanilla doesn't have slabs of such materials, so in Vanilla no vertical slabs will have a need for coloring. However if you try my mod in combination with another mod that adds horizontal slabs of grass or foliage or whatever other block that needs coloring you will see that the vertical slabs will appear and will be tinted correctly :)

I'm glad you could figure out the other problem anyway

In case of the Server How did you workaround that? I heard you can use the DistExecutor but lambda expression still overwhelm me so... I'm having problems with that.

My Constructor looks like this:

public UtilityBlocks()
    {
        IEventBus eventBus = FMLJavaModLoadingContext.get().getModEventBus();

        ModItems.register(eventBus);
        ModBlocks.register(eventBus);
        ModBuildingBlocks.register(eventBus);

        eventBus.addListener(this::setup);
        eventBus.addListener(this::clientSetup);

        
        eventBus.addListener(this::registerBlockColors);
        eventBus.addListener(this::registerItemColors);

        // Register ourselves for server and other game events we are interested in
        MinecraftForge.EVENT_BUS.register(this);
    }

But as you already said this way it is not runnable on a server. Do you know an easy way to outsource that?

Link to comment
Share on other sites

13 minutes ago, Brainterminator said:

In case of the Server How did you workaround that? I heard you can use the DistExecutor but lambda expression still overwhelm me so... I'm having problems with that.

My Constructor looks like this:

public UtilityBlocks()
    {
        IEventBus eventBus = FMLJavaModLoadingContext.get().getModEventBus();

        ModItems.register(eventBus);
        ModBlocks.register(eventBus);
        ModBuildingBlocks.register(eventBus);

        eventBus.addListener(this::setup);
        eventBus.addListener(this::clientSetup);

        
        eventBus.addListener(this::registerBlockColors);
        eventBus.addListener(this::registerItemColors);

        // Register ourselves for server and other game events we are interested in
        MinecraftForge.EVENT_BUS.register(this);
    }

But as you already said this way it is not runnable on a server. Do you know an easy way to outsource that?

As I said in my first reply, what I did was to directly subscribe a class that would handle the color events:

@EventBusSubscriber(value = Dist.CLIENT, bus = Bus.MOD)
public class ColorHandlerEventHandler {

  @SubscribeEvent
  public static void onColorHandlerEventBlock(ColorHandlerEvent.Block event) {
    // do stuff
  }

  @SubscribeEvent
  public static void onColorHandlerEventItem(ColorHandlerEvent.Item event) {
    // do stuff
  }
}

The important parts here are the Annotation for the class and the fact that its methods are static. If you do this you should also remove the lines in your constructor where you add those methods as listeners on the bus.

So, to sum it up, remove the lines that register registerBlockColors and registerItemColors, move those two methods into a separate class and make them static, annotate the class with @EventBusSubscriber(value = Dist.CLIENT, bus = Bus.MOD) and you're good to go.

Link to comment
Share on other sites

4 minutes ago, X-Lomir said:

As I said in my first reply, what I did was to directly subscribe a class that would handle the color events:

@EventBusSubscriber(value = Dist.CLIENT, bus = Bus.MOD)
public class ColorHandlerEventHandler {

  @SubscribeEvent
  public static void onColorHandlerEventBlock(ColorHandlerEvent.Block event) {
    // do stuff
  }

  @SubscribeEvent
  public static void onColorHandlerEventItem(ColorHandlerEvent.Item event) {
    // do stuff
  }
}

The important parts here are the Annotation for the class and the fact that its methods are static. If you do this you should also remove the lines in your constructor where you add those methods as listeners on the bus.

So, to sum it up, remove the lines that register registerBlockColors and registerItemColors, move those two methods into a separate class and make them static, annotate the class with @EventBusSubscriber(value = Dist.CLIENT, bus = Bus.MOD) and you're good to go.

I tried replicating your steps with my mod:

package net.brain.utilityblocks.handler;

import net.brain.utilityblocks.block.ModBuildingBlocks;
import net.minecraft.client.renderer.BiomeColors;
import net.minecraft.world.level.FoliageColor;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
import net.minecraft.client.color.item.ItemColor;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.client.event.ColorHandlerEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.api.distmarker.Dist;

@EventBusSubscriber(value = Dist.CLIENT, bus = Bus.MOD)
public class ColorHandlerEventHandler {
    @SubscribeEvent
    public void registerBlockColors(ColorHandlerEvent.Block event){
        event.getBlockColors().register((p_92626_, p_92627_, p_92628_, p_92629_) -> {
            return p_92627_ != null && p_92628_ != null ? BiomeColors.getAverageFoliageColor(p_92627_, p_92628_) : FoliageColor.getDefaultColor();
        }, ModBuildingBlocks.CONNECTABLE_OAK_LEAF_WALL.get());
    }

    @SubscribeEvent
    public void registerItemColors(ColorHandlerEvent.Item event){
        event.getItemColors().register(new ItemColor() {
            @Override
            public int getColor(ItemStack pStack, int pTintIndex) {
                return FoliageColor.getDefaultColor();
            }
        }, ModBuildingBlocks.CONNECTABLE_OAK_LEAF_WALL.get());
    }
}

but somehow it doesn't work. When I declare the registerBlockColors function in my Main Class and call "eventBus.addListener(this::registerBlockColors);" from the Constructor it works. 

 

Link to comment
Share on other sites

1 minute ago, Brainterminator said:

I tried replicating your steps with my mod:

package net.brain.utilityblocks.handler;

import net.brain.utilityblocks.block.ModBuildingBlocks;
import net.minecraft.client.renderer.BiomeColors;
import net.minecraft.world.level.FoliageColor;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
import net.minecraft.client.color.item.ItemColor;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.client.event.ColorHandlerEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.api.distmarker.Dist;

@EventBusSubscriber(value = Dist.CLIENT, bus = Bus.MOD)
public class ColorHandlerEventHandler {
    @SubscribeEvent
    public void registerBlockColors(ColorHandlerEvent.Block event){
        event.getBlockColors().register((p_92626_, p_92627_, p_92628_, p_92629_) -> {
            return p_92627_ != null && p_92628_ != null ? BiomeColors.getAverageFoliageColor(p_92627_, p_92628_) : FoliageColor.getDefaultColor();
        }, ModBuildingBlocks.CONNECTABLE_OAK_LEAF_WALL.get());
    }

    @SubscribeEvent
    public void registerItemColors(ColorHandlerEvent.Item event){
        event.getItemColors().register(new ItemColor() {
            @Override
            public int getColor(ItemStack pStack, int pTintIndex) {
                return FoliageColor.getDefaultColor();
            }
        }, ModBuildingBlocks.CONNECTABLE_OAK_LEAF_WALL.get());
    }
}

but somehow it doesn't work. When I declare the registerBlockColors function in my Main Class and call "eventBus.addListener(this::registerBlockColors);" from the Constructor it works. 

 

I told you, the methods need to be static. This is because with the annotation you're subscribing the class, not an instance of it.

Quote from @diesieben07: "@EventBusSubscriber registers the class to the event bus, as such your event handler methods must be static."

Quotes from me: "be careful to make your methods static if you do the same", "The important parts here are the Annotation for the class and the fact that its methods are static", "move those two methods into a separate class and make them static".

Link to comment
Share on other sites

30 minutes ago, X-Lomir said:

I told you, the methods need to be static. This is because with the annotation you're subscribing the class, not an instance of it.

Quote from @diesieben07: "@EventBusSubscriber registers the class to the event bus, as such your event handler methods must be static."

Quotes from me: "be careful to make your methods static if you do the same", "The important parts here are the Annotation for the class and the fact that its methods are static", "move those two methods into a separate class and make them static".

First of all thank you for all your help I have been stuck with this for a while! 
Okay so the @EventBusSubscriber makes it so I don't have to call the method, Forge automatically does?

 

EDIT: THANK YOU SO MUCH NOW EVERYTHING WORKS FINE!
YOU'RE A GOD DAMN LEGEND

Edited by Brainterminator
Fixed it!
Link to comment
Share on other sites

11 minutes ago, Brainterminator said:

First of all thank you for all your help I have been stuck with this for a while! 
Okay so the @EventBusSubscriber makes it so I don't have to call the method, Forge automatically does?

Yep. Instead of telling Forge a specific method needs to be called upon a certain event (which is what you were doing in the constructor) you're telling Forge to register that class (not instance, so only the static fields) to the event bus. Then, by adding @SubscribeEvent and the type of the event as parameter to the methods Forge will know that it has to call them upon the specified event.

By the way if you think about it you're never calling any method you register to the event listeners (this::methodName passed the method as parameter, doesn't call it), you're instead passing them as parameter so that Forge knows what to call and when. The key difference is that in the constructor you're registering the methods to the event bus by calling IEventBus#addListener, instead with the separate class you're using annotations to do it.

I am glad I was of help and I hope this explanation was helpful too.

Link to comment
Share on other sites

28 minutes ago, X-Lomir said:

Yep. Instead of telling Forge a specific method needs to be called upon a certain event (which is what you were doing in the constructor) you're telling Forge to register that class (not instance, so only the static fields) to the event bus. Then, by adding @SubscribeEvent and the type of the event as parameter to the methods Forge will know that it has to call them upon the specified event.

By the way if you think about it you're never calling any method you register to the event listeners (this::methodName passed the method as parameter, doesn't call it), you're instead passing them as parameter so that Forge knows what to call and when. The key difference is that in the constructor you're registering the methods to the event bus by calling IEventBus#addListener, instead with the separate class you're using annotations to do it.

I am glad I was of help and I hope this explanation was helpful too.

It definitely was! Thank you so much again! It was also really helpful to get it explained for once! I was also on a discord and when I asked them about it they were like "just use lambda", " if you don't even understand this don't even bother making a mc mod"

Link to comment
Share on other sites

  • 1 month later...

@diesieben07I have a new bug that I can't understand why it's happening. For a bit of context, I added the feature of double vertical slabs, similar to double slabs. However the bug happens when a vertical slab that emits lights becomes double: at that point it stops emitting light.

Normal vertical slab just placed: https://imgur.com/a/QCXa16B

Double vertical slab just placed: https://imgur.com/i43sHvt

And as you can see in both cases the level property stays to 15, however when it's double light is not emitted, not even after updating the chunk.

The relevant code is the following:

public BlockState getStateForPlacement(BlockPlaceContext placeContext) {
  BlockPos pos = placeContext.getClickedPos();
  Level level = placeContext.getLevel();
  BlockState referredSlabState = VerticalSlabUtils.getReferredSlabState(placeContext.getItemInHand());
  // if item in hand and block clicked on have the same referredSlabStates, then they are both the same kind of vertical slabs
  if (referredSlabState == VerticalSlabUtils.getReferredSlabState(level, pos)) {
    BlockState blockstate = this.defaultBlockState().setValue(WATERLOGGED, false).setValue(DOUBLE, true);
    if (referredSlabState != null) {
      BlockState referredBlockState = VerticalSlabUtils.getReferredBlockState(referredSlabState);
      BlockState referredState = referredBlockState != null ? referredBlockState : referredSlabState;
      blockstate = blockstate
        .setValue(LEVEL, getReferredProperty(referredState::getLightEmission, referredState::getLightEmission, level, pos)) // Set the level property exactly as below
        .setValue(OCCLUSION, referredState.useShapeForLightOcclusion());
    }
    return blockstate;
  } else {
    BlockState blockstate = this.defaultBlockState().setValue(FACING, placeContext.getHorizontalDirection()).setValue(WATERLOGGED, level.getFluidState(pos).getType() == Fluids.WATER);
    if (referredSlabState != null) {
      BlockState referredBlockState = VerticalSlabUtils.getReferredBlockState(referredSlabState);
      blockstate = blockstate
        .setValue(LEVEL, getReferredProperty(referredSlabState::getLightEmission, referredSlabState::getLightEmission, level, pos)) // Setting the level property like this works for normal vertical slabs
        .setValue(OCCLUSION, (referredBlockState != null ? referredBlockState : referredSlabState).useShapeForLightOcclusion());
    }
    return blockstate.setValue(SHAPE, getStairsShape(blockstate, level, pos)).setValue(DOUBLE, false);
  }
}
public VerticalSlabBlock(Material material) {
  super(
    BlockBehaviour.Properties.of(material)
    .isValidSpawn((state, getter, pos, entityType) -> false)
    .isRedstoneConductor((state, getter, pos) -> false)
    .isSuffocating((state, getter, pos) -> false)
    .lightLevel(LightBlock.LIGHT_EMISSION)
    .dynamicShape()
  );
  this.registerDefaultState(
    this.defaultBlockState()
      .setValue(FACING, Direction.NORTH)
      .setValue(SHAPE, StairsShape.STRAIGHT)
      .setValue(WATERLOGGED, false)
      .setValue(LEVEL, 0)
      .setValue(OCCLUSION, false)
      .setValue(DOUBLE, false)
  );
}

If there's any other part of the code that's needed let me know, anyway as always here you can find the whole repo.

Edited by X-Lomir
Misclicked when posted the first time and updated code snippets.
Link to comment
Share on other sites

If it's needed to test it out, you can just hardcode the LEVEL values in both methods to 15, removing the 0 in the constructor and removing the calls to getReferredProperty.

Btw getReferredProperty I'm sure works fine because it works with normal vertical slabs and it keeps the correct light level for double vertical slabs, and anyway the bug is still there even when hardcoding 15.

I really have no clue on why this happens, it's the last bug I have to fix before I can release a new stable version and I've been trying to solve this for days and I made no progress 😅

Link to comment
Share on other sites

Update:

I discovered that it's not just a bug of double vertical slabs, it affects also normal vertical slabs.

The actual bug is the following: "external" faces (faces that align with the edge of the block) do not emit light, only "internal" (faces within the block) do.

Here a couple of images to better understand the situation: https://imgur.com/a/ryaevWb (I used the hardcoding trick explained before here, that's why a oak slab is emitting light).

So at first I noticed the bug only with double vertical slabs as they are naturally without "internal" faces that can emit light, but upon further inspection this is what the bug actually was.

Honestly I still have no idea on how to fix this, but maybe this new info can help in getting some help 😄

Link to comment
Share on other sites

Okay, I actually finally managed to solve it and, as usual, it was a very trivial mistake: I had useShapeForLightOcclusion returning true regardless of whether the vertical slab was supposed to emit light. Adding a check for the light emission level solved my issue.

Link to comment
Share on other sites

  • 2 months later...

I'm trying to port to 1.19 and I managed to updated everything but one thing: the creative tabs.

I had the following method handle updating the creative search tree:

public static final void addToSearchTree() {
  int intialSize = inSearchTree.size();
  MutableSearchTree<ItemStack> creativeSearchTree = Minecraft.getInstance().getSearchTree(SearchRegistry.CREATIVE_NAMES);
  for(BlockState referredSlabState : MapsManager.slabStateMap.values()) {
    if (!inSearchTree.containsKey(referredSlabState)) {
      creativeSearchTree.add(VerticalSlabUtils.getVerticalSlabItem(referredSlabState, VerticalSlabUtils.isTranslucent(referredSlabState)));
      inSearchTree.put(referredSlabState, true);
    }
  }
  if (intialSize != inSearchTree.size()) {
    creativeSearchTree.refresh();
  }
}

However in 1.19 it looks like getSearchTree returns a SearchTree and MutableSearchTree disappeared.

Link to comment
Share on other sites

I also just found out a bug that makes the game crash...

It has something to do with the item rendering. In the inventory it works fine, but as soon as I drop the item or try to look at it in F5, the game crashes.

java.lang.IllegalStateException: Pose stack not empty
	at net.minecraft.client.renderer.LevelRenderer.checkPoseStack(LevelRenderer.java:1430) ~[forge-1.19.2-43.1.1_mapped_official_1.19.2-recomp.jar%23183!/:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}
	at net.minecraft.client.renderer.LevelRenderer.renderLevel(LevelRenderer.java:1229) ~[forge-1.19.2-43.1.1_mapped_official_1.19.2-recomp.jar%23183!/:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}
	at net.minecraft.client.renderer.GameRenderer.renderLevel(GameRenderer.java:1068) ~[forge-1.19.2-43.1.1_mapped_official_1.19.2-recomp.jar%23183!/:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}
	at net.minecraft.client.renderer.GameRenderer.render(GameRenderer.java:840) ~[forge-1.19.2-43.1.1_mapped_official_1.19.2-recomp.jar%23183!/:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}
	at net.minecraft.client.Minecraft.runTick(Minecraft.java:1115) ~[forge-1.19.2-43.1.1_mapped_official_1.19.2-recomp.jar%23183!/:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}
	at net.minecraft.client.Minecraft.run(Minecraft.java:700) ~[forge-1.19.2-43.1.1_mapped_official_1.19.2-recomp.jar%23183!/:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}
	at net.minecraft.client.main.Main.run(Main.java:212) ~[forge-1.19.2-43.1.1_mapped_official_1.19.2-recomp.jar%23183!/:?] {re:classloading,pl:runtimedistcleaner:A}
	at net.minecraft.client.main.Main.main(Main.java:51) ~[forge-1.19.2-43.1.1_mapped_official_1.19.2-recomp.jar%23183!/:?] {re:classloading,pl:runtimedistcleaner:A}
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?] {}
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:?] {}
	at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:?] {}
	at java.lang.reflect.Method.invoke(Unknown Source) ~[?:?] {}
	at net.minecraftforge.fml.loading.targets.ForgeClientUserdevLaunchHandler.lambda$launchService$0(ForgeClientUserdevLaunchHandler.java:25) ~[fmlloader-1.19.2-43.1.1.jar%2395!/:?] {}
	at cpw.mods.modlauncher.LaunchServiceHandlerDecorator.launch(LaunchServiceHandlerDecorator.java:30) [modlauncher-10.0.8.jar%23108!/:?] {}
	at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:53) [modlauncher-10.0.8.jar%23108!/:?] {}
	at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:71) [modlauncher-10.0.8.jar%23108!/:?] {}
	at cpw.mods.modlauncher.Launcher.run(Launcher.java:106) [modlauncher-10.0.8.jar%23108!/:?] {}
	at cpw.mods.modlauncher.Launcher.main(Launcher.java:77) [modlauncher-10.0.8.jar%23108!/:?] {}
	at cpw.mods.modlauncher.BootstrapLaunchConsumer.accept(BootstrapLaunchConsumer.java:26) [modlauncher-10.0.8.jar%23108!/:?] {}
	at cpw.mods.modlauncher.BootstrapLaunchConsumer.accept(BootstrapLaunchConsumer.java:23) [modlauncher-10.0.8.jar%23108!/:?] {}
	at cpw.mods.bootstraplauncher.BootstrapLauncher.main(BootstrapLauncher.java:141) [bootstraplauncher-1.1.2.jar:?] {}


A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

-- Head --
Thread: Render thread
Stacktrace:
	at net.minecraft.client.renderer.LevelRenderer.checkPoseStack(LevelRenderer.java:1430) ~[forge-1.19.2-43.1.1_mapped_official_1.19.2-recomp.jar%23183!/:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}
	at net.minecraft.client.renderer.LevelRenderer.renderLevel(LevelRenderer.java:1229) ~[forge-1.19.2-43.1.1_mapped_official_1.19.2-recomp.jar%23183!/:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}
	at net.minecraft.client.renderer.GameRenderer.renderLevel(GameRenderer.java:1068) ~[forge-1.19.2-43.1.1_mapped_official_1.19.2-recomp.jar%23183!/:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}

Here the log of the crash and below what I believe the relevant code is:

// Inside my VerticalSlabBakedModel
@Override
public BakedModel applyTransform(TransformType transformType, PoseStack poseStack, boolean applyLeftHandTransform) {
  Transformation transformation = VerticalSlabPerspectiveTransformer.getTransformation(transformType);
  if (!transformation.isIdentity()) {
    transformation.push(poseStack);
  }
  return this;
}
public class VerticalSlabPerspectiveTransformer {
  /**
   * Map of all the Vertical Slab Item {@link Transformation transformations} associated with their respective {@link TransformType}.
   */
  private static final Map<TransformType, Transformation> TRANSFORMATIONS = Map.ofEntries(
    entry(TransformType.GUI, getTransformation(new Vector3f(0.1F, -0.05F, 0), new Vector3f(30, 45, 0), new Vector3f(0.625F, 0.625F, 0.625F))),
    entry(TransformType.GROUND, getTransformation(new Vector3f(0, 0.015F, 0.075F), Vector3f.ZERO, new Vector3f(0.25F, 0.25F, 0.25F))),
    entry(TransformType.FIXED, getTransformation(Vector3f.ZERO, Vector3f.ZERO, new Vector3f(0.5F, 0.5F, 0.5F))),
    entry(TransformType.FIRST_PERSON_LEFT_HAND, getTransformation(Vector3f.ZERO, new Vector3f(0, 315, 0), new Vector3f(0.4F, 0.4F, 0.4F))),
    entry(TransformType.FIRST_PERSON_RIGHT_HAND, getTransformation(Vector3f.ZERO, new Vector3f(0, 135, 0), new Vector3f(0.4F, 0.4F, 0.4F))),
    entry(TransformType.THIRD_PERSON_LEFT_HAND, getTransformation(new Vector3f(0F, 0.175F, 0), new Vector3f(75, 315, 0), new Vector3f(0.375F, 0.375F, 0.375F))),
    entry(TransformType.THIRD_PERSON_RIGHT_HAND, getTransformation(new Vector3f(0F, 0.175F, 0), new Vector3f(75, 135, 0), new Vector3f(0.375F, 0.375F, 0.375F)))
  );

  /**
   * Returns a new {@link Transformation} given the translation, rotation and scale {@link Vector3f vectors}.
   * 
   * @param translation - translation {@link Vector3f}.
   * @param rotation - rotation {@link Vector3f}, in degrees.
   * @param scale - scale {@link Vector3f}.
   * @return a new {@link Transformation}.
   */
  private static final Transformation getTransformation(Vector3f translation, Vector3f rotation, Vector3f scale) {
    return new Transformation(translation, TransformationHelper.quatFromXYZ(rotation, true), scale, null);
  }

  /**
   * Returns the correct Vertical Slab Item {@link Transformation} given the {@link TransformType}.
   * 
   * @param transformType - {@link TransformType}.
   * @return one of {@link #TRANSFORMATIONS Vertical Slab Item Transformations}.
   */
  public static final Transformation getTransformation(TransformType transformType) {
    return TRANSFORMATIONS.getOrDefault(transformType, Transformation.identity());
  }
}

All code is available here.

Link to comment
Share on other sites

Start new threads for new questions and don't mix topics.

This thread is already way too long.

Edited by warjort

Boilerplate:

If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one.

If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install

Large files should be posted to a file sharing site like https://gist.github.com  You should also read the support forum sticky post.

Link to comment
Share on other sites

Just now, warjort said:

Don't hijack other people's threads.

If you are not answering the original poster's question, start your own thread.

This is my thread, I had created it for this mod. Since it's relevant to the same mod so I thought it would be fine to post here

Link to comment
Share on other sites

Yes I noticed that and changed my response.

It's still impossible to keep track of and answer a thread that is a random collection of unrelated questions.

Being in the same mod does not make them the same topic.

Boilerplate:

If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one.

If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install

Large files should be posted to a file sharing site like https://gist.github.com  You should also read the support forum sticky post.

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.




  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Hello I cannot resize my minecraft anymore when I try it does only crash. I don't know what is happening with this game I'm using Forge 1.20.1-47.2.17 and here's the link of the latest log https://paste.ee/p/y00ed Edit: I decided to create a new world and it crashed too so I got this other link https://paste.ee/p/RZdaD  
    • Wait guys, I still don't don't understand... I shall send my code -- Define the function to decrease hunger local function decreaseHunger(player)     local currentHunger = player.getHunger()          -- Check if hunger is not already zero     if currentHunger > 0 then         player.setHunger(currentHunger - 1)     end end -- Register event to decrease hunger over time script.registerEvent(EntityPlayer, function(player)     while true do         -- Decrease hunger every few seconds         decreaseHunger(player)         script.sleep(1000) -- Sleep for 1 second     end end)     Any help appriecated. It's been a while since I learnt Javascript or whatever Minecraft is made with... ... ... ... Nicknotname Hungerinpeaceful xx
    • good days  i get this error: java.lang.ClassCastException: class net.minecraft.client.player.LocalPlayer cannot be cast to class net.minecraftforge.common.extensions.IForgeServerPlayer (net.minecraft.client.player.LocalPlayer is in module minecraft@1.20.4 of loader 'TRANSFORMER' @3e8b3b79; net.minecraftforge.common.extensions.IForgeServerPlayer is in module forge@49.0.26 of loader 'TRANSFORMER' @3e8b3b79)     at mercmod.blocks.classes.panel_whit_entity_inside.use(panel_whit_entity_inside.java:576) ~[main/:?] {re:classloading}     at net.minecraft.world.level.block.state.BlockBehaviour$BlockStateBase.use(BlockBehaviour.java:826) ~[forge-1.20.4-49.0.26_mapped_official_1.20.4-recomp.jar:?] {re:classloading}     at net.minecraft.client.multiplayer.MultiPlayerGameMode.performUseItemOn(MultiPlayerGameMode.java:324) ~[forge-1.20.4-49.0.26_mapped_official_1.20.4-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A}     at net.minecraft.client.multiplayer.MultiPlayerGameMode.lambda$useItemOn$4(MultiPlayerGameMode.java:292) ~[forge-1.20.4-49.0.26_mapped_official_1.20.4-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A}     at net.minecraft.client.multiplayer.MultiPlayerGameMode.startPrediction(MultiPlayerGameMode.java:251) ~[forge-1.20.4-49.0.26_mapped_official_1.20.4-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A}     at net.minecraft.client.multiplayer.MultiPlayerGameMode.useItemOn(MultiPlayerGameMode.java:291) ~[forge-1.20.4-49.0.26_mapped_official_1.20.4-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A}     at net.minecraft.client.Minecraft.startUseItem(Minecraft.java:1799) ~[forge-1.20.4-49.0.26_mapped_official_1.20.4-recomp.jar:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}     at net.minecraft.client.Minecraft.handleKeybinds(Minecraft.java:2083) ~[forge-1.20.4-49.0.26_mapped_official_1.20.4-recomp.jar:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}     at net.minecraft.client.Minecraft.tick(Minecraft.java:1902) ~[forge-1.20.4-49.0.26_mapped_official_1.20.4-recomp.jar:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}     at net.minecraft.client.Minecraft.runTick(Minecraft.java:1216) ~[forge-1.20.4-49.0.26_mapped_official_1.20.4-recomp.jar:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}     at net.minecraft.client.Minecraft.run(Minecraft.java:801) ~[forge-1.20.4-49.0.26_mapped_official_1.20.4-recomp.jar:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}     at net.minecraft.client.main.Main.main(Main.java:234) ~[forge-1.20.4-49.0.26_mapped_official_1.20.4-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A} ------------------------------------------------------------------------------------------------------------------   context:  im updating the briefcase from mi mod an i need to make a gui whit this image that gonna be launched from a block and from a item soo im using kapenjoe tutorials  ---------------------------------------------------------------------------------------- The problem is that tutorial is for 1.20.1 and im using 1.20.4 and i really dont get how to call and open the gui from the block nor from the item i made this based on post i made short ago everything seems find but when right click the block to open the gui it crash the game  @Override public InteractionResult use(BlockState blkstate, Level warudo, BlockPos pos, Player pe, InteractionHand hand, BlockHitResult hitresult) {     if(warudo.isClientSide()){         BlockEntity blkentity = warudo.getBlockEntity(pos);         if(blkentity instanceof Panel_BlockEntity){             //   ↓↓↓  open the menu from the block              IForgeServerPlayer ifpe = (IForgeServerPlayer)pe; //<--- this is wrong  "class net.minecraft.client.player.LocalPlayer cannot be cast to class net.minecraftforge.common.extensions.IForgeServerPlayer"             ifpe.openMenu( (Panel_BlockEntity) blkentity, pos ); //<-- i need an example of how open a gui in 1.20.4         }     } return InteractionResult.sidedSuccess(warudo.isClientSide()); } Theres nothing highlighted in red in the code like everything where right an possible but dont works  ####################################################################################################### i need to see an example, just the piece of code for the use() method of the block whit the block entity for 1.20.4  and the same  but for the item     @Override     public @NotNull InteractionResultHolder<ItemStack> use(@NotNull Level warudo, @NotNull Player pe, @NotNull InteractionHand interactionHand)     {         if (!warudo.isClientSide())         {             ItemStack heldItem = pe.getItemInHand(interactionHand);                          if (heldItem.getCapability(ForgeCapabilities.ITEM_HANDLER).isPresent())             {                 //   ↓↓↓  open the menu from the item                 NetworkHooks.openScreen((ServerPlayer) pe, this);             }         }         return super.use(warudo, pe, interactionHand);     }   thanks for your attention           
    • It depends on the data you want to save, but generally speaking you should use some custom Player Capabilities, attach to the Player and use them to store/retrieve any kind of data you want. You can find how to make them work for 1.20.x in the documentation here: https://docs.minecraftforge.net/en/latest/datastorage/capabilities/
  • Topics

×
×
  • Create New...

Important Information

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