Jump to content

Recommended Posts

Posted

I want to make some vanilla blocks to have no collision under certain condition, so I override the block (in this example, glass block):

public class CustomGlassBlock extends GlassBlock {
    public CustomGlassBlock(Block block) {
        super(Properties.from(block));
    }

    @Override
    public VoxelShape getCollisionShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
        if(/*some condition*/) {
          return VoxelShapes.empty();
        }
        return super.getCollisionShape(state, worldIn, pos, context);
    }
}

As far as I know, returning VoxelShapes.empty() in Block#getCollisionShape will actually make the block have no collision, at least I think that is true.

When testing, the block does have no collision, but it is still pushing me out. What am I missing?

Posted

Block.Properties#doesNotBlockMovement()

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted
5 hours ago, NorthWestWind said:

I want to make some vanilla blocks to have no collision under certain condition, so I override the block (in this example, glass block):

Do you want to make the Vanilla block have no collision or your custom block? You cannot modify a vanilla block behaviour by extending the block and overriding a method in your custom block

Check out the port of the BetterEnd fabric mod (WIP): https://www.curseforge.com/minecraft/mc-mods/betterend-forge-port

Posted
Quote

Do you want to make the Vanilla block have no collision or your custom block?

I want to make the Vanilla block have no collision.
 

Quote

You cannot modify a vanilla block behaviour by extending the block and overriding a method in your custom block

But I do that on other blocks and it works. I extend the block and register the block again.

Posted
25 minutes ago, Beethoven92 said:

What Draco18 suggested you should be fine

But I want it to have collision under some conditions. I don't think I can do that with Block.Properties#doesNotBlockMovement()?

Posted (edited)

Well, if you specify doesNotBlockMovement in the block properties, instead of returning a VoxelShapes#empty under your conditions,you could instead return the collision shape of the block when the condition is not verified. Basically invert what you were doing here:

    @Override
    public VoxelShape getCollisionShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
        if(/*some condition*/) {
          return VoxelShapes.empty();
        }
        return super.getCollisionShape(state, worldIn, pos, context);
    }

 

Edited by Beethoven92

Check out the port of the BetterEnd fabric mod (WIP): https://www.curseforge.com/minecraft/mc-mods/betterend-forge-port

Posted

I tried to remove the bounding box of the player by Entity#setBoundingBox in onEntityCollision and it didn't go well.

As soon as I touch the block, my entire game runs at 1 fps and I found myself at the bottom of the world.

I have a feeling that I used the set bounding box method wrongly because I just get the bounding box of the entity and use AxisAlignedBB#shrink to get rid of the bounding box.

Posted

😆 i guess by removing the entity (your player in this case) bounding box, collision with the ground are not checked anymore, thats why you just sank out of the world. Don't touch the entity bounding box...i was thinking at something like...is there a collision between your block and the player? Is your condition satisfied? ----> get rid of the collision shape of the block , else the block is acting as normal with the collisions and all the rest

Check out the port of the BetterEnd fabric mod (WIP): https://www.curseforge.com/minecraft/mc-mods/betterend-forge-port

Posted (edited)

I did cancel the collision shape of the block (in the very first try) and I'm sure the condition is satisfied since when I have the item, I can clip into the block (and it covers my screen), but there is a force constantly pushing me out and doesn't allow me to walk through the block. Without that item, the block just acts like normal block.

Edited by NorthWestWind
Posted (edited)

So...i tried to code that myself and i made it work, but my solution may not be the best or the most elegant one. Turns out that onEntityCollision happens only if the shape of the block is set to be smaller than the full block. So i set two different voxel shapes, a null voxel shape and one that is slightly smaller than the cube, with dimensions:

Block.makeCuboidShape(0.1F, 0.1F, 0.1F, 15.9F, 15.9F, 15.9F)

which doesn't basically change anything visually but lets the collision event happen (For some reason i am still unable to understand). Inside the event i just check for the condition and select the appropriate voxel shape, which then needs to be returned by getShape (not getCollisionShape). It works but as i said before this seems to be a slightly "hacky" solution and also present some issues:

1) you will be able to walk on the border of your block when in its solid form

2) any other entity will be able to walk through your block while you are inside the block with your condition being verified

3) being the voxel shapes static and shared between all blocks of the same type, when you make one of them not solid, if other are present they will all become not solid

Edited by Beethoven92

Check out the port of the BetterEnd fabric mod (WIP): https://www.curseforge.com/minecraft/mc-mods/betterend-forge-port

Posted (edited)
52 minutes ago, Beethoven92 said:

being the voxel shapes static and shared between all blocks of the same type, when you make one of them not solid, if other are present they will all become not solid

It won't

edit: i meant "They won't"

Edited by Crazzy4999
Posted

But you're only doing it for the block at a given position.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted
2 minutes ago, Draco18s said:

But you're only doing it for the block at a given position.

That's what i was thinking, but after testing with multiple blocks it appears that with my code if i am inside one block (and so its voxel shape its null), all the other blocks also have null voxel shapes 🤔

Check out the port of the BetterEnd fabric mod (WIP): https://www.curseforge.com/minecraft/mc-mods/betterend-forge-port

Posted

I think getShape is just used to render the block's outline. It cannot change the collision shape by itself, but since getCollisionShape just call getShape by default, overriding getShape also overrides getCollisionShape.

 

I took a look at what Properties#doesNotBlockMovement does before and turns out it only changes the collision shape, not the shape itself. A good example would be torches because they have no collision, but at the same time have an outline.

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • It is 1.12.2 - I have no idea if there is a 1.12 pack
    • Okay, but does the modpack works with 1.12 or just with 1.12.2, because I need the Forge client specifically for Minecraft 1.12, not 1.12.2
    • Version 1.19 - Forge 41.0.63 I want to create a wolf entity that I can ride, so far it seems to be working, but the problem is that when I get on the wolf, I can’t control it. I then discovered that the issue is that the server doesn’t detect that I’m riding the wolf, so I’m struggling with synchronization. However, it seems to not be working properly. As I understand it, the server receives the packet but doesn’t register it correctly. I’m a bit new to Java, and I’ll try to provide all the relevant code and prints *The comments and prints are translated by chatgpt since they were originally in Spanish* Thank you very much in advance No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. MountableWolfEntity package com.vals.valscraft.entity; import com.vals.valscraft.network.MountSyncPacket; import com.vals.valscraft.network.NetworkHandler; import net.minecraft.client.Minecraft; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.animal.Wolf; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.Entity; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.network.PacketDistributor; public class MountableWolfEntity extends Wolf { private boolean hasSaddle; private static final EntityDataAccessor<Byte> DATA_ID_FLAGS = SynchedEntityData.defineId(MountableWolfEntity.class, EntityDataSerializers.BYTE); public MountableWolfEntity(EntityType<? extends Wolf> type, Level level) { super(type, level); this.hasSaddle = false; } @Override protected void defineSynchedData() { super.defineSynchedData(); this.entityData.define(DATA_ID_FLAGS, (byte)0); } public static AttributeSupplier.Builder createAttributes() { return Wolf.createAttributes() .add(Attributes.MAX_HEALTH, 20.0) .add(Attributes.MOVEMENT_SPEED, 0.3); } @Override public InteractionResult mobInteract(Player player, InteractionHand hand) { ItemStack itemstack = player.getItemInHand(hand); if (itemstack.getItem() == Items.SADDLE && !this.hasSaddle()) { if (!player.isCreative()) { itemstack.shrink(1); } this.setSaddle(true); return InteractionResult.SUCCESS; } else if (!level.isClientSide && this.hasSaddle()) { player.startRiding(this); MountSyncPacket packet = new MountSyncPacket(true); // 'true' means the player is mounted NetworkHandler.CHANNEL.sendToServer(packet); // Ensure the server handles the packet return InteractionResult.SUCCESS; } return InteractionResult.PASS; } @Override public void travel(Vec3 travelVector) { if (this.isVehicle() && this.getControllingPassenger() instanceof Player) { System.out.println("The wolf has a passenger."); System.out.println("The passenger is a player."); Player player = (Player) this.getControllingPassenger(); // Ensure the player is the controller this.setYRot(player.getYRot()); this.yRotO = this.getYRot(); this.setXRot(player.getXRot() * 0.5F); this.setRot(this.getYRot(), this.getXRot()); this.yBodyRot = this.getYRot(); this.yHeadRot = this.yBodyRot; float forward = player.zza; float strafe = player.xxa; if (forward <= 0.0F) { forward *= 0.25F; } this.flyingSpeed = this.getSpeed() * 0.1F; this.setSpeed((float) this.getAttributeValue(Attributes.MOVEMENT_SPEED) * 1.5F); this.setDeltaMovement(new Vec3(strafe, travelVector.y, forward).scale(this.getSpeed())); this.calculateEntityAnimation(this, false); } else { // The wolf does not have a passenger or the passenger is not a player System.out.println("No player is mounted, or the passenger is not a player."); super.travel(travelVector); } } public boolean hasSaddle() { return this.hasSaddle; } public void setSaddle(boolean hasSaddle) { this.hasSaddle = hasSaddle; } @Override protected void dropEquipment() { super.dropEquipment(); if (this.hasSaddle()) { this.spawnAtLocation(Items.SADDLE); this.setSaddle(false); } } @SubscribeEvent public static void onServerTick(TickEvent.ServerTickEvent event) { if (event.phase == TickEvent.Phase.START) { MinecraftServer server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(); if (server != null) { for (ServerPlayer player : server.getPlayerList().getPlayers()) { if (player.isPassenger() && player.getVehicle() instanceof MountableWolfEntity) { MountableWolfEntity wolf = (MountableWolfEntity) player.getVehicle(); System.out.println("Tick: " + player.getName().getString() + " is correctly mounted on " + wolf); } } } } } private boolean lastMountedState = false; @Override public void tick() { super.tick(); if (!this.level.isClientSide) { // Only on the server boolean isMounted = this.isVehicle() && this.getControllingPassenger() instanceof Player; // Only print if the state changed if (isMounted != lastMountedState) { if (isMounted) { Player player = (Player) this.getControllingPassenger(); // Verify the passenger is a player System.out.println("Server: Player " + player.getName().getString() + " is now mounted."); } else { System.out.println("Server: The wolf no longer has a passenger."); } lastMountedState = isMounted; } } } @Override public void addPassenger(Entity passenger) { super.addPassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(true)); } } } @Override public void removePassenger(Entity passenger) { super.removePassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is no longer mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(false)); } } } @Override public boolean isControlledByLocalInstance() { Entity entity = this.getControllingPassenger(); return entity instanceof Player; } @Override public void positionRider(Entity passenger) { if (this.hasPassenger(passenger)) { double xOffset = Math.cos(Math.toRadians(this.getYRot() + 90)) * 0.4; double zOffset = Math.sin(Math.toRadians(this.getYRot() + 90)) * 0.4; passenger.setPos(this.getX() + xOffset, this.getY() + this.getPassengersRidingOffset() + passenger.getMyRidingOffset(), this.getZ() + zOffset); } } } MountSyncPacket package com.vals.valscraft.network; import com.vals.valscraft.entity.MountableWolfEntity; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class MountSyncPacket { private final boolean isMounted; public MountSyncPacket(boolean isMounted) { this.isMounted = isMounted; } public void encode(FriendlyByteBuf buffer) { buffer.writeBoolean(isMounted); } public static MountSyncPacket decode(FriendlyByteBuf buffer) { return new MountSyncPacket(buffer.readBoolean()); } public void handle(NetworkEvent.Context context) { context.enqueueWork(() -> { ServerPlayer player = context.getSender(); // Get the player from the context if (player != null) { // Verifies if the player has dismounted if (!isMounted) { Entity vehicle = player.getVehicle(); if (vehicle instanceof MountableWolfEntity wolf) { // Logic to remove the player as a passenger wolf.removePassenger(player); System.out.println("Server: Player " + player.getName().getString() + " is no longer mounted."); } } } }); context.setPacketHandled(true); // Marks the packet as handled } } networkHandler package com.vals.valscraft.network; import com.vals.valscraft.valscraft; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.network.NetworkRegistry; import net.minecraftforge.network.simple.SimpleChannel; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class NetworkHandler { private static final String PROTOCOL_VERSION = "1"; public static final SimpleChannel CHANNEL = NetworkRegistry.newSimpleChannel( new ResourceLocation(valscraft.MODID, "main"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals ); public static void init() { int packetId = 0; // Register the mount synchronization packet CHANNEL.registerMessage( packetId++, MountSyncPacket.class, MountSyncPacket::encode, MountSyncPacket::decode, (msg, context) -> msg.handle(context.get()) // Get the context with context.get() ); } }  
  • Topics

×
×
  • Create New...

Important Information

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