Jump to content

Robsutar

Members
  • Posts

    8
  • Joined

  • Last visited

Posts posted by Robsutar

  1. How is BlockState sent from the server to a client using Packets? I plan to use this BlockState for renderings
     

        public static void encode(CarrierBlocksPacket msg, FriendlyByteBuf buf) {
            BlockState state = msg.blockState;
            buf.write....?
        }
    
        public static CarrierBlocksPacket decode(FriendlyByteBuf buf) {
            BlockState state = buf.read....?
        }

     

  2. I'm trying to import a .jar, located in my project's libs folder

    build.gradle:
     

    {
      repositories {...}
      dependencies {
          	minecraft 'net.minecraftforge:forge:1.19.2-43.2.11'
          	implementation files("libs/rbullet.jar")
      }
    }

    That way I manage to call a constructor from a class of `rbullet`, but when I open the game, I get the following error:

     

    	Caused by 1: java.lang.NoClassDefFoundError: com/robsutar/rbullet/CorpoRigido
    		at com.example.examplemod.ExampleMod.<init>(ExampleMod.java:63) ~[%23193!/:?] {re:classloading}
    		at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:?] {}
    		at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77) ~[?:?] {}
    		at jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:?] {}
    		at java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) ~[?:?] {}
    		at java.lang.reflect.Constructor.newInstance(Constructor.java:480) ~[?:?] {}
    		at net.minecraftforge.fml.javafmlmod.FMLModContainer.constructMod(FMLModContainer.java:68) ~[javafmllanguage-1.19.2-43.2.11.jar%23189!/:?] {}
    		at net.minecraftforge.fml.ModContainer.lambda$buildTransitionHandler$10(ModContainer.java:121) ~[fmlcore-1.19.2-43.2.11.jar%23192!/:?] {}
    		at java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1804) ~[?:?] {}
    		at java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1796) ~[?:?] {}
    		at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373) ~[?:?] {}
    		at java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182) ~[?:?] {}
    		at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655) ~[?:?] {}
    		at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622) ~[?:?] {}
    		at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165) ~[?:?] {}

    it's like examplemod just to demonstrate that it's not a compatibility issue with anything else, but I've tried putting it in my main project and I'm getting the same error

    rbullet is a project I created, which has only one class `CorpoRigido`, and I can reference this class, using gradle in the same way, without any problem in other projects that are not of the forge architecture (new java project). Am I forgetting something?

  3. I would like to know if there is a faster method of generating VoxelShapes in different directions in a less boring way, currently I go to the blockbench, rotate my block to a certain direction, and export the model's VoxelShape in that direction. I have to do this for all six directions (north, east, south, west, up, down) every time I create a new rotating block.

    Code:

        private static final VoxelShape NORTH = Shapes.box(0.25, 0.25, 0, 0.75, 0.75, 0.25);
        private static final VoxelShape EAST = Shapes.box(0.75, 0.25, 0.25, 1, 0.75, 0.75);
        private static final VoxelShape SOUTH = Shapes.box(0.25, 0.25, 0.75, 0.75, 0.75, 1);
        private static final VoxelShape WEST = Shapes.box(0, 0.25, 0.25, 0.25, 0.75, 0.75);
        private static final VoxelShape UP = Shapes.box(0.25, 0.75, 0.25, 0.75, 1, 0.75);
        private static final VoxelShape DOWN = Shapes.box(0.25, 0, 0.25, 0.75, 0.25, 0.75);
        @Override
        public @NotNull VoxelShape getShape(BlockState state, BlockGetter p_60556_, BlockPos p_60557_, CollisionContext p_60558_) {
            switch (state.getValue(FACING)) {
                case DOWN -> {
                    return DOWN;
                }
                case UP -> {
                    return UP;
                }
                case SOUTH -> {
                    return SOUTH;
                }
                case WEST -> {
                    return WEST;
                }
                case EAST -> {
                    return EAST;
                }
                default -> {
                    return NORTH;
                }
            }
        }

    File generated by Blockbench (using extension) in north direction:

    public VoxelShape makeShape(){
    	VoxelShape shape = VoxelShapes.empty();
    	shape = VoxelShapes.join(shape, VoxelShapes.box(0.25, 0.25, 0, 0.75, 0.75, 0.25), IBooleanFunction.OR);
        	//                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the values used in the static field "NORTH"
    	return shape;
    }

    Remembering that the model from all directions is the same, but rotated.

  4. Taking a look at AbstractContainerScreen.renderSlot() I got the following code:

    Method created in my AbstractContainerScreen class:

    private void renderCustomSlot(PoseStack poseStack,ItemStack itemstack,int x, int y) {
            boolean visible = true;
            boolean hover = false;
    
            this.setBlitOffset(100);
            this.itemRenderer.blitOffset = 100.0F;
    
            if (visible) {
                if (hover) {
                    //Draw a rectangle behind the item
                    fill(poseStack, x, y, x + 16, y + 16, -2130706433);
                }
    
                //Render item icon
                RenderSystem.enableDepthTest();
                this.itemRenderer.renderAndDecorateItem(this.minecraft.player, itemstack, x, y, x + y * this.imageWidth);
    
                //Render item string count
                PoseStack posestack = new PoseStack();
                if (itemstack.getCount() != 1) {
                    String s = String.valueOf(itemstack.getCount());
                    posestack.translate(0.0D, 0.0D, itemRenderer.blitOffset + 200.0F);
                    MultiBufferSource.BufferSource multibuffersource$buffersource = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder());
    
                    /*
                    float scale;
                    if (s.length()<3){
                        scale=1f;
                    }else if (s.length()<4){
                        scale = 0.75f;
                    }else {
                        scale=0.5f;
                        s = s.substring(0,s.length()-3)+"k";
                    }
    
                    float compensatingScale = 1/scale;
    
                    float stringX = (x + 19f - 2 - font.width(s)*scale)*compensatingScale;
                    float stringY =(y + 6f + 3)*compensatingScale;
    
                    posestack.scale(scale,scale,scale);
    				*/
    				float stringX = (x + 19f - 2 - font.width(s));
                    float stringY =(y + 6f + 3);
                    font.drawInBatch(s,stringX,stringY,16777215, true, posestack.last().pose(), multibuffersource$buffersource, false, 0, 15728880);
                    //posestack.scale(compensatingScale,compensatingScale,compensatingScale);
    
                    multibuffersource$buffersource.endBatch();
                }
            }
    
            this.itemRenderer.blitOffset = 0.0F;
            this.setBlitOffset(0);
        }


    Now it works correctly:

    imagem-2022-07-02-122610834.png

    Thanks to warjort for the tip!

  5. render method in my AbstractContainerScreen class

     

    @Override
        protected void renderBg(PoseStack poseStack, float pPartialTick, int mouseX, int mouseY) {
            RenderSystem.setShader(GameRenderer::getPositionTexShader);
            RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
            RenderSystem.setShaderTexture(0, TEXTURE);
            this.blit(poseStack,leftPos,topPos,0,0, imageWidth, imageHeight);
    
            ItemStack stack = new ItemStack(SItems.REDSTONE_SILICON,64);
            String count = String.valueOf(stack.getCount());
      		//render item model
            itemRenderer.renderGuiItem(stack,mouseX,mouseY);
      		//render my string (64 in iamge)
            font.draw(poseStack,count,mouseX+(-font.width(count)+20),mouseY+10,0xFFFFFF);
    
        }
    
    @Override
        public void render(PoseStack poseStack, int mouseX, int mouseY, float delta) {
            renderBackground(poseStack);
            super.render(poseStack, mouseX, mouseY, delta);
            renderTooltip(poseStack, mouseX, mouseY);
        }


    but the string is below the item:

    imagem-2022-07-01-195053801.png

  6. On 6/21/2022 at 9:10 PM, Robsutar said:

    I would like to make a block that changes its model according to adjacent blocks of the same type, linke applied, mekanism, pipez, and other mods that update the model of the cables when there is an adjacent one, also changing the VoxelShape, or collision box.

    Forge version: 1.18.2

    About the custom template:

    I used Boolean Property (Check the official tutorial on the forge website) to determine which model I would like to use, and I used a multipart model mine block, using the conditions of the Boolean Property
     

    public class Cable extends Block{
        public static final BooleanProperty SOUTH_CONNECTED = BooleanProperty.create("south"); //Boolean Property
        /*   it is possible to put others, in the example I will only do it with the south direction
        public static final BooleanProperty NORTH_CONNECTED = BooleanProperty.create("north");
        public static final BooleanProperty NORTH_CONNECTED = BooleanProperty.create("north");
        */
    
    
        public Cable() {
                super(Properties.copy(Blocks.GLASS_PANE).dynamicShape());
    			//register Default Block State
                this.registerDefaultState(stateDefinition.any()
                        //.setValue(NORTH_CONNECTED, false),
                        .setValue(SOUTH_CONNECTED, false); //by default I want it to be desconected
        }
    
    	//Register boolean properties
    	@Override
        protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> p_49915_) {
            p_49915_.add(/*UP,DOWN,NORTH,EAST,*/SOUTH);
        }
    
    	//Change Boolean Property when checking adjacent blocks
    	@Override
        public BlockState getStateForPlacement(BlockPlaceContext context) {
            return getState(context.getLevel(), context.getClickedPos());
        }
    
        private BlockState getState(Level world, BlockPos pos) {
            return defaultBlockState()
                    //.setValue(NORTH_CONNECTED, getSideValue(world, pos, Direction.NORTH),
                    .setValue(SOUTH_CONNECTED, getSideValue(world, pos, Direction.SOUTH));
        }
    
        private bool getSideValue(Level world, BlockPos pos, Direction facing) {
            BlockState state = world.getBlockState(pos.relative(facing));
            Block block = state.getBlock();
    		//If it's a Cable class block, I want it to connect
            return (block instanceof Cable);
        }
    
    	//Updating boolean properties when an adjacent block is updated, was having a problem, when I broke a cable, it kept plugged in in the air;
    	@Override
        public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos pos1, boolean b) {
            super.neighborChanged(state, world, pos, block, pos1, b);
            world.setBlockAndUpdate(pos,getState(world,pos));
        }
    }


    About the model:
    The following json file is the blockstate of the block, located in "resources/assets/mod_id/blockstates/cable.json", but the models cited in the file ("sutarstorage:block/cable_core" and "sutarstorage:block/cable_part") are located in "resources/assets/mod_id/models/block/cabe_(part/core).json", both models were made using Blockbench

     

    I made the json manually, but I'm already aware that there are ways to automate its generation.In case you want to copy the code, you will have to remove the comments

    {
      "multipart": [
        {   "apply": { "model": "sutarstorage:block/cable_core" }},  ---> the base model, always visible
    
    	--- Models that will only be rendered with certain condition
        {   "when": { "north": "true" },
          "apply": { "model": "sutarstorage:block/cable_part", "uvlock": false }
        },
        {   "when": { "south": "true" },
          "apply": { "model": "sutarstorage:block/cable_part", "y": 180, "uvlock": false }
        },
    	---Note that the template is the same ("block/cable_part"), but rotated, it is possible to use other models instead
    }


    Special thanks to JimiIT92 and aferrercrafter

×
×
  • Create New...

Important Information

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