Jump to content

[1.15.2] Custom Sign Edit Screen Missing Texture


killerjdog51
 Share

Recommended Posts

I've updated my 1.14.4 mod to 1.15.2 and it turns out sign rendering has been somewhat improved/changed. So I changed from using a direct resource path to the atlas. Good thing is that the sign render for the block works, problem is that the sign render for the sign edit screen doesn't because that uses packets to communicate from server to client and I just don't understand that stuff. So I'm asking for help to get my sign edit screen working, below are images of the issue along with my code. Thank you in advanced. 

 

Sign edit screen:

spacer.png

Sign:

spacer.png

 

Wood Types:

package biome_enhancments.util;

import java.util.Set;

import it.unimi.dsi.fastutil.objects.ObjectArraySet;
import net.minecraft.block.WoodType;

public class ModWoodTypes extends WoodType
{
	   private static final Set<WoodType> VALUES = new ObjectArraySet<>();
	   public static final WoodType BAOBAB = register(new ModWoodTypes("baobab"));
	   public static final WoodType MANGROVE = register(new ModWoodTypes("mangrove"));
	   public static final WoodType PALM = register(new ModWoodTypes("palm"));

	   private final String name;

	protected ModWoodTypes(String nameIn) {
		super(nameIn);
	    this.name = nameIn;

	}

	 private static WoodType register(WoodType woodTypeIn) {
	      VALUES.add(woodTypeIn);
	      return woodTypeIn;
	   }
	 
	 public String getName() {
	      return this.name;
	   }
}

 

Sign Item:

	public static final Item BAOBAB_SIGN = new ModSignItem(new Item.Properties().maxStackSize(16).group(ItemGroup.DECORATIONS), ModBlocks.BAOBAB_SIGN, ModBlocks.BAOBAB_WALL_SIGN);
	public static final Item MANGROVE_SIGN = new ModSignItem(new Item.Properties().maxStackSize(16).group(ItemGroup.DECORATIONS), ModBlocks.MANGROVE_SIGN, ModBlocks.MANGROVE_WALL_SIGN);
	public static final Item PALM_SIGN = new ModSignItem(new Item.Properties().maxStackSize(16).group(ItemGroup.DECORATIONS), ModBlocks.PALM_SIGN, ModBlocks.PALM_WALL_SIGN);
package biome_enhancments.items;

import javax.annotation.Nullable;

import biome_enhancments.tileentity.ModSignTileEntity;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.SignItem;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

public class ModSignItem extends SignItem{

	public ModSignItem(Properties propertiesIn, Block floorBlockIn, Block wallBlockIn) {
		super(propertiesIn, floorBlockIn, wallBlockIn);
	}

	@Override
	protected boolean onBlockPlaced(BlockPos pos, World worldIn, @Nullable PlayerEntity player, ItemStack stack, BlockState state) {
	      boolean flag = super.onBlockPlaced(pos, worldIn, player, stack, state);
	      if (!worldIn.isRemote && !flag && player != null) {
	         player.openSignEditor((ModSignTileEntity)worldIn.getTileEntity(pos));
	      }

	      return flag;
	   }
}

 

Sign Block:

	public static final Block BAOBAB_SIGN = new ModStandingSignBlock(Block.Properties.create(Material.WOOD, MaterialColor.ADOBE).doesNotBlockMovement().hardnessAndResistance(1.0F).sound(SoundType.WOOD), ModWoodTypes.BAOBAB);
	public static final Block BAOBAB_WALL_SIGN = new ModWallSignBlock(Block.Properties.create(Material.WOOD, MaterialColor.ADOBE).doesNotBlockMovement().hardnessAndResistance(1.0F).sound(SoundType.WOOD).lootFrom(BAOBAB_SIGN), ModWoodTypes.BAOBAB);
	public static final Block MANGROVE_SIGN = new ModStandingSignBlock(Block.Properties.create(Material.WOOD, MaterialColor.OBSIDIAN).doesNotBlockMovement().hardnessAndResistance(1.0F).sound(SoundType.WOOD), ModWoodTypes.MANGROVE);
	public static final Block MANGROVE_WALL_SIGN = new ModWallSignBlock(Block.Properties.create(Material.WOOD, MaterialColor.OBSIDIAN).doesNotBlockMovement().hardnessAndResistance(1.0F).sound(SoundType.WOOD).lootFrom(MANGROVE_SIGN), ModWoodTypes.MANGROVE);
	public static final Block PALM_SIGN = new ModStandingSignBlock(Block.Properties.create(Material.WOOD, MaterialColor.SAND).doesNotBlockMovement().hardnessAndResistance(1.0F).sound(SoundType.WOOD), ModWoodTypes.PALM);
	public static final Block PALM_WALL_SIGN = new ModWallSignBlock(Block.Properties.create(Material.WOOD, MaterialColor.SAND).doesNotBlockMovement().hardnessAndResistance(1.0F).sound(SoundType.WOOD).lootFrom(PALM_SIGN), ModWoodTypes.PALM);
	
package biome_enhancments.blocks;

import biome_enhancments.tileentity.ModSignTileEntity;
import net.minecraft.block.StandingSignBlock;
import net.minecraft.block.WoodType;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.IBlockReader;

public class ModStandingSignBlock extends StandingSignBlock {

	public ModStandingSignBlock(Properties properties, WoodType woodType) {
		super(properties, woodType);
	}

	@Override
	public TileEntity createNewTileEntity(IBlockReader worldIn) {
	      return new ModSignTileEntity();
	   }
}
package biome_enhancments.blocks;

import biome_enhancments.tileentity.ModSignTileEntity;
import net.minecraft.block.WallSignBlock;
import net.minecraft.block.WoodType;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.IBlockReader;

public class ModWallSignBlock extends WallSignBlock {

	public ModWallSignBlock(Properties properties, WoodType woodType) {
		super(properties, woodType);
	}

	@Override
	public TileEntity createNewTileEntity(IBlockReader worldIn) {
	      return new ModSignTileEntity();
	   }
}

 

Sign Tile Entity:

	public static final TileEntityType<ModSignTileEntity> SIGN = TileEntityType.Builder.create(ModSignTileEntity::new , ModBlocks.BAOBAB_SIGN, ModBlocks.BAOBAB_WALL_SIGN, ModBlocks.MANGROVE_SIGN, ModBlocks.MANGROVE_WALL_SIGN, ModBlocks.PALM_SIGN, ModBlocks.PALM_WALL_SIGN).build(null);
package biome_enhancments.tileentity;

import biome_enhancments.init.ModTileEntityTypes;
import net.minecraft.tileentity.SignTileEntity;
import net.minecraft.tileentity.TileEntityType;

public class ModSignTileEntity extends SignTileEntity
{
	@Override
	public TileEntityType<?> getType() {
	      return ModTileEntityTypes.SIGN;
	   }

}

 

Sign Render:

package biome_enhancments.tileentity;

import java.util.List;

import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.vertex.IVertexBuilder;

import biome_enhancments.BiomeEnhancements;
import biome_enhancments.blocks.ModStandingSignBlock;
import biome_enhancments.blocks.ModWallSignBlock;
import biome_enhancments.init.ModBlocks;
import net.minecraft.block.AbstractSignBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.StandingSignBlock;
import net.minecraft.block.WallSignBlock;
import net.minecraft.block.WoodType;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.RenderComponentsUtil;
import net.minecraft.client.renderer.Atlases;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.client.renderer.model.Material;
import net.minecraft.client.renderer.texture.NativeImage;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.tileentity.SignTileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.tileentity.SignTileEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

@OnlyIn(Dist.CLIENT)
public class ModSignTileEntityRenderer extends TileEntityRenderer<ModSignTileEntity>
{
	   private final SignTileEntityRenderer.SignModel model = new SignTileEntityRenderer.SignModel();

	    public ModSignTileEntityRenderer(TileEntityRendererDispatcher rendererDispatcherIn) {
	        super(rendererDispatcherIn);
	     }
	    
	 	public void render(ModSignTileEntity tileEntityIn, float partialTicks, MatrixStack matrixStackIn, IRenderTypeBuffer bufferIn, int combinedLightIn, int combinedOverlayIn) {
	 	      BlockState blockstate = tileEntityIn.getBlockState();
	 	      matrixStackIn.push();
	 	      float f = 0.6666667F;
	 	      if (blockstate.getBlock() instanceof StandingSignBlock) {
	 	         matrixStackIn.translate(0.5D, 0.5D, 0.5D);
	 	         float f1 = -((float)(blockstate.get(StandingSignBlock.ROTATION) * 360) / 16.0F);
	 	         matrixStackIn.rotate(Vector3f.YP.rotationDegrees(f1));
	 	         this.model.signStick.showModel = true;
	 	      } else {
	 	         matrixStackIn.translate(0.5D, 0.5D, 0.5D);
	 	         float f4 = -blockstate.get(WallSignBlock.FACING).getHorizontalAngle();
	 	         matrixStackIn.rotate(Vector3f.YP.rotationDegrees(f4));
	 	         matrixStackIn.translate(0.0D, -0.3125D, -0.4375D);
	 	         this.model.signStick.showModel = false;
	 	      }

	 	      matrixStackIn.push();
	 	      matrixStackIn.scale(0.6666667F, -0.6666667F, -0.6666667F);
	 	      Material material = getMaterial(blockstate.getBlock());
	 	      IVertexBuilder ivertexbuilder = material.getBuffer(bufferIn, this.model::getRenderType);
	 	      this.model.signBoard.render(matrixStackIn, ivertexbuilder, combinedLightIn, combinedOverlayIn);
	 	      this.model.signStick.render(matrixStackIn, ivertexbuilder, combinedLightIn, combinedOverlayIn);
	 	      matrixStackIn.pop();
	 	      FontRenderer fontrenderer = this.renderDispatcher.getFontRenderer();
	 	      float f2 = 0.010416667F;
	 	      matrixStackIn.translate(0.0D, (double)0.33333334F, (double)0.046666667F);
	 	      matrixStackIn.scale(0.010416667F, -0.010416667F, 0.010416667F);
	 	      int i = tileEntityIn.getTextColor().getTextColor();
	 	      double d0 = 0.4D;
	 	      int j = (int)((double)NativeImage.getRed(i) * 0.4D);
	 	      int k = (int)((double)NativeImage.getGreen(i) * 0.4D);
	 	      int l = (int)((double)NativeImage.getBlue(i) * 0.4D);
	 	      int i1 = NativeImage.getCombined(0, l, k, j);

	 	      for(int j1 = 0; j1 < 4; ++j1) {
	 	         String s = tileEntityIn.getRenderText(j1, (p_212491_1_) -> {
	 	            List<ITextComponent> list = RenderComponentsUtil.splitText(p_212491_1_, 90, fontrenderer, false, true);
	 	            return list.isEmpty() ? "" : list.get(0).getFormattedText();
	 	         });
	 	         if (s != null) {
	 	            float f3 = (float)(-fontrenderer.getStringWidth(s) / 2);
	 	            fontrenderer.renderString(s, f3, (float)(j1 * 10 - tileEntityIn.signText.length * 5), i1, false, matrixStackIn.getLast().getMatrix(), bufferIn, false, 0, combinedLightIn);
	 	         }
	 	      }

	 	      matrixStackIn.pop();
	 	   }

	 	 public static Material getMaterial(Block blockIn) {
	 	      WoodType woodtype;
	 	      if (blockIn instanceof AbstractSignBlock) {
	 	         woodtype = ((AbstractSignBlock)blockIn).getWoodType();
	 	      } else {
	 	         woodtype = WoodType.OAK;
	 	      }

	 	      return getSignMaterial(woodtype);
	 	   }

	 	   public static Material getSignMaterial(WoodType woodtype) {
	 	      return new Material(Atlases.SIGN_ATLAS, new ResourceLocation(BiomeEnhancements.MOD_ID, "entity/signs/" + woodtype.getName()));
	 	   }
}
package biome_enhancments.tileentity;

import biome_enhancments.BiomeEnhancements;
import net.minecraft.client.renderer.Atlases;
import net.minecraft.client.renderer.texture.AtlasTexture;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

@Mod.EventBusSubscriber(modid = BiomeEnhancements.MOD_ID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD)
public class ModSignTextureStitch {

	public static final ResourceLocation BAOBAB = new ResourceLocation(BiomeEnhancements.MOD_ID, "entity/signs/baobab");
	public static final ResourceLocation MANGROVE = new ResourceLocation(BiomeEnhancements.MOD_ID, "entity/signs/mangrove");
	public static final ResourceLocation PALM = new ResourceLocation(BiomeEnhancements.MOD_ID, "entity/signs/palm");

	@SubscribeEvent
    public static void onStitchEvent(TextureStitchEvent.Pre event)
    {
		ResourceLocation stitching = event.getMap().getTextureLocation();
        if(!stitching.equals(Atlases.SIGN_ATLAS))
        {
            return;
        }
        
        boolean added = event.addSprite(BAOBAB);
        added = event.addSprite(MANGROVE);
        added = event.addSprite(PALM);

    }

}

 

Edited by killerjdog51
Link to comment
Share on other sites

13 hours ago, killerjdog51 said:

because that uses packets to communicate from server to client and I just don't understand that stuff.

Not true, no client synchronization nonsense is going on here. It's the same reason as it was last time when you replaced getSignMaterial within the TER. You are calling EditSignScreen which grabs the material via SignTileEntityRenderer::getMaterial which hardcodes to the vanilla asset library. So, create a custom screen that uses your entry instead of vanilla's.

Link to comment
Share on other sites

On 10/18/2020 at 6:08 AM, ChampionAsh5357 said:

Not true, no client synchronization nonsense is going on here. It's the same reason as it was last time when you replaced getSignMaterial within the TER. You are calling EditSignScreen which grabs the material via SignTileEntityRenderer::getMaterial which hardcodes to the vanilla asset library. So, create a custom screen that uses your entry instead of vanilla's.

I had the same problem a while ago, i created the custom sign screen but i don't know how to open the custom screen instead of the vanilla one.
In the ClientPlayerEntity class, the EditSignScreen is hardcoded

this.mc.displayGuiScreen(new EditSignScreen(signTile));

 

So in a custom SignItem, i cannot use:

player.openSignEditor(worldIn.getTileEntity(pos) as CustomSignTileEntity)

 

I also tried using this code, but the game crash after placing the sign.

class CustomSignItem(propertiesIn: Properties?, floorBlockIn: Block?, wallBlockIn: Block?) : WallOrFloorItem(floorBlockIn, wallBlockIn, propertiesIn) {
    override fun onBlockPlaced(
        pos: BlockPos,
        worldIn: World,
        player: PlayerEntity?,
        stack: ItemStack,
        state: BlockState
    ): Boolean {
        val flag = super.onBlockPlaced(pos, worldIn, player, stack, state)
        if (!worldIn.isRemote && !flag && player != null) {
            Minecraft.getInstance().displayGuiScreen(CustomEditSignScreen(worldIn.getTileEntity(pos) as CustomSignTileEntity))
        }
        return flag
    }
}

 

How i can override them?

Edited by jhonny97
Link to comment
Share on other sites

2 hours ago, jhonny97 said:

I also tried using this code, but the game crash after placing the sign.

Oh, Kotlin. Haven't seen that here before.

 

That's quite a simple answer, you're checking to display the screen on the logical server instead of the logical client. You need to check if you're on the logical client and not logical server before calling that method. Also, you shouldn't call the method so directly and instead leave it in some sort of object reference as that piece of code cannot guarantee that it will be executed not on a physical server. Isolate your client only code somewhere else and reference via a DistExecutor.

Link to comment
Share on other sites

16 hours ago, ChampionAsh5357 said:

Oh, Kotlin. Haven't seen that here before.

 

That's quite a simple answer, you're checking to display the screen on the logical server instead of the logical client. You need to check if you're on the logical client and not logical server before calling that method. Also, you shouldn't call the method so directly and instead leave it in some sort of object reference as that piece of code cannot guarantee that it will be executed not on a physical server. Isolate your client only code somewhere else and reference via a DistExecutor.

I tried checking for logical client, but by calling it directly, Minecraft stuck after i place the sign.

I will try with DistExecutor.

Link to comment
Share on other sites

I used the DistExecutor and the code is now the following

val flag = super.onBlockPlaced(pos, worldIn, player, stack, state)
        if (worldIn.isRemote && !flag && player != null) {
            DistExecutor.safeRunWhenOn(Dist.CLIENT) {
                DistExecutor.SafeRunnable {
                    Minecraft.getInstance().displayGuiScreen(CustomEditSignScreen(worldIn.getTileEntity(pos) as CustomSignTileEntity))
                }
            }
        }
        return flag

 

Now my custom sign screen is opened and i can edit it, but when i exit and re-enter the world, the sign is blank.

If i use

!worldIn.isRemote

instead of

worldIn.isRemote

 the game crash even if i use the DistExecutor

Edited by jhonny97
Link to comment
Share on other sites

27 minutes ago, jhonny97 said:

!worldIn.isRemote

We've already went over that why it doesn't work.

27 minutes ago, jhonny97 said:

Now my custom sign screen is opened and i can edit it, but when i exit and re-enter the world, the sign is blank.

Then you're not saving the information in the TE and/or syncing it to the client on chunk load.

Link to comment
Share on other sites

13 minutes ago, ChampionAsh5357 said:

We've already went over that why it doesn't work.

Then you're not saving the information in the TE and/or syncing it to the client on chunk load.

My tile entity extend the SignTileEntity

class CustomSignTileEntity : SignTileEntity() {
    override fun getType(): TileEntityType<*> {
        return TileEntityInit.signTileEntity
    }
}
val signTileEntity: TileEntityType<CustomSignTileEntity> by tileEntities.register("my_sign") {
        TileEntityType.Builder.create({ CustomSignTileEntity() }, BlockInit.mySign, BlockInit.myWallSign).build(null)
    }

 

If i extend SignTileEntity, the TE sync shouldn't happen by itself?

Link to comment
Share on other sites

18 minutes ago, diesieben07 said:

This is something that would need to be checked in the debugger. There are so many things that could be wrong here, it is nearly impossible to tell by just staring at incomplete code snippets.

Please post a Git repo of your mod that shows this problem.

This is the Git repo

https://github.com/michele-grifa/MoreStuffMod.git

 

The branch is the 1.16.1

Edited by jhonny97
Link to comment
Share on other sites

11 minutes ago, diesieben07 said:

The code you posted for your sign TileEntity is not the same as the code in your repository. The code in your repository uses the TileEntityType for the vanilla sign, so your tile entity gets saved as a vanilla sign.

I was doing some testing and i accidentally pushed the changes.

I replaced TileEntityType.SIGN with my custom type, but the result is the same

Link to comment
Share on other sites

11 hours ago, diesieben07 said:

ServerPlayerEntity#openSignEditor does one crucial thing: It calls signTile.setPlayer(this) - you don't do that.

I don't know where to place that code, the only place that possibly can go is the DistExecutor, but not work.

I updated the repo to reflect this change.

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



×
×
  • Create New...

Important Information

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