diff --git a/game/client/src/main/java/net/minecraft/client/player/controller/PlayerController.java b/game/client/src/main/java/net/minecraft/client/player/controller/PlayerController.java index 0b94d52bb..109f4a818 100644 --- a/game/client/src/main/java/net/minecraft/client/player/controller/PlayerController.java +++ b/game/client/src/main/java/net/minecraft/client/player/controller/PlayerController.java @@ -102,7 +102,12 @@ public abstract class PlayerController { } final Block mineBlock = world.getBlockType(tilePos); - if (!mineBlock.canCollideCheck(world.getBlockData(tilePos), false)) return; + if (!mineBlock.canCollideCheck(world.getBlockData(tilePos), false)) { + this.destroyProgress = 0.0f; + this.oDestroyProgress = 0.0f; + this.setMineBlock(null); + return; + } this.syncCurrentPlayItem(); diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicDoor.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicDoor.java index 00f5e7676..b9a16b98a 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicDoor.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicDoor.java @@ -61,14 +61,14 @@ public class BlockLogicDoor } @Override - protected int getMatcherEquivalenceData(final int data) { + protected int getMatcherEquivalenceData(int data) { final int MASK_NON_COLOR = MASK_OPENED | MASK_HINGE | MASK_ROTATION; - int d1 = data & ~MASK_NON_COLOR; - int d2 = data & MASK_NON_COLOR; assert (MASK_HINGE >>> 1) == MASK_OPENED; - d2 ^= d2 >>> 1; // flips the opened bit if hinge bit is set - d1 |= d2; - return d1 & ~(MASK_HINGE | MASK_ROTATION); + int data2 = data | ((data & MASK_HINGE) >>> 1); // flips the opened bit if hinge bit is set + data &= ~MASK_NON_COLOR; + data2 &= MASK_NON_COLOR; + data |= data2; + return data; } @Override diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFlower.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFlower.java index 340eaa8f8..0faccf85a 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFlower.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFlower.java @@ -162,6 +162,6 @@ public class BlockLogicFlower @Override protected int getMatcherEquivalenceData(int data) { - return data & ~((this.killedByWeather) ? MASK_PERMANENT : 0); + return data & ~ MASK_PERMANENT; } } diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicJar.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicJar.java index 2160d52ec..ae7d3de80 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicJar.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicJar.java @@ -18,6 +18,8 @@ import net.minecraft.core.util.helper.Side; import net.minecraft.core.world.World; import net.minecraft.core.world.WorldSource; import net.minecraft.core.world.pos.TilePosc; +import net.minecraft.core.world.wind.WindProvider; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.joml.primitives.AABBd; @@ -101,6 +103,7 @@ public class BlockLogicJar extends BlockLogic implements ISupportable { } flowerJar.flowerData = BlockLogicFlowerStackable.setPermanent(BlockLogicFlowerStackable.setStackCount(metadata, currentStackCount + 1), true); + world.notifyBlocksOfNeighborChange(tilePos, this.block); world.playBlockSoundEffect(player, tilePos.x() + 0.5f, tilePos.y() + 0.5f, tilePos.z() + 0.5f, this.block, EnumBlockSoundEffectType.PLACE); player.getHeldItem().consumeItem(player); return true; @@ -132,4 +135,21 @@ public class BlockLogicJar extends BlockLogic implements ISupportable { public @NotNull ISupport getSupportConstraint(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side) { return PartialSupport.INSTANCE.center(); } + + @Override + public boolean isEquivalent(@NotNull World world, @NotNull TilePosc thisPos, @NotNull TilePosc thatPos) { + assert world.getBlockType(thisPos) == this.block; + if (world.getBlockType(thatPos) != this.block) return false; + final int thisData, thatData; { + thisData = world.getBlockData(thisPos); + thatData = world.getBlockData(thatPos); + } + if ((thisData | thatData) == 0) return true; + if (!(world.getTileEntity(thisPos) instanceof TileEntityFlowerJar thisFlowerJar) || + !(world.getTileEntity(thatPos) instanceof TileEntityFlowerJar thatFlowerJar)) + return false; + if (thisFlowerJar.flowerInPot != thatFlowerJar.flowerInPot) return false; + if (thisFlowerJar.flowerData != thatFlowerJar.flowerData) return false; + return true; + } } \ No newline at end of file diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLamp.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLamp.java index a0286ec70..2fec961c1 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLamp.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLamp.java @@ -174,11 +174,6 @@ public class BlockLogicLamp extends BlockLogic implements IPainted { @Override protected boolean isSameBlockForMatcher(final @NotNull Block other) { - return other.getLogic() instanceof BlockLogicLamp; - } - - @Override - protected int getMatcherEquivalenceData(final int data) { - return (this.isActive ? 1 : 0) | (data & 0x0F); + return other.getLogic() instanceof BlockLogicLamp lamp && this.isActive == lamp.isActive; } } \ No newline at end of file diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMatcher.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMatcher.java index 00d53ac83..e1066c02f 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMatcher.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMatcher.java @@ -2,6 +2,7 @@ package net.minecraft.core.block; import net.minecraft.core.block.entity.TileEntity; import net.minecraft.core.block.material.Materials; +import net.minecraft.core.block.motion.CarriedBlock; import net.minecraft.core.block.piston.IMovingBlock; import net.minecraft.core.block.piston.MovingLine; import net.minecraft.core.block.piston.TileEntityMovingPistonBlock; @@ -105,6 +106,12 @@ public class BlockLogicMatcher extends BlockLogicAxisAligned { this.scheduleUpdate(world, targetPos); } + @Override + public void onFlung(@NotNull World world, @NotNull TilePosc sourcePos, int data, @NotNull CarriedBlock block) { + // technically it should poweroff 4 ticks later, but we don't have clean abstract block update scheduling yet + block.blockId = Blocks.MATCHER.id(); + } + public void updateState(@NotNull World world, @NotNull TilePosc tilePos) { Axis a = BlockLogicAxisAligned.metaToAxis(world.getBlockData(tilePos) & BlockLogicAxisAligned.MASK_DIRECTION); diff --git a/game/core/src/main/java/net/minecraft/core/entity/Entity.java b/game/core/src/main/java/net/minecraft/core/entity/Entity.java index 5a6dfade0..ef904d406 100644 --- a/game/core/src/main/java/net/minecraft/core/entity/Entity.java +++ b/game/core/src/main/java/net/minecraft/core/entity/Entity.java @@ -465,12 +465,12 @@ public abstract class Entity double bbWidth = this.bb.maxX - this.bb.minX - 0.05; if (isSneaking()) { // Edge safety behavior - if (zd != 0.0) { - workingBox1.setMin(this.bb.minX, this.bb.minY - 1.0, this.bb.minZ); - workingBox1.setMax(this.bb.maxX, this.bb.minY, this.bb.maxZ); - MathHelper.aabbExpand(workingBox1, 0.0, 0.0, zd, workingBox1); - List collidingBoxes = this.world.getCubes(this, workingBox1); - if (!collidingBoxes.isEmpty()) { + workingBox1.setMin(this.bb.minX, this.bb.minY - 1.0, this.bb.minZ); + workingBox1.setMax(this.bb.maxX, this.bb.minY, this.bb.maxZ); + MathHelper.aabbExpand(workingBox1, xd, 0.0, zd, workingBox1); + List collidingBoxes = this.world.getCubes(this, workingBox1); + if (!collidingBoxes.isEmpty()) { + if (xd != 0.0) { double limitX = 0.0; for (int i = 0; i < collidingBoxes.size(); i++) { AABBdc bb1 = collidingBoxes.get(i); @@ -486,12 +486,7 @@ public abstract class Entity oldXd = xd = Math.min(xd, limitX); } } - } - if (zd != 0.0) { - AABBd floor = new AABBd(this.bb.minX, this.bb.minY - 1.0, this.bb.minZ, this.bb.maxX, this.bb.minY, this.bb.maxZ); - MathHelper.aabbExpand(floor, 0.0, 0.0, zd, floor); - List collidingBoxes = this.world.getCubes(this, floor); - if (!collidingBoxes.isEmpty()) { + if (zd != 0.0) { double limitZ = 0.0; for (int i = 0; i < collidingBoxes.size(); i++) { AABBdc bb1 = collidingBoxes.get(i); @@ -511,17 +506,6 @@ public abstract class Entity } List cubes = this.world.getCubes(this, MathHelper.aabbExpand(this.bb, xd, yd, zd, workingBox2)); - List solidEntities = this.world.getEntitiesWithinAABBExcludingEntity(this, MathHelper.aabbExpand(this.bb, xd, yd, zd, workingBox2)); - - for (int i = 0; i < solidEntities.size(); i++) { - Entity solidEnt = solidEntities.get(i); - - if (solidEnt.hasCollision() && solidEnt.getCollisionAABB() != null) { - if (this.collidesWith(solidEnt) && solidEnt.collidesWith(this)) { - cubes.add(solidEnt.getCollisionAABB()); - } - } - } // Check collision on Y Axis for (int i = 0; i < cubes.size(); i++) { diff --git a/game/core/src/main/java/net/minecraft/core/entity/ICollidable.java b/game/core/src/main/java/net/minecraft/core/entity/ICollidable.java new file mode 100644 index 000000000..ef892352b --- /dev/null +++ b/game/core/src/main/java/net/minecraft/core/entity/ICollidable.java @@ -0,0 +1,8 @@ +package net.minecraft.core.entity; + +import org.jetbrains.annotations.Nullable; +import org.joml.primitives.AABBdc; + +public interface ICollidable { + @Nullable AABBdc getCollisionAABB(); +} diff --git a/game/core/src/main/java/net/minecraft/core/entity/vehicle/EntityBoat.java b/game/core/src/main/java/net/minecraft/core/entity/vehicle/EntityBoat.java index b5694f797..1536ee0d6 100644 --- a/game/core/src/main/java/net/minecraft/core/entity/vehicle/EntityBoat.java +++ b/game/core/src/main/java/net/minecraft/core/entity/vehicle/EntityBoat.java @@ -7,6 +7,7 @@ import net.minecraft.core.block.entity.TileEntityFlag; import net.minecraft.core.block.material.Materials; import net.minecraft.core.block.tag.BlockTags; import net.minecraft.core.entity.Entity; +import net.minecraft.core.entity.ICollidable; import net.minecraft.core.entity.player.Player; import net.minecraft.core.item.Items; import net.minecraft.core.item.ItemStack; @@ -23,7 +24,7 @@ import org.joml.primitives.AABBdc; import java.util.List; -public class EntityBoat extends Entity { +public class EntityBoat extends Entity implements ICollidable { private static final double MAX_BOAT_SPEED = 0.8D; private static final double ACCELERATION = 0.0065D; private static final float MAX_ROTATION_SPEED = 5f; diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemBucket.java b/game/core/src/main/java/net/minecraft/core/item/ItemBucket.java index 5ed5c8f78..19fb9d14e 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemBucket.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemBucket.java @@ -17,6 +17,7 @@ import net.minecraft.core.util.HardIllegalArgumentException; import net.minecraft.core.util.collection.NamespaceID; import net.minecraft.core.util.helper.Direction; import net.minecraft.core.util.helper.Side; +import net.minecraft.core.util.phys.HitResult; import net.minecraft.core.world.LevelListener; import net.minecraft.core.world.World; import net.minecraft.core.world.pos.TilePos; @@ -236,10 +237,11 @@ public abstract class ItemBucket extends ItemFood implements IItemContainer { @Override public boolean interactsWithFluid(@NotNull ItemStack selfStack) { - final NamespaceID currentStateId = getState(selfStack); - final BucketState currentState = getBucketState(currentStateId); - if (!currentState.canPlace() && currentState.isEdible()) return false; - return STATE_EMPTY.equals(currentStateId) || getCharges(selfStack) < this.maxCharges; + return false; + // final NamespaceID currentStateId = getState(selfStack); + // final BucketState currentState = getBucketState(currentStateId); + // if (!currentState.canPlace() && currentState.isEdible()) return false; + // return STATE_EMPTY.equals(currentStateId) || getCharges(selfStack) < this.maxCharges; } @Override @@ -250,10 +252,59 @@ public abstract class ItemBucket extends ItemFood implements IItemContainer { return currentState.canPlace() || !currentState.isEdible(); } + @Override + public @Nullable ItemStack onUse(@NotNull ItemStack selfStack, @NotNull World world, @NotNull Player player) { + final NamespaceID currentStateId = getState(selfStack); + final BucketState currentState = getBucketState(currentStateId); + + if (currentState.isEdible() && !currentState.canPlace()) { + return handleAirClick(selfStack, world, player); + } + + final var reachDistance = player.getGamemode().getBlockReachDistance(); + final HitResult hitResult = player.rayCast(reachDistance, 1f, true, false, false); + if (!(hitResult instanceof HitResult.Tile hit)) { + assert !(hitResult instanceof HitResult.Entity); + return handleAirClick(selfStack, world, player); + } + final boolean mayBeSource = world.getBlockData(hit.tilePos) == 0; + if (mayBeSource) pick_src: { + final NamespaceID targetStateId = getFluidStateAt(world, hit.tilePos); + if (targetStateId == null) break pick_src; + + final boolean isEmptyScoop = STATE_EMPTY.equals(currentStateId); + if (!isEmptyScoop) { + final boolean isRefillScoop = + currentStateId.equals(targetStateId) && + getCharges(selfStack) < this.maxCharges; + if (!isRefillScoop) break pick_src; + } + final var res = tryPickupFluid(selfStack, world, player, hit.tilePos, targetStateId, new UseResult()); + if (res.used) player.swingItem(); + return res.itemStack; + } + + if (currentState.canPlace()) { + final NamespaceID aimedFluid = getFluidStateAt(world, hit.tilePos); + if (currentStateId.equals(aimedFluid) && getCharges(selfStack) < this.maxCharges) { + return selfStack; + } + + final HitResult hitResultNoFluid = player.rayCast(reachDistance, 1f, false, false, false); + if (hitResultNoFluid instanceof HitResult.Tile hit2) { + final var res = tryPlaceFluid(selfStack, world, player, hit2.tilePos, hit2.side, new UseResult()); + if (res.used) player.swingItem(); + return res.itemStack; + } + } + + return handleAirClick(selfStack, world, player); + } + @Override public boolean useOnEntity(@NotNull ItemStack selfStack, @NotNull Player player, @NotNull Mob mob) { - NamespaceID currentStateId = getState(selfStack); - BucketState currentState = getBucketState(currentStateId); + final NamespaceID currentStateId = getState(selfStack); + final BucketState currentState = getBucketState(currentStateId); if (currentState.isEdible() && !currentState.canPlace()) return false; @@ -267,56 +318,56 @@ public abstract class ItemBucket extends ItemFood implements IItemContainer { return isDifferent; } - @Override - public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) { - final NamespaceID currentStateId = getState(selfStack); - final BucketState currentState = getBucketState(currentStateId); + // @Override + // public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) { + // final NamespaceID currentStateId = getState(selfStack); + // final BucketState currentState = getBucketState(currentStateId); - if (currentState.isEdible() && !currentState.canPlace()) return false; + // if (currentState.isEdible() && !currentState.canPlace()) return false; - final @NotNull UseResult result; + // final @NotNull UseResult result; - interface ctx { @NotNull UseResult result = new UseResult(); } - interact: synchronized(ctx.result) { - ctx.result.used = false; - ctx.result.itemStack = null; + // interface ctx { @NotNull UseResult result = new UseResult(); } + // interact: synchronized(ctx.result) { + // ctx.result.used = false; + // ctx.result.itemStack = null; - if (world.getBlockData(tilePos) == 0) { - final NamespaceID targetStateId = getFluidStateAt(world, tilePos); + // if (world.getBlockData(tilePos) == 0) { + // final NamespaceID targetStateId = getFluidStateAt(world, tilePos); - final boolean isEmptyScoop = STATE_EMPTY.equals(currentStateId); - final boolean isRefillScoop = !isEmptyScoop && - currentStateId.equals(targetStateId) && getCharges(selfStack) < this.maxCharges; + // final boolean isEmptyScoop = STATE_EMPTY.equals(currentStateId); + // final boolean isRefillScoop = !isEmptyScoop && + // currentStateId.equals(targetStateId) && getCharges(selfStack) < this.maxCharges; - if (targetStateId != null && (isEmptyScoop || isRefillScoop)) { - result = tryPickupFluid(selfStack, world, player, tilePos, targetStateId, ctx.result); - break interact; - } - } + // if (targetStateId != null && (isEmptyScoop || isRefillScoop)) { + // result = tryPickupFluid(selfStack, world, player, tilePos, targetStateId, ctx.result); + // break interact; + // } + // } - if (currentState.canPlace()) { - final NamespaceID aimedFluid = getFluidStateAt(world, tilePos); - if (currentStateId.equals(aimedFluid) && getCharges(selfStack) < this.maxCharges) { - result = ctx.result; - break interact; - } - - result = tryPlaceFluid(selfStack, world, player, tilePos, side, ctx.result); - break interact; - } - return false; - } - - if (result.used && result.itemStack != null) { - player.inventory.setItem(player.inventory.getCurrentSlot(), result.itemStack); - } - return result.used; - } - - @Override - public ItemStack onUse(@NotNull ItemStack itemStack, @NotNull World world, @NotNull Player player) { - return handleAirClick(itemStack, world, player); - } + // if (currentState.canPlace()) { + // final NamespaceID aimedFluid = getFluidStateAt(world, tilePos); + // if (currentStateId.equals(aimedFluid) && getCharges(selfStack) < this.maxCharges) { + // result = ctx.result; + // break interact; + // } + + // result = tryPlaceFluid(selfStack, world, player, tilePos, side, ctx.result); + // break interact; + // } + // return false; + // } + + // if (result.used && result.itemStack != null) { + // player.inventory.setItem(player.inventory.getCurrentSlot(), result.itemStack); + // } + // return result.used; + // } + + // @Override + // public ItemStack onUse(@NotNull ItemStack itemStack, @NotNull World world, @NotNull Player player) { + // return handleAirClick(itemStack, world, player); + // } protected static class UseResult { public boolean used = false; @@ -352,6 +403,7 @@ public abstract class ItemBucket extends ItemFood implements IItemContainer { @NotNull ItemStack itemStack, @NotNull World world, @NotNull Player player, @NotNull TilePosc tilePos, @NotNull Side side, @NotNull UseResult result ) { + result.itemStack = itemStack; if (!world.canMineBlock(player, tilePos)) return result; final NamespaceID stateId = getState(itemStack); diff --git a/game/core/src/main/java/net/minecraft/core/world/World.java b/game/core/src/main/java/net/minecraft/core/world/World.java index 0e2a2d058..e892660e7 100644 --- a/game/core/src/main/java/net/minecraft/core/world/World.java +++ b/game/core/src/main/java/net/minecraft/core/world/World.java @@ -1433,8 +1433,9 @@ public abstract class World implements MutableWorldSource { } final double radius = 0.25D; - final List entities = this.getEntitiesWithinAABBExcludingEntity(entity, MathHelper.aabbGrow(aabb, radius, radius, radius, workingBox)); + final List entities = this.getCollidableEntitiesWithinAABB(MathHelper.aabbGrow(aabb, radius, radius, radius, workingBox)); for (final Entity e : entities) { + if (e == entity) continue; final AABBdc entityBB = e.getCollisionAABB(); if (entityBB != null && entityBB.intersectsAABB((AABBd) aabb)) { this.collidingBoundingBoxes.add(entityBB); @@ -1813,15 +1814,12 @@ public abstract class World implements MutableWorldSource { for (tilePos.y = minY; tilePos.y < maxY; tilePos.y++) { for (tilePos.z = minZ; tilePos.z < maxZ; tilePos.z++) { final @NotNull Block block = this.getBlockType(tilePos); - if (!this.isMaterialInBB(aabb, material)) { - continue; - } + if (block.getMaterial() != material) continue; + if (!aabb.intersectsAABB(block.getBoundsFromState(this, tilePos).translate(tilePos.x, tilePos.y, tilePos.z, this.workingBox))) continue; flag = true; block.onEntityInside(this, tilePos, entity, velDir); } - } - } if (velDir.length() > 0.0D && addVelocity) { @@ -2338,6 +2336,23 @@ public abstract class World implements MutableWorldSource { this.randomDisplayUpdates(new TilePos(x, y, z)); } + public @NotNull List<@NotNull Entity> getCollidableEntitiesWithinAABB(@NotNull final AABBdc aabb) { + this.entityBuffer.clear(); + final int minX = MathHelper.floor((aabb.minX() - 2D) / Chunk.CHUNK_SIZE_X); + final int maxX = MathHelper.floor((aabb.maxX() + 2D) / Chunk.CHUNK_SIZE_X); + final int minZ = MathHelper.floor((aabb.minZ() - 2D) / Chunk.CHUNK_SIZE_Z); + final int maxZ = MathHelper.floor((aabb.maxZ() + 2D) / Chunk.CHUNK_SIZE_Z); + for (int x = minX; x <= maxX; x++) { + for (int z = minZ; z <= maxZ; z++) { + if (this.isChunkLoaded(x, z)) { + this.getChunkFromChunkCoords(x, z).getCollidableEntitiesWithin(aabb, this.entityBuffer); + } + } + } + + return this.entityBuffer; + } + public @NotNull List<@NotNull Entity> getEntitiesWithinAABBExcludingEntity(@Nullable final Entity entity, @NotNull final AABBdc aabb) { this.entityBuffer.clear(); final int minX = MathHelper.floor((aabb.minX() - 2D) / Chunk.CHUNK_SIZE_X); diff --git a/game/core/src/main/java/net/minecraft/core/world/chunk/Chunk.java b/game/core/src/main/java/net/minecraft/core/world/chunk/Chunk.java index f8628f9ff..b3675369c 100644 --- a/game/core/src/main/java/net/minecraft/core/world/chunk/Chunk.java +++ b/game/core/src/main/java/net/minecraft/core/world/chunk/Chunk.java @@ -738,6 +738,10 @@ public class Chunk { this.isModified = true; } + public final @NotNull ChunkSection @NotNull[] getSectionsDirect() { + return this.sections; + } + public void getEntitiesWithin(@Nullable Entity toExclude, @NotNull AABBdc aabb, @NotNull List<@NotNull Entity> entities) { int minSection = Math.max(0, MathHelper.floor((aabb.minY() - 2D) / 16D)); int maxSection = Math.min(MathHelper.floor((aabb.maxY() + 2D) / 16D), CHUNK_SECTIONS - 1); @@ -746,6 +750,14 @@ public class Chunk { } } + public void getCollidableEntitiesWithin(@NotNull AABBdc aabb, @NotNull List<@NotNull Entity> entities) { + int minSection = Math.max(0, MathHelper.floor((aabb.minY() - 2D) / 16D)); + int maxSection = Math.min(MathHelper.floor((aabb.maxY() + 2D) / 16D), CHUNK_SECTIONS - 1); + for (int section = minSection; section <= maxSection; section++) { + getSection(section).getCollidableEntitiesWithin(aabb, entities); + } + } + public void getEntitiesWithin(@NotNull Class ofClass, @NotNull AABBdc aabb, @NotNull List<@NotNull T> entities) { int minSection = Math.max(0, MathHelper.floor((aabb.minY() - 2D) / 16D)); int maxSection = Math.min(MathHelper.floor((aabb.maxY() + 2D) / 16D), CHUNK_SECTIONS - 1); diff --git a/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkSection.java b/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkSection.java index 698845cb7..d5b3e4ec5 100644 --- a/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkSection.java +++ b/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkSection.java @@ -3,6 +3,7 @@ package net.minecraft.core.world.chunk; import net.minecraft.core.block.Blocks; import net.minecraft.core.data.registry.Registries; import net.minecraft.core.entity.Entity; +import net.minecraft.core.entity.ICollidable; import net.minecraft.core.enums.LightLayer; import net.minecraft.core.util.helper.LightIndexHelper; import net.minecraft.core.world.World; @@ -33,6 +34,8 @@ public class ChunkSection { public byte @NotNull [] biome = new byte[Chunk.CHUNK_SIZE_X * Chunk.CHUNK_SIZE_Z * (SECTION_SIZE_Y >> 3)]; public @NotNull List<@NotNull Entity> entities = new ArrayList<>(); + public @NotNull List<@NotNull Entity> collidableEntities = new ArrayList<>(); + public ChunkSection(final @NotNull Chunk chunk, final int yPosition) { this.chunk = chunk; this.yPosition = yPosition; @@ -222,10 +225,12 @@ public class ChunkSection { public void addEntity(final @NotNull Entity entity) { this.entities.add(entity); + if (entity instanceof ICollidable) this.collidableEntities.add(entity); } public void removeEntity(final @NotNull Entity entity) { this.entities.remove(entity); + this.collidableEntities.remove(entity); } public void getEntitiesWithin(final @Nullable Entity toExclude, final @NotNull AABBdc aabb, final @NotNull List<@NotNull Entity> entities) { @@ -236,6 +241,14 @@ public class ChunkSection { } } + public void getCollidableEntitiesWithin(final @NotNull AABBdc aabb, final @NotNull List<@NotNull Entity> entities) { + for (final @NotNull Entity e : this.collidableEntities) { + if (e.bb.intersectsAABB((AABBd) aabb)) { + entities.add(e); + } + } + } + public void getEntitiesWithin(@NotNull Class ofClass, @NotNull AABBdc aabb, @NotNull List<@NotNull T> entities) { for (Entity e : this.entities) { if (ofClass.isAssignableFrom(e.getClass()) && e.bb.intersectsAABB((AABBd) aabb)) { diff --git a/util/datagen/src/main/java/net/minecraft/datagen/SmeltingGenerator.java b/util/datagen/src/main/java/net/minecraft/datagen/SmeltingGenerator.java index ce7c50a54..bf4db129c 100644 --- a/util/datagen/src/main/java/net/minecraft/datagen/SmeltingGenerator.java +++ b/util/datagen/src/main/java/net/minecraft/datagen/SmeltingGenerator.java @@ -57,30 +57,24 @@ public class SmeltingGenerator { blastRecipe("log_to_scorched_log", "minecraft:logs", Blocks.BLOCK_ASH.getDefaultStack(), Blocks.LOG_SCORCHED.getDefaultStack()); - addOreConversions(BlockLogicOreCoal.variantMap); - addOreConversions(BlockLogicOreIron.variantMap); - addOreConversions(BlockLogicOreGold.variantMap); - addOreConversions(BlockLogicOreLapis.variantMap); - addOreConversions(BlockLogicOreRedstone.variantMap); - addOreConversions(BlockLogicOreDiamond.variantMap); - addOreConversions(BlockLogicOreNetherCoal.variantMap); + addOreConversions(BlockLogicOreCoal.variantMap, "minecraft:coal_ores"); + addOreConversions(BlockLogicOreIron.variantMap, "minecraft:iron_ores"); + addOreConversions(BlockLogicOreGold.variantMap, "minecraft:gold_ores"); + addOreConversions(BlockLogicOreLapis.variantMap, "minecraft:lapis_ores"); + addOreConversions(BlockLogicOreRedstone.variantMap, "minecraft:redstone_ores"); + addOreConversions(BlockLogicOreDiamond.variantMap, "minecraft:diamond_ores"); + addOreConversions(BlockLogicOreNetherCoal.variantMap, "minecraft:nethercoal_ores"); } - private static void addOreConversions(Int2IntArrayMap variantMap) { - for (int fromParentId : variantMap.keySet()) { - for (int toParentId : variantMap.keySet()) { - if (fromParentId == toParentId) continue; + private static void addOreConversions(Int2IntArrayMap variantMap, String oreGroup) { + for (int toParentId : variantMap.keySet()) { + final Block toParent = Blocks.getBlock(toParentId); + final Block toChild = Blocks.getBlock(variantMap.get(toParentId)); - final Block toParent = Blocks.getBlock(toParentId); - - final Block fromChild = Blocks.getBlock(variantMap.get(fromParentId)); - final Block toChild = Blocks.getBlock(variantMap.get(toParentId)); - - blastRecipe( - String.format("%s_to_%s", fromChild.getKey(), toChild.getKey()), - toParent.getDefaultStack(), fromChild.getDefaultStack(), toChild.getDefaultStack() - ); - } + blastRecipe( + String.format("%s_to_%s", oreGroup, toChild.getKey()), + toParent.getDefaultStack(), oreGroup, toChild.getDefaultStack() + ); } } @@ -104,6 +98,10 @@ public class SmeltingGenerator { RecipeBuilder.BlastFurnace(RecipesGenerator.CORE_NAMESPACE).setInput(inputA, inputB).create(id, output); } + private static void blastRecipe(String id, ItemStack inputA, String inputB, ItemStack output) { + RecipeBuilder.BlastFurnace(RecipesGenerator.CORE_NAMESPACE).setInput(new RecipeSymbol(inputA), new RecipeSymbol(inputB)).create(id, output); + } + private static void blastRecipe(String id, String inputGroup, ItemStack inputStack, ItemStack output) { RecipeBuilder.BlastFurnace(RecipesGenerator.CORE_NAMESPACE).setInput(new RecipeSymbol(inputGroup), new RecipeSymbol(inputStack)).create(id, output); }