Jump to content

Recommended Posts

Posted

Hi,

For my mod I would like to be able to create a 3x3x3 block.
But I cannot find anywhere how to do this.

Even the bed and the door are 2x1x1 at most.

I tried with a BlockBench model, but positive coordinates only support 3x3x2.
If I want to do the full 3x3x3, then I have to use negative coordinates in BlockBench.
Which I think would make the model appearing partly under the floor.

Is it something possible, and if so, can someone show me a tutorial on how to do it?

It is a simple block, not a machine nor container.
Nothing fancy.

But I have been struggling for the past few days trying to figure out how to do it.

Posted (edited)

Then how do you explain things like the Digital Miner in Mekanism which is 3x3x2 ?

It I have to treat the Block as something else to get the 3x3x3 I am ok with it.

I tried to follow the logic/code of the Digital Miner but it is still in 1.16.
So much has changed in MC/Forge since then that I am struggling to find replacement functions.

Or, if making a 3x3x3 (in any ways) is really impossible, is it possible then to place the 27 blocks (3x3x3 = 27) automatically when I use the block item on a location?

Edited by Ideki
Posted

Hum, not according to CurseForge.

Ok, so in this case, is it possible to use a BlockEntityRenderer to render a 3x3x3 ?
I would be fine with that I would just need to find how to make a 3x3x3 model because BlockBench kinda limit the model to -16 - +32
And I need the full 48 above 0.

Posted

What is AABB ?

I saw it in some tutorials I read.
But it was not explained what it was.
So adapting it makes it difficult without understanding the underlying concept. 

Posted

Thanks.

So I have been looking at a couple of 1.18 mods that implement multiblock blocks (ex: Waystones).
And they are using net.minecraft.world.level.block.state.properties.DoubleBlockHalf to define half 'structures' with that enum.
But that does not meet my need for a 3x3x3 since I am using more than DoubleBlockHalf.
I would somehow need a 'TripleBlockThird' 🤨

Posted (edited)

I defined my boundaries like this:
 

    @Override
    public AABB getRenderBoundingBox() {
        return new AABB(
                worldPosition.getX(),
                worldPosition.getY(),
                worldPosition.getZ(),
                worldPosition.getX() + 3,
                worldPosition.getY() + 3,
                worldPosition.getZ() + 3);
    }

 

Edited by Ideki
Posted
5 hours ago, Ideki said:

And they are using net.minecraft.world.level.block.state.properties.DoubleBlockHalf to define half 'structures' with that enum.
But that does not meet my need for a 3x3x3 since I am using more than DoubleBlockHalf.

you should only copy the logic not the code exactly and iirc the enum was for the Blockstate so the UpperBlock has a other texture than the LowerBlock

5 hours ago, Ideki said:

I defined my boundaries like this

In this case your main Block is a corner, if you do this it means you render the Block in a BER this means you only need one Block

Posted

Ok, so I am almost there.

I can see the block boundaries with the thin lines.

But the texture seems to be applied in the wrong position on the X & Z axis.

The Y axis I am guessing is because of the model.
But is I change the elements from/to to be 0 - 48 then MC complains that it is out of the boundaries.
 

Quote

Unable to load model: 'testmod:block/rune_block' referenced from: testmod:rune_block#: com.google.gson.JsonParseException: 'to' specifier exceeds the allowed boundaries: [48.0, 48.0, 48.0]

If I change the from/to back to -16 - 32 then it's not complaining, but it looks wrong.

Also I can walk through the block.
I thought the getRenderBoundingBox would prevent that.
I guess I was wrong on how it works.

This is what I see now when I place the block:

pYKJHL9.png

z5C6ccI.png

This is my block model:

{
	"credit": "Made with Blockbench",
	"texture_size": [48, 48],
	"textures": {
		"0": "testmod:blocks/rune_block",
		"particle": "testmod:blocks/rune_block"
	},
	"elements": [
		{
			"from": [-16, -16, -16],
			"to": [32, 32, 32],
			"faces": {
				"north": {"uv": [0, 0, 16, 16], "texture": "#0"},
				"east": {"uv": [0, 0, 16, 16], "texture": "#0"},
				"south": {"uv": [0, 0, 16, 16], "texture": "#0"},
				"west": {"uv": [0, 0, 16, 16], "texture": "#0"},
				"up": {"uv": [0, 0, 16, 16], "texture": "#0"},
				"down": {"uv": [0, 0, 16, 16], "texture": "#0"}
			}
		}
	],
	"display": {
		"thirdperson_righthand": {
			"scale": [0.1, 0.1, 0.1]
		},
		"thirdperson_lefthand": {
			"scale": [0.1, 0.1, 0.1]
		},
		"firstperson_righthand": {
			"scale": [0.1, 0.1, 0.1]
		},
		"firstperson_lefthand": {
			"scale": [0.1, 0.1, 0.1]
		},
		"ground": {
			"translation": [0, 1.25, 0],
			"scale": [0.2, 0.2, 0.2]
		},
		"gui": {
			"rotation": [20, -30, 0],
			"scale": [0.2, 0.2, 0.2]
		},
		"head": {
			"translation": [0, 9, 0],
			"scale": [0.3, 0.3, 0.3]
		},
		"fixed": {
			"scale": [0.3, 0.3, 0.3]
		}
	}
}

 

Posted

Ok.


But then  how come some mods can create big machines that are 2x2x2 or 3x3x3?
Are they actually placing 3x3x3 = 27 blocks with connected texture?
Because those machines really look, and act, like 1 block.

I do not mind having to place 27 blocks as long as I can do it automatically.
Any idea/lead on how I can do that?

Posted (edited)
1 hour ago, Ideki said:

Are they actually placing 3x3x3 = 27 blocks with connected texture?

yeah thats the way to got

1 hour ago, Ideki said:

Because those machines really look, and act, like 1 block.

you need to customise a lot of behaviour but this is possible

 

1 hour ago, Ideki said:

I do not mind having to place 27 blocks as long as I can do it automatically.
Any idea/lead on how I can do that?

create one method which place them in the World (Level),
call this method every time you want to place the Blocks

there are also a lot ways to do this maualy for example a for loop
and store the Blocks in a Map with the BlockPos e.g. (the following code is a example i have no idea if this would work or id this is the best way to do this):

Spoiler
// map of all Blocks
Util.make(Maps.newHashMap(), (map) -> {
	map.put(new BlockPos(-1, 0, -1), Blocks.ACACIA_PLANKS);
	map.put(new BlockPos(0, 0, -1), Blocks.ACACIA_PLANKS);
	map.put(new BlockPos(1, 0, -1), Blocks.ACACIA_PLANKS);
	// and so on
});
		
for (int x = -1; x <= 1; x++) {
	for (int y = -1; y <= 1; y++) {
		for (int z = -1; z <= 1; z++) {
			Block block = blocks.get(new BlockPos(x, y, z));
            // place the BlockState
		}
	}
}

 

Note: you need to add the Blocks in the correct order to the Map you want to read (get) them

Edited by Luis_ST
Posted

Do you think it would be possible position the texture I have now (the 3x3x3) correctly, and fill it inside with 27 blocks ?
Or would the texture of the 27 blocks appear through the 3x3x3 I have now ?

Otherwise I will have to create 27 blocks with individual textures that I would assemble automatically into a 3x3x3 using a map like you suggested.

Posted
On 2/9/2022 at 8:40 AM, Ideki said:

Hi,

For my mod I would like to be able to create a 3x3x3 block.
But I cannot find anywhere how to do this.

Even the bed and the door are 2x1x1 at most.

I tried with a BlockBench model, but positive coordinates only support 3x3x2.
If I want to do the full 3x3x3, then I have to use negative coordinates in BlockBench.
Which I think would make the model appearing partly under the floor.

Is it something possible, and if so, can someone show me a tutorial on how to do it?

It is a simple block, not a machine nor container.
Nothing fancy.

But I have been struggling for the past few days trying to figure out how to do it.

install a plugin for blockbench called ModUtils(i dont know if you solved your problem yet but here is this)

it lets you export your normal model AND the VoxelShape for all the 4 directions

one problem is that you can collide with your block as normally but the other outlines can be replaced with a block and you can trasspass your block(again from 1 side), you will see in-game what i mean if you do this trick for make it easier

https://www.youtube.com/watch?v=NblmRqf1wW8

Posted (edited)
2 hours ago, ElTotisPro50 said:

install a plugin for blockbench called ModUtils(i dont know if you solved your problem yet but here is this)

it lets you export your normal model AND the VoxelShape for all the 4 directions

one problem is that you can collide with your block as normally but the other outlines can be replaced with a block and you can trasspass your block(again from 1 side), you will see in-game what i mean if you do this trick for make it easier

this only works for 1x1x1 Blocks, and this is not the problem here

2 hours ago, Ideki said:

Do you think it would be possible position the texture I have now (the 3x3x3) correctly, and fill it inside with 27 blocks ?

yeah, place in the middle a Block which has the logic of your machine (block) and add the BER to it then render the texture there (and about the position error of the texture show your BER)
then add 28 Blocks around

2 hours ago, Ideki said:

Or would the texture of the 27 blocks appear through the 3x3x3 I have now ?

also possible but more complicated than the other case

Edited by Luis_ST
Posted (edited)

Following your suggestions I made progress.
I changed my approach to use an item that will place the blocks in the world.
The blocks are placed, but something is still wonky as they do not appear until I quit and join again the world.

Could someone tell me why this is happening?
I am posting here my code.

public class RuneCubeItem extends Item {

    public RuneCubeItem() {
        super(ITEM_PROPERTIES);
    }

    @Override
    public InteractionResult useOn(UseOnContext context) {
        System.out.println("useOn");

        Player player = context.getPlayer();

        if (player instanceof ServerPlayer) {
            System.out.println("A");
            build((ServerPlayer) player);
        }
        System.out.println("B");

        return super.useOn(context);
    }

    private void build(ServerPlayer player) {
        Level world = player.level;

        HashMap<BlockPos, Block> coords =  Util.make(Maps.newHashMap(), (map) -> {
            map.put(new BlockPos(-1, 0, -1), Blocks.STONE);
            map.put(new BlockPos(0, 0, -1), Blocks.STONE);
            map.put(new BlockPos(1, 0, -1), Blocks.STONE);
            // and so on
        });

        for (Map.Entry<BlockPos, Block> entry : coords.entrySet()) {
            BlockPos coordinate = entry.getKey();
            Block block = entry.getValue();
            placeBlock(world, player, coordinate, block);
        }
    }

    private void placeBlock(Level world, ServerPlayer player, BlockPos pos, Block setBlock) {
        System.out.println("C");
        if ((pos.getY() > world.getMaxBuildHeight() || pos.getY() < world.getMinBuildHeight()) || !player.mayBuild()) {
            System.out.println("D");
            return;
        }

        ItemStack heldItem = new ItemStack(setBlock, 1);
        if (heldItem.isEmpty()) {
            System.out.println("E");
            return;
        }

        BlockSnapshot blockSnapshot = BlockSnapshot.create(world.dimension(), world, pos);
        if (ForgeEventFactory.onBlockPlace(player, blockSnapshot, Direction.UP) || !world.mayInteract(player, pos)) {
            System.out.println("F");
            return;
        }

        Vec3 playerPosition = player.position();
        BlockPos newPos = new BlockPos(
                playerPosition.x + pos.getX(),
                playerPosition.y + pos.getY(),
                playerPosition.z + pos.getZ());

        System.out.println("G");
        //BlockItem item = (BlockItem) stack.getItem();
        BlockState state = setBlock.defaultBlockState();
        world.setBlock(newPos, state, 3);
    }
}

 

Edited by Ideki
Posted

i've tested your code and i just modified your code a bit (moved it to a Event),
and it works. this is the modified code

and i think your this is the issue:
also i have no idea why you add this code, since the first part (with the ItemStack) is completely irrelevant
and the second part is called by Forge somewhere else so you don't need to call it

41 minutes ago, Ideki said:
        ItemStack heldItem = new ItemStack(setBlock, 1);
        if (heldItem.isEmpty()) {
            System.out.println("E");
            return;
        }

        BlockSnapshot blockSnapshot = BlockSnapshot.create(world.dimension(), world, pos);
        if (ForgeEventFactory.onBlockPlace(player, blockSnapshot, Direction.UP) || !world.mayInteract(player, pos)) {
            System.out.println("F");
            return;
        }
Posted

The extra code are left overs from code I found in another mod.
I am still in the process of learning what everything does. :/

I took a look at your code, and I am not sure how the 
PlayerInteractEvent.RightClickBlock applies to the item I am using to place the blocks.

When I integrate your rightClickBlock function into my item, it did nothing.

Is it not something that should be applied to a block directly?
I mean an event that a block receives when the player right click on it ?
If so, that would be the opposite of what I am trying to achieve.

Posted (edited)

Got it!


I am still using the onUse override.
The only thing I was missing for all the blocks to show was a call the following function after the level.setBlock :

level.sendBlockUpdated(pos, blockState, blockState, Block.UPDATE_ALL_IMMEDIATE);

Edited by Ideki

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



×
×
  • Create New...

Important Information

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