diff --git a/game/client/src/main/java/net/minecraft/client/Minecraft.java b/game/client/src/main/java/net/minecraft/client/Minecraft.java index f4c5a0f09..84665e3d8 100644 --- a/game/client/src/main/java/net/minecraft/client/Minecraft.java +++ b/game/client/src/main/java/net/minecraft/client/Minecraft.java @@ -1184,9 +1184,9 @@ public class Minecraft if (leftClickDown && this.objectMouseOver instanceof final @NotNull HitResult.Tile hitTile) { final double xPlaced; - if (hitTile.side.getAxis() == Axis.X) { + if (hitTile.side.axis() == Axis.X) { xPlaced = hitTile.location.x() - hitTile.tilePos.x(); - } else if (hitTile.side.getAxis() == Axis.Z) { + } else if (hitTile.side.axis() == Axis.Z) { xPlaced = hitTile.location.z() - hitTile.tilePos.z(); } else { xPlaced = hitTile.location.x() - hitTile.tilePos.x(); @@ -1225,9 +1225,9 @@ public class Minecraft MathHelper.floor(this.thePlayer.z) ); - Direction playerDirection = Direction.getHorizontalDirection(this.thePlayer); + Direction playerDirection = Direction.getHorizontalLockable(this.thePlayer); if (playerDirection.isVertical()) break bridge; - Side side = playerDirection.getSide(); + Side side = playerDirection.side(); double yPlaced = 0.5d; double xPlaced = 0.5d; @@ -1262,9 +1262,9 @@ public class Minecraft } else if (this.objectMouseOver instanceof HitResult.Tile hitTile) { double xPlaced; double yPlaced = hitTile.location.y() - hitTile.tilePos.y(); - if (hitTile.side.getAxis() == Axis.X) { + if (hitTile.side.axis() == Axis.X) { xPlaced = hitTile.location.x() - hitTile.tilePos.x(); - } else if (hitTile.side.getAxis() == Axis.Z) { + } else if (hitTile.side.axis() == Axis.Z) { xPlaced = hitTile.location.z() - hitTile.tilePos.z(); } else { xPlaced = hitTile.location.x() - hitTile.tilePos.x(); @@ -1777,10 +1777,10 @@ public class Minecraft GameSettings.ROTATION_OVERLAY_MODE.value++; GameSettings.ROTATION_OVERLAY_MODE.value %= 4; } else { - if (this.thePlayer.rotationLock == null || this.thePlayer.rotationLock == Direction.NONE) { - this.thePlayer.rotationLock = Direction.getDirection(this.thePlayer); - this.thePlayer.rotationLockHorizontal = Direction.getHorizontalDirection(this.thePlayer); - this.thePlayer.rotationLockVertical = Direction.getVerticalDirection(this.thePlayer); + if (this.thePlayer.rotationLock == null) { + this.thePlayer.rotationLock = Direction.getLockable(this.thePlayer); + this.thePlayer.rotationLockHorizontal = Direction.getHorizontalLockable(this.thePlayer); + this.thePlayer.rotationLockVertical = Direction.getVerticalLockable(this.thePlayer); } else { this.thePlayer.rotationLock = null; this.thePlayer.rotationLockHorizontal = null; diff --git a/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocal.java b/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocal.java index 75279c62e..52068315a 100644 --- a/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocal.java +++ b/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocal.java @@ -441,8 +441,8 @@ public class PlayerLocal extends Player { pushDirection = Direction.SOUTH; } final float pushStrength = 0.1F; - this.xd = pushDirection.getOffsetX() * pushStrength; - this.zd = pushDirection.getOffsetZ() * pushStrength; + this.xd = pushDirection.offsetX() * pushStrength; + this.zd = pushDirection.offsetZ() * pushStrength; return true; } return false; diff --git a/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java b/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java index c1e672c65..96eda5d1a 100644 --- a/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java +++ b/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java @@ -237,9 +237,9 @@ public class PlayerLocalMultiplayer extends PlayerLocal implements Player.Player super.syncPlacementMode(); byte[] data = new byte[4]; - data[0] = (byte) (rotationLock != null ? rotationLock.getId() : -1); - data[1] = (byte) (rotationLockHorizontal != null ? rotationLockHorizontal.getId() : -1); - data[2] = (byte) (rotationLockVertical != null ? rotationLockVertical.getId() : -1); + data[0] = (byte) (rotationLock != null ? rotationLock.id : -1); + data[1] = (byte) (rotationLockHorizontal != null ? rotationLockHorizontal.id : -1); + data[2] = (byte) (rotationLockVertical != null ? rotationLockVertical.id : -1); data[3] = (byte) (placementModeOverride != null ? placementModeOverride.index() : -1); sendQueue.addToSendQueue(new PacketCustomPayload(PacketCustomPayload.CHANNEL_ROTATION_LOCK, data)); diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngame.java b/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngame.java index e315fd2c7..221b99f5e 100644 --- a/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngame.java +++ b/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngame.java @@ -265,7 +265,7 @@ public class HudIngame extends Gui { int yaw = DynamicTexture.pmod(java.lang.Math.round(this.mc.thePlayer.yRot), 360); int pitch = java.lang.Math.round(this.mc.thePlayer.xRot); - drawDebugScreenLine("Facing: " + yaw + "°, " + pitch + "° (" + I18n.getInstance().translateKey(getFacingDirection(this.mc.thePlayer).getTranslationKey()) + ")"); + drawDebugScreenLine("Facing: " + yaw + "°, " + pitch + "° (" + I18n.getInstance().translateKey(getFacingDirection(this.mc.thePlayer).translationKey) + ")"); } else { drawDebugScreenLine("Hold a compass for more information"); } @@ -366,9 +366,9 @@ public class HudIngame extends Gui { int lightZ = hitTile.tilePos.z(); Side side = hitTile.side; - lightX += side.getOffsetX(); - lightY += side.getOffsetY(); - lightZ += side.getOffsetZ(); + lightX += side.offsetX(); + lightY += side.offsetY(); + lightZ += side.offsetZ(); drawDebugScreenLineRight("Light: Sky: " + this.mc.currentWorld.getSavedLightValue(LightLayer.Sky, lightX, lightY, lightZ) + " Block: " + this.mc.currentWorld.getSavedLightValue(LightLayer.Block, lightX, lightY, lightZ)); } diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentInfoOverlay.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentInfoOverlay.java index 61f3dbabf..a9b59b7a7 100644 --- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentInfoOverlay.java +++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentInfoOverlay.java @@ -103,7 +103,7 @@ public class HudComponentInfoOverlay extends HudComponentMovable { } } if (GameSettings.DIRECTION_IN_OVERLAY.value) { - lines.add(new RenderLine(I18n.getInstance().translateKey(HudIngame.getFacingDirection(mc.thePlayer).getTranslationKey()), 0xFFFFFFFF)); + lines.add(new RenderLine(I18n.getInstance().translateKey(HudIngame.getFacingDirection(mc.thePlayer).translationKey), 0xFFFFFFFF)); } } @@ -176,7 +176,7 @@ public class HudComponentInfoOverlay extends HudComponentMovable { } boolean dirEnabled = GameSettings.DIRECTION_IN_OVERLAY.value; - lines.add(new RenderLine(I18n.getInstance().translateKey(Direction.NORTH.getTranslationKey()), getPreviewColor(0xFFFFFFFF, dirEnabled))); + lines.add(new RenderLine(I18n.getInstance().translateKey(Direction.NORTH.translationKey), getPreviewColor(0xFFFFFFFF, dirEnabled))); int clockColor = (GameSettings.OVERLAY_MODE.value == 2) ? 0xFFFFFF80 : 0xFFFFFFFF; boolean timeEnabled = GameSettings.TIME_IN_OVERLAY.value; diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentRotationLock.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentRotationLock.java index 8e8e5f8b9..51c83c970 100644 --- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentRotationLock.java +++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentRotationLock.java @@ -21,7 +21,7 @@ public class HudComponentRotationLock if (mc.thePlayer == null) { return GameSettings.IMMERSIVE_MODE.drawOverlays(); } - return mc.thePlayer.rotationLock != null && mc.thePlayer.rotationLock != Direction.NONE && GameSettings.IMMERSIVE_MODE.drawOverlays(); + return mc.thePlayer.rotationLock != null && GameSettings.IMMERSIVE_MODE.drawOverlays(); } @Override @@ -40,10 +40,10 @@ public class HudComponentRotationLock boolean facingUp = player.xRot < -45; boolean facingDown = player.xRot > 45; - Direction dir = Direction.getDirection(player); + Direction dir = Direction.getLockable(player); if (dir.isHorizontal()) { - dir = dir.rotate(-Direction.getHorizontalDirection(player.yRot).rotate(2).index); + dir = dir.rotateY(Direction.fromYaw(player.yRot).rotateY(2).legacyIndex()); if (facingUp) { if (dir == Direction.SOUTH) dir = Direction.UP; @@ -70,10 +70,10 @@ public class HudComponentRotationLock } String[] dirTextures = new String[]{"down", "up", "back", "front", "left", "right"}; - hud.drawGuiIcon(x, y, 16, 16, TextureRegistry.getTexture("minecraft:gui/hud/rotation/" + prefix + "_" + dirTextures[dir.getId()])); - dir = Direction.getVerticalDirection(player); + hud.drawGuiIcon(x, y, 16, 16, TextureRegistry.getTexture("minecraft:gui/hud/rotation/" + prefix + "_" + dirTextures[dir.id])); + dir = Direction.getVerticalLockable(player); dirTextures = new String[]{"downer", "upper", "back", "front", "left", "right"}; - hud.drawGuiIcon(x + 16, y + 4, 8, 8, TextureRegistry.getTexture("minecraft:gui/hud/rotation/" + prefix + "_" + dirTextures[dir.getId()])); + hud.drawGuiIcon(x + 16, y + 4, 8, 8, TextureRegistry.getTexture("minecraft:gui/hud/rotation/" + prefix + "_" + dirTextures[dir.id])); } @Override diff --git a/game/client/src/main/java/net/minecraft/client/gui/modelviewer/categories/ViewerCategoryBlock.java b/game/client/src/main/java/net/minecraft/client/gui/modelviewer/categories/ViewerCategoryBlock.java index f2dabc63c..b6f7835b4 100644 --- a/game/client/src/main/java/net/minecraft/client/gui/modelviewer/categories/ViewerCategoryBlock.java +++ b/game/client/src/main/java/net/minecraft/client/gui/modelviewer/categories/ViewerCategoryBlock.java @@ -27,6 +27,7 @@ import net.minecraft.core.block.Blocks; import net.minecraft.core.block.IPainted; import net.minecraft.core.block.piston.BlockLogicPistonBase; import net.minecraft.core.block.piston.BlockLogicPistonHead; +import net.minecraft.core.block.piston.PistonCommon; import net.minecraft.core.entity.EntityItem; import net.minecraft.core.enums.EnumDropCause; import net.minecraft.core.item.ItemStack; @@ -217,13 +218,12 @@ public class ViewerCategoryBlock extends ModelViewerCategory ly = (y + 1) + d; case DOWN -> ly = (y) - d; @@ -2010,7 +2010,7 @@ public class RenderGlobal public static Side unpackEventConduitSide(int packed) { int sideId = (packed >> 4) & 0x07; - return Side.getSideById(sideId); + return Side.fromId(sideId); } public static int unpackEventConduitStrength(int packed) { diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelAxisAligned.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelAxisAligned.java index e7e375603..663aaece5 100644 --- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelAxisAligned.java +++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelAxisAligned.java @@ -57,8 +57,8 @@ public class BlockModelAxisAligned extends BlockModelStand } public Side getRotatedSide(Side side, int data) { - int d = (6 * (data & 3) + side.getId()); - return d < Sides.orientationLookUpXYZAligned.length ? Side.getSideById(Sides.orientationLookUpXYZAligned[d]) : Side.NONE; + int d = (6 * (data & 3) + side.id); + return d < Sides.orientationLookUpXYZAligned.length ? Side.fromId(Sides.orientationLookUpXYZAligned[d]) : Side.NONE; } } diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDispatcher.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDispatcher.java index 326f64167..92e9a6ad9 100644 --- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDispatcher.java +++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDispatcher.java @@ -386,6 +386,7 @@ public final class BlockModelDispatcher addDispatch(new BlockModelGenericRepeater<>(Blocks.REPEATER_IDLE)); addDispatch(new BlockModelGenericRepeater<>(Blocks.REPEATER_ACTIVE)); + addDispatch(new BlockModelGenericTimer<>(Blocks.TIMER)); addDispatch(new BlockModelGenericPiston<>(Blocks.PISTON_BASE, loadDataModel("minecraft:block/piston/base"), loadDataModel("minecraft:block/piston/extended"))); addDispatch(new BlockModelGenericPiston<>(Blocks.PISTON_BASE_STICKY, loadDataModel("minecraft:block/piston_sticky/base"), loadDataModel("minecraft:block/piston_sticky/extended"))); @@ -393,11 +394,27 @@ public final class BlockModelDispatcher addDispatch(new BlockModelEmpty<>(Blocks.PISTON_MOVING).setAllTextures((IconCoordinate) null)); addDispatch(new BlockModelGenericPistonHead<>(Blocks.PISTON_HEAD, - loadDataModel("minecraft:block/piston/head"), loadDataModel("minecraft:block/piston_sticky/head"), loadDataModel("minecraft:block/piston_steel/head"), - loadDataModel("minecraft:block/piston/head_half"), loadDataModel("minecraft:block/piston_sticky/head_half"), loadDataModel("minecraft:block/piston_steel/head_half"))); + loadDataModel("minecraft:block/piston/head"), + loadDataModel("minecraft:block/piston_sticky/head"), + loadDataModel("minecraft:block/piston_steel/head"), + // loadDataModel("minecraft:block/piston/head_half"), + // loadDataModel("minecraft:block/piston_sticky/head_half"), + // loadDataModel("minecraft:block/piston_steel/head_half"), + loadDataModel("minecraft:block/piston/head_short"), + loadDataModel("minecraft:block/piston_sticky/head_short"), + loadDataModel("minecraft:block/piston_steel/head_short") + )); addDispatch(new BlockModelGenericPistonHead<>(Blocks.PISTON_HEAD_STEEL, - loadDataModel("minecraft:block/piston/head"), loadDataModel("minecraft:block/piston_sticky/head"), loadDataModel("minecraft:block/piston_steel/head"), - loadDataModel("minecraft:block/piston/head_half"), loadDataModel("minecraft:block/piston_sticky/head_half"), loadDataModel("minecraft:block/piston_steel/head_half"))); + loadDataModel("minecraft:block/piston/head"), + loadDataModel("minecraft:block/piston_sticky/head"), + loadDataModel("minecraft:block/piston_steel/head"), + // loadDataModel("minecraft:block/piston/head_half"), + // loadDataModel("minecraft:block/piston_sticky/head_half"), + // loadDataModel("minecraft:block/piston_steel/head_half"), + loadDataModel("minecraft:block/piston/head_short"), + loadDataModel("minecraft:block/piston_sticky/head_short"), + loadDataModel("minecraft:block/piston_steel/head_short") + )); addDispatch(new BlockModelGeneric<>(Blocks.NOTEBLOCK, loadDataModel("minecraft:block/noteblock"))); diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDoor.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDoor.java index 2f7d22214..a45b80f7d 100644 --- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDoor.java +++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDoor.java @@ -73,8 +73,8 @@ public class BlockModelDoor extends BlockModelStandard protected boolean shouldFlipTexture(@NotNull Side side, int meta) { if (side == Side.TOP || side == Side.BOTTOM) return false; int state = this.block.getLogic().getRotation(meta); - int l = state / 2 + (side.getId() & 1 ^ state); - if ((state == 0 || state == 2) ^ (side.getId() <= 3)) { + int l = state / 2 + (side.id & 1 ^ state); + if ((state == 0 || state == 2) ^ (side.id <= 3)) { return false; } l += (meta & 4) / 4; diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFluid.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFluid.java index f9645e68b..5e9a2d954 100644 --- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFluid.java +++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFluid.java @@ -202,7 +202,7 @@ public class BlockModelFluid extends BlockModelStanda case 2 -> posB.set(x - 1, y, z); // West case 3 -> posB.set(x + 1, y, z); // East } - IconCoordinate texture = getBlockTextureFromSideAndMetadata(Side.getSideById(side + 2), meta); + IconCoordinate texture = getBlockTextureFromSideAndMetadata(Side.fromId(side + 2), meta); if (!renderBlocks.renderAllFaces && !sideRenderFlags[side]) { continue; } diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFullyRotatable.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFullyRotatable.java index d8b60d364..7c24811eb 100644 --- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFullyRotatable.java +++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFullyRotatable.java @@ -71,9 +71,9 @@ public class BlockModelFullyRotatable extends BlockModelSt @Override public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) { final Direction dir = BlockLogicFullyRotatable.metaToDirection(data); - if (side == dir.getSide()) { + if (side == dir.side()) { return this.blockTextures.get(Side.TOP); } - return side.getDirection() != dir.getOpposite() ? this.blockTextures.get(Side.NORTH) : this.blockTextures.get(Side.BOTTOM); + return side.direction() != dir.opposite() ? this.blockTextures.get(Side.NORTH) : this.blockTextures.get(Side.BOTTOM); } } \ No newline at end of file diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelHorizontalRotation.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelHorizontalRotation.java index abdc96b9b..b11b7f690 100644 --- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelHorizontalRotation.java +++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelHorizontalRotation.java @@ -26,8 +26,8 @@ public class BlockModelHorizontalRotation extends BlockMod @Override public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) { - int index = Sides.orientationLookUpHorizontal[6 * Math.min(data & BlockLogicRotatable.MASK_DIRECTION, 5) + side.getId()]; + int index = Sides.orientationLookUpHorizontal[6 * Math.min(data & BlockLogicRotatable.MASK_DIRECTION, 5) + side.id]; if (index >= Sides.orientationLookUpHorizontal.length) return this.blockTextures.get(Side.BOTTOM); - return super.getBlockTextureFromSideAndMetadata(Side.getSideById(index), data); + return super.getBlockTextureFromSideAndMetadata(Side.fromId(index), data); } } diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelRotatable.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelRotatable.java index d73c9d3f5..cc944aa94 100644 --- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelRotatable.java +++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelRotatable.java @@ -15,7 +15,7 @@ public class BlockModelRotatable extends BlockModelStandar @Override public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) { - int index = Sides.orientationLookUp[6 * data + side.getId()]; - return this.blockTextures.get(Side.getSideById(index)); + int index = Sides.orientationLookUp[6 * data + side.id]; + return this.blockTextures.get(Side.fromId(index)); } } diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelStandard.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelStandard.java index 666176f6e..0bd99cd7c 100644 --- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelStandard.java +++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelStandard.java @@ -276,7 +276,7 @@ public class BlockModelStandard extends BlockModel { public TextureLayer set(@Nullable IconCoordinate coordinate, Side... sides) { for (Side s : sides) { assert s != Side.NONE : "Cannot set texture on a 'NONE' side!"; - this.coordinates[s.getId()] = coordinate; + this.coordinates[s.id] = coordinate; } this.hasTexture = false; @@ -309,7 +309,7 @@ public class BlockModelStandard extends BlockModel { public @Nullable IconCoordinate get(@NotNull Side side) { assert side != Side.NONE : "Cannot set texture on a 'NONE' side!"; - return this.coordinates[side.getId()]; + return this.coordinates[side.id]; } public @Nullable IconCoordinate get(int index) { diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelTrapDoor.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelTrapDoor.java index 14cf408fd..5ed5ccf1f 100644 --- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelTrapDoor.java +++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelTrapDoor.java @@ -79,10 +79,10 @@ public class BlockModelTrapDoor extends BlockModelStandard public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) { int orientation = data & 0b11; if (BlockLogicTrapDoor.isTrapdoorOpen(data)) { - int index = Sides.orientationLookUpTrapdoorOpen[6 * orientation + side.getId()]; + int index = Sides.orientationLookUpTrapdoorOpen[6 * orientation + side.id]; return this.blockTextures.get(index); } else { - if (side.getAxis() == Axis.Y) { + if (side.axis() == Axis.Y) { return this.blockTextures.get(Side.BOTTOM); } else { return this.blockTextures.get(Side.SOUTH); diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelVeryRotatable.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelVeryRotatable.java index 470553f46..c4b82c4ff 100644 --- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelVeryRotatable.java +++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelVeryRotatable.java @@ -64,9 +64,9 @@ public class BlockModelVeryRotatable extends BlockModelSta final Direction dir = BlockLogicVeryRotatable.metaToDirection(data); return switch (dir) { // I love brute forcing fixes so much :3 case SOUTH -> side; - case EAST -> side.getDirection().rotate(1).getSide(); - case NORTH -> side.getDirection().rotate(2).getSide(); - case WEST -> side.getDirection().rotate(3).getSide(); + case EAST -> side.direction().rotateY(3).side(); + case NORTH -> side.direction().rotateY(2).side(); + case WEST -> side.direction().rotateY(1).side(); case UP -> switch (side) { case NORTH -> Side.TOP; case SOUTH -> Side.BOTTOM; diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/RenderBlocks.java b/game/client/src/main/java/net/minecraft/client/render/block/model/RenderBlocks.java index 81a98d504..01ec287f8 100644 --- a/game/client/src/main/java/net/minecraft/client/render/block/model/RenderBlocks.java +++ b/game/client/src/main/java/net/minecraft/client/render/block/model/RenderBlocks.java @@ -91,9 +91,9 @@ public final class RenderBlocks { public void setRenderSide(@NotNull Side side, boolean shouldRender) { if (!shouldRender) { - this.renderBitMask |= (byte) (1 << side.getId()); + this.renderBitMask |= (byte) (1 << side.id); } else { - this.renderBitMask &= (byte) ~(1 << side.getId()); + this.renderBitMask &= (byte) ~(1 << side.id); } } @@ -212,7 +212,7 @@ public final class RenderBlocks { int lefX, int lefY, int lefZ, float lefP, float rigP ) { IconCoordinate tex = blockModel.getBlockTexture(worldSource, tilePos, side); - if (tex == null || ((this.renderBitMask >> side.getId()) & 1) != 0) return false; + if (tex == null || ((this.renderBitMask >> side.id) & 1) != 0) return false; boolean rendered = false; if (this.renderAllFaces || blockModel.shouldSideBeRendered(worldSource, bounds, tilePos.add(dirX, dirY, dirZ, new TilePos()), side, meta)) { diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPiston.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPiston.java index df0372f54..cd622adc5 100644 --- a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPiston.java +++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPiston.java @@ -4,7 +4,7 @@ import net.minecraft.client.render.tessellator.TessellatorGeneral; import net.minecraft.core.block.Block; import net.minecraft.core.block.BlockLogic; import net.minecraft.core.block.BlockLogicVeryRotatable; -import net.minecraft.core.block.piston.BlockLogicPistonBase; +import net.minecraft.core.block.piston.PistonCommon; import net.minecraft.core.util.helper.Direction; import net.minecraft.core.world.WorldSource; import net.minecraft.core.world.pos.TilePos; @@ -46,8 +46,8 @@ public class BlockModelGenericPiston extends BlockModelGen @Override public @NotNull StaticBlockModel getModelFromData(int data) { - boolean extended = /*noCulling || */(data & BlockLogicPistonBase.MASK_POWERED) != 0; -// Direction direction = BlockLogicPistonBase.getDirection(meta); - return extended ? this.extended : super.getModelFromData(data); + return (/*noCulling || */PistonCommon.IS_DETACHED_OR_EXTENDED.bool(data)) + ? this.extended + : super.getModelFromData(data); } } diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPistonHead.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPistonHead.java index 21092070a..4373c7aa8 100644 --- a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPistonHead.java +++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPistonHead.java @@ -3,9 +3,7 @@ package net.minecraft.client.render.block.model.generic; import net.minecraft.client.render.tessellator.TessellatorGeneral; import net.minecraft.core.block.Block; import net.minecraft.core.block.BlockLogic; -import net.minecraft.core.block.BlockLogicVeryRotatable; -import net.minecraft.core.block.piston.BlockLogicPistonBase; -import net.minecraft.core.block.piston.BlockLogicPistonHead; +import net.minecraft.core.block.piston.PistonCommon; import net.minecraft.core.util.helper.Direction; import net.minecraft.core.world.WorldSource; import net.minecraft.core.world.pos.TilePos; @@ -14,55 +12,50 @@ import org.useless.dragonfly.data.block.BlockModelData; import org.useless.dragonfly.models.block.StaticBlockModel; public class BlockModelGenericPistonHead extends BlockModelGenericVeryRotatable { - public final @NotNull StaticBlockModel sticky; - public final @NotNull StaticBlockModel steel; - public final @NotNull StaticBlockModel baseHalf; - public final @NotNull StaticBlockModel stickyHalf; - public final @NotNull StaticBlockModel steelHalf; - public BlockModelGenericPistonHead(@NotNull Block block, @NotNull BlockModelData piston, @NotNull BlockModelData sticky, @NotNull BlockModelData steel, @NotNull BlockModelData pistonHalf, @NotNull BlockModelData stickyHalf, @NotNull BlockModelData steelHalf) { + + public final @NotNull StaticBlockModel[] normal; + public final @NotNull StaticBlockModel[] schort; + // // it seems like the short versions are good enough for hiding the shaft while extending + // // should we delete the block model assets as well? + // public final @NotNull StaticBlockModel[] half; + + public BlockModelGenericPistonHead( + @NotNull Block block, + @NotNull BlockModelData piston, @NotNull BlockModelData sticky, @NotNull BlockModelData steel, + // @NotNull BlockModelData pistonHalf, @NotNull BlockModelData stickyHalf, @NotNull BlockModelData steelHalf, + @NotNull BlockModelData pistonShort, @NotNull BlockModelData stickyShort, @NotNull BlockModelData steelShort + ) { super(block, piston); - this.sticky = sticky.asModel(); - this.steel = steel.asModel(); - this.baseHalf = pistonHalf.asModel(); - this.stickyHalf = stickyHalf.asModel(); - this.steelHalf = steelHalf.asModel(); + this.normal = new StaticBlockModel[] { piston.asModel(), sticky.asModel(), steel.asModel() }; + // this.half = new StaticBlockModel[] { pistonHalf.asModel(), stickyHalf.asModel(), steelHalf.asModel() }; + this.schort = new StaticBlockModel[] { pistonShort.asModel(), stickyShort.asModel(), steelShort.asModel() }; } + public void renderPistonHeadNoCulling(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, int meta, @NotNull TilePos tilePos, boolean flag) { - var model = switch (BlockLogicPistonHead.getPistonType(meta)) { - case BlockLogicPistonHead.TYPE_STICKY -> flag ? this.sticky : this.stickyHalf; - case BlockLogicPistonHead.TYPE_STEEL -> flag ? this.steel : this.steelHalf; - default -> flag ? this.staticModel : this.baseHalf; - }; - final Direction dir = BlockLogicVeryRotatable.metaToDirection(worldSource.getBlockData(tilePos)); + final var type = PistonCommon.TYPE.get(meta); + final var model = (flag) ? normal[type] : schort[type]; + + final var dir = Direction.fromId(PistonCommon.DIRECTION.get(meta)); + final int rx, ry, rz; switch (dir) { - case UP -> { - model.renderAttached(this, tessellator, worldSource, tilePos, 1, 0, 0, 0, 0, 0, false, false, null); - } - case DOWN -> { - model.renderAttached(this, tessellator, worldSource, tilePos, -1, 0, 0, 0, 0, 0, false, false, null); - } - case NORTH -> { - model.renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, false, null); - } - case SOUTH -> { - model.renderAttached(this, tessellator, worldSource, tilePos, 0, 2, 0, 0, 0, 0, false, false, null); - } - case WEST -> { - model.renderAttached(this, tessellator, worldSource, tilePos, 0, 1, 0, 0, 0, 0, false, false, null); - } - case EAST -> { - model.renderAttached(this, tessellator, worldSource, tilePos, 0, 3, 0, 0, 0, 0, false, false, null); - } + case UP -> { rx = 1; ry = 0; rz = 0; } + case DOWN -> { rx = -1; ry = 0; rz = 0; } + case NORTH -> { rx = 0; ry = 0; rz = 0; } + case SOUTH -> { rx = 0; ry = 2; rz = 0; } + case WEST -> { rx = 0; ry = 1; rz = 0; } + case EAST -> { rx = 0; ry = 3; rz = 0; } + default -> { return; } } - } + model.renderAttached(this, tessellator, worldSource, tilePos, rx, ry, rz, 0, 0, 0, false, false, null); + } @Override public @NotNull StaticBlockModel getModelFromData(int data) { - return switch (BlockLogicPistonHead.getPistonType(data)) { - case BlockLogicPistonHead.TYPE_STICKY -> this.sticky; - case BlockLogicPistonHead.TYPE_STEEL -> this.steel; - default -> this.staticModel; - }; + int type = PistonCommon.TYPE.get(data); + if (type >= 3) type = 0; + return PistonCommon.IS_DETACHED.bool(data) + ? schort[type] + : normal[type]; } } diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericRope.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericRope.java index 86d6f3407..44b83b468 100644 --- a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericRope.java +++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericRope.java @@ -27,8 +27,7 @@ public class BlockModelGenericRope extends BlockModelGener @Override public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) { - Block below = worldSource.getBlockType(tilePos.down(new TilePos())); - boolean hasFloor = below != null && below.canPlaceOnSurface(); + boolean hasFloor = worldSource.isBlockOpaqueCube(tilePos.down(new TilePos())); boolean hasBlockNegX = canConnect(worldSource, tilePos, Direction.WEST); boolean hasBlockPosX = canConnect(worldSource, tilePos, Direction.EAST); boolean hasBlockNegY = canConnect(worldSource, tilePos, Direction.DOWN) || hasFloor; diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericTimer.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericTimer.java new file mode 100644 index 000000000..c063da90f --- /dev/null +++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericTimer.java @@ -0,0 +1,38 @@ +package net.minecraft.client.render.block.model.generic; + +import net.minecraft.client.render.block.model.BlockModelDispatcher; +import net.minecraft.client.render.tessellator.TessellatorGeneral; +import net.minecraft.client.render.texture.stitcher.IconCoordinate; +import net.minecraft.core.block.Block; +import net.minecraft.core.block.BlockLogicRepeater; +import net.minecraft.core.block.BlockLogicTimer; +import net.minecraft.core.world.WorldSource; +import net.minecraft.core.world.pos.TilePosc; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.useless.dragonfly.models.block.StaticBlockModel; + +public class BlockModelGenericTimer extends BlockModelGeneric { + public final @NotNull StaticBlockModel[] modelsA = new StaticBlockModel[4]; + public final @NotNull StaticBlockModel[] modelsB = new StaticBlockModel[4]; + public BlockModelGenericTimer(@NotNull Block block) { + super(block, BlockModelDispatcher.loadDataModel("minecraft:block/timer/0_a")); + for (int i = 0; i < 4; i++) { + this.modelsA[i] = BlockModelDispatcher.loadDataModel("minecraft:block/timer/" + i + "_a").asModel(); + this.modelsB[i] = BlockModelDispatcher.loadDataModel("minecraft:block/timer/" + i + "_b").asModel(); + } + } + + @Override + public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) { + final int meta = worldSource.getBlockData(tilePos); + final int axis = meta & BlockLogicTimer.MASK_AXIS; + final int output = meta & BlockLogicTimer.MASK_OUTPUT; + final int tickDelay = meta & BlockLogicTimer.MASK_TICK_DELAY; + + final @NotNull StaticBlockModel[] modelSet = (output == BlockLogicTimer.OUTPUT_A) ? this.modelsB : this.modelsA; + final int rotY = axis == BlockLogicTimer.AXIS_WEST_EAST ? 0 : 1; + + return (modelSet[tickDelay >> 2]).renderAttached(this, tessellator, worldSource, tilePos, 0, rotY, 0, 0, 0, 0, false, cullFaces, overrideTexture); + } +} diff --git a/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelDispatcher.java b/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelDispatcher.java index 0621b6019..a7c79b435 100644 --- a/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelDispatcher.java +++ b/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelDispatcher.java @@ -287,6 +287,8 @@ public class ItemModelDispatcher extends Dispatcher { addDispatch(new ItemModelMap(Items.MAP, "minecraft")); addDispatch(new ItemModelStandard(Items.TOOL_SHEARS, "minecraft")); + addDispatch(new ItemModelStandard(Items.TIMER, "minecraft")); + addDispatch(new ItemModelStandard(Items.NETHERCOAL, "minecraft").setFullBright()); addDispatch(new ItemModelStandard(Items.ARMOR_HELMET_STEEL, "minecraft")); diff --git a/game/client/src/main/java/net/minecraft/client/render/particle/Particle.java b/game/client/src/main/java/net/minecraft/client/render/particle/Particle.java index cf6ec065b..66f7294e6 100644 --- a/game/client/src/main/java/net/minecraft/client/render/particle/Particle.java +++ b/game/client/src/main/java/net/minecraft/client/render/particle/Particle.java @@ -150,7 +150,7 @@ public class Particle { switch (hitTile.side) { case EAST: case WEST: { - this.x = hitTile.location.x() + hitTile.side.getOffsetX() * 0.1d * this.size; + this.x = hitTile.location.x() + hitTile.side.offsetX() * 0.1d * this.size; this.y += yd; this.z += zd; this.xd = 0; @@ -160,7 +160,7 @@ public class Particle { this.onGround = true; case BOTTOM: { this.x += xd; - this.y = hitTile.location.y() + hitTile.side.getOffsetY() * 0.1d * this.size; + this.y = hitTile.location.y() + hitTile.side.offsetY() * 0.1d * this.size; this.z += zd; this.yd = 0; break; @@ -169,7 +169,7 @@ public class Particle { case NORTH: { this.x += xd; this.y += yd; - this.z = hitTile.location.z() + hitTile.side.getOffsetZ() * 0.1d * this.size; + this.z = hitTile.location.z() + hitTile.side.offsetZ() * 0.1d * this.size; this.zd = 0; break; } @@ -240,7 +240,7 @@ public class Particle { if (tMin < maxT) { return new HitResult.Tile( tilePos, - direction.getSide(), + direction.side(), new Vector3d(ray.oX + tMin * ray.dX, ray.oY + tMin * ray.dY, ray.oZ + tMin * ray.dZ)); } } diff --git a/game/client/src/main/java/net/minecraft/client/render/particle/ParticleDispatcher.java b/game/client/src/main/java/net/minecraft/client/render/particle/ParticleDispatcher.java index d67c0d5ca..d1a1dbea5 100644 --- a/game/client/src/main/java/net/minecraft/client/render/particle/ParticleDispatcher.java +++ b/game/client/src/main/java/net/minecraft/client/render/particle/ParticleDispatcher.java @@ -253,7 +253,7 @@ public final class ParticleDispatcher extends Dispatcher public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) { float pitch = 0; float yaw = 0; - switch (Direction.getDirectionById(data)) { + switch (Direction.fromId(data)) { case DOWN -> { pitch = 0.0f; yaw = 0.0f; diff --git a/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMovingPiston.java b/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMovingPiston.java index 496689bb9..c5b41a1ba 100644 --- a/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMovingPiston.java +++ b/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMovingPiston.java @@ -15,7 +15,6 @@ import net.minecraft.client.render.tessellator.TessellatorGeneral; import net.minecraft.core.block.Block; import net.minecraft.core.block.Blocks; import net.minecraft.core.block.entity.TileEntity; -import net.minecraft.core.block.piston.BlockLogicPistonBaseSteel; import net.minecraft.core.block.piston.BlockLogicPistonHead; import net.minecraft.core.block.piston.TileEntityMovingPistonBlock; import net.minecraft.core.world.BlocksContainer; @@ -33,8 +32,8 @@ public class TileEntityRendererMovingPiston extends TileEntityRenderer block = tileEntity.getMovedBlock(); - if (tileEntity.getProgress(partialTick) < 1.0F) { + Block block = tileEntity.movingBlock(); + if (tileEntity.progress(partialTick) < 1.0F) { if (this.container == null || this.container.world != tileEntity.worldObj) { this.container = new BlocksContainer(tileEntity.worldObj); } @@ -45,20 +44,18 @@ public class TileEntityRendererMovingPiston extends TileEntityRenderer) BlockModelDispatcher.getInstance().getDispatch(block)).renderPistonHeadNoCulling(tessellator, tileEntity.worldObj, tileEntity.getBlockMeta(), tileEntPos, false); } else if (tileEntity.isSourcePiston() && !tileEntity.isExtending()) { - BlockModelGenericPiston pistonBase = (BlockModelGenericPiston) BlockModelDispatcher.getInstance().getDispatch(block); - if (Block.hasLogicClass(block, BlockLogicPistonBaseSteel.class)) { // Todo remove this terrible hardcoded render code - ((BlockModelGenericPistonHead) BlockModelDispatcher.getInstance().getDispatch(Blocks.PISTON_HEAD_STEEL)).renderPistonHeadNoCulling(tessellator, tileEntity.worldObj, BlockLogicPistonHead.TYPE_STEEL << 3, tileEntPos, tileEntity.getProgress(partialTick) < 0.5F); - } else { - ((BlockModelGenericPistonHead) BlockModelDispatcher.getInstance().getDispatch(Blocks.PISTON_HEAD)).renderPistonHeadNoCulling(tessellator, tileEntity.worldObj, tileEntity.getBlockMeta(), tileEntPos, tileEntity.getProgress(partialTick) < 0.5F); - } + ((BlockModelGenericPistonHead) BlockModelDispatcher.getInstance().getDispatch(Blocks.PISTON_HEAD)).renderPistonHeadNoCulling(tessellator, tileEntity.worldObj, tileEntity.getBlockMeta(), tileEntPos, tileEntity.progress(partialTick) < 0.5F); tessellator.setTranslation((float) x - (float) tileEntity.tilePos.x, (float) y - (float) tileEntity.tilePos.y, (float) z - (float) tileEntity.tilePos.z); - pistonBase.renderHeadless(tessellator, tileEntity.worldObj, tileEntPos); + ((BlockModelGenericPiston) BlockModelDispatcher.getInstance().getDispatch(block)).renderHeadless(tessellator, tileEntity.worldObj, tileEntPos); } else { - this.container.setBlock(tileEntity.tilePos.x, tileEntity.tilePos.y, tileEntity.tilePos.z, block.id(), tileEntity.getMovedData(), tileEntity.getMovedEntity()); + this.container.setBlockTypeData(tileEntity.tilePos, block, tileEntity.movingBlockData()); + if (tileEntity.movingTileEntity() != null) { + this.container.setTileEntity(tileEntity.tilePos, tileEntity.movingTileEntity()); + } BlockModelDispatcher.getInstance().getDispatch(block).renderNoCulling(tessellator, this.container, tileEntPos); this.container.setLightReferenceEntity(null); this.container.clear(); @@ -66,11 +63,11 @@ public class TileEntityRendererMovingPiston extends TileEntityRenderer renderer = TileEntityRenderDispatcher.instance.getRenderer(movedEntity); if (renderer != null) { GLRenderer.pushFrame(); - GLRenderer.modelM4f().translate(tileEntity.getXOff(partialTick), tileEntity.getYOff(partialTick), tileEntity.getZOff(partialTick)); + GLRenderer.modelM4f().translate(tileEntity.xOffset(partialTick), tileEntity.yOffset(partialTick), tileEntity.zOffset(partialTick)); renderer.doRender(tessellator, movedEntity, x, y, z, partialTick); GLRenderer.popFrame(); } diff --git a/game/client/src/main/java/org/useless/dragonfly/data/block/mojang/CompiledBlockModelMojangData.java b/game/client/src/main/java/org/useless/dragonfly/data/block/mojang/CompiledBlockModelMojangData.java index 2120bd1c3..e48dcc3c2 100644 --- a/game/client/src/main/java/org/useless/dragonfly/data/block/mojang/CompiledBlockModelMojangData.java +++ b/game/client/src/main/java/org/useless/dragonfly/data/block/mojang/CompiledBlockModelMojangData.java @@ -80,12 +80,12 @@ public class CompiledBlockModelMojangData { this.particleIndices = new int[6]; if (data.particleIndices != null) { - this.particleIndices[Direction.UP.getId()] = data.particleIndices.getOrDefault(Direction.UP, 0); - this.particleIndices[Direction.DOWN.getId()] = data.particleIndices.getOrDefault(Direction.DOWN, 0); - this.particleIndices[Direction.NORTH.getId()] = data.particleIndices.getOrDefault(Direction.NORTH, 0); - this.particleIndices[Direction.SOUTH.getId()] = data.particleIndices.getOrDefault(Direction.SOUTH, 0); - this.particleIndices[Direction.WEST.getId()] = data.particleIndices.getOrDefault(Direction.WEST, 0); - this.particleIndices[Direction.EAST.getId()] = data.particleIndices.getOrDefault(Direction.EAST, 0); + this.particleIndices[Direction.UP.id] = data.particleIndices.getOrDefault(Direction.UP, 0); + this.particleIndices[Direction.DOWN.id] = data.particleIndices.getOrDefault(Direction.DOWN, 0); + this.particleIndices[Direction.NORTH.id] = data.particleIndices.getOrDefault(Direction.NORTH, 0); + this.particleIndices[Direction.SOUTH.id] = data.particleIndices.getOrDefault(Direction.SOUTH, 0); + this.particleIndices[Direction.WEST.id] = data.particleIndices.getOrDefault(Direction.WEST, 0); + this.particleIndices[Direction.EAST.id] = data.particleIndices.getOrDefault(Direction.EAST, 0); } this.renderLayer = data.renderLayer == null ? 0 : data.renderLayer; diff --git a/game/client/src/main/java/org/useless/dragonfly/data/entity/mojang/Cube.java b/game/client/src/main/java/org/useless/dragonfly/data/entity/mojang/Cube.java index 813b609a0..2463611a9 100644 --- a/game/client/src/main/java/org/useless/dragonfly/data/entity/mojang/Cube.java +++ b/game/client/src/main/java/org/useless/dragonfly/data/entity/mojang/Cube.java @@ -75,17 +75,17 @@ public class Cube { final double sizeX = this.size[0]; final double sizeY = this.size[1]; final double sizeZ = this.size[2]; - this.faces[Direction.UP.getId()] = new Face.Builder(u + sizeZ, v, sizeX, sizeZ); - this.faces[Direction.DOWN.getId()] = new Face.Builder(u + sizeX + sizeZ, v + sizeZ, sizeX, -sizeZ); - this.faces[Direction.NORTH.getId()] = new Face.Builder(u + sizeZ, v + sizeZ, sizeX, sizeY); - this.faces[Direction.SOUTH.getId()] = new Face.Builder(u + (sizeZ * 2) + sizeX, v + sizeZ, sizeX, sizeY); - this.faces[Direction.EAST.getId()] = new Face.Builder(u, v + sizeZ, sizeZ, sizeY); - this.faces[Direction.WEST.getId()] = new Face.Builder(u + sizeZ + sizeX, v + sizeZ, sizeZ, sizeY); + this.faces[Direction.UP.id] = new Face.Builder(u + sizeZ, v, sizeX, sizeZ); + this.faces[Direction.DOWN.id] = new Face.Builder(u + sizeX + sizeZ, v + sizeZ, sizeX, -sizeZ); + this.faces[Direction.NORTH.id] = new Face.Builder(u + sizeZ, v + sizeZ, sizeX, sizeY); + this.faces[Direction.SOUTH.id] = new Face.Builder(u + (sizeZ * 2) + sizeX, v + sizeZ, sizeX, sizeY); + this.faces[Direction.EAST.id] = new Face.Builder(u, v + sizeZ, sizeZ, sizeY); + this.faces[Direction.WEST.id] = new Face.Builder(u + sizeZ + sizeX, v + sizeZ, sizeZ, sizeY); return this; } public @NotNull Builder setFace(final @NotNull Direction direction, final @Nullable Face.Builder builder) { - this.faces[direction.getId()] = builder; + this.faces[direction.id] = builder; return this; } @@ -111,9 +111,9 @@ public class Cube { } protected void mirror() { - final Face.Builder west = this.faces[Direction.WEST.getId()]; - this.faces[Direction.WEST.getId()] = this.faces[Direction.EAST.getId()]; - this.faces[Direction.EAST.getId()] = west; + final Face.Builder west = this.faces[Direction.WEST.id]; + this.faces[Direction.WEST.id] = this.faces[Direction.EAST.id]; + this.faces[Direction.EAST.id] = west; for (final Face.Builder builder : this.faces) { if (builder == null) continue; builder.setMirror(); diff --git a/game/client/src/main/java/org/useless/dragonfly/models/block/mojang/StaticBlockModelMojang.java b/game/client/src/main/java/org/useless/dragonfly/models/block/mojang/StaticBlockModelMojang.java index 0b7b5cb8e..78971b1c4 100644 --- a/game/client/src/main/java/org/useless/dragonfly/models/block/mojang/StaticBlockModelMojang.java +++ b/game/client/src/main/java/org/useless/dragonfly/models/block/mojang/StaticBlockModelMojang.java @@ -104,17 +104,17 @@ public class StaticBlockModelMojang implements StaticBlockModel { for (int face = 0; face < element.faces; face++) { Direction cullDir = element.cullfaces[face]; if (cullFaces && cullDir != null) { - cullDir = Direction.rotateZ(Direction.rotateY(Direction.rotateX(cullDir, rotX), rotY), rotZ); - if ((cullCache & (1 << cullDir.getId())) != 0) { + cullDir = cullDir.rotateX(rotX).rotateY(rotY).rotateZ(rotZ); + if ((cullCache & (1 << cullDir.id)) != 0) { continue; } if (sourceModel.cullSide(worldSource, blockPos, cullDir)) { - cullCache |= (byte) (1 << cullDir.getId()); + cullCache |= (byte) (1 << cullDir.id); continue; } } final IconCoordinate coordinate = overrideTexture == null ? element.textures[face] : overrideTexture; - Direction direction = Direction.rotateZ(Direction.rotateY(Direction.rotateX(element.directions[face], rotX), rotY), rotZ); + Direction direction = element.directions[face].rotateX(rotX).rotateY(rotY).rotateZ(rotZ); final float minBrightness = element.lightEmission / 15f; @@ -252,9 +252,9 @@ public class StaticBlockModelMojang implements StaticBlockModel { b = 1; } - final int dirX = element.flip ? -direction.getOffsetX() : direction.getOffsetX(); - final int dirY = element.flip ? -direction.getOffsetY() : direction.getOffsetY(); - final int dirZ = element.flip ? -direction.getOffsetZ() : direction.getOffsetZ(); + final int dirX = element.flip ? -direction.offsetX() : direction.offsetX(); + final int dirY = element.flip ? -direction.offsetY() : direction.offsetY(); + final int dirZ = element.flip ? -direction.offsetZ() : direction.offsetZ(); final byte lightIndexTopLeft; final byte lightIndexBottomLeft; @@ -489,7 +489,7 @@ public class StaticBlockModelMojang implements StaticBlockModel { float v = uvs.y() - 0.5f; rotX = (rotX & 0b11); while (rotX > 0) { - if (dir.getAxis() == Axis.X) { + if (dir.axis() == Axis.X) { if (dir == Direction.WEST) { float _u = u; u = -v; @@ -505,13 +505,13 @@ public class StaticBlockModelMojang implements StaticBlockModel { u = -u; } } - dir = Direction.rotateX(dir, 1); + dir = dir.rotateX(1); rotX--; } rotY = (rotY & 0b11); while (rotY > 0) { - if (dir.getAxis() == Axis.Y) { + if (dir.axis() == Axis.Y) { if (dir == Direction.DOWN) { float _v = v; v = u; @@ -522,13 +522,13 @@ public class StaticBlockModelMojang implements StaticBlockModel { v = -_u; } } - dir = Direction.rotateY(dir, 1); + dir = dir.rotateY(1); rotY--; } rotZ = (rotZ & 0b11); while (rotZ > 0) { - if (dir.getAxis() == Axis.Z) { + if (dir.axis() == Axis.Z) { if (dir == Direction.NORTH) { float _u = u; u = -v; @@ -545,7 +545,7 @@ public class StaticBlockModelMojang implements StaticBlockModel { u = _v; } } - dir = Direction.rotateZ(dir, 1); + dir = dir.rotateZ(1); rotZ--; } @@ -560,12 +560,12 @@ public class StaticBlockModelMojang implements StaticBlockModel { @Override public @Nullable IconCoordinate getParticle(@NotNull Side side) { - return this.compiled.textures.get("#particle_" + side.getDirection().name().toLowerCase(Locale.ROOT)); + return this.compiled.textures.get("#particle_" + side.direction().name().toLowerCase(Locale.ROOT)); } @Override public int particleColorIndex(@NotNull Side side) { - return this.compiled.particleIndices[side.getId()]; + return this.compiled.particleIndices[side.id]; } @Override diff --git a/game/client/src/main/java/org/useless/dragonfly/models/entity/mojang/StaticEntityModelMojang.java b/game/client/src/main/java/org/useless/dragonfly/models/entity/mojang/StaticEntityModelMojang.java index 70c8bc788..59187d286 100644 --- a/game/client/src/main/java/org/useless/dragonfly/models/entity/mojang/StaticEntityModelMojang.java +++ b/game/client/src/main/java/org/useless/dragonfly/models/entity/mojang/StaticEntityModelMojang.java @@ -174,7 +174,7 @@ public class StaticEntityModelMojang implements StaticEntityModel { final double maxZ = minZ + cube.size[2] + (cube.inflate + bone.inflate + this.inflation) * 2; // Top - Face face = cube.faces[Direction.UP.getId()]; + Face face = cube.faces[Direction.UP.id]; if (face != null) { final double uMin = (face.uv[0]) / this.data.textureWidth; final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth; @@ -200,7 +200,7 @@ public class StaticEntityModelMojang implements StaticEntityModel { } // Bottom - face = cube.faces[Direction.DOWN.getId()]; + face = cube.faces[Direction.DOWN.id]; if (face != null) { final double uMin = (face.uv[0]) / this.data.textureWidth; final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth; @@ -225,7 +225,7 @@ public class StaticEntityModelMojang implements StaticEntityModel { } // Front - face = cube.faces[Direction.NORTH.getId()]; + face = cube.faces[Direction.NORTH.id]; if (face != null) { final double uMin = (face.uv[0]) / this.data.textureWidth; final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth; @@ -250,7 +250,7 @@ public class StaticEntityModelMojang implements StaticEntityModel { } // Back - face = cube.faces[Direction.SOUTH.getId()]; + face = cube.faces[Direction.SOUTH.id]; if (face != null) { final double uMin = (face.uv[0]) / this.data.textureWidth; final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth; @@ -275,7 +275,7 @@ public class StaticEntityModelMojang implements StaticEntityModel { } // Right - face = cube.faces[Direction.WEST.getId()]; + face = cube.faces[Direction.WEST.id]; if (face != null) { final double uMin = (face.uv[0]) / this.data.textureWidth; final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth; @@ -300,7 +300,7 @@ public class StaticEntityModelMojang implements StaticEntityModel { } // Left - face = cube.faces[Direction.EAST.getId()]; + face = cube.faces[Direction.EAST.id]; if (face != null) { final double uMin = (face.uv[0]) / this.data.textureWidth; final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth; diff --git a/game/client/src/main/resources/assets/minecraft/models/block/piston/head.json b/game/client/src/main/resources/assets/minecraft/models/block/piston/head.json index b1107d71b..f866f84d0 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/piston/head.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/piston/head.json @@ -20,7 +20,7 @@ "faces": { "north": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "north"}, "east": {"uv": [0, 0, 16, 4], "rotation": 90, "texture": "#head"}, - "south": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "south"}, + "south": {"uv": [0, 0, 16, 16], "texture": "#face"}, "west": {"uv": [0, 0, 16, 4], "rotation": 270, "texture": "#head", "cullface": "west"}, "up": {"uv": [0, 0, 16, 4], "texture": "#head", "cullface": "up"}, "down": {"uv": [0, 0, 16, 4], "rotation": 180, "texture": "#head", "cullface": "down"} diff --git a/game/client/src/main/resources/assets/minecraft/models/block/piston/head_half.json b/game/client/src/main/resources/assets/minecraft/models/block/piston/head_half.json index e638ca51f..e41f71cc2 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/piston/head_half.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/piston/head_half.json @@ -20,7 +20,7 @@ "faces": { "north": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "north"}, "east": {"uv": [0, 0, 16, 4], "rotation": 90, "texture": "#head"}, - "south": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "south"}, + "south": {"uv": [0, 0, 16, 16], "texture": "#face"}, "west": {"uv": [0, 0, 16, 4], "rotation": 270, "texture": "#head", "cullface": "west"}, "up": {"uv": [0, 0, 16, 4], "texture": "#head", "cullface": "up"}, "down": {"uv": [0, 0, 16, 4], "rotation": 180, "texture": "#head", "cullface": "down"} diff --git a/game/client/src/main/resources/assets/minecraft/models/block/piston/head_short.json b/game/client/src/main/resources/assets/minecraft/models/block/piston/head_short.json new file mode 100644 index 000000000..0681ef1dc --- /dev/null +++ b/game/client/src/main/resources/assets/minecraft/models/block/piston/head_short.json @@ -0,0 +1,43 @@ +{ + "format_version": "1.21.6", + "credit": "Made with Blockbench", + "textures": { + "face": "block/piston/face", + "head": "block/piston/head", + "shaft": "block/piston/shaft", + "shaft_end": "block/piston/shaft_end", + "overlay": "#face", + "particle_up": "#head", + "particle_down": "#head", + "particle_north": "#face", + "particle_south": "#face", + "particle_west": "#head", + "particle_east": "#head" + }, + "elements": [ + { + "from": [0, 0, 0], + "to": [16, 16, 4], + "faces": { + "north": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "north"}, + "east": {"uv": [0, 0, 16, 4], "rotation": 90, "texture": "#head"}, + "south": {"uv": [0, 0, 16, 16], "texture": "#face"}, + "west": {"uv": [0, 0, 16, 4], "rotation": 270, "texture": "#head", "cullface": "west"}, + "up": {"uv": [0, 0, 16, 4], "texture": "#head", "cullface": "up"}, + "down": {"uv": [0, 0, 16, 4], "rotation": 180, "texture": "#head", "cullface": "down"} + } + }, + { + "from": [6, 6, 4], + "to": [10, 10, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [6, 6, 6]}, + "faces": { + "east": {"uv": [6, 0, 10, 12], "rotation": 90, "texture": "#shaft"}, + "west": {"uv": [10, 4, 6, 16], "rotation": 90, "texture": "#shaft"}, + "up": {"uv": [6, 0, 10, 12], "texture": "#shaft"}, + "down": {"uv": [10, 4, 6, 16], "texture": "#shaft"}, + "south": {"uv": [6, 6, 10, 10], "texture": "#shaft_end"} + } + } + ] +} \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/head.json b/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/head.json index 1678b1f46..3e703ebfa 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/head.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/head.json @@ -20,7 +20,7 @@ "faces": { "north": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "north"}, "east": {"uv": [0, 0, 16, 6], "rotation": 90, "texture": "#head"}, - "south": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "south"}, + "south": {"uv": [0, 0, 16, 16], "texture": "#face"}, "west": {"uv": [0, 0, 16, 6], "rotation": 270, "texture": "#head", "cullface": "west"}, "up": {"uv": [0, 0, 16, 6], "texture": "#head", "cullface": "up"}, "down": {"uv": [0, 0, 16, 6], "rotation": 180, "texture": "#head", "cullface": "down"} diff --git a/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/head_half.json b/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/head_half.json index bf91915d6..702cd8bbc 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/head_half.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/head_half.json @@ -20,7 +20,7 @@ "faces": { "north": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "north"}, "east": {"uv": [0, 0, 16, 6], "rotation": 90, "texture": "#head"}, - "south": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "south"}, + "south": {"uv": [0, 0, 16, 16], "texture": "#face"}, "west": {"uv": [0, 0, 16, 6], "rotation": 270, "texture": "#head", "cullface": "west"}, "up": {"uv": [0, 0, 16, 6], "texture": "#head", "cullface": "up"}, "down": {"uv": [0, 0, 16, 6], "rotation": 180, "texture": "#head", "cullface": "down"} diff --git a/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/head_short.json b/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/head_short.json new file mode 100644 index 000000000..4da8264d4 --- /dev/null +++ b/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/head_short.json @@ -0,0 +1,42 @@ +{ + "format_version": "1.21.6", + "credit": "Made with Blockbench", + "textures": { + "face": "block/piston_steel/face", + "head": "block/piston_steel/head", + "shaft": "block/piston_steel/shaft", + "overlay": "#face", + "particle_up": "#head", + "particle_down": "#head", + "particle_north": "#face", + "particle_south": "#face", + "particle_west": "#head", + "particle_east": "#head" + }, + "elements": [ + { + "from": [0, 0, 0], + "to": [16, 16, 6], + "faces": { + "north": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "north"}, + "east": {"uv": [0, 0, 16, 6], "rotation": 90, "texture": "#head"}, + "south": {"uv": [0, 0, 16, 16], "texture": "#face"}, + "west": {"uv": [0, 0, 16, 6], "rotation": 270, "texture": "#head", "cullface": "west"}, + "up": {"uv": [0, 0, 16, 6], "texture": "#head", "cullface": "up"}, + "down": {"uv": [0, 0, 16, 6], "rotation": 180, "texture": "#head", "cullface": "down"} + } + }, + { + "from": [4, 4, 6], + "to": [12, 12, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [6, 6, 6]}, + "faces": { + "east": {"uv": [4, 0, 12, 12], "rotation": 90, "texture": "#shaft"}, + "west": {"uv": [12, 4, 4, 16], "rotation": 90, "texture": "#shaft"}, + "up": {"uv": [4, 0, 12, 12], "texture": "#shaft"}, + "down": {"uv": [12, 4, 4, 16], "texture": "#shaft"}, + "south": {"uv": [4, 4, 12, 12], "texture": "#shaft"} + } + } + ] +} \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/head.json b/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/head.json index 425d0cabe..f93b104ad 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/head.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/head.json @@ -21,7 +21,7 @@ "faces": { "north": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "north"}, "east": {"uv": [0, 0, 16, 4], "rotation": 90, "texture": "#head"}, - "south": {"uv": [0, 0, 16, 16], "texture": "#back", "cullface": "south"}, + "south": {"uv": [0, 0, 16, 16], "texture": "#back"}, "west": {"uv": [0, 0, 16, 4], "rotation": 270, "texture": "#head", "cullface": "west"}, "up": {"uv": [0, 0, 16, 4], "texture": "#head", "cullface": "up"}, "down": {"uv": [0, 0, 16, 4], "rotation": 180, "texture": "#head", "cullface": "down"} diff --git a/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/head_half.json b/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/head_half.json index fe345b6c1..c7a3c402c 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/head_half.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/head_half.json @@ -21,7 +21,7 @@ "faces": { "north": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "north"}, "east": {"uv": [0, 0, 16, 4], "rotation": 90, "texture": "#head"}, - "south": {"uv": [0, 0, 16, 16], "texture": "#back", "cullface": "south"}, + "south": {"uv": [0, 0, 16, 16], "texture": "#back"}, "west": {"uv": [0, 0, 16, 4], "rotation": 270, "texture": "#head", "cullface": "west"}, "up": {"uv": [0, 0, 16, 4], "texture": "#head", "cullface": "up"}, "down": {"uv": [0, 0, 16, 4], "rotation": 180, "texture": "#head", "cullface": "down"} diff --git a/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/head_short.json b/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/head_short.json new file mode 100644 index 000000000..5c43f0a00 --- /dev/null +++ b/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/head_short.json @@ -0,0 +1,44 @@ +{ + "format_version": "1.21.6", + "credit": "Made with Blockbench", + "textures": { + "face": "block/piston_sticky/face", + "back": "block/piston/face", + "head": "block/piston/head", + "shaft": "block/piston/shaft", + "shaft_end": "block/piston/shaft_end", + "overlay": "#face", + "particle_up": "#head", + "particle_down": "#head", + "particle_north": "#face", + "particle_south": "#back", + "particle_west": "#head", + "particle_east": "#head" + }, + "elements": [ + { + "from": [0, 0, 0], + "to": [16, 16, 4], + "faces": { + "north": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "north"}, + "east": {"uv": [0, 0, 16, 4], "rotation": 90, "texture": "#head"}, + "south": {"uv": [0, 0, 16, 16], "texture": "#back"}, + "west": {"uv": [0, 0, 16, 4], "rotation": 270, "texture": "#head", "cullface": "west"}, + "up": {"uv": [0, 0, 16, 4], "texture": "#head", "cullface": "up"}, + "down": {"uv": [0, 0, 16, 4], "rotation": 180, "texture": "#head", "cullface": "down"} + } + }, + { + "from": [6, 6, 4], + "to": [10, 10, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [6, 6, 6]}, + "faces": { + "east": {"uv": [6, 0, 10, 12], "rotation": 90, "texture": "#shaft"}, + "west": {"uv": [10, 4, 6, 16], "rotation": 90, "texture": "#shaft"}, + "up": {"uv": [6, 0, 10, 12], "texture": "#shaft"}, + "down": {"uv": [10, 4, 6, 16], "texture": "#shaft"}, + "south": {"uv": [6, 6, 10, 10], "texture": "#shaft_end"} + } + } + ] +} \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/timer/0_a.json b/game/client/src/main/resources/assets/minecraft/models/block/timer/0_a.json new file mode 100644 index 000000000..8f50b81d0 --- /dev/null +++ b/game/client/src/main/resources/assets/minecraft/models/block/timer/0_a.json @@ -0,0 +1,60 @@ +{ + "ambientocclusion": false, + "textures": { + "slab": "minecraft:block/polished_stone_top", + "top": "minecraft:block/timer/top_a", + "unlit": "minecraft:block/torch_redstone_idle", + "lit": "minecraft:block/torch_redstone_active", + "overlay": "#top", + "particle_up": "#top", + "particle_down": "#slab", + "particle_north": "#slab", + "particle_south": "#slab", + "particle_west": "#slab", + "particle_east": "#slab" + }, + "elements": [ + { "from": [ 0, 0, 0 ], + "to": [ 16, 2, 16 ], + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#slab", "cullface": "down" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" }, + "north": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "north" }, + "south": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "south" }, + "west": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "west" }, + "east": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "east" } + } + }, + { "from": [ 10, 2, 7 ], + "to": [ 12, 7, 9 ], + "faces": { + "down": { "uv": [ 7, 13, 9, 15 ], "texture": "#unlit" }, + "up": { "uv": [ 7, 6, 9, 8 ], "texture": "#unlit" }, + "north": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "south": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "west": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "east": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" } + } + }, + { "from": [ 4, 7, 7 ], + "to": [ 6, 7, 9 ], + "faces": { + "up": { "uv": [ 7, 6, 9, 8 ], "texture": "#lit" } + } + }, + { "from": [ 4, 2, 6 ], + "to": [ 6, 8, 10 ], + "faces": { + "west": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }, + "east": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" } + } + }, + { "from": [ 3, 2, 7 ], + "to": [ 7, 8, 9 ], + "faces": { + "north": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }, + "south": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" } + } + } + ] +} diff --git a/game/client/src/main/resources/assets/minecraft/models/block/timer/0_b.json b/game/client/src/main/resources/assets/minecraft/models/block/timer/0_b.json new file mode 100644 index 000000000..024ee53a5 --- /dev/null +++ b/game/client/src/main/resources/assets/minecraft/models/block/timer/0_b.json @@ -0,0 +1,60 @@ +{ + "ambientocclusion": false, + "textures": { + "slab": "minecraft:block/polished_stone_top", + "top": "minecraft:block/timer/top_b", + "unlit": "minecraft:block/torch_redstone_idle", + "lit": "minecraft:block/torch_redstone_active", + "overlay": "#top", + "particle_up": "#top", + "particle_down": "#slab", + "particle_north": "#slab", + "particle_south": "#slab", + "particle_west": "#slab", + "particle_east": "#slab" + }, + "elements": [ + { "from": [ 0, 0, 0 ], + "to": [ 16, 2, 16 ], + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#slab", "cullface": "down" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" }, + "north": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "north" }, + "south": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "south" }, + "west": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "west" }, + "east": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "east" } + } + }, + { "from": [ 4, 2, 7 ], + "to": [ 6, 7, 9 ], + "faces": { + "down": { "uv": [ 7, 13, 9, 15 ], "texture": "#unlit" }, + "up": { "uv": [ 7, 6, 9, 8 ], "texture": "#unlit" }, + "north": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "south": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "west": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "east": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" } + } + }, + { "from": [ 10, 7, 7 ], + "to": [ 12, 7, 9 ], + "faces": { + "up": { "uv": [ 7, 6, 9, 8 ], "texture": "#lit" } + } + }, + { "from": [ 10, 2, 6 ], + "to": [ 12, 8, 10 ], + "faces": { + "west": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }, + "east": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" } + } + }, + { "from": [ 9, 2, 7 ], + "to": [ 13, 8, 9 ], + "faces": { + "north": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }, + "south": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" } + } + } + ] +} diff --git a/game/client/src/main/resources/assets/minecraft/models/block/timer/1_a.json b/game/client/src/main/resources/assets/minecraft/models/block/timer/1_a.json new file mode 100644 index 000000000..86efe5839 --- /dev/null +++ b/game/client/src/main/resources/assets/minecraft/models/block/timer/1_a.json @@ -0,0 +1,60 @@ +{ + "ambientocclusion": false, + "textures": { + "slab": "minecraft:block/polished_stone_top", + "top": "minecraft:block/timer/top_a", + "unlit": "minecraft:block/torch_redstone_idle", + "lit": "minecraft:block/torch_redstone_active", + "overlay": "#top", + "particle_up": "#top", + "particle_down": "#slab", + "particle_north": "#slab", + "particle_south": "#slab", + "particle_west": "#slab", + "particle_east": "#slab" + }, + "elements": [ + { "from": [ 0, 0, 0 ], + "to": [ 16, 2, 16 ], + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#slab", "cullface": "down" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" }, + "north": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "north" }, + "south": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "south" }, + "west": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "west" }, + "east": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "east" } + } + }, + { "from": [ 11, 2, 7 ], + "to": [ 13, 7, 9 ], + "faces": { + "down": { "uv": [ 7, 13, 9, 15 ], "texture": "#unlit" }, + "up": { "uv": [ 7, 6, 9, 8 ], "texture": "#unlit" }, + "north": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "south": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "west": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "east": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" } + } + }, + { "from": [ 3, 7, 7 ], + "to": [ 5, 7, 9 ], + "faces": { + "up": { "uv": [ 7, 6, 9, 8 ], "texture": "#lit" } + } + }, + { "from": [ 3, 2, 6 ], + "to": [ 5, 8, 10 ], + "faces": { + "west": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }, + "east": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" } + } + }, + { "from": [ 2, 2, 7 ], + "to": [ 6, 8, 9 ], + "faces": { + "north": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }, + "south": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" } + } + } + ] +} diff --git a/game/client/src/main/resources/assets/minecraft/models/block/timer/1_b.json b/game/client/src/main/resources/assets/minecraft/models/block/timer/1_b.json new file mode 100644 index 000000000..501ad687c --- /dev/null +++ b/game/client/src/main/resources/assets/minecraft/models/block/timer/1_b.json @@ -0,0 +1,60 @@ +{ + "ambientocclusion": false, + "textures": { + "slab": "minecraft:block/polished_stone_top", + "top": "minecraft:block/timer/top_b", + "unlit": "minecraft:block/torch_redstone_idle", + "lit": "minecraft:block/torch_redstone_active", + "overlay": "#top", + "particle_up": "#top", + "particle_down": "#slab", + "particle_north": "#slab", + "particle_south": "#slab", + "particle_west": "#slab", + "particle_east": "#slab" + }, + "elements": [ + { "from": [ 0, 0, 0 ], + "to": [ 16, 2, 16 ], + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#slab", "cullface": "down" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" }, + "north": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "north" }, + "south": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "south" }, + "west": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "west" }, + "east": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "east" } + } + }, + { "from": [ 3, 2, 7 ], + "to": [ 5, 7, 9 ], + "faces": { + "down": { "uv": [ 7, 13, 9, 15 ], "texture": "#unlit" }, + "up": { "uv": [ 7, 6, 9, 8 ], "texture": "#unlit" }, + "north": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "south": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "west": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "east": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" } + } + }, + { "from": [ 11, 7, 7 ], + "to": [ 13, 7, 9 ], + "faces": { + "up": { "uv": [ 7, 6, 9, 8 ], "texture": "#lit" } + } + }, + { "from": [ 11, 2, 6 ], + "to": [ 13, 8, 10 ], + "faces": { + "west": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }, + "east": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" } + } + }, + { "from": [ 10, 2, 7 ], + "to": [ 14, 8, 9 ], + "faces": { + "north": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }, + "south": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" } + } + } + ] +} diff --git a/game/client/src/main/resources/assets/minecraft/models/block/timer/2_a.json b/game/client/src/main/resources/assets/minecraft/models/block/timer/2_a.json new file mode 100644 index 000000000..49d9544c8 --- /dev/null +++ b/game/client/src/main/resources/assets/minecraft/models/block/timer/2_a.json @@ -0,0 +1,60 @@ +{ + "ambientocclusion": false, + "textures": { + "slab": "minecraft:block/polished_stone_top", + "top": "minecraft:block/timer/top_a", + "unlit": "minecraft:block/torch_redstone_idle", + "lit": "minecraft:block/torch_redstone_active", + "overlay": "#top", + "particle_up": "#top", + "particle_down": "#slab", + "particle_north": "#slab", + "particle_south": "#slab", + "particle_west": "#slab", + "particle_east": "#slab" + }, + "elements": [ + { "from": [ 0, 0, 0 ], + "to": [ 16, 2, 16 ], + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#slab", "cullface": "down" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" }, + "north": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "north" }, + "south": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "south" }, + "west": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "west" }, + "east": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "east" } + } + }, + { "from": [ 12, 2, 7 ], + "to": [ 14, 7, 9 ], + "faces": { + "down": { "uv": [ 7, 13, 9, 15 ], "texture": "#unlit" }, + "up": { "uv": [ 7, 6, 9, 8 ], "texture": "#unlit" }, + "north": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "south": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "west": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "east": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" } + } + }, + { "from": [ 2, 7, 7 ], + "to": [ 4, 7, 9 ], + "faces": { + "up": { "uv": [ 7, 6, 9, 8 ], "texture": "#lit" } + } + }, + { "from": [ 2, 2, 6 ], + "to": [ 4, 8, 10 ], + "faces": { + "west": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }, + "east": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" } + } + }, + { "from": [ 1, 2, 7 ], + "to": [ 5, 8, 9 ], + "faces": { + "north": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }, + "south": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" } + } + } + ] +} diff --git a/game/client/src/main/resources/assets/minecraft/models/block/timer/2_b.json b/game/client/src/main/resources/assets/minecraft/models/block/timer/2_b.json new file mode 100644 index 000000000..7954566bc --- /dev/null +++ b/game/client/src/main/resources/assets/minecraft/models/block/timer/2_b.json @@ -0,0 +1,60 @@ +{ + "ambientocclusion": false, + "textures": { + "slab": "minecraft:block/polished_stone_top", + "top": "minecraft:block/timer/top_b", + "unlit": "minecraft:block/torch_redstone_idle", + "lit": "minecraft:block/torch_redstone_active", + "overlay": "#top", + "particle_up": "#top", + "particle_down": "#slab", + "particle_north": "#slab", + "particle_south": "#slab", + "particle_west": "#slab", + "particle_east": "#slab" + }, + "elements": [ + { "from": [ 0, 0, 0 ], + "to": [ 16, 2, 16 ], + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#slab", "cullface": "down" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" }, + "north": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "north" }, + "south": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "south" }, + "west": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "west" }, + "east": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "east" } + } + }, + { "from": [ 2, 2, 7 ], + "to": [ 4, 7, 9 ], + "faces": { + "down": { "uv": [ 7, 13, 9, 15 ], "texture": "#unlit" }, + "up": { "uv": [ 7, 6, 9, 8 ], "texture": "#unlit" }, + "north": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "south": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "west": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "east": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" } + } + }, + { "from": [ 12, 7, 7 ], + "to": [ 14, 7, 9 ], + "faces": { + "up": { "uv": [ 7, 6, 9, 8 ], "texture": "#lit" } + } + }, + { "from": [ 12, 2, 6 ], + "to": [ 14, 8, 10 ], + "faces": { + "west": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }, + "east": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" } + } + }, + { "from": [ 11, 2, 7 ], + "to": [ 15, 8, 9 ], + "faces": { + "north": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }, + "south": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" } + } + } + ] +} diff --git a/game/client/src/main/resources/assets/minecraft/models/block/timer/3_a.json b/game/client/src/main/resources/assets/minecraft/models/block/timer/3_a.json new file mode 100644 index 000000000..b0d493e20 --- /dev/null +++ b/game/client/src/main/resources/assets/minecraft/models/block/timer/3_a.json @@ -0,0 +1,60 @@ +{ + "ambientocclusion": false, + "textures": { + "slab": "minecraft:block/polished_stone_top", + "top": "minecraft:block/timer/top_a", + "unlit": "minecraft:block/torch_redstone_idle", + "lit": "minecraft:block/torch_redstone_active", + "overlay": "#top", + "particle_up": "#top", + "particle_down": "#slab", + "particle_north": "#slab", + "particle_south": "#slab", + "particle_west": "#slab", + "particle_east": "#slab" + }, + "elements": [ + { "from": [ 0, 0, 0 ], + "to": [ 16, 2, 16 ], + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#slab", "cullface": "down" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" }, + "north": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "north" }, + "south": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "south" }, + "west": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "west" }, + "east": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "east" } + } + }, + { "from": [ 13, 2, 7 ], + "to": [ 15, 7, 9 ], + "faces": { + "down": { "uv": [ 7, 13, 9, 15 ], "texture": "#unlit" }, + "up": { "uv": [ 7, 6, 9, 8 ], "texture": "#unlit" }, + "north": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "south": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "west": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "east": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" } + } + }, + { "from": [ 1, 7, 7 ], + "to": [ 3, 7, 9 ], + "faces": { + "up": { "uv": [ 7, 6, 9, 8 ], "texture": "#lit" } + } + }, + { "from": [ 1, 2, 6 ], + "to": [ 3, 8, 10 ], + "faces": { + "west": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }, + "east": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" } + } + }, + { "from": [ 0, 2, 7 ], + "to": [ 4, 8, 9 ], + "faces": { + "north": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }, + "south": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" } + } + } + ] +} diff --git a/game/client/src/main/resources/assets/minecraft/models/block/timer/3_b.json b/game/client/src/main/resources/assets/minecraft/models/block/timer/3_b.json new file mode 100644 index 000000000..74468e0f7 --- /dev/null +++ b/game/client/src/main/resources/assets/minecraft/models/block/timer/3_b.json @@ -0,0 +1,60 @@ +{ + "ambientocclusion": false, + "textures": { + "slab": "minecraft:block/polished_stone_top", + "top": "minecraft:block/timer/top_b", + "unlit": "minecraft:block/torch_redstone_idle", + "lit": "minecraft:block/torch_redstone_active", + "overlay": "#top", + "particle_up": "#top", + "particle_down": "#slab", + "particle_north": "#slab", + "particle_south": "#slab", + "particle_west": "#slab", + "particle_east": "#slab" + }, + "elements": [ + { "from": [ 0, 0, 0 ], + "to": [ 16, 2, 16 ], + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#slab", "cullface": "down" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" }, + "north": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "north" }, + "south": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "south" }, + "west": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "west" }, + "east": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "east" } + } + }, + { "from": [ 1, 2, 7 ], + "to": [ 3, 7, 9 ], + "faces": { + "down": { "uv": [ 7, 13, 9, 15 ], "texture": "#unlit" }, + "up": { "uv": [ 7, 6, 9, 8 ], "texture": "#unlit" }, + "north": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "south": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "west": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" }, + "east": { "uv": [ 7, 6, 9, 11 ], "texture": "#unlit" } + } + }, + { "from": [ 13, 7, 7 ], + "to": [ 15, 7, 9 ], + "faces": { + "up": { "uv": [ 7, 6, 9, 8 ], "texture": "#lit" } + } + }, + { "from": [ 13, 2, 6 ], + "to": [ 15, 8, 10 ], + "faces": { + "west": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }, + "east": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" } + } + }, + { "from": [ 12, 2, 7 ], + "to": [ 16, 8, 9 ], + "faces": { + "north": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }, + "south": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" } + } + } + ] +} diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/piston/shaft.png b/game/client/src/main/resources/assets/minecraft/textures/block/piston/shaft.png index 35b8c6db8..343d3fa77 100644 Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/piston/shaft.png and b/game/client/src/main/resources/assets/minecraft/textures/block/piston/shaft.png differ diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/piston/shaft_end.png b/game/client/src/main/resources/assets/minecraft/textures/block/piston/shaft_end.png new file mode 100644 index 000000000..5b09dd000 Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/piston/shaft_end.png differ diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/timer/top_a.emiss.png b/game/client/src/main/resources/assets/minecraft/textures/block/timer/top_a.emiss.png new file mode 100644 index 000000000..f5b203585 Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/timer/top_a.emiss.png differ diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/timer/top_a.png b/game/client/src/main/resources/assets/minecraft/textures/block/timer/top_a.png new file mode 100644 index 000000000..8379ac8e1 Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/timer/top_a.png differ diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/timer/top_b.emiss.png b/game/client/src/main/resources/assets/minecraft/textures/block/timer/top_b.emiss.png new file mode 100644 index 000000000..0079962d7 Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/timer/top_b.emiss.png differ diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/timer/top_b.png b/game/client/src/main/resources/assets/minecraft/textures/block/timer/top_b.png new file mode 100644 index 000000000..14965ba62 Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/timer/top_b.png differ diff --git a/game/client/src/main/resources/assets/minecraft/textures/item/timer.png b/game/client/src/main/resources/assets/minecraft/textures/item/timer.png new file mode 100644 index 000000000..f55158e44 Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/item/timer.png differ diff --git a/game/core/src/main/java/net/minecraft/core/block/Block.java b/game/core/src/main/java/net/minecraft/core/block/Block.java index 645222364..d983689be 100644 --- a/game/core/src/main/java/net/minecraft/core/block/Block.java +++ b/game/core/src/main/java/net/minecraft/core/block/Block.java @@ -296,26 +296,11 @@ public final class Block return this.logic.isCubeShaped(); } - @Override - public boolean canPlaceOnSurface() { - return this.logic.canPlaceOnSurface(); - } - - @Override - public boolean canPlaceOnSurfaceOnCondition(final @NotNull World world, final @NotNull TilePosc tilePos) { - return this.logic.canPlaceOnSurfaceOnCondition(world, tilePos); - } - @Override public boolean renderAsNormalBlockOnCondition(final @NotNull WorldSource source, final @NotNull TilePosc tilePos) { return this.logic.renderAsNormalBlockOnCondition(source, tilePos); } - - @Override - public boolean canPlaceOnSurface(final @NotNull World world, final @NotNull TilePosc tilePos) { - return this.logic.canPlaceOnSurface(world, tilePos); - } - + @Override public @NotNull ItemStack @Nullable [] getBreakResult(final @NotNull World world, final @NotNull EnumDropCause dropCause, final @NotNull TilePosc tilePos, final int data, final @Nullable TileEntity tileEntity) { return this.logic.getBreakResult(world, dropCause, tilePos, data, tileEntity); diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockInterface.java b/game/core/src/main/java/net/minecraft/core/block/BlockInterface.java index d4d212a36..1025fba80 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockInterface.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockInterface.java @@ -39,17 +39,6 @@ interface BlockInterface { boolean isCubeShaped(); - @Deprecated - boolean canPlaceOnSurface(); - - @Deprecated - boolean canPlaceOnSurfaceOnCondition(final @NotNull World world, final @NotNull TilePosc tilePos); - - @Deprecated - default boolean canPlaceOnSurfaceOnCondition(final @NotNull World world, final int x, final int y, final int z) { - return this.canPlaceOnSurfaceOnCondition(world, new TilePos(x, y, z)); - } - boolean renderAsNormalBlockOnCondition(final @NotNull WorldSource source, final @NotNull TilePosc tilePos); @Deprecated @@ -57,14 +46,6 @@ interface BlockInterface { return this.renderAsNormalBlockOnCondition(world, new TilePos(x, y, z)); } - @Deprecated - boolean canPlaceOnSurface(final @NotNull World world, final @NotNull TilePosc tilePos); - - @Deprecated - default boolean canPlaceOnSurfaceOfBlock(final @NotNull World world, final int x, final int y, final int z) { - return this.canPlaceOnSurface(world, new TilePos(x, y, z)); - } - /** * Make sure if this gets overridden in a block that {@link net.minecraft.core.block.Block#getBreakResult(World, EnumDropCause, int, TileEntity)} also has a valid method since {@link EntityFallingBlock EntityFallingBlock} uses it! */ diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogic.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogic.java index 3d75f6085..bde66452d 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogic.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogic.java @@ -78,26 +78,11 @@ public class BlockLogic implements BlockInterface, IItemConvertible { return true; } - @Override - public boolean canPlaceOnSurface() { - return this.isCubeShaped(); - } - - @Override - public boolean canPlaceOnSurfaceOnCondition(final @NotNull World world, final @NotNull TilePosc tilePos) { - return this.canPlaceOnSurface(); - } - @Override public boolean renderAsNormalBlockOnCondition(final @NotNull WorldSource source, final @NotNull TilePosc tilePos) { return this.isCubeShaped(); } - @Override - public boolean canPlaceOnSurface(final @NotNull World world, final @NotNull TilePosc tilePos) { - return this.canPlaceOnSurface(); - } - @Override public @NotNull ItemStack @Nullable [] getBreakResult(final @NotNull World world, final @NotNull EnumDropCause dropCause, final @NotNull TilePosc tilePos, final int data, final @Nullable TileEntity tileEntity) { return this.getBreakResult(world, dropCause, data, tileEntity); @@ -410,6 +395,10 @@ public class BlockLogic implements BlockInterface, IItemConvertible { } } + + /** + * Note: tilePos is not necessarily a real position where the block exist, keep that in mind when overriding! + */ @Override public void dropWithCause(final @NotNull World world, final @NotNull EnumDropCause dropCause, final @NotNull TilePosc tilePos, final int data, final @Nullable TileEntity tileEntity, final @Nullable Player player) { if (world.isClientSide) @@ -443,7 +432,7 @@ public class BlockLogic implements BlockInterface, IItemConvertible { public @NotNull ISupport getSupport(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Side side) { return FullSupport.INSTANCE; } - + @Override public boolean canStay(final @NotNull World world, final @NotNull TilePosc tilePos) { return true; diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicActivator.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicActivator.java index 4aa798ee7..20dea1629 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicActivator.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicActivator.java @@ -50,9 +50,9 @@ public class BlockLogicActivator if (!activator.locked(activator.stackSelector)) { final @Nullable ItemStack itemStack = activator.getNextStack(); - final double px = direction.getOffsetX() * 0.6D + 0.5D; - final double py = direction.getOffsetY() * 0.6D + 0.5D; - final double pz = direction.getOffsetZ() * 0.6D + 0.5D; + final double px = direction.offsetX() * 0.6D + 0.5D; + final double py = direction.offsetY() * 0.6D + 0.5D; + final double pz = direction.offsetZ() * 0.6D + 0.5D; if (itemStack == null) { final @Nullable Block block = world.getBlockType(tilePos.add(direction, new TilePos())); @@ -67,7 +67,7 @@ public class BlockLogicActivator item.onUseByActivator(itemStack, world, activator, random, tilePos, direction, px, py, pz); activator.nullDeadItems(); world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, tilePos.x(), tilePos.y(), tilePos.z(), "tile.activator.use", 1, 1); - world.playBlockEvent(tilePos, LevelListener.EVENT_DISPENSER_PARTICLES, direction.getId()); + world.playBlockEvent(tilePos, LevelListener.EVENT_DISPENSER_PARTICLES, direction.id); } } else { activator.shiftSelector(); diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicAir.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicAir.java index bc9aa1af8..93f4ffb1d 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicAir.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicAir.java @@ -32,26 +32,11 @@ public class BlockLogicAir return false; } - @Override - public boolean canPlaceOnSurface() { - return false; - } - - @Override - public boolean canPlaceOnSurfaceOnCondition(final @NotNull World world, final @NotNull TilePosc tilePos) { - return false; - } - @Override public boolean renderAsNormalBlockOnCondition(final @NotNull WorldSource source, final @NotNull TilePosc tilePos) { return false; } - @Override - public boolean canPlaceOnSurface(final @NotNull World world, final @NotNull TilePosc tilePos) { - return false; - } - @Override public @NotNull ItemStack @Nullable [] getBreakResult(final @NotNull World world, final @NotNull EnumDropCause dropCause, final int data, final @Nullable TileEntity tileEntity) { return null; diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicAxisAligned.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicAxisAligned.java index 5305375e2..1f78a5629 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicAxisAligned.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicAxisAligned.java @@ -19,14 +19,14 @@ public class BlockLogicAxisAligned @Override public void onPlacedByMob(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Side side, final @NotNull Mob mob, final double xHit, final double yHit) { - final @NotNull Axis axis = mob.getPlacementDirection(side, PlacementMode.SIDE).getAxis(); + final @NotNull Axis axis = mob.getPlacementDirection(side, PlacementMode.SIDE).axis(); world.setBlockDataNotify(tilePos, axisToMeta(axis)); } @Override public void onPlacedOnSide(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Side side, final double xHit, final double yHit) { - final @NotNull Axis axis = side.getAxis(); + final @NotNull Axis axis = side.axis(); world.setBlockDataNotify(tilePos, axisToMeta(axis)); } diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicBasket.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicBasket.java index 2c3d16b1c..0dfcb1aae 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicBasket.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicBasket.java @@ -92,18 +92,13 @@ public class BlockLogicBasket extends BlockLogic { @Override public void onPlacedByWorld(final @NotNull World world, final @NotNull TilePosc tilePos) { - TilePos queryPos = new TilePos(); - for (final @NotNull Direction d : Direction.directions) { - world.notifyBlocksOfNeighborChange(tilePos.add(d, queryPos), this.block); - } + // world.notifyBlocksInRadiusOfNeighborChange(2, tilePos, this.block); } @Override public void onRemoved(final @NotNull World world, final @NotNull TilePosc tilePos, final int data) { - TilePos queryPos = new TilePos(); - for (final @NotNull Direction d : Direction.directions) { - world.notifyBlocksOfNeighborChange(tilePos.add(d, queryPos), this.block); - } + // // let tile entity handles ranged update + // world.notifyBlocksInRadiusOfNeighborChange(2, tilePos, this.block); } @Override diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicBed.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicBed.java index e8f021467..c2f57246a 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicBed.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicBed.java @@ -4,7 +4,9 @@ import net.minecraft.core.achievement.Achievements; import net.minecraft.core.block.entity.TileEntity; import net.minecraft.core.block.material.Material; import net.minecraft.core.block.material.Materials; +import net.minecraft.core.block.support.FullSupport; import net.minecraft.core.block.support.ISupport; +import net.minecraft.core.block.support.ISupportable; import net.minecraft.core.block.support.PartialSupport; import net.minecraft.core.entity.player.Player; import net.minecraft.core.enums.EnumDropCause; @@ -12,7 +14,6 @@ import net.minecraft.core.enums.EnumSleepStatus; import net.minecraft.core.item.Items; import net.minecraft.core.item.ItemStack; import net.minecraft.core.util.PackedField; -import net.minecraft.core.util.helper.Direction; import net.minecraft.core.util.helper.Side; import net.minecraft.core.world.World; import net.minecraft.core.world.pos.TilePos; @@ -23,7 +24,8 @@ import org.jetbrains.annotations.Nullable; import java.util.Objects; public class BlockLogicBed - extends BlockLogic { + extends BlockLogic + implements ISupportable { public BlockLogicBed(final @NotNull Block block) { super(block, Materials.WOOD); @@ -39,27 +41,27 @@ public class BlockLogicBed int data = world.getBlockData(tilePos); final @NotNull TilePosc headPos; final @NotNull TilePosc footPos; - if (!IS_HEAD.bool(data)) { - final int dir = DIRECTION.get(data); + final var f2hDir = footToHeadMap[DIRECTION.get(data)].direction(); + if (IS_HEAD.bool(data)) { headPos = tilePos; - footPos = tilePos.add(headBlockToFootBlockMap[dir].getDirection(), new TilePos()); + footPos = tilePos.sub(f2hDir, new TilePos()); if (world.getBlockType(footPos) != this.block) return true; + data = world.getBlockData(footPos); } else { - final int dir = DIRECTION.get(data); footPos = tilePos; - headPos = tilePos.sub(headBlockToFootBlockMap[dir].getDirection(), new TilePos()); + headPos = tilePos.add(f2hDir, new TilePos()); if (world.getBlockType(headPos) != this.block) return true; } // Explode in invalid dimensions if (!world.getWorldType().mayRespawn()) { - world.setBlockType(headPos, Blocks.AIR); assert world.getBlockType(footPos) == this.block; // made sure from above + world.setBlockType(headPos, Blocks.AIR); world.setBlockType(footPos, Blocks.AIR); - // prevents dupe... tho the dupe would need to be pretty funny to work - world.notifyBlockChange(headPos, Blocks.AIR); - world.notifyBlockChange(footPos, Blocks.AIR); + world.markBlockNeedsUpdate(headPos); + world.markBlockNeedsUpdate(footPos); + world.notifyBlocksInCapsuleOfNeighborChange(f2hDir, footPos, this.block); player.addStat(Achievements.SLEEP_NETHER, 1); world.createExplosion(null, tilePos.x() + 0.5F, tilePos.y() + 0.5F, tilePos.z() + 0.5F, 5F, true, false); @@ -130,7 +132,7 @@ public class BlockLogicBed public static @Nullable TilePos otherHalf(final @NotNull World world, @NotNull TilePosc tilePos, int data) { final var isHead = IS_HEAD.bool(data); final var dir = DIRECTION.get(data); - final var direction = headBlockToFootBlockMap[DIRECTION.get(data)].getDirection(); + final var direction = footToHeadMap[DIRECTION.get(data)].direction(); final var otherPos = (isHead) ? tilePos.sub(direction, new TilePos()) : tilePos.add(direction, new TilePos()); @@ -157,9 +159,9 @@ public class BlockLogicBed for (int d = 0; d <= 1; d++) { final @NotNull TilePos minPos = new TilePos( - tilePos.x - headBlockToFootBlockMap[direction].getOffsetX() * d - 1, + tilePos.x - footToHeadMap[direction].offsetX() * d - 1, tilePos.y, - tilePos.z - headBlockToFootBlockMap[direction].getOffsetZ() * d - 1 + tilePos.z - footToHeadMap[direction].offsetZ() * d - 1 ); final @NotNull TilePos maxPos = minPos.add(2, 0, 2, new TilePos()); @@ -186,10 +188,15 @@ public class BlockLogicBed return null; } - public static final @NotNull Side @NotNull [] headBlockToFootBlockMap = { + public static final @NotNull Side @NotNull [] footToHeadMap = { Side.SOUTH, Side.WEST, Side.NORTH, Side.EAST }; + + @Override + public @NotNull ISupport getSupportConstraint(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side) { + return FullSupport.INSTANCE; + } } diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicBoneShale.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicBoneShale.java index 761c1bcd3..deba70176 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicBoneShale.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicBoneShale.java @@ -20,7 +20,7 @@ public class BlockLogicBoneShale final @NotNull Direction direction = BlockLogicFullyRotatable.metaToDirection(data); float blockHardness = this.block.getHardness(); - if (side != direction.getSide()) { + if (side != direction.side()) { blockHardness *= 66.6f; } diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicButton.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicButton.java index 100b70b02..68835d3a5 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicButton.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicButton.java @@ -16,7 +16,6 @@ import net.minecraft.core.util.helper.DyeColor; 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.TilePos; import net.minecraft.core.world.pos.TilePosc; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -69,7 +68,7 @@ public class BlockLogicButton @Override public boolean canPlaceOnSide(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Side side) { - final @NotNull Side checkSide = side.getOpposite(); + final @NotNull Side checkSide = side.opposite(); return this.isSupported(world, tilePos, checkSide); } @@ -131,7 +130,7 @@ public class BlockLogicButton public void onPlacedOnSide(final @NotNull World world, final @NotNull TilePosc tilePos, @NotNull Side side, final double xHit, final double yHit) { int orientation = -1; if (side.isHorizontal()) { - side = side.getOpposite(); + side = side.opposite(); } switch (side) { case BOTTOM: @@ -254,6 +253,18 @@ public class BlockLogicButton return this.press(world, tilePos, player); } + private static @NotNull Direction getDirection(int directionWeird) { + return switch (directionWeird) { + default -> Direction.NONE; + case SIDE_WEST -> Direction.WEST; + case SIDE_EAST -> Direction.EAST; + case SIDE_NORTH -> Direction.NORTH; + case SIDE_SOUTH -> Direction.SOUTH; + case SIDE_TOP -> Direction.UP; + case SIDE_BOTTOM -> Direction.DOWN; + }; + } + private boolean press(final @NotNull World world, final @NotNull TilePosc tilePos, final @Nullable Player player) { final int meta = world.getBlockData(tilePos); final int direction = meta & MASK_DIRECTION; @@ -261,31 +272,11 @@ public class BlockLogicButton if (isPowered) { return false; } - world.setBlockDataNotify(tilePos, (meta & ~MASK_DIRECTION) | direction | MASK_POWERED); - world.markBlockDirty(tilePos); + world.setBlockData(tilePos, (meta & ~MASK_DIRECTION) | direction | MASK_POWERED); + world.markBlockNeedsUpdate(tilePos); world.playSoundEffect(player, SoundCategory.WORLD_SOUNDS, tilePos.x() + 0.5D, tilePos.y() + 0.5D, tilePos.z() + 0.5D, "random.click", 0.3F, 0.6F); - world.notifyBlocksOfNeighborChange(tilePos, this.block); - switch (direction) { - case SIDE_WEST: - world.notifyBlocksOfNeighborChange(tilePos.add(Direction.WEST, new TilePos()), this.block); - break; - case SIDE_EAST: - world.notifyBlocksOfNeighborChange(tilePos.add(Direction.EAST, new TilePos()), this.block); - break; - case SIDE_NORTH: - world.notifyBlocksOfNeighborChange(tilePos.add(Direction.NORTH, new TilePos()), this.block); - break; - case SIDE_SOUTH: - world.notifyBlocksOfNeighborChange(tilePos.add(Direction.SOUTH, new TilePos()), this.block); - break; - case SIDE_TOP: - world.notifyBlocksOfNeighborChange(tilePos.add(Direction.UP, new TilePos()), this.block); - break; - case SIDE_BOTTOM: - world.notifyBlocksOfNeighborChange(tilePos.add(Direction.DOWN, new TilePos()), this.block); - break; - } + world.notifyBlocksInCapsuleOfNeighborChange(getDirection(direction), tilePos, this.block); world.scheduleBlockUpdate(tilePos, this.block, this.tickDelay()); return true; } @@ -298,28 +289,8 @@ public class BlockLogicButton @Override public void onRemoved(final @NotNull World world, final @NotNull TilePosc tilePos, final int data) { if ((data & MASK_POWERED) != 0) { - world.notifyBlocksOfNeighborChange(tilePos, this.block); final int direction = data & MASK_DIRECTION; - switch (direction) { - case SIDE_WEST: - world.notifyBlocksOfNeighborChange(tilePos.add(Direction.WEST, new TilePos()), this.block); - break; - case SIDE_EAST: - world.notifyBlocksOfNeighborChange(tilePos.add(Direction.EAST, new TilePos()), this.block); - break; - case SIDE_NORTH: - world.notifyBlocksOfNeighborChange(tilePos.add(Direction.NORTH, new TilePos()), this.block); - break; - case SIDE_SOUTH: - world.notifyBlocksOfNeighborChange(tilePos.add(Direction.SOUTH, new TilePos()), this.block); - break; - case SIDE_TOP: - world.notifyBlocksOfNeighborChange(tilePos.add(Direction.UP, new TilePos()), this.block); - break; - case SIDE_BOTTOM: - world.notifyBlocksOfNeighborChange(tilePos.add(Direction.DOWN, new TilePos()), this.block); - break; - } + world.notifyBlocksInCapsuleOfNeighborChange(getDirection(direction), tilePos, this.block); } super.onRemoved(world, tilePos, data); } @@ -361,32 +332,12 @@ public class BlockLogicButton if ((meta & MASK_POWERED) == 0) { return; } - world.setBlockDataNotify(tilePos, meta & ~MASK_POWERED); - world.notifyBlocksOfNeighborChange(tilePos, this.block); final int direction = meta & MASK_DIRECTION; - switch (direction) { - case SIDE_WEST: - world.notifyBlocksOfNeighborChange(tilePos.add(Direction.WEST, new TilePos()), this.block); - break; - case SIDE_EAST: - world.notifyBlocksOfNeighborChange(tilePos.add(Direction.EAST, new TilePos()), this.block); - break; - case SIDE_NORTH: - world.notifyBlocksOfNeighborChange(tilePos.add(Direction.NORTH, new TilePos()), this.block); - break; - case SIDE_SOUTH: - world.notifyBlocksOfNeighborChange(tilePos.add(Direction.SOUTH, new TilePos()), this.block); - break; - case SIDE_TOP: - world.notifyBlocksOfNeighborChange(tilePos.add(Direction.UP, new TilePos()), this.block); - break; - case SIDE_BOTTOM: - world.notifyBlocksOfNeighborChange(tilePos.add(Direction.DOWN, new TilePos()), this.block); - break; - } + world.setBlockData(tilePos, meta & ~MASK_POWERED); + world.markBlockNeedsUpdate(tilePos); + world.notifyBlocksInCapsuleOfNeighborChange(getDirection(direction), tilePos, this.block); world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, tilePos.x() + 0.5D, tilePos.y() + 0.5D, tilePos.z() + 0.5D, "random.click", 0.3F, 0.5F); - world.markBlockDirty(tilePos); } @Override diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicCactus.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicCactus.java index 983adec37..62d75eadb 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicCactus.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicCactus.java @@ -52,8 +52,11 @@ public class BlockLogicCactus if (cactusHeight < 3) { final int data = world.getBlockData(tilePos); if (data == 15) { - world.setBlockTypeNotify(tilePos.add(Direction.UP, queryPos), this.block); - world.setBlockDataNotify(tilePos, 0); + world.setBlockData(tilePos, 0); + world.setBlockType(tilePos.add(Direction.UP, queryPos), this.block); + world.markBlockNeedsUpdate(tilePos); + world.markBlockNeedsUpdate(queryPos); + world.notifyBlocksInCapsuleOfNeighborChange(Direction.UP, tilePos, this.block); } else { world.setBlockDataNotify(tilePos, data + 1); } diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicChest.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicChest.java index fc75af867..690af327d 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicChest.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicChest.java @@ -27,12 +27,12 @@ public class BlockLogicChest @Override public void onPlacedByMob(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Side side, final @NotNull Mob mob, final double xHit, final double yHit) { - @NotNull Direction direction = mob.getHorizontalPlacementDirection(side).getOpposite(); + @NotNull Direction direction = mob.getHorizontalPlacementDirection(side).opposite(); @NotNull Type type = Type.SINGLE; TilePos queryPos = new TilePos(); - if (mob.isSneaking() && side.isHorizontal() && (mob.rotationLockHorizontal == null || mob.rotationLockHorizontal == Direction.NONE)) { - final @NotNull TilePos placedOn = tilePos.sub(side.getDirection(), new TilePos()); + if (mob.isSneaking() && side.isHorizontal() && mob.rotationLockHorizontal == null) { + final @NotNull TilePos placedOn = tilePos.sub(side.direction(), new TilePos()); if (isSingleChest(world, placedOn)) { final @NotNull Direction direction2 = getDirectionFromMeta(world.getBlockData(placedOn)); @@ -137,7 +137,7 @@ public class BlockLogicChest @Override public void onPlacedOnSide(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Side side, final double xHit, final double yHit) { - final Direction direction = side.getDirection(); + final Direction direction = side.direction(); Type type = Type.SINGLE; TilePos queryPos = new TilePos(); if (direction == Direction.NORTH) { diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicConduit.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicConduit.java index 448a650a7..adad84a0d 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicConduit.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicConduit.java @@ -136,21 +136,21 @@ public class BlockLogicConduit extends BlockLogic { */ @Override public void onPlacedByMob(final @NotNull World world, final @NotNull TilePosc cTilePos, final @NotNull Side sidePlacedOnto, final @NotNull Mob mob, final double xHit, final double yHit) { - Side sideFacingPlayer = Direction.getDirection(mob).getOpposite().getSide(); - Side sideClickedAgainst = sidePlacedOnto.getOpposite(); + Side sideFacingPlayer = Direction.getLockable(mob).opposite().side(); + Side sideClickedAgainst = sidePlacedOnto.opposite(); int stateToPlaceAs = 0; if (mob instanceof Player player) { - if (player.rotationLock != null && player.rotationLock != Direction.NONE) { - Side lockSide = player.rotationLock.getSide(); - stateToPlaceAs = getStateFromTwoSides(lockSide, lockSide.getOpposite()); + if (player.rotationLock != null) { + Side lockSide = player.rotationLock.side(); + stateToPlaceAs = getStateFromTwoSides(lockSide, lockSide.opposite()); } } if (stateToPlaceAs == 0 && mob.isSneaking()) { boolean openedClosedFace = false; - TilePos clickedPos = new TilePos(cTilePos.x() + sideClickedAgainst.getOffsetX(), cTilePos.y() + sideClickedAgainst.getOffsetY(), cTilePos.z() + sideClickedAgainst.getOffsetZ()); + TilePos clickedPos = new TilePos(cTilePos.x() + sideClickedAgainst.offsetX(), cTilePos.y() + sideClickedAgainst.offsetY(), cTilePos.z() + sideClickedAgainst.offsetZ()); if (world.getBlockType(clickedPos) == this.block) { int clickedData = world.getBlockData(clickedPos); @@ -170,12 +170,12 @@ public class BlockLogicConduit extends BlockLogic { } if (openedClosedFace) { - stateToPlaceAs = getStateFromTwoSides(sideClickedAgainst, sideClickedAgainst.getOpposite()); + stateToPlaceAs = getStateFromTwoSides(sideClickedAgainst, sideClickedAgainst.opposite()); } else { if (sideClickedAgainst != sideFacingPlayer && sideFacingPlayer != Side.NONE) { stateToPlaceAs = getStateFromTwoSides(sideClickedAgainst, sideFacingPlayer); } else { - stateToPlaceAs = getStateFromTwoSides(sideClickedAgainst, sideClickedAgainst.getOpposite()); + stateToPlaceAs = getStateFromTwoSides(sideClickedAgainst, sideClickedAgainst.opposite()); } } } @@ -183,12 +183,12 @@ public class BlockLogicConduit extends BlockLogic { List validSides = new ArrayList<>(); for (Side side : Side.values()) { - TilePos nTilePos = new TilePos(cTilePos.x() + side.getOffsetX(), cTilePos.y() + side.getOffsetY(), cTilePos.z() + side.getOffsetZ()); + TilePos nTilePos = new TilePos(cTilePos.x() + side.offsetX(), cTilePos.y() + side.offsetY(), cTilePos.z() + side.offsetZ()); if (world.getBlockType(nTilePos) == this.block) { int nData = world.getBlockData(nTilePos); - if (isSideOpen(nData, side.getOpposite())) { + if (isSideOpen(nData, side.opposite())) { validSides.add(side); } } @@ -202,7 +202,7 @@ public class BlockLogicConduit extends BlockLogic { if (sideFacingPlayer != autoConnectedSide && sideFacingPlayer != Side.NONE) { stateToPlaceAs = getStateFromTwoSides(autoConnectedSide, sideFacingPlayer); } else { - stateToPlaceAs = getStateFromTwoSides(autoConnectedSide, autoConnectedSide.getOpposite()); + stateToPlaceAs = getStateFromTwoSides(autoConnectedSide, autoConnectedSide.opposite()); } } else if (numOfValidSides == 2) { stateToPlaceAs = getStateFromTwoSides(validSides.get(0), validSides.get(1)); @@ -216,7 +216,7 @@ public class BlockLogicConduit extends BlockLogic { if (sideFacingPlayer != sideClickedAgainst && sideFacingPlayer != Side.NONE) { stateToPlaceAs = getStateFromTwoSides(sideClickedAgainst, sideFacingPlayer); } else { - stateToPlaceAs = getStateFromTwoSides(sideClickedAgainst, sideClickedAgainst.getOpposite()); + stateToPlaceAs = getStateFromTwoSides(sideClickedAgainst, sideClickedAgainst.opposite()); } } } @@ -311,7 +311,7 @@ public class BlockLogicConduit extends BlockLogic { public static byte packEventConduitData(Side side, int strength) { if (side == null) side = Side.NONE; int s = Math.max(0, Math.min(PROPAGATION_LENGTH, strength)); - int sideId = side.getId() & 0x07; + int sideId = side.id & 0x07; return (byte) ((sideId << POWER_SHIFT) | (s & POWER_MASK)); } @@ -331,17 +331,17 @@ public class BlockLogicConduit extends BlockLogic { if (currentPower == 0) return false; - TilePos receiverPos = new TilePos(tilePos).add(side.getOpposite()); + TilePos receiverPos = new TilePos(tilePos).add(side.opposite()); if (world.getBlockType(receiverPos) == Blocks.WIRE_REDSTONE) { return false; } - return isSideOpen(data, side.getOpposite()); + return isSideOpen(data, side.opposite()); } private int getNextState(int currentState, @NotNull Side sideQueried) { if (currentState == 0) { - return getStateFromTwoSides(sideQueried, sideQueried.getOpposite()); + return getStateFromTwoSides(sideQueried, sideQueried.opposite()); } Side[] currentSides = STATE_TABLE[currentState]; @@ -383,7 +383,7 @@ public class BlockLogicConduit extends BlockLogic { */ public static int getAndConvertNeighborSignal(@NotNull WorldSource world, @NotNull TilePosc cTilePos, @NotNull Side side) { - TilePos nTilePos = new TilePos(cTilePos.x() + side.getOffsetX(), cTilePos.y() + side.getOffsetY(), cTilePos.z() + side.getOffsetZ()); + TilePos nTilePos = new TilePos(cTilePos.x() + side.offsetX(), cTilePos.y() + side.offsetY(), cTilePos.z() + side.offsetZ()); Block nBlockType = world.getBlockType(nTilePos); int cStrength = (world.getBlockData(cTilePos) >> POWER_SHIFT) & POWER_MASK; @@ -396,7 +396,7 @@ public class BlockLogicConduit extends BlockLogic { if (nBlockType == Blocks.CONDUIT) { int nData = world.getBlockData(nTilePos); - if (isSideOpen(nData, side.getOpposite())) { + if (isSideOpen(nData, side.opposite())) { int nStrength = (nData >> POWER_SHIFT) & POWER_MASK; if (nStrength <= cStrength) return 0; @@ -411,7 +411,7 @@ public class BlockLogicConduit extends BlockLogic { if (world1.isBlockNormalCube(nTilePos) && !isPowerCube) { for (Side s : Side.sides) { - TilePos queryPos = new TilePos(nTilePos.x() + s.getOffsetX(), nTilePos.y() + s.getOffsetY(), nTilePos.z() + s.getOffsetZ()); + TilePos queryPos = new TilePos(nTilePos.x() + s.offsetX(), nTilePos.y() + s.offsetY(), nTilePos.z() + s.offsetZ()); Block queryBlock = world1.getBlockType(queryPos); if (queryBlock != Blocks.WIRE_REDSTONE && queryBlock != Blocks.CONDUIT) { diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicDispenser.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicDispenser.java index 223ca8dbc..47ef77a98 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicDispenser.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicDispenser.java @@ -47,9 +47,9 @@ public class BlockLogicDispenser extends BlockLogicVeryRotatable { private void dispenseItem(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Random random) { final @NotNull Direction direction = BlockLogicVeryRotatable.metaToDirection(world.getBlockData(tilePos)); - final int xOffset = direction.getOffsetX(); - final int yOffset = direction.getOffsetY(); - final int zOffset = direction.getOffsetZ(); + final int xOffset = direction.offsetX(); + final int yOffset = direction.offsetY(); + final int zOffset = direction.offsetZ(); final @NotNull TileEntityDispenser tileEntity = (TileEntityDispenser) Objects.requireNonNull(world.getTileEntity(tilePos)); int stackIndex = tileEntity.getRandomStackIndexFromInventory(); @@ -97,7 +97,7 @@ public class BlockLogicDispenser extends BlockLogicVeryRotatable { } world.playBlockEvent(tilePos, LevelListener.EVENT_DISPENSER_ITEM, 0); } - world.playBlockEvent(tilePos, LevelListener.EVENT_DISPENSER_PARTICLES, direction.getId()); + world.playBlockEvent(tilePos, LevelListener.EVENT_DISPENSER_PARTICLES, direction.id); } if (stackIndex >= 0 && itemStack != null && itemStack.stackSize <= 0) { tileEntity.setItem(stackIndex, null); 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 d7163bb7e..86a67a49d 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 @@ -56,12 +56,13 @@ public class BlockLogicDoor public void onPlacedOnSide(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Side side, final double xHit, final double yHit) { final int meta = world.getBlockData(tilePos); if (world.hasNeighborSignal(tilePos)) { - world.setBlockDataNotify(tilePos, meta | MASK_OPENED); - if (this.isTop) { - world.setBlockDataNotify(tilePos.down(new TilePos()), meta | MASK_OPENED); - } else { - world.setBlockDataNotify(tilePos.up(new TilePos()), meta | MASK_OPENED); - } + world.setBlockData(tilePos, meta | MASK_OPENED); + final var dir = this.isTop ? Direction.DOWN : Direction.UP; + world.setBlockData(tilePos.add(dir, new TilePos()), meta | MASK_OPENED); + + world.markBlockNeedsUpdate(tilePos); + world.markBlockNeedsUpdate(tilePos.add(dir, new TilePos())); + world.notifyBlocksInCapsuleOfNeighborChange(dir, tilePos, this.block); world.playBlockEvent(tilePos, LevelListener.EVENT_DOOR_SOUND, 0); } } @@ -163,7 +164,7 @@ public class BlockLogicDoor @Override public void onActivatorInteracted(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull TileEntityActivator activator, final @NotNull Direction direction) { - this.onInteracted(world, tilePos, null, direction.getSide(), 0.5, 0.5); + this.onInteracted(world, tilePos, null, direction.side(), 0.5, 0.5); } public void onPoweredBlockChange(final @NotNull World world, final @NotNull TilePosc tilePos, boolean isPowered) { @@ -300,22 +301,22 @@ public class BlockLogicDoor switch (this.getRotation(data)) { case 0: { side = Side.WEST; - hingeSupport = world.getSupport(tilePos.add(side.getDirection(), queryPos), side.getOpposite()); + hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite()); return sBelow.canSupport(PartialSupport.INSTANCE.up(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.right(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.right(), side); } case 1: { side = Side.NORTH; - hingeSupport = world.getSupport(tilePos.add(side.getDirection(), queryPos), side.getOpposite()); + hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite()); return sBelow.canSupport(PartialSupport.INSTANCE.right(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.down(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.right(), side); } case 2: { side = Side.EAST; - hingeSupport = world.getSupport(tilePos.add(side.getDirection(), queryPos), side.getOpposite()); + hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite()); return sBelow.canSupport(PartialSupport.INSTANCE.down(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.left(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.right(), side); } case 3: { side = Side.SOUTH; - hingeSupport = world.getSupport(tilePos.add(side.getDirection(), queryPos), side.getOpposite()); + hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite()); return sBelow.canSupport(PartialSupport.INSTANCE.left(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.up(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.right(), side); } @@ -324,22 +325,22 @@ public class BlockLogicDoor switch (this.getRotation(data)) { case 0: { side = Side.NORTH; - hingeSupport = world.getSupport(tilePos.add(side.getDirection(), queryPos), side.getOpposite()); + hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite()); return sBelow.canSupport(PartialSupport.INSTANCE.up(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.left(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.left(), side); } case 1: { side = Side.EAST; - hingeSupport = world.getSupport(tilePos.add(side.getDirection(), queryPos), side.getOpposite()); + hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite()); return sBelow.canSupport(PartialSupport.INSTANCE.right(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.up(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.left(), side); } case 2: { side = Side.SOUTH; - hingeSupport = world.getSupport(tilePos.add(side.getDirection(), queryPos), side.getOpposite()); + hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite()); return sBelow.canSupport(PartialSupport.INSTANCE.down(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.right(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.left(), side); } case 3: { side = Side.WEST; - hingeSupport = world.getSupport(tilePos.add(side.getDirection(), queryPos), side.getOpposite()); + hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite()); return sBelow.canSupport(PartialSupport.INSTANCE.left(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.down(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.left(), side); } } @@ -349,22 +350,22 @@ public class BlockLogicDoor switch (this.getRotation(data)) { case 0: { side = Side.NORTH; - hingeSupport = world.getSupport(tilePos.add(side.getDirection(), queryPos), side.getOpposite()); + hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite()); return sBelow.canSupport(PartialSupport.INSTANCE.up(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.right(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.right(), side); } case 1: { side = Side.EAST; - hingeSupport = world.getSupport(tilePos.add(side.getDirection(), queryPos), side.getOpposite()); + hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite()); return sBelow.canSupport(PartialSupport.INSTANCE.right(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.down(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.right(), side); } case 2: { side = Side.SOUTH; - hingeSupport = world.getSupport(tilePos.add(side.getDirection(), queryPos), side.getOpposite()); + hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite()); return sBelow.canSupport(PartialSupport.INSTANCE.down(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.left(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.right(), side); } case 3: { side = Side.WEST; - hingeSupport = world.getSupport(tilePos.add(side.getDirection(), queryPos), side.getOpposite()); + hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite()); return sBelow.canSupport(PartialSupport.INSTANCE.left(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.up(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.right(), side); } @@ -373,22 +374,22 @@ public class BlockLogicDoor switch (this.getRotation(data)) { case 0: { side = Side.EAST; - hingeSupport = world.getSupport(tilePos.add(side.getDirection(), queryPos), side.getOpposite()); + hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite()); return sBelow.canSupport(PartialSupport.INSTANCE.up(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.left(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.left(), side); } case 1: { side = Side.SOUTH; - hingeSupport = world.getSupport(tilePos.add(side.getDirection(), queryPos), side.getOpposite()); + hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite()); return sBelow.canSupport(PartialSupport.INSTANCE.right(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.up(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.left(), side); } case 2: { side = Side.WEST; - hingeSupport = world.getSupport(tilePos.add(side.getDirection(), queryPos), side.getOpposite()); + hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite()); return sBelow.canSupport(PartialSupport.INSTANCE.down(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.right(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.left(), side); } case 3: { side = Side.NORTH; - hingeSupport = world.getSupport(tilePos.add(side.getDirection(), queryPos), side.getOpposite()); + hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite()); return sBelow.canSupport(PartialSupport.INSTANCE.left(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.down(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.left(), side); } } diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFence.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFence.java index 9df34cb76..315461b50 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFence.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFence.java @@ -25,11 +25,6 @@ public class BlockLogicFence super(block, Materials.WOOD); } - @Override - public boolean canPlaceOnSurface() { - return true; - } - @Override public @NotNull ISupport getSupport(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Side side) { if (side.isVertical()) { @@ -89,8 +84,8 @@ public class BlockLogicFence public boolean canConnectTo(final @NotNull WorldSource source, final @NotNull TilePosc tilePos, final @NotNull Side side) { TilePos queryPos = new TilePos(); - final @NotNull Block b = source.getBlockType(tilePos.add(side.getDirection(), queryPos)); - return Blocks.hasTag(b, BlockTags.FENCES_CONNECT) || b.getAttachedSide(source, tilePos.add(side.getDirection(), queryPos)) == side.getOpposite(); + final @NotNull Block b = source.getBlockType(tilePos.add(side.direction(), queryPos)); + return Blocks.hasTag(b, BlockTags.FENCES_CONNECT) || b.getAttachedSide(source, tilePos.add(side.direction(), queryPos)) == side.opposite(); } @Deprecated diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceChainlink.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceChainlink.java index 072597a2c..806039014 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceChainlink.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceChainlink.java @@ -18,8 +18,8 @@ public class BlockLogicFenceChainlink extends BlockLogicFenceThin { @Override public boolean canConnectTo(final @NotNull WorldSource source, final @NotNull TilePosc tilePos, final @NotNull Side side) { TilePos queryPos = new TilePos(); - final @Nullable Block b = source.getBlockType(tilePos.add(side.getDirection(), queryPos)); - return Blocks.hasTag(b, BlockTags.CHAINLINK_FENCES_CONNECT) || (b != null && b.getAttachedSide(source, tilePos.add(side.getDirection(), queryPos)) == side.getOpposite()); + final @Nullable Block b = source.getBlockType(tilePos.add(side.direction(), queryPos)); + return Blocks.hasTag(b, BlockTags.CHAINLINK_FENCES_CONNECT) || (b != null && b.getAttachedSide(source, tilePos.add(side.direction(), queryPos)) == side.opposite()); } @Override diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceGate.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceGate.java index c74ebaa0f..eefc919c8 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceGate.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceGate.java @@ -74,7 +74,7 @@ public class BlockLogicFenceGate @Override public void onPlacedByMob(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Side side, final @NotNull Mob mob, final double xHit, final double yHit) { - final int direction = mob.getHorizontalPlacementDirection(side).getHorizontalIndex(); + final int direction = mob.getHorizontalPlacementDirection(side).legacyHorizontalIndex(); final int meta = world.getBlockData(tilePos); world.setBlockDataNotify(tilePos, direction | (meta & ~MASK_DIRECTION)); } @@ -84,7 +84,7 @@ public class BlockLogicFenceGate if (!side.isHorizontal()) { side = Side.NORTH; } - final int direction = side.getDirection().getHorizontalIndex(); + final int direction = side.direction().legacyHorizontalIndex(); final int meta = world.getBlockData(tilePos); world.setBlockDataNotify(tilePos, direction | (meta & ~MASK_DIRECTION)); } @@ -134,7 +134,7 @@ public class BlockLogicFenceGate @Override public void onActivatorInteracted(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull TileEntityActivator activator, final @NotNull Direction direction) { - this.onInteracted(world, tilePos, null, direction.getSide(), 0.5, 0.5); + this.onInteracted(world, tilePos, null, direction.side(), 0.5, 0.5); } public static boolean isOpen(final int meta) { diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceSteel.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceSteel.java index 1493510e1..cdc450111 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceSteel.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceSteel.java @@ -18,7 +18,7 @@ public class BlockLogicFenceSteel @Override public boolean canConnectTo(final @NotNull WorldSource source, final @NotNull TilePosc tilePos, final @NotNull Side side) { TilePos queryPos = new TilePos(); - final @Nullable Block b = source.getBlockType(tilePos.add(side.getDirection(), queryPos)); - return Blocks.hasTag(b, BlockTags.CHAINLINK_FENCES_CONNECT) || (b != null && b.getAttachedSide(source, tilePos.add(side.getDirection(), queryPos)) == side.getOpposite()); + final @Nullable Block b = source.getBlockType(tilePos.add(side.direction(), queryPos)); + return Blocks.hasTag(b, BlockTags.CHAINLINK_FENCES_CONNECT) || (b != null && b.getAttachedSide(source, tilePos.add(side.direction(), queryPos)) == side.opposite()); } } diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceThin.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceThin.java index 14058f6be..1613ad4f4 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceThin.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceThin.java @@ -21,11 +21,6 @@ public abstract class BlockLogicFenceThin super(block, material); } - @Override - public boolean canPlaceOnSurface() { - return true; - } - @Override public @NotNull ISupport getSupport(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Side side) { if (side.isVertical()) { diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceWallPaper.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceWallPaper.java index a4c258f97..a1655ba49 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceWallPaper.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceWallPaper.java @@ -18,7 +18,7 @@ public class BlockLogicFenceWallPaper @Override public boolean canConnectTo(final @NotNull WorldSource source, final @NotNull TilePosc tilePos, final @NotNull Side side) { TilePos queryPos = new TilePos(); - final @Nullable Block b = source.getBlockType(tilePos.add(side.getDirection(), queryPos)); - return Blocks.hasTag(b, BlockTags.FENCES_CONNECT) || (b != null && b.getAttachedSide(source, tilePos.add(side.getDirection(), queryPos)) == side.getOpposite()); + final @Nullable Block b = source.getBlockType(tilePos.add(side.direction(), queryPos)); + return Blocks.hasTag(b, BlockTags.FENCES_CONNECT) || (b != null && b.getAttachedSide(source, tilePos.add(side.direction(), queryPos)) == side.opposite()); } } diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluidFlowing.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluidFlowing.java index 5a927c736..55dd2555a 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluidFlowing.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluidFlowing.java @@ -69,7 +69,7 @@ public class BlockLogicFluidFlowing extends BlockLogicFluid { } else { world.setBlockDataNotify(tilePos, localFlowDecay); world.scheduleBlockUpdate(tilePos, this.block, tickDelay()); - world.notifyBlocksOfNeighborChange(tilePos, this.block); // ? + world.notifyBlocksOfNeighborChange(tilePos, this.block); } } else { setFluidStill(world, tilePos); diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFullyRotatable.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFullyRotatable.java index 3d67c7024..2313016d4 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFullyRotatable.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFullyRotatable.java @@ -16,20 +16,20 @@ public class BlockLogicFullyRotatable extends BlockLogic { @Override public void onPlacedByMob(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, @NotNull Mob mob, double xHit, double yHit) { - final Direction direction = mob.getPlacementDirection(side).getOpposite(); + final Direction direction = mob.getPlacementDirection(side).opposite(); world.setBlockDataNotify(tilePos, directionToMeta(direction)); } @Override public void onPlacedOnSide(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) { - world.setBlockDataNotify(tilePos, directionToMeta(side.getDirection())); + world.setBlockDataNotify(tilePos, directionToMeta(side.direction())); } public static int directionToMeta(Direction direction) { - return direction.getId() & MASK_DIRECTION; + return direction.id; } public static @NotNull Direction metaToDirection(final int data) { - return Direction.getDirectionById(data & MASK_DIRECTION); + return Direction.fromId(data & MASK_DIRECTION); } } diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLadder.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLadder.java index 7969695e9..3d43989b9 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLadder.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLadder.java @@ -78,7 +78,7 @@ public class BlockLogicLadder extends BlockLogic implements ISupportable { public @Nullable Side getSideForPlacement(@NotNull World world, @NotNull TilePos tilePos, @NotNull Side clickedSide) { TilePosc p = tilePos; if (!world.canPlaceInsideBlock(tilePos)) { - p = p.add(clickedSide.getDirection(), new TilePos()); + p = p.add(clickedSide.direction(), new TilePos()); } if (canExistAt(world, p, getMetaForSide(clickedSide))) return clickedSide; @@ -91,7 +91,7 @@ public class BlockLogicLadder extends BlockLogic implements ISupportable { } public boolean canExistAt(@NotNull World world, @NotNull TilePosc tilePos, int meta) { - Side side = getSideFromMeta(meta).getOpposite(); + Side side = getSideFromMeta(meta).opposite(); return isSupported(world, tilePos, side); } diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerAsh.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerAsh.java index 06b608fd0..64492b0b8 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerAsh.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerAsh.java @@ -25,8 +25,7 @@ public class BlockLogicLayerAsh extends BlockLogicLayerBase int myMetadata = world.getBlockData(tilePos); if (myMetadata == 0x7) return; - for (int i = 0; i < Direction.horizontalDirections.length; i++) { - Direction dir = Direction.horizontalDirections[i]; + for (final var dir : Direction.horizontal) { TilePos dirPos = tilePos.add(dir, new TilePos()); if (!((world.isBlockOpaqueCube(dirPos)) || (world.getBlockType(dirPos) == this.block && world.getBlockData(dirPos) >= myMetadata))) return; } diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerLeaves.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerLeaves.java index 52b510ea7..07cc209bc 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerLeaves.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerLeaves.java @@ -35,8 +35,8 @@ public class BlockLogicLayerLeaves extends BlockLogicLayerBase { int myMetadata = world.getBlockData(tilePos); if (myMetadata == 0x7) return; - for (int i = 0; i < Direction.horizontalDirections.length; i++) { - TilePos p = tilePos.add(Direction.horizontalDirections[i], new TilePos()); + for (final var dir : Direction.horizontal) { + TilePos p = tilePos.add(dir, new TilePos()); if (!((world.isBlockOpaqueCube(p)) || (world.getBlockType(p) == this.block && world.getBlockData(p) >= myMetadata))) { return; diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerSnow.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerSnow.java index c4d25e101..a853eafd6 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerSnow.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerSnow.java @@ -32,8 +32,7 @@ public class BlockLogicLayerSnow extends BlockLogicLayerBase { int myMetadata = world.getBlockData(tilePos); if (myMetadata == 0x7) return; - for (int i = 0; i < Direction.horizontalDirections.length; i++) { - Direction dir = Direction.horizontalDirections[i]; + for (final var dir : Direction.horizontal) { TilePos dirPos = tilePos.add(dir, new TilePos()); if (!((world.isBlockOpaqueCube(dirPos)) || (world.getBlockType(dirPos) == this.block && world.getBlockData(dirPos) >= myMetadata))) return; diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLever.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLever.java index d0a5d984c..b14ad73dd 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLever.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLever.java @@ -61,7 +61,7 @@ public class BlockLogicLever extends BlockLogic implements ISupportable { @Override public boolean canPlaceOnSide(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side) { - Side checkSide = side.getOpposite(); + Side checkSide = side.opposite(); return isSupported(world, tilePos, checkSide); } @@ -84,12 +84,12 @@ public class BlockLogicLever extends BlockLogic implements ISupportable { switch (side) { case BOTTOM: if (isSupported(world, tilePos, Side.TOP)) { - rotation = ROTATION_BOTTOM_NS + (mob.getHorizontalPlacementDirection(side).getAxis() == Axis.Z ? 1 : 0); + rotation = ROTATION_BOTTOM_NS + (mob.getHorizontalPlacementDirection(side).axis() == Axis.Z ? 1 : 0); } break; case TOP: if (isSupported(world, tilePos, Side.BOTTOM)) { - rotation = ROTATION_TOP_NS + (mob.getHorizontalPlacementDirection(side).getAxis() == Axis.Z ? 1 : 0); + rotation = ROTATION_TOP_NS + (mob.getHorizontalPlacementDirection(side).axis() == Axis.Z ? 1 : 0); } break; case NORTH: @@ -127,7 +127,7 @@ public class BlockLogicLever extends BlockLogic implements ISupportable { int meta = world.getBlockData(tilePos); boolean isPowered = isPowered(meta); int rotation = -1; - switch (side.getOpposite()) { + switch (side.opposite()) { case BOTTOM -> { if (isSupported(world, tilePos, Side.TOP)) { rotation = ROTATION_BOTTOM_NS; @@ -226,29 +226,31 @@ public class BlockLogicLever extends BlockLogic implements ISupportable { return true; } + private static @NotNull Direction getDirection(int rotation) { + return switch (rotation) { + default -> Direction.NONE; + case ROTATION_EAST -> Direction.WEST; + case ROTATION_WEST -> Direction.EAST; + case ROTATION_SOUTH -> Direction.NORTH; + case ROTATION_NORTH -> Direction.SOUTH; + case ROTATION_TOP_NS, ROTATION_TOP_WE -> Direction.DOWN; + case ROTATION_BOTTOM_NS, ROTATION_BOTTOM_WE -> Direction.UP; + }; + } + public void flip(@NotNull World world, @NotNull TilePosc tilePos, @Nullable Player player) { int meta = world.getBlockData(tilePos); int rotation = getRotation(meta); if (isPowered(meta)) { - world.setBlockDataNotify(tilePos, meta & ~MASK_POWERED); + world.setBlockData(tilePos, meta & ~MASK_POWERED); } else { - world.setBlockDataNotify(tilePos, meta | MASK_POWERED); + world.setBlockData(tilePos, meta | MASK_POWERED); } - world.markBlocksDirty(tilePos, tilePos); + world.markBlockNeedsUpdate(tilePos); world.playSoundEffect(player, SoundCategory.WORLD_SOUNDS, (double) tilePos.x() + 0.5D, (double) tilePos.y() + 0.5D, (double) tilePos.z() + 0.5D, "random.click", 0.3F, isPowered(meta) ? 0.5F : 0.6F); - world.notifyBlocksOfNeighborChange(tilePos, this.block); - TilePos queryPos = new TilePos(); - switch (rotation) { - case ROTATION_EAST -> world.notifyBlocksOfNeighborChange(tilePos.west(queryPos), this.block); - case ROTATION_WEST -> world.notifyBlocksOfNeighborChange(tilePos.east(queryPos), this.block); - case ROTATION_SOUTH -> world.notifyBlocksOfNeighborChange(tilePos.north(queryPos), this.block); - case ROTATION_NORTH -> world.notifyBlocksOfNeighborChange(tilePos.south(queryPos), this.block); - case ROTATION_TOP_NS, ROTATION_TOP_WE -> - world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), this.block); - default -> world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), this.block); - } + world.notifyBlocksInCapsuleOfNeighborChange(getDirection(rotation), tilePos, this.block); } @Override @@ -259,18 +261,8 @@ public class BlockLogicLever extends BlockLogic implements ISupportable { @Override public void onRemoved(@NotNull World world, @NotNull TilePosc tilePos, int data) { if (isPowered(data)) { - world.notifyBlocksOfNeighborChange(tilePos, this.block); - TilePos queryPos = new TilePos(); int rotation = getRotation(data); - switch (rotation) { - case ROTATION_EAST -> world.notifyBlocksOfNeighborChange(tilePos.west(queryPos), this.block); - case ROTATION_WEST -> world.notifyBlocksOfNeighborChange(tilePos.east(queryPos), this.block); - case ROTATION_SOUTH -> world.notifyBlocksOfNeighborChange(tilePos.north(queryPos), this.block); - case ROTATION_NORTH -> world.notifyBlocksOfNeighborChange(tilePos.south(queryPos), this.block); - case ROTATION_TOP_NS, ROTATION_TOP_WE -> - world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), this.block); - default -> world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), this.block); - } + world.notifyBlocksInCapsuleOfNeighborChange(getDirection(rotation), tilePos, this.block); } super.onRemoved(world, tilePos, data); } diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMagma.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMagma.java index 33229309b..448ef8f85 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMagma.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMagma.java @@ -52,7 +52,7 @@ public class BlockLogicMagma extends BlockLogic { public boolean canMelt(@NotNull World world, @NotNull TilePosc tilePos) { boolean canMelt = false; TilePos queryPos = new TilePos(); - for (Direction dir : Direction.directions) { + for (final var dir : Direction.all) { Block block = world.getBlockType(tilePos.add(dir, queryPos)); Material adjacentMaterial = block == null ? Materials.AIR : block.getMaterial(); if (adjacentMaterial == Materials.WATER) { 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 639ef05cc..d247ec354 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 @@ -42,7 +42,7 @@ public class BlockLogicMatcher extends BlockLogicAxisAligned { @Override public void onPlacedByMob(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, @NotNull Mob mob, double xHit, double yHit) { - Axis axis = mob.getPlacementDirection(side, PlacementMode.FACING).getAxis(); + Axis axis = mob.getPlacementDirection(side, PlacementMode.FACING).axis(); world.setBlockDataNotify(tilePos, axisToMeta(axis)); world.scheduleBlockUpdate(tilePos, this.block, tickDelay()); @@ -111,7 +111,7 @@ public class BlockLogicMatcher extends BlockLogicAxisAligned { @Override public boolean isEmittingSignal(@NotNull WorldSource source, @NotNull TilePosc tilePos, @NotNull Side side) { - return this.isActive && (BlockLogicAxisAligned.metaToAxis(source.getBlockData(tilePos)) != side.getAxis()); + return this.isActive && (BlockLogicAxisAligned.metaToAxis(source.getBlockData(tilePos)) != side.axis()); } @Override diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMesh.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMesh.java index 99ea73638..e413fb88e 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMesh.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMesh.java @@ -23,12 +23,6 @@ public class BlockLogicMesh extends BlockLogicTransparent return false; } - @Override - public boolean canPlaceOnSurface() - { - return true; - } - @Override public boolean collidesWithEntity(@NotNull Entity entity, @NotNull World world, @NotNull TilePosc tilePos) { return !(entity instanceof EntityItem); diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMobSpawnerDeactivated.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMobSpawnerDeactivated.java index e2058485e..1792e738d 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMobSpawnerDeactivated.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMobSpawnerDeactivated.java @@ -23,12 +23,6 @@ public class BlockLogicMobSpawnerDeactivated extends BlockLogicTransparent { return false; } - @Override - public boolean canPlaceOnSurface() - { - return true; - } - @Override public boolean collidesWithEntity(@NotNull Entity entity, @NotNull World world, @NotNull TilePosc tilePos) { return !(entity instanceof EntityItem); diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMoss.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMoss.java index 54cd8e48f..3e0fc96f6 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMoss.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMoss.java @@ -36,7 +36,7 @@ public class BlockLogicMoss extends BlockLogic implements IBonemealable { if (world.areBlocksLoaded(tilePos, 16)) { if (rand.nextInt(20) == 0 && airExposed(world, tilePos)) { - Direction rDir = Direction.getDirectionById(rand.nextInt(6)); + Direction rDir = Direction.ID_MAP[rand.nextInt(6)]; TilePos randomPos = tilePos.add(rDir, new TilePos()); if (canMossSpread(world, randomPos)) { @Nullable Block mossStone = getMossBlock(world.getBlockType(randomPos)); @@ -54,8 +54,7 @@ public class BlockLogicMoss extends BlockLogic implements IBonemealable { int maxBlockLight = 0; int maxSkyLight = 0; TilePos queryPos = new TilePos(); - for (int i = 0; i < Direction.directions.length; i++) { - Direction dir = Direction.directions[i]; + for (final var dir : Direction.all) { TilePos offsetPos = tilePos.add(dir, queryPos); int blockLight = world.getBlockLightValue(offsetPos); int skyLight = world.getSavedLightValue(LightLayer.Sky, offsetPos); @@ -134,8 +133,7 @@ public class BlockLogicMoss extends BlockLogic implements IBonemealable { public boolean airExposed(@NotNull World world, @NotNull TilePosc tilePos) { TilePos queryPos = new TilePos(); - for (int i = 0; i < Direction.directions.length; i++) { - Direction dir = Direction.directions[i]; + for (final var dir : Direction.all) { if (world.isAirBlock(tilePos.add(dir, queryPos))) return true; } return false; diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMotionSensor.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMotionSensor.java index 7b2c23008..794d81e3e 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMotionSensor.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMotionSensor.java @@ -35,8 +35,7 @@ public class BlockLogicMotionSensor extends BlockLogicVeryRotatable { TilePos queryPos = new TilePos(); final int brightness = 10; double d = 0.0625; - for (int i = 0; i < Direction.directions.length; i++) { - Direction dir = Direction.directions[i]; + for (final var dir : Direction.all) { double px = (double) tilePos.x() + rand.nextFloat(); double py = (double) tilePos.y() + rand.nextFloat(); double pz = (double) tilePos.z() + rand.nextFloat(); diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreRedstone.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreRedstone.java index 8e9237aae..28070ac04 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreRedstone.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreRedstone.java @@ -111,8 +111,7 @@ public class BlockLogicOreRedstone extends BlockLogic { final double d = 0.0625; TilePos queryPos = new TilePos(); - for (int i = 0; i < Direction.directions.length; i++) { - Direction dir = Direction.directions[i]; + for (final var dir : Direction.all) { double px = (double) tilePos.x() + random.nextFloat(); double py = (double) tilePos.y() + random.nextFloat(); double pz = (double) tilePos.z() + random.nextFloat(); diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOverlayPebbles.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOverlayPebbles.java index c9032d5f7..abacf19c0 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOverlayPebbles.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOverlayPebbles.java @@ -2,7 +2,9 @@ package net.minecraft.core.block; import net.minecraft.core.block.entity.TileEntity; import net.minecraft.core.block.material.Material; +import net.minecraft.core.block.support.FullSupport; import net.minecraft.core.block.support.ISupport; +import net.minecraft.core.block.support.ISupportable; import net.minecraft.core.block.support.PartialSupport; import net.minecraft.core.enums.EnumDropCause; import net.minecraft.core.item.Items; @@ -16,7 +18,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.joml.primitives.AABBdc; -public class BlockLogicOverlayPebbles extends BlockLogic { +public class BlockLogicOverlayPebbles extends BlockLogic + implements ISupportable +{ public static final int MAX_PEBBLES = 3; public static final int MASK_PEBBLE_AMOUNT = 0b0000_0011; public BlockLogicOverlayPebbles(@NotNull Block block, @NotNull Material material) { @@ -37,8 +41,7 @@ public class BlockLogicOverlayPebbles extends BlockLogic { @Override public boolean canPlaceAt(@NotNull World world, @NotNull TilePosc tilePos) { - Block block = world.getBlockType(tilePos.down(new TilePos())); - return block.getMaterial().isSolid(); + return this.isSupported(world, tilePos, Side.BOTTOM); } @Override @@ -89,4 +92,9 @@ public class BlockLogicOverlayPebbles extends BlockLogic { public static int getStackCount(int data) { return data & MASK_PEBBLE_AMOUNT; } + + @Override + public @NotNull ISupport getSupportConstraint(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side) { + return FullSupport.INSTANCE; + } } diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPressurePlate.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPressurePlate.java index 32902034e..10a3271ae 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPressurePlate.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPressurePlate.java @@ -109,7 +109,7 @@ public class BlockLogicPressurePlate extends BlockLogic implem private void updateState(@NotNull World world, @NotNull TilePosc tilePos) { int meta = world.getBlockData(tilePos); boolean isPressed = isPressed(meta); - Direction dir = sideFromMeta(meta).getDirection(); + Direction dir = sideFromMeta(meta).direction(); boolean isSteppedOn = false; float pixel = 0.125F; List list = switch (sideFromMeta(meta)) { @@ -134,15 +134,15 @@ public class BlockLogicPressurePlate extends BlockLogic implem } } if (isSteppedOn && !isPressed) { - world.setBlockDataNotify(tilePos, meta | MASK_POWERED); - // world.notifyBlocksOfNeighborChange(tilePos, this.block); - world.notifyBlocksOfNeighborChange(tilePos.add(dir, new TilePos()), this.block); + world.setBlockData(tilePos, meta | MASK_POWERED); + world.markBlockNeedsUpdate(tilePos); + world.notifyBlocksInCapsuleOfNeighborChange(dir, tilePos, this.block); world.markBlocksDirty(tilePos, tilePos); world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, (double) tilePos.x() + 0.5D, (double) tilePos.y() + 0.1D, (double) tilePos.z() + 0.5D, "random.click", 0.3F, 0.6F); } else if (!isSteppedOn && isPressed) { - world.setBlockDataNotify(tilePos, meta & ~MASK_POWERED); - // world.notifyBlocksOfNeighborChange(tilePos, this.block); - world.notifyBlocksOfNeighborChange(tilePos.add(dir, new TilePos()), this.block); + world.setBlockData(tilePos, meta & ~MASK_POWERED); + world.markBlockNeedsUpdate(tilePos); + world.notifyBlocksInCapsuleOfNeighborChange(dir, tilePos, this.block); world.markBlocksDirty(tilePos, tilePos); world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, (double) tilePos.x() + 0.5D, (double) tilePos.y() + 0.1D, (double) tilePos.z() + 0.5D, "random.click", 0.3F, 0.5F); } @@ -155,8 +155,7 @@ public class BlockLogicPressurePlate extends BlockLogic implem public void onRemoved(@NotNull World world, @NotNull TilePosc tilePos, int data) { if (isPressed(data)) { Side side = sideFromMeta(world.getBlockData(tilePos)); - world.notifyBlocksOfNeighborChange(tilePos, this.block); - world.notifyBlocksOfNeighborChange(tilePos.add(side.getDirection(), new TilePos()), this.block); + world.notifyBlocksInCapsuleOfNeighborChange(side.direction(), tilePos, this.block); } super.onRemoved(world, tilePos, data); } @@ -185,7 +184,7 @@ public class BlockLogicPressurePlate extends BlockLogic implem public boolean isEmittingDirectSignal(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side) { int meta = world.getBlockData(tilePos); if (isPressed(meta)) { - return side == sideFromMeta(meta).getOpposite(); + return side == sideFromMeta(meta).opposite(); } else { return false; } @@ -196,11 +195,11 @@ public class BlockLogicPressurePlate extends BlockLogic implem } public static int setSide(int meta, @NotNull Side side) { - return (meta & ~MASK_SIDE) | (side.getId() << 1); + return (meta & ~MASK_SIDE) | (side.id << 1); } public static @NotNull Side sideFromMeta(int meta) { - return Side.getSideById((meta & MASK_SIDE) >> 1); + return Side.fromId((meta & MASK_SIDE) >> 1); } @Override @@ -216,7 +215,7 @@ public class BlockLogicPressurePlate extends BlockLogic implem @Override public void onPlacedOnSide(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) { int meta = world.getBlockData(tilePos); - side = side.getOpposite(); + side = side.opposite(); if (!isSupported(world, tilePos, side)) { side = getDefaultSide(world, tilePos); } diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumice.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumice.java index df4f52456..b69ebfa67 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumice.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumice.java @@ -89,7 +89,7 @@ public class BlockLogicPumice extends BlockLogic { @Override public void animationTick(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Random rand) { if (this.isWet) { - Direction direction = Direction.directions[rand.nextInt(6)]; // Get random side + Direction direction = Direction.ID_MAP[rand.nextInt(6)]; // Get random side if (direction == Direction.UP || world.isBlockOpaqueCube(tilePos.add(direction, new TilePos()))) return; float off1 = rand.nextFloat() * 0.9f + 0.05f; float off2 = rand.nextFloat() * 0.9f + 0.05f; diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumpkin.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumpkin.java index b54fa7cf8..bab15fb27 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumpkin.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumpkin.java @@ -30,7 +30,7 @@ public class BlockLogicPumpkin extends BlockLogicVeryRotatable ItemStack heldItem = player.getHeldItem(); if (heldItem != null && heldItem.getItem() instanceof ItemToolSword){ heldItem.damageItem(1,player); - world.setBlockTypeDataNotify(tilePos, Blocks.PUMPKIN_CARVED_IDLE, player.getHorizontalPlacementDirection(Direction.getHorizontalDirection(player).getSide()).getOpposite().getId()); + world.setBlockTypeDataNotify(tilePos, Blocks.PUMPKIN_CARVED_IDLE, player.getHorizontalPlacementDirection(Direction.getHorizontalLockable(player).side()).opposite().id); return true; } return false; diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumpkinRedstone.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumpkinRedstone.java index 381ab4251..3fe46ef80 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumpkinRedstone.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumpkinRedstone.java @@ -18,16 +18,13 @@ public class BlockLogicPumpkinRedstone extends BlockLogicVeryRotatable { @Override public void onPlacedByWorld(@NotNull World world, @NotNull TilePosc tilePos) { - TilePos queryPos = new TilePos(); - for (Direction dir : Direction.directions){ - world.notifyBlocksOfNeighborChange(tilePos.add(dir, queryPos), this.block); - } + world.notifyShellBlocksInRadiusOfNeighborChange(2, tilePos, this.block); } @Override public void onRemoved(@NotNull World world, @NotNull TilePosc tilePos, int data) { TilePos queryPos = new TilePos(); - for (Direction dir : Direction.directions){ + for (final var dir : Direction.all){ world.notifyBlocksOfNeighborChange(tilePos.add(dir, queryPos), this.block); } } @@ -39,8 +36,8 @@ public class BlockLogicPumpkinRedstone extends BlockLogicVeryRotatable { @Override public boolean isEmittingSignal(@NotNull WorldSource source, @NotNull TilePosc tilePos, @NotNull Side side) { - Side mySide = Side.getSideById(source.getBlockData(tilePos)); - return mySide == side.getOpposite(); + Side mySide = Side.fromId(source.getBlockData(tilePos)); + return mySide == side.opposite(); } @Override diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRail.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRail.java index 029969654..b55e3f37e 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRail.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRail.java @@ -9,6 +9,7 @@ import net.minecraft.core.block.support.ISupportable; import net.minecraft.core.block.support.PartialSupport; import net.minecraft.core.enums.EnumDropCause; import net.minecraft.core.util.helper.Axis; +import net.minecraft.core.util.helper.Direction; import net.minecraft.core.util.helper.Side; import net.minecraft.core.world.World; import net.minecraft.core.world.WorldSource; @@ -134,18 +135,25 @@ public class BlockLogicRail extends BlockLogic implements ISupportable { boolean changedMeta = false; if (gettingPower && !isPoweredFlagSet) { // Set powered bit - world.setBlockDataNotify(tilePos, railDirection.meta | MASK_POWERED); + world.setBlockData(tilePos, railDirection.meta | MASK_POWERED); changedMeta = true; } else if (!gettingPower && isPoweredFlagSet) { // Remove powered bit - world.setBlockDataNotify(tilePos, railDirection.meta); + world.setBlockData(tilePos, railDirection.meta); changedMeta = true; } + world.markBlockNeedsUpdate(tilePos); + if (changedMeta) { - world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), this.block); - if (railDirection.isSloped()) { - world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), this.block); + if (!railDirection.isSloped()) { + world.notifyBlocksInCapsuleOfNeighborChange(Direction.DOWN, tilePos, this.block); + } else { + world.notifyBlocksOfNeighborChanges(new TilePosc[] { + tilePos, + tilePos.down(queryPos), + tilePos.up(new TilePos()), + }, this.block); } } } else if (block != null && block.isSignalSource() && new Rail(world, tilePos).getAdjacentTracks() == 3) { diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRailDetector.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRailDetector.java index c20b3a53b..ebaf81c12 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRailDetector.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRailDetector.java @@ -5,6 +5,7 @@ import java.util.Random; import net.minecraft.core.entity.Entity; import net.minecraft.core.entity.vehicle.EntityMinecart; +import net.minecraft.core.util.helper.Direction; import net.minecraft.core.util.helper.Side; import net.minecraft.core.world.WorldSource; import net.minecraft.core.world.World; @@ -76,15 +77,15 @@ public class BlockLogicRailDetector extends BlockLogicRail { } if (minecartPresent && !isPowered) { // Set rail to powered - world.setBlockDataNotify(tilePos, meta | MASK_POWERED); - world.notifyBlocksOfNeighborChange(tilePos, this.block); - world.notifyBlocksOfNeighborChange(tilePos.down(new TilePos()), this.block); + world.setBlockData(tilePos, meta | MASK_POWERED); + world.markBlockNeedsUpdate(tilePos); + world.notifyBlocksInCapsuleOfNeighborChange(Direction.DOWN, tilePos, this.block); world.markBlockDirty(tilePos); } else if (!minecartPresent && isPowered) { // Set rail to unpowered - world.setBlockDataNotify(tilePos, meta & ~MASK_POWERED); - world.notifyBlocksOfNeighborChange(tilePos, this.block); - world.notifyBlocksOfNeighborChange(tilePos.down(new TilePos()), this.block); + world.setBlockData(tilePos, meta & ~MASK_POWERED); + world.markBlockNeedsUpdate(tilePos); + world.notifyBlocksInCapsuleOfNeighborChange(Direction.DOWN, tilePos, this.block); world.markBlockDirty(tilePos); } if (minecartPresent) { diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRedstone.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRedstone.java index 3b548f2df..b5c8862f7 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRedstone.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRedstone.java @@ -33,18 +33,12 @@ public class BlockLogicRedstone extends BlockLogic { @Override public void onPlacedByWorld(@NotNull World world, @NotNull TilePosc tilePos) { - TilePos queryPos = new TilePos(); - for (Direction dir : Direction.directions) { - world.notifyBlocksOfNeighborChange(tilePos.add(dir, queryPos), this.block); - } + world.notifyBlocksInRadiusOfNeighborChange(2, tilePos, this.block); } @Override public void onRemoved(@NotNull World world, @NotNull TilePosc tilePos, int data) { - TilePos queryPos = new TilePos(); - for (Direction dir : Direction.directions) { - world.notifyBlocksOfNeighborChange(tilePos.add(dir, queryPos), this.block); - } + world.notifyBlocksInRadiusOfNeighborChange(2, tilePos, this.block); } @@ -56,38 +50,38 @@ public class BlockLogicRedstone extends BlockLogic { final double d = 0.0625; TilePos queryPos = new TilePos(); - for (Direction dir : Direction.directions) { + for (final var dir : Direction.all) { double px = (double) tilePos.x() + random.nextFloat(); double py = (double) tilePos.y() + random.nextFloat(); double pz = (double) tilePos.z() + random.nextFloat(); switch (dir) { case DOWN: - if (!world.isBlockOpaqueCube(tilePos.add(dir.getOpposite(), queryPos))) { + if (!world.isBlockOpaqueCube(tilePos.add(dir.opposite(), queryPos))) { py = (tilePos.y() + 1) + d; } break; case UP: - if (!world.isBlockOpaqueCube(tilePos.add(dir.getOpposite(), queryPos))) { + if (!world.isBlockOpaqueCube(tilePos.add(dir.opposite(), queryPos))) { py = (tilePos.y() + 0) - d; } break; case NORTH: - if (!world.isBlockOpaqueCube(tilePos.add(dir.getOpposite(), queryPos))) { + if (!world.isBlockOpaqueCube(tilePos.add(dir.opposite(), queryPos))) { pz = (tilePos.z() + 1) + d; } break; case SOUTH: - if (!world.isBlockOpaqueCube(tilePos.add(dir.getOpposite(), queryPos))) { + if (!world.isBlockOpaqueCube(tilePos.add(dir.opposite(), queryPos))) { pz = (tilePos.z() + 0) - d; } break; case WEST: - if (!world.isBlockOpaqueCube(tilePos.add(dir.getOpposite(), queryPos))) { + if (!world.isBlockOpaqueCube(tilePos.add(dir.opposite(), queryPos))) { px = (tilePos.x() + 1) + d; } break; case EAST: - if (!world.isBlockOpaqueCube(tilePos.add(dir.getOpposite(), queryPos))) { + if (!world.isBlockOpaqueCube(tilePos.add(dir.opposite(), queryPos))) { px = (tilePos.x() + 0) - d; } break; diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRepeater.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRepeater.java index b4a081d48..7fa8e6d3f 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRepeater.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRepeater.java @@ -67,17 +67,22 @@ public class BlockLogicRepeater extends BlockLogic implements ISupportable { @Override public boolean canStay(@NotNull World world, @NotNull TilePosc tilePos) { - return world.canPlaceOnSurfaceOfBlock(tilePos.down(new TilePos())) && super.canStay(world, tilePos); + return this.isSupported(world, tilePos, Side.BOTTOM) && super.canStay(world, tilePos); } @Override public void updateTick(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Random rand, boolean isRandomTick) { int meta = world.getBlockData(tilePos); boolean powered = isGettingPower(world, tilePos, meta); + var side = getSideFromMeta(meta); if (this.isRepeaterPowered && !powered) { - world.setBlockTypeDataNotify(tilePos, Blocks.REPEATER_IDLE, meta); + world.setBlockTypeDataRaw(tilePos, Blocks.REPEATER_IDLE, meta); + world.markBlockNeedsUpdate(tilePos); + world.notifyBlocksInCapsuleOfNeighborChange(side.opposite(), tilePos, Blocks.REPEATER_IDLE); } else if (!this.isRepeaterPowered) { - world.setBlockTypeDataNotify(tilePos, Blocks.REPEATER_ACTIVE, meta); + world.setBlockTypeDataRaw(tilePos, Blocks.REPEATER_ACTIVE, meta); + world.markBlockNeedsUpdate(tilePos); + world.notifyBlocksInCapsuleOfNeighborChange(side.opposite(), tilePos, Blocks.REPEATER_IDLE); if (!powered) { int tickDelay = (meta & MASK_TICK_DELAY) >> 2; world.scheduleBlockUpdate(tilePos, Blocks.REPEATER_ACTIVE, tickDelayMap[tickDelay] * 2); @@ -96,8 +101,8 @@ public class BlockLogicRepeater extends BlockLogic implements ISupportable { @Override public void onRemoved(@NotNull World world, @NotNull TilePosc tilePos, int data) { Side back = getSideFromMeta(data); - Side front = back.getOpposite(); - world.notifyBlocksOfNeighborChange(tilePos.add(front.getDirection(), new TilePos()), this.block); + Side front = back.opposite(); + world.notifyBlocksOfNeighborChange(tilePos.add(front.direction(), new TilePos()), this.block); } @Override @@ -144,7 +149,7 @@ public class BlockLogicRepeater extends BlockLogic implements ISupportable { Side direction = getSideFromMeta(meta); if (direction.isVertical()) return false; - TilePos p = tilePos.add(direction.getDirection(), new TilePos()); + TilePos p = tilePos.add(direction.direction(), new TilePos()); return world.hasSignal(p, direction) || (world.getBlockType(p) == Blocks.WIRE_REDSTONE && (world.getBlockData(p) & BlockLogicWireRedstone.MASK_POWER) != 0); } @@ -168,7 +173,7 @@ public class BlockLogicRepeater extends BlockLogic implements ISupportable { @Override public void onPlacedByMob(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, @NotNull Mob mob, double xHit, double yHit) { - int l = mob.getHorizontalPlacementDirection(side).index; + int l = mob.getHorizontalPlacementDirection(side).legacyIndex(); world.setBlockDataNotify(tilePos, l); if (isGettingPower(world, tilePos, l)) { world.scheduleBlockUpdate(tilePos, this.block, 1); @@ -178,7 +183,7 @@ public class BlockLogicRepeater extends BlockLogic implements ISupportable { @Override public void onPlacedOnSide(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) { if (!side.isHorizontal()) side = Side.NORTH; - int l = side.getDirection().index; + int l = side.direction().legacyIndex(); world.setBlockDataNotify(tilePos, l); if (isGettingPower(world, tilePos, l)) { world.scheduleBlockUpdate(tilePos, this.block, 1); diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRotatable.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRotatable.java index b446cf34a..df176e776 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRotatable.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRotatable.java @@ -17,22 +17,22 @@ public abstract class BlockLogicRotatable extends BlockLogic { } public static @NotNull Direction getDirectionFromMeta(int meta) { - return Direction.getDirectionById(meta & MASK_DIRECTION); + return Direction.fromId(meta & MASK_DIRECTION); } public static int setDirection(int meta, Direction direction) { - return (meta & ~MASK_DIRECTION) | direction.getId(); + return (meta & ~MASK_DIRECTION) | direction.id; } @Override public void onPlacedByMob(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, @NotNull Mob mob, double xHit, double yHit) { - world.setBlockDataNotify(tilePos, mob.getHorizontalPlacementDirection(side).getOpposite().getId()); + world.setBlockDataNotify(tilePos, mob.getHorizontalPlacementDirection(side).opposite().id); } @Override public void onPlacedOnSide(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) { if (!side.isHorizontal()) side = Side.SOUTH; - world.setBlockDataNotify(tilePos, BlockLogicRotatable.setDirection(0, side.getDirection())); + world.setBlockDataNotify(tilePos, BlockLogicRotatable.setDirection(0, side.direction())); } public static void setDefaultDirection(@NotNull World world, @NotNull TilePosc tilePos) { diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglass.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglass.java index 73e0d2fa8..79e2988bf 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglass.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglass.java @@ -36,13 +36,12 @@ public class BlockLogicRubyglass extends BlockLogic } if (rand.nextInt(10) == 0) { - final int dir = rand.nextInt(6); - final @NotNull Direction direction = Direction.getDirectionById(dir); + final @NotNull Direction direction = Direction.ID_MAP[rand.nextInt(6)]; final @NotNull TilePos checkPos = tilePos.add(direction, new TilePos()); final @NotNull Block checkBlock = world.getBlockType(checkPos); if (checkBlock == Blocks.AIR) { - world.spawnParticle("rubyglassLightning", tilePos.x(), tilePos.y(), tilePos.z(), 0, 0, 0, dir, 1600d, true); + world.spawnParticle("rubyglassLightning", tilePos.x(), tilePos.y(), tilePos.z(), 0, 0, 0, direction.id, 1600d, true); } } } diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglassSprout.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglassSprout.java index 35fff8255..026c98085 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglassSprout.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglassSprout.java @@ -32,7 +32,7 @@ public class BlockLogicRubyglassSprout extends BlockLogic { || (side == Side.WEST && world.isBlockNormalCube(tilePos.east(temp))) || (side == Side.BOTTOM && world.isBlockNormalCube(tilePos.up(temp))) || (side == Side.TOP && world.isBlockNormalCube(tilePos.down(temp)))) { - world.setBlockDataNotify(tilePos, BlockLogicRotatable.setDirection(0, side.getDirection())); + world.setBlockDataNotify(tilePos, BlockLogicRotatable.setDirection(0, side.direction())); } else { world.setBlockDataNotify(tilePos, BlockLogicRotatable.setDirection(0, getOrientation(world, tilePos))); } @@ -43,26 +43,26 @@ public class BlockLogicRubyglassSprout extends BlockLogic { final @NotNull TilePos temp = new TilePos(); if(world.isBlockNormalCube(tilePos.west(temp))) { - return Side.EAST.getDirection(); + return Side.EAST.direction(); } if(world.isBlockNormalCube(tilePos.east(temp))) { - return Side.WEST.getDirection(); + return Side.WEST.direction(); } if(world.isBlockNormalCube(tilePos.south(temp))) { - return Side.NORTH.getDirection(); + return Side.NORTH.direction(); } if (world.isBlockNormalCube(tilePos.north(temp))){ - return Side.SOUTH.getDirection(); + return Side.SOUTH.direction(); } if (world.isBlockNormalCube(tilePos.down(temp))){ - return Side.TOP.getDirection(); + return Side.TOP.direction(); } if (world.isBlockNormalCube(tilePos.up(temp))){ - return Side.BOTTOM.getDirection(); + return Side.BOTTOM.direction(); } - return Side.TOP.getDirection(); + return Side.TOP.direction(); } @Override @@ -170,7 +170,7 @@ public class BlockLogicRubyglassSprout extends BlockLogic { { direction = Direction.DOWN; } - world.setBlockDataNotify(tilePos, direction.getId()); + world.setBlockDataNotify(tilePos, direction.id); } @Override @@ -190,7 +190,7 @@ public class BlockLogicRubyglassSprout extends BlockLogic { } public static Direction metaToDirection(int meta) { - return Direction.getDirectionById(meta & MASK_DIRECTION); + return Direction.fromId(meta & MASK_DIRECTION); } } diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSlab.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSlab.java index 9dfd95b90..cd85f0a6f 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSlab.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSlab.java @@ -82,12 +82,6 @@ public class BlockLogicSlab extends BlockLogic return (meta & MASK_STATE) == STATE_DOUBLE; } - @Override - public boolean canPlaceOnSurfaceOnCondition(@NotNull World world, @NotNull TilePosc tilePos) { - int meta = world.getBlockData(tilePos); - return (meta & MASK_STATE) != STATE_LOWER; - } - @Override public @NotNull ISupport getSupport(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side) { int state = world.getBlockData(tilePos) & MASK_STATE; diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSpikes.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSpikes.java index 185255109..8236bc71d 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSpikes.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSpikes.java @@ -46,16 +46,16 @@ public class BlockLogicSpikes extends BlockLogic meta |= MASK_POWERED; } - Direction placeDir = sidePlacedOnto.getOpposite().getDirection(); + Direction placeDir = sidePlacedOnto.opposite().direction(); if (mob instanceof Player player) { - if (player.rotationLock != null && player.rotationLock != Direction.NONE) { + if (player.rotationLock != null) { placeDir = player.rotationLock; } } meta &= ~MASK_DIRECTION; - meta |= ((placeDir.getId() << 1) & MASK_DIRECTION); + meta |= placeDir.id << 1; world.setBlockDataNotify(tilePos, meta); } @@ -145,7 +145,7 @@ public class BlockLogicSpikes extends BlockLogic } public static @NotNull Direction getDirectionFromData(int data) { - return Direction.getDirectionById((data & MASK_DIRECTION) >> 1); + return Direction.fromId((data & MASK_DIRECTION) >> 1); } @Override diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSponge.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSponge.java index 171e60515..2a1c03195 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSponge.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSponge.java @@ -51,8 +51,7 @@ public class BlockLogicSponge extends BlockLogic { public boolean inWater(@NotNull World world, @NotNull TilePosc tilePos) { TilePos queryPos = new TilePos(); - for (int i = 0; i < Direction.directions.length; i++) { - Direction dir = Direction.directions[i]; + for (final var dir : Direction.all) { Block b = world.getBlockType(tilePos.add(dir, queryPos)); if (Blocks.hasTag(b, BlockTags.IS_WATER)) return true; } @@ -61,8 +60,7 @@ public class BlockLogicSponge extends BlockLogic { public boolean inHot(@NotNull World world, @NotNull TilePosc tilePos) { TilePos queryPos = new TilePos(); - for (int i = 0; i < Direction.directions.length; i++) { - Direction dir = Direction.directions[i]; + for (final var dir : Direction.all) { Block b = world.getBlockType(tilePos.add(dir, queryPos)); if (b == Blocks.MAGMA || Blocks.hasTag(b, BlockTags.IS_LAVA)) return true; } @@ -89,7 +87,7 @@ public class BlockLogicSponge extends BlockLogic { public void animationTick(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Random rand) { if (this.isWet) { Side side = Side.sides[rand.nextInt(6)]; // Get random side - if (side == Side.TOP || world.isBlockOpaqueCube(tilePos.add(side.getDirection(), new TilePos()))) return; + if (side == Side.TOP || world.isBlockOpaqueCube(tilePos.add(side.direction(), new TilePos()))) return; float off1 = rand.nextFloat() * 0.9f + 0.05f; float off2 = rand.nextFloat() * 0.9f + 0.05f; float lOff = 0.01f; // Dumb offset to fix bad lighting diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicStairs.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicStairs.java index e4379a2b9..3ce6bd769 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicStairs.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicStairs.java @@ -200,19 +200,14 @@ public class BlockLogicStairs extends BlockLogic { return false; } - @Override - public boolean canPlaceOnSurfaceOnCondition(@NotNull World world, @NotNull TilePosc tilePos) { - return (world.getBlockData(tilePos) & MASK_ROTATION_VERTICAL) != 0; - } - @Override public @NotNull ISupport getSupport(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side) { int meta = world.getBlockData(tilePos); int hRot = meta & MASK_ROTATION_HORIZONTAL; if ((meta & MASK_ROTATION_VERTICAL) != 0) { - return upperStairsSupportMapping[side.getId() * 4 + hRot]; + return upperStairsSupportMapping[side.id * 4 + hRot]; } else { - return lowerStairsSupportMapping[side.getId() * 4 + hRot]; + return lowerStairsSupportMapping[side.id * 4 + hRot]; } } @@ -340,7 +335,7 @@ public class BlockLogicStairs extends BlockLogic { public void onPlacedByMob(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, @NotNull Mob mob, double xHit, double yHit) { int meta = world.getBlockData(tilePos) & 0xF0; - Direction hRotation = mob.getHorizontalPlacementDirection(side).getOpposite(); + Direction hRotation = mob.getHorizontalPlacementDirection(side).opposite(); if (hRotation == Direction.NORTH) meta |= H_ROTATION_NORTH; if (hRotation == Direction.EAST) meta |= H_ROTATION_EAST; if (hRotation == Direction.SOUTH) meta |= H_ROTATION_SOUTH; @@ -357,16 +352,16 @@ public class BlockLogicStairs extends BlockLogic { public void onPlacedOnSide(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) { int meta = world.getBlockData(tilePos) & 0xF0; - side = side.getOpposite(); + side = side.opposite(); Side hSide = !side.isHorizontal() ? Side.NORTH : side; - Direction hRotation = hSide.getOpposite().getDirection(); + Direction hRotation = hSide.opposite().direction(); if (hRotation == Direction.NORTH) meta |= H_ROTATION_NORTH; if (hRotation == Direction.EAST) meta |= H_ROTATION_EAST; if (hRotation == Direction.SOUTH) meta |= H_ROTATION_SOUTH; if (hRotation == Direction.WEST) meta |= H_ROTATION_WEST; Side vSide = !side.isVertical() ? Side.BOTTOM : side; - Direction vRotation = vSide.getDirection(); + Direction vRotation = vSide.direction(); // if (vRotation == Direction.DOWN) meta |= 0b0000; if (vRotation == Direction.UP) meta |= MASK_ROTATION_VERTICAL; diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicTimer.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTimer.java new file mode 100644 index 000000000..21648dc61 --- /dev/null +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTimer.java @@ -0,0 +1,214 @@ +package net.minecraft.core.block; + +import net.minecraft.core.block.entity.TileEntity; +import net.minecraft.core.block.entity.TileEntityActivator; +import net.minecraft.core.block.entity.TileEntityTimer; +import net.minecraft.core.block.material.Materials; +import net.minecraft.core.block.support.FullSupport; +import net.minecraft.core.block.support.ISupport; +import net.minecraft.core.block.support.ISupportable; +import net.minecraft.core.block.support.PartialSupport; +import net.minecraft.core.entity.Mob; +import net.minecraft.core.entity.player.Player; +import net.minecraft.core.enums.EnumDropCause; +import net.minecraft.core.item.ItemStack; +import net.minecraft.core.item.Items; +import net.minecraft.core.util.helper.Axis; +import net.minecraft.core.util.helper.Direction; +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.TilePos; +import net.minecraft.core.world.pos.TilePosc; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Random; + +public class BlockLogicTimer extends BlockLogic implements ISupportable { + public static final double[] torchPosOffset = { + -0.0625D, 0.0625D, 0.1875D, 0.3125D + }; + public static final int[] tickDelayMap = { + 4, 8, 12, 16 + }; + + public static final int MASK_AXIS = 0b0000_0001; + public static final int AXIS_SOUTH_NORTH = 0; + public static final int AXIS_WEST_EAST = 1; + + public static final int MASK_OUTPUT = 0b0000_0010; + public static final int OUTPUT_A = 0 << 1; + public static final int OUTPUT_B = 1 << 1; + + public static final int MASK_DIRECTION = MASK_AXIS | MASK_OUTPUT; + public static final int DIRECTION_SOUTH = OUTPUT_A | AXIS_SOUTH_NORTH; + public static final int DIRECTION_WEST = OUTPUT_A | AXIS_WEST_EAST; + public static final int DIRECTION_NORTH = OUTPUT_B | AXIS_SOUTH_NORTH; + public static final int DIRECTION_EAST = OUTPUT_B | AXIS_WEST_EAST; + + public static final int MASK_TICK_DELAY = 0b0000_1100; + + public BlockLogicTimer(@NotNull Block block) { + super(block, Materials.DECORATION); + setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); + block.withEntity(TileEntityTimer::new); + } + + @Override + public boolean isCubeShaped() { + return false; + } + + @Override + public @NotNull ISupport getSupport(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side) { + return PartialSupport.INSTANCE; + } + + @Override + public boolean canPlaceAt(@NotNull World world, @NotNull TilePosc tilePos) { + return this.isSupported(world, tilePos, Side.BOTTOM); + } + + @Override + public ItemStack[] getBreakResult(@NotNull World world, @NotNull EnumDropCause dropCause, int data, @Nullable TileEntity tileEntity) { + return new ItemStack[]{new ItemStack(Items.TIMER)}; + } + + @Override + public boolean canStay(@NotNull World world, @NotNull TilePosc tilePos) { + return this.isSupported(world, tilePos, Side.BOTTOM) && super.canStay(world, tilePos); + } + + // Ensure that timers can activate doors, tnt, and other redstone components through powering a neighboring block. + @Override + public boolean isSignalSource() { + return true; + } + + // Cause block updates on the target block when removing a timer, + // which prevents redstone components on the other wide of the target block from staying powered. + @Override + public void onRemoved(@NotNull World world, @NotNull TilePosc tilePos, int data) { + Side back = getSideFromMeta(data); + Side front = back.opposite(); + world.notifyBlocksOfNeighborChange(tilePos.add(front.direction(), new TilePos()), this.block); + } + + @Override + public boolean isEmittingDirectSignal(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side) { + return isEmittingSignal(world, tilePos, side); + } + + @Override + public boolean isEmittingSignal(@NotNull WorldSource source, @NotNull TilePosc tilePos, @NotNull Side side) { + return side == getSideFromMeta(source.getBlockData(tilePos)); + } + + public static @NotNull Side getSideFromMeta(final int meta) { + return switch (meta & MASK_DIRECTION) { + case DIRECTION_SOUTH -> Side.SOUTH; + case DIRECTION_WEST -> Side.WEST; + case DIRECTION_NORTH -> Side.NORTH; + case DIRECTION_EAST -> Side.EAST; + default -> throw new RuntimeException("No side for direction " + (meta & 0b11) + "!"); + }; + } + + @Override + public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block block) { + if (!canStay(world, tilePos)) { + dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null); + world.setBlockTypeNotify(tilePos, Blocks.AIR); + } + } + + @Override + public boolean onInteracted(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Player player, @Nullable Side side, double xHit, double yHit) { + int metadata = world.getBlockData(tilePos); + int tickDelay = (metadata & MASK_TICK_DELAY) >> 2; + tickDelay = ((tickDelay + 1) << 2) & MASK_TICK_DELAY; + world.setBlockDataNotify(tilePos, tickDelay | metadata & MASK_DIRECTION); + return true; + } + + @Override + public void onActivatorInteracted(@NotNull World world, @NotNull TilePosc tilePos, @NotNull TileEntityActivator activator, @NotNull Direction direction) { + int metadata = world.getBlockData(tilePos); + int tickDelay = (metadata & MASK_TICK_DELAY) >> 2; + tickDelay = ((tickDelay + 1) << 2) & MASK_TICK_DELAY; + world.setBlockDataNotify(tilePos, tickDelay | metadata & MASK_DIRECTION); + } + + @Override + public void onPlacedByMob(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, @NotNull Mob mob, double xHit, double yHit) { + final @NotNull Axis axis = mob.getHorizontalPlacementDirection(side).axis(); + assert(axis == Axis.X || axis == Axis.Z); + world.setBlockDataNotify(tilePos, axis == Axis.Z ? AXIS_SOUTH_NORTH : AXIS_WEST_EAST); + } + + @Override + public void onPlacedOnSide(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) { + if (!side.isHorizontal()) side = Side.NORTH; + final @NotNull Axis axis = side.direction().axis(); + assert(axis == Axis.X || axis == Axis.Z); + world.setBlockDataNotify(tilePos, axis == Axis.Z ? AXIS_SOUTH_NORTH : AXIS_WEST_EAST); + } + + @Override + public boolean isSolidRender() { + return false; + } + + @Override + public void animationTick(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Random rand) { + int meta = world.getBlockData(tilePos); + double px = (tilePos.x() + 0.5D) + (rand.nextFloat() - 0.5D) * 0.2D; + double py = (tilePos.y() + 0.4D) + (rand.nextFloat() - 0.5D) * 0.2D; + double pz = (tilePos.z() + 0.5D) + (rand.nextFloat() - 0.5D) * 0.2D; + + double xOffset = 0.0; + double zOffset = 0.0; + + final int redstoneBrightness = 15; + int tickDelay = (meta & MASK_TICK_DELAY) >> 2; + + if (rand.nextInt(2) == 0) { + switch (getSideFromMeta(meta)) { + case SOUTH: + zOffset = -torchPosOffset[tickDelay]; + break; + case NORTH: + zOffset = torchPosOffset[tickDelay]; + break; + case EAST: + xOffset = -torchPosOffset[tickDelay]; + break; + case WEST: + xOffset = torchPosOffset[tickDelay]; + break; + } + } else { + switch (getSideFromMeta(meta)) { + case SOUTH: + zOffset = torchPosOffset[tickDelay]; + break; + case NORTH: + zOffset = -torchPosOffset[tickDelay]; + break; + case EAST: + xOffset = torchPosOffset[tickDelay]; + break; + case WEST: + xOffset = -torchPosOffset[tickDelay]; + break; + } + } + world.spawnParticle("reddust", px + xOffset, py, pz + zOffset, 0, 0, 0, redstoneBrightness, false); + } + + @Override + public @NotNull ISupport getSupportConstraint(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side) { + return FullSupport.INSTANCE; + } +} diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicTorch.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTorch.java index 3480259ad..540fa475e 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicTorch.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTorch.java @@ -74,14 +74,14 @@ public class BlockLogicTorch extends BlockLogic implements ISupportable { @Override public void onPlacedByMob(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, @NotNull Mob mob, double xHit, double yHit) { - if (side.isHorizontal()) side = side.getOpposite(); + if (side.isHorizontal()) side = side.opposite(); onPlacedOnSide(world, tilePos, side, xHit, yHit); } @Override public void onPlacedOnSide(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) { int orientation = SIDE_NONE; - if (side.isHorizontal()) side = side.getOpposite(); + if (side.isHorizontal()) side = side.opposite(); switch (side) { case TOP: if (isSupported(world, tilePos, Side.BOTTOM)) { diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicTorchRedstone.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTorchRedstone.java index 11ee242b9..f1b94382d 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicTorchRedstone.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTorchRedstone.java @@ -32,28 +32,12 @@ public class BlockLogicTorchRedstone extends BlockLogicTorch { if (world.getBlockData(tilePos) == SIDE_NONE) { super.onPlacedByWorld(world, tilePos); } - TilePos queryPos = new TilePos(); - if (this.torchActive) { - world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), this.block); - world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), this.block); - world.notifyBlocksOfNeighborChange(tilePos.west(queryPos), this.block); - world.notifyBlocksOfNeighborChange(tilePos.east(queryPos), this.block); - world.notifyBlocksOfNeighborChange(tilePos.north(queryPos), this.block); - world.notifyBlocksOfNeighborChange(tilePos.south(queryPos), this.block); - } + world.notifyShellBlocksInRadiusOfNeighborChange(2, tilePos, this.block); } @Override public void onRemoved(@NotNull World world, @NotNull TilePosc tilePos, int data) { - TilePos queryPos = new TilePos(); - if (this.torchActive) { - world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), this.block); - world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), this.block); - world.notifyBlocksOfNeighborChange(tilePos.west(queryPos), this.block); - world.notifyBlocksOfNeighborChange(tilePos.east(queryPos), this.block); - world.notifyBlocksOfNeighborChange(tilePos.north(queryPos), this.block); - world.notifyBlocksOfNeighborChange(tilePos.south(queryPos), this.block); - } + world.notifyShellBlocksInRadiusOfNeighborChange(2, tilePos, this.block); } @Override diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicTrapDoor.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTrapDoor.java index a78b3754a..c9d86983b 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicTrapDoor.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTrapDoor.java @@ -150,7 +150,7 @@ public class BlockLogicTrapDoor extends BlockLogic implements IPaintable { @Override public int getPlacedData(@Nullable Player player, @NotNull ItemStack itemStack, @NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) { - int meta = getMetaForDirection(player == null ? side.getDirection().getOpposite() : player.getHorizontalPlacementDirection(side, PlacementMode.SIDE)); + int meta = getMetaForDirection(player == null ? side.direction().opposite() : player.getHorizontalPlacementDirection(side, PlacementMode.SIDE)); if (player != null && player.getVerticalPlacementDirection(side, yHit) == Direction.UP) { meta = setUpperHalf(meta, true); } @@ -165,7 +165,7 @@ public class BlockLogicTrapDoor extends BlockLogic implements IPaintable { if (isTrapdoorOpen(meta) && (block != null && block.getLogic() instanceof BlockLogicLadder ladder)) { Side ladderSide = ladder.getSideFromMeta(world.getBlockData(tilePos.down(queryPos))); Direction trapdoorDirection = getDirectionForMeta(meta); - return ladderSide.getDirection() == trapdoorDirection.getOpposite(); + return ladderSide.direction() == trapdoorDirection.opposite(); } return false; } diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicVeryRotatable.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicVeryRotatable.java index 886abf81b..ef39e7d8e 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicVeryRotatable.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicVeryRotatable.java @@ -18,22 +18,22 @@ public abstract class BlockLogicVeryRotatable @Override public void onPlacedByMob(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Side side, final @NotNull Mob mob, final double xHit, final double yHit) { - final @NotNull Direction direction = mob.getPlacementDirection(side).getOpposite(); + final @NotNull Direction direction = mob.getPlacementDirection(side).opposite(); world.setBlockDataNotify(tilePos, setDirection(0, direction)); } @Override public void onPlacedOnSide(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Side side, final double xHit, final double yHit) { - world.setBlockDataNotify(tilePos, setDirection(0, side.getDirection())); + world.setBlockDataNotify(tilePos, setDirection(0, side.direction())); } public static int setDirection(final int meta, final @NotNull Direction direction) { - return (meta & ~MASK_DIRECTION) | (direction.getId() & MASK_DIRECTION); + return (meta & ~MASK_DIRECTION) | direction.id; } public static @NotNull Direction metaToDirection(final int meta) { - return Direction.getDirectionById(meta & MASK_DIRECTION); + return Direction.fromId(meta & MASK_DIRECTION); } } \ No newline at end of file diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicWireRedstone.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicWireRedstone.java index 0754aeb82..3621bd2a6 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicWireRedstone.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicWireRedstone.java @@ -369,7 +369,7 @@ public class BlockLogicWireRedstone extends BlockLogic implements ISupportable { boolean isXConnected = posXShouldConnectTo || negXShouldConnectTo; boolean isZConnected = posZShouldConnectTo || negZShouldConnectTo; - return !isZConnected && !isXConnected && side.getAxis() != Axis.Y // Default single dust + return !isZConnected && !isXConnected && side.axis() != Axis.Y // Default single dust // When the signal request comes from a block that dust connects to (usually power sources) || side == Side.SOUTH && negZShouldConnectTo || side == Side.NORTH && posZShouldConnectTo @@ -418,17 +418,21 @@ public class BlockLogicWireRedstone extends BlockLogic implements ISupportable { } if (block == Blocks.PUMPKIN_REDSTONE) { if (side == Side.NONE || side.isVertical()) return false; - return Side.getSideById(source.getBlockData(tilePos)).getOpposite() == side; + return Side.fromId(source.getBlockData(tilePos)).opposite() == side; } if (block == Blocks.MATCHER || block == Blocks.MATCHER_ACTIVE) { - return BlockLogicAxisAligned.metaToAxis(source.getBlockData(tilePos)) != side.getAxis(); + return BlockLogicAxisAligned.metaToAxis(source.getBlockData(tilePos)) != side.axis(); } if (block == Blocks.REPEATER_IDLE || block == Blocks.REPEATER_ACTIVE) { final Side direction = BlockLogicRepeater.getSideFromMeta(source.getBlockData(tilePos)); - return side == direction || side == direction.getOpposite(); + return side == direction || side == direction.opposite(); + } + if (block == Blocks.TIMER) { + final Side direction = BlockLogicTimer.getSideFromMeta(source.getBlockData(tilePos)); + return side == direction || side == direction.opposite(); } if (block == Blocks.CONDUIT) { - return BlockLogicConduit.isSideOpen(source.getBlockData(tilePos), side.getOpposite()); + return BlockLogicConduit.isSideOpen(source.getBlockData(tilePos), side.opposite()); } return block.isSignalSource(); } @@ -453,7 +457,7 @@ public class BlockLogicWireRedstone extends BlockLogic implements ISupportable { if (side2 == Side.BOTTOM) { //top wire looking down at bottom if (side1 != Side.NONE) { - TilePos wallTilePos = new TilePos(tilePos).add(side1.getOpposite()); + TilePos wallTilePos = new TilePos(tilePos).add(side1.opposite()); if (isBlockingConduit(worldSource, wallTilePos, side1)) return false; //transparent diagonal connection @@ -468,7 +472,7 @@ public class BlockLogicWireRedstone extends BlockLogic implements ISupportable { } else { //fallback for (Side fSide : new Side[]{Side.NORTH, Side.SOUTH, Side.EAST, Side.WEST}) { - TilePos wallTilePos = new TilePos(tilePos).add(fSide.getOpposite()); + TilePos wallTilePos = new TilePos(tilePos).add(fSide.opposite()); if (worldSource.getBlockType(new TilePos(wallTilePos).up()) == Blocks.WIRE_REDSTONE) { if (isBlockingConduit(worldSource, wallTilePos, fSide)) return false; @@ -487,11 +491,11 @@ public class BlockLogicWireRedstone extends BlockLogic implements ISupportable { //bottom wire is looking up at top TilePos wallTilePos = new TilePos(tilePos).down(); if (side1 != Side.NONE) { - if (isBlockingConduit(worldSource, wallTilePos, side1.getOpposite())) return false; + if (isBlockingConduit(worldSource, wallTilePos, side1.opposite())) return false; //transparent diagonal connection - if (!isSolidWallForWire(worldSource, wallTilePos, side1.getOpposite())) { - TilePos bottomWireTilePos = new TilePos(wallTilePos).add(side1.getOpposite()); + if (!isSolidWallForWire(worldSource, wallTilePos, side1.opposite())) { + TilePos bottomWireTilePos = new TilePos(wallTilePos).add(side1.opposite()); int bottomPower = worldSource.getBlockData(bottomWireTilePos) & MASK_POWER; int topPower = worldSource.getBlockData(tilePos) & MASK_POWER; @@ -546,7 +550,7 @@ public class BlockLogicWireRedstone extends BlockLogic implements ISupportable { return true; } if (world.getBlockType(wallTilePos) == Blocks.CONDUIT) { - return !BlockLogicConduit.isSideOpen(world.getBlockData(wallTilePos), directionToWall.getOpposite()); + return !BlockLogicConduit.isSideOpen(world.getBlockData(wallTilePos), directionToWall.opposite()); } return false; } diff --git a/game/core/src/main/java/net/minecraft/core/block/Blocks.java b/game/core/src/main/java/net/minecraft/core/block/Blocks.java index 197abfabe..0f412e6ec 100644 --- a/game/core/src/main/java/net/minecraft/core/block/Blocks.java +++ b/game/core/src/main/java/net/minecraft/core/block/Blocks.java @@ -7,8 +7,7 @@ import net.minecraft.core.block.material.Materials; import net.minecraft.core.block.piston.BlockLogicPistonBase; import net.minecraft.core.block.piston.BlockLogicPistonHead; import net.minecraft.core.block.piston.BlockLogicPistonMoving; -import net.minecraft.core.block.piston.BlockLogicPistonBaseSteel; -import net.minecraft.core.block.piston.BlockLogicPistonBaseSticky; +import net.minecraft.core.block.piston.PistonCommon; import net.minecraft.core.block.tag.BlockTags; import net.minecraft.core.data.tag.Tag; import net.minecraft.core.entity.Entity; @@ -16,6 +15,7 @@ import net.minecraft.core.entity.Mob; import net.minecraft.core.entity.animal.MobButterfly; import net.minecraft.core.entity.animal.MobFireflyCluster; import net.minecraft.core.entity.player.Player; +import net.minecraft.core.enums.EnumDropCause; import net.minecraft.core.item.Item; import net.minecraft.core.item.Items; import net.minecraft.core.item.block.*; @@ -802,20 +802,38 @@ public final class Blocks { public static final @NotNull Block REPEATER_ACTIVE = register("repeater.active", "minecraft:block/repeater_active", 511, (BlockLogicSupplier)b -> new BlockLogicRepeater(b, true)) .withSound(BlockSounds.STONE).withHardness(0.0F).withLightEmission(0.625F).withDisabledStats().withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.redstone).setStatParent(() -> REPEATER_IDLE) .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.PREVENT_MOB_SPAWNS); + public static final @NotNull Block TIMER = register("timer", "minecraft:block/timer", 512, BlockLogicTimer::new) + .withSound(BlockSounds.STONE).withHardness(0.0F).withDisabledStats().withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.redstone).setStatParent(() -> Items.TIMER) + .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.PREVENT_MOB_SPAWNS); - public static final @NotNull Block PISTON_BASE = register("piston.base", "minecraft:block/piston_base", 520, (BlockLogicSupplier)b -> new BlockLogicPistonBase(b, 12)) + public static final @NotNull Block PISTON_BASE = register("piston.base", "minecraft:block/piston_base", 520, (BlockLogicSupplier)b -> + new BlockLogicPistonBase( + b, PistonCommon.TYPE_NORMAL, + (byte)12, (byte)1, EnumDropCause.SILK_TOUCH, false, Double.NaN + )) .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange() .withTags(BlockTags.MINEABLE_BY_PICKAXE); - public static final @NotNull Block PISTON_BASE_STICKY = register("piston.base.sticky", "minecraft:block/piston_base_sticky", 521, (BlockLogicSupplier)b -> new BlockLogicPistonBaseSticky(b, 12)) + public static final @NotNull Block PISTON_BASE_STICKY = register("piston.base.sticky", "minecraft:block/piston_base_sticky", 521, (BlockLogicSupplier)b -> + new BlockLogicPistonBase( + b, PistonCommon.TYPE_STICKY, + (byte)12, (byte)1, null, true, Double.NaN + )) .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange() .withTags(BlockTags.MINEABLE_BY_PICKAXE); + public static final @NotNull Block PISTON_HEAD = register("piston.head", "minecraft:block/piston_head", 522, (BlockLogicSupplier)(b) -> new BlockLogicPistonHead(b, 4/16d, 4/16d)) .withSound(BlockSounds.WOOD).withDisabledNeighborNotifyOnMetadataChange().withDisabledStats().withImmovableFlagSet() .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE); + public static final @NotNull Block PISTON_MOVING = register("piston.moving", "minecraft:block/piston_moving", 523, BlockLogicPistonMoving::new) .withSound(BlockSounds.STONE).withDisabledStats() .withTags(BlockTags.NOT_IN_CREATIVE_MENU); - public static final @NotNull Block PISTON_BASE_STEEL = register("piston.base.steel", "minecraft:block/piston_base_steel", 524, (BlockLogicSupplier)b -> new BlockLogicPistonBaseSteel(b, 24)) + + public static final @NotNull Block PISTON_BASE_STEEL = register("piston.base.steel", "minecraft:block/piston_base_steel", 524, (BlockLogicSupplier)b -> + new BlockLogicPistonBase( + b, PistonCommon.TYPE_STEEL, + (byte)24, (byte)1, EnumDropCause.PISTON_CRUSH, false, 2.0 + )) .withSound(BlockSounds.METAL) .withHardness(5F) .withBlastResistance(2000F) diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntity.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntity.java index b7a2a0605..535d28847 100644 --- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntity.java +++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntity.java @@ -37,15 +37,8 @@ public abstract class TileEntity implements ICarriable public void setChanged() { - if(worldObj != null) - { - int id = getBlockId(); - if (id != 0 && Blocks.getBlock(id).isSignalSource()) { - for (Side s : Side.sides){ - worldObj.notifyBlocksOfNeighborChange(tilePos.x + s.getOffsetX(), tilePos.y + s.getOffsetY(), tilePos.z + s.getOffsetZ(), getBlockId()); - } - } - worldObj.updateTileEntityChunkAndSendToPlayer(tilePos.x, tilePos.y, tilePos.z, this); + if(worldObj != null) { + worldObj.updateTileEntityChunkAndSendToPlayer(tilePos, this); } } @@ -143,9 +136,9 @@ public abstract class TileEntity implements ICarriable @Override public boolean tryPlace(World world, Entity holder, int blockX, int blockY, int blockZ, Side side, double xPlaced, double yPlaced) { CarriedBlock carriedBlock = this.carriedBlock; - tilePos.x = blockX + side.getOffsetX(); - tilePos.y = blockY + side.getOffsetY(); - tilePos.z = blockZ + side.getOffsetZ(); + tilePos.x = blockX + side.offsetX(); + tilePos.y = blockY + side.offsetY(); + tilePos.z = blockZ + side.offsetZ(); Block currentBlock = world.getBlock(tilePos.x, tilePos.y, tilePos.z); if (currentBlock != null && !currentBlock.hasTag(BlockTags.PLACE_OVERWRITES)) return false; @@ -159,12 +152,8 @@ public abstract class TileEntity implements ICarriable if (b != null && holder instanceof Mob) { b.onBlockPlacedByMob(world, tilePos.x, tilePos.y, tilePos.z, side, (Mob) holder, xPlaced, yPlaced); } - world.notifyBlockChange(tilePos.x, tilePos.y, tilePos.z, carriedBlock.blockId); - if (carriedBlock.blockId != 0 && Blocks.getBlock(carriedBlock.blockId).isSignalSource()) { - for (Side s : Side.sides){ - world.notifyBlocksOfNeighborChange(tilePos.x + s.getOffsetX(), tilePos.y + s.getOffsetY(), tilePos.z + s.getOffsetZ(), getBlockId()); - } - } + final boolean isSignal = Blocks.getBlock(carriedBlock.blockId).isSignalSource(); + world.notifyBlocksInRadiusOfNeighborChange((isSignal) ? 2 : 1, tilePos, currentBlock); return true; } @@ -193,13 +182,8 @@ public abstract class TileEntity implements ICarriable int currentMeta = world.getBlockMetadata(tilePos.x, tilePos.y, tilePos.z); world.removeBlockTileEntity(tilePos.x, tilePos.y, tilePos.z); world.setBlockRaw(tilePos.x, tilePos.y, tilePos.z, 0); - world.notifyBlockChange(tilePos.x, tilePos.y, tilePos.z, 0); - int id = getBlockId(); - if (currentBlock.isSignalSource()) { - for (Side s : Side.sides){ - worldObj.notifyBlocksOfNeighborChange(tilePos.x + s.getOffsetX(), tilePos.y + s.getOffsetY(), tilePos.z + s.getOffsetZ(), getBlockId()); - } - } + final boolean isSignal = this.getBlock().isSignalSource(); + world.notifyBlocksInRadiusOfNeighborChange((isSignal) ? 2 : 1, tilePos, currentBlock); this.worldObj = null; this.carriedBlock = getCarriedEntry(world, holder, currentBlock, currentMeta); return carriedBlock; diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityBasket.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityBasket.java index 67f4f074d..0dc111172 100644 --- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityBasket.java +++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityBasket.java @@ -4,7 +4,6 @@ import java.util.*; import it.unimi.dsi.fastutil.objects.Object2IntArrayMap; import it.unimi.dsi.fastutil.objects.Object2IntMap; -import net.minecraft.core.block.Blocks; import net.minecraft.core.entity.Entity; import net.minecraft.core.entity.EntityItem; import net.minecraft.core.entity.player.Player; @@ -33,7 +32,8 @@ public class TileEntityBasket extends TileEntity implements ICarrySource { int currentNumInside = calcNumUnitsInside(); if (currentNumInside != numUnitsInside && worldObj != null) { this.numUnitsInside = currentNumInside; - worldObj.notifyBlockChange(tilePos.x, tilePos.y, tilePos.z, worldObj.getBlockId(tilePos.x, tilePos.y, tilePos.z)); + worldObj.markBlockNeedsUpdate(tilePos); + worldObj.notifyBlocksInRadiusOfNeighborChange(2, tilePos, getBlock()); setChanged(); } } @@ -109,7 +109,6 @@ public class TileEntityBasket extends TileEntity implements ICarrySource { } updateNumUnits(); - world.notifyBlockChange(this.tilePos.x, this.tilePos.y, this.tilePos.z, Blocks.BASKET.id()); } @Override @@ -168,12 +167,7 @@ public class TileEntityBasket extends TileEntity implements ICarrySource { } } - if (shouldUpdate) { - if (this.worldObj != null) { - this.worldObj.notifyBlockChange(this.tilePos.x, this.tilePos.y, this.tilePos.z, Blocks.BASKET.id()); - } - updateNumUnits(); - } + if (shouldUpdate) updateNumUnits(); } private boolean importItemStack(final ItemStack stack) { @@ -232,7 +226,6 @@ public class TileEntityBasket extends TileEntity implements ICarrySource { this.contents.clear(); - world.notifyBlockChange(x, y, z, Blocks.BASKET.id()); updateNumUnits(); } diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityDispatcher.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityDispatcher.java index 6137d822f..c43ced3f4 100644 --- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityDispatcher.java +++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityDispatcher.java @@ -90,6 +90,7 @@ public class TileEntityDispatcher { addMapping(TileEntityMesh.class, NamespaceID.fromPool("minecraft", "mesh")); addMapping(TileEntityMeshGold.class, NamespaceID.fromPool("minecraft", "mesh_gold")); addMapping(TileEntityStatue.class, NamespaceID.fromPool("minecraft", "statue_stone")); + addMapping(TileEntityTimer.class, NamespaceID.fromPool("minecraft", "timer")); } @Deprecated diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMesh.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMesh.java index 73fac3ed1..6f08d6bd5 100644 --- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMesh.java +++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMesh.java @@ -72,11 +72,11 @@ public class TileEntityMesh extends TileEntity { if (entity instanceof EntityItem item && entity.isInWater()) { if(item.meshSiphoning == null && item.siphonDirection == Direction.NONE){ - item.siphonDirection = direction.getOpposite(); + item.siphonDirection = direction.opposite(); item.meshSiphoning = this; } - if(direction.getOpposite().equals(item.siphonDirection) && item.meshSiphoning == this) { + if(direction.opposite().equals(item.siphonDirection) && item.meshSiphoning == this) { if (!this.worldObj.isClientSide) { Player player = entity.world.getClosestPlayer(tilePos.x, tilePos.y, tilePos.z, 12); @@ -148,14 +148,14 @@ public class TileEntityMesh extends TileEntity { double centerZ = tilePos.z + 0.5; // move the center to the edge of the block face - centerX += facing.getOffsetX() * 0.5; - centerY += facing.getOffsetY() * 0.5; - centerZ += facing.getOffsetZ() * 0.5; + centerX += facing.offsetX() * 0.5; + centerY += facing.offsetY() * 0.5; + centerZ += facing.offsetZ() * 0.5; // move height distance further in the facing direction - double farX = centerX + (facing.getOffsetX() * siphonHeight); - double farY = centerY + (facing.getOffsetY() * siphonHeight); - double farZ = centerZ + (facing.getOffsetZ() * siphonHeight); + double farX = centerX + (facing.offsetX() * siphonHeight); + double farY = centerY + (facing.offsetY() * siphonHeight); + double farZ = centerZ + (facing.offsetZ() * siphonHeight); // need a half width since in middle of block @@ -171,15 +171,15 @@ public class TileEntityMesh extends TileEntity { double maxZ = Math.max(centerZ, farZ); // expand based on the axis we are NOT facing - if (facing.getAxis() != Axis.X) { + if (facing.axis() != Axis.X) { minX -= hw; maxX += hw; } - if (facing.getAxis() != Axis.Y) { + if (facing.axis() != Axis.Y) { minY -= hw; maxY += hw; } - if (facing.getAxis() != Axis.Z) { + if (facing.axis() != Axis.Z) { minZ -= hw; maxZ += hw; } @@ -227,10 +227,10 @@ public class TileEntityMesh extends TileEntity { //axis check to make sure the swirl behaves correctly depending on facing direction double sX = 0, sY = 0, sZ = 0; - if (direction.getAxis() == Axis.Y) { + if (direction.axis() == Axis.Y) { sX = -diffZ; sZ = diffX; - } else if (direction.getAxis() == Axis.Z) { + } else if (direction.axis() == Axis.Z) { sX = -diffY; sY = diffX; } else { diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMeshGold.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMeshGold.java index 0ad61f978..557c0796f 100644 --- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMeshGold.java +++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMeshGold.java @@ -105,10 +105,10 @@ public class TileEntityMeshGold extends TileEntityMesh { if (entity instanceof EntityItem item && entity.isInWater()) { if(item.meshSiphoning == null && item.siphonDirection == Direction.NONE){ - item.siphonDirection = direction.getOpposite(); + item.siphonDirection = direction.opposite(); item.meshSiphoning = this; } - if(direction.getOpposite().equals(item.siphonDirection) && item.meshSiphoning == this) { + if(direction.opposite() == item.siphonDirection && item.meshSiphoning == this) { if (item.item.getItem() == this.filterItem.getItem() && item.item.getMetadata() == this.filterItem.getMetadata()) { Player player = entity.world.getClosestPlayer(tilePos.x, tilePos.y, tilePos.z, 12); diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntitySensor.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntitySensor.java index b22191f02..81624ba86 100644 --- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntitySensor.java +++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntitySensor.java @@ -25,15 +25,15 @@ public class TileEntitySensor extends TileEntity { } int range = 4; - int blockInFront = world.getBlockId(MathHelper.round(x + facing.getOffsetX()), MathHelper.round(y + facing.getOffsetY()), MathHelper.round(z + facing.getOffsetZ())); + int blockInFront = world.getBlockId(MathHelper.round(x + facing.offsetX()), MathHelper.round(y + facing.offsetY()), MathHelper.round(z + facing.offsetZ())); if (Blocks.hasTag(blockInFront, BlockTags.EXTENDS_MOTION_SENSOR_RANGE)) { range = 8; } for (int i = 1; i <= range; i++) { - int x1 = MathHelper.round(x + facing.getOffsetX() * i); - int y1 = MathHelper.round(y + facing.getOffsetY() * i); - int z1 = MathHelper.round(z + facing.getOffsetZ() * i); + int x1 = MathHelper.round(x + facing.offsetX() * i); + int y1 = MathHelper.round(y + facing.offsetY() * i); + int z1 = MathHelper.round(z + facing.offsetZ() * i); int id = world.getBlockId(x1, y1, z1); if (Blocks.solid[id] && !Blocks.hasTag(id, BlockTags.EXTENDS_MOTION_SENSOR_RANGE)) { return i - 1; @@ -44,13 +44,13 @@ public class TileEntitySensor extends TileEntity { } private @NotNull AABBdc getDetectionBox(double x, double y, double z, @NotNull Direction facing, int range) { - double x1 = x + facing.getOffsetX(); - double y1 = y + facing.getOffsetY(); - double z1 = z + facing.getOffsetZ(); + double x1 = x + facing.offsetX(); + double y1 = y + facing.offsetY(); + double z1 = z + facing.offsetZ(); - double x2 = x + facing.getOffsetX() * range; - double y2 = y + facing.getOffsetY() * range; - double z2 = z + facing.getOffsetZ() * range; + double x2 = x + facing.offsetX() * range; + double y2 = y + facing.offsetY() * range; + double z2 = z + facing.offsetZ() * range; double minX = Math.min(x1, x2); double minY = Math.min(y1, y2); @@ -154,7 +154,9 @@ public class TileEntitySensor extends TileEntity { final var block = (active) ? Blocks.MOTION_SENSOR_ACTIVE : Blocks.MOTION_SENSOR_IDLE; - world.setBlockTypeDataNotify(this.tilePos, block, meta); + world.setBlockTypeData(this.tilePos, block, meta); + world.markBlockNeedsUpdate(this.tilePos); + world.notifyBlocksInRadiusOfNeighborChange(2, this.tilePos, block); } } } diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTimer.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTimer.java new file mode 100644 index 000000000..6c5434e25 --- /dev/null +++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTimer.java @@ -0,0 +1,56 @@ +package net.minecraft.core.block.entity; + +import com.mojang.nbt.tags.CompoundTag; +import net.minecraft.core.block.Block; +import net.minecraft.core.block.BlockLogicTimer; +import net.minecraft.core.block.Blocks; +import net.minecraft.core.util.helper.Axis; +import net.minecraft.core.util.helper.Side; +import net.minecraft.core.world.pos.TilePos; +import org.jetbrains.annotations.NotNull; + +public class TileEntityTimer extends TileEntity { + // This has got to be one of the simplest tile entities of all time. + + @Override + public void readAdditionalData(@NotNull CompoundTag compoundTag) { + // Do nothing + } + + @Override + public void writeAdditionalData(@NotNull CompoundTag compoundTag) { + // Do nothing + } + + @Override + public void tick() { + if (this.worldObj == null || this.worldObj.isClientSide) { + return; + } + + Block block = this.worldObj.getBlockType(this.tilePos); + if (block != Blocks.TIMER) { + return; + } + + final int currentMeta = this.worldObj.getBlockData(this.tilePos); + final int currentAxis = currentMeta & BlockLogicTimer.MASK_AXIS; + final int currentDelay = currentMeta & BlockLogicTimer.MASK_TICK_DELAY; + + final long currentTick = this.worldObj.getTotalWorldTime(); + final long interval = BlockLogicTimer.tickDelayMap[currentDelay >> 2]; + if (currentTick % interval == 0) { + final int newOutput = + ((currentTick % (interval * 2) == 0) ? BlockLogicTimer.OUTPUT_A : BlockLogicTimer.OUTPUT_B); + final int newMeta = currentDelay | newOutput | currentAxis; + + this.worldObj.setBlockData(this.tilePos, newMeta); + this.worldObj.markBlockNeedsUpdate(this.tilePos); + + final Side side = BlockLogicTimer.getSideFromMeta(currentMeta); + + this.worldObj.notifyBlocksInCapsuleOfNeighborChange(side, this.tilePos, Blocks.TIMER); + this.worldObj.notifyBlocksInCapsuleOfNeighborChange(side.opposite(), this.tilePos, Blocks.TIMER); + } + } +} diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTrommel.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTrommel.java index 21f4555e3..691d2cbe5 100644 --- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTrommel.java +++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTrommel.java @@ -312,10 +312,12 @@ public class TileEntityTrommel extends TileEntity if(itemResult!=null) { // Check if chest is adjacent - - int adjacentId = this.worldObj != null ? this.worldObj.getBlockId(this.tilePos.x + direction.getOffsetX(), this.tilePos.y + direction.getOffsetY(), this.tilePos.z + direction.getOffsetZ()) : 0; + final var queryPos = new TilePos(); + int adjacentId = this.worldObj != null + ? this.worldObj.getBlockType(queryPos.set(this.tilePos).add(direction)).id() + : 0; if (this.worldObj != null && Block.hasLogicClass(Blocks.blocksList[adjacentId], BlockLogicChest.class)) { - Container chest = BlockLogicChest.getInventory(this.worldObj, new TilePos(this.tilePos.x + direction.getOffsetX(), this.tilePos.y + direction.getOffsetY(), this.tilePos.z + direction.getOffsetZ())); + Container chest = BlockLogicChest.getInventory(this.worldObj, queryPos); for (int i = 0; i < chest.getContainerSize(); i++) { @@ -346,12 +348,12 @@ public class TileEntityTrommel extends TileEntity if(itemResult.stackSize > 0) { if (this.worldObj != null) { if (this.worldObj.isAirBlock(new TilePos(this.tilePos.x, this.tilePos.y, this.tilePos.z).add(direction))) { - EntityItem droppedItem = new EntityItem(this.worldObj, this.tilePos.x + 0.5 + direction.getOffsetX() * 0.5, this.tilePos.y + 0.5 + direction.getOffsetY() * 0.5, this.tilePos.z + 0.5 + direction.getOffsetZ() * 0.5, itemResult); + EntityItem droppedItem = new EntityItem(this.worldObj, this.tilePos.x + 0.5 + direction.offsetX() * 0.5, this.tilePos.y + 0.5 + direction.offsetY() * 0.5, this.tilePos.z + 0.5 + direction.offsetZ() * 0.5, itemResult); droppedItem.pickupDelay = 10; - droppedItem.fling(direction.getOffsetX() * 0.3125, direction.getOffsetY() * 0.3125, direction.getOffsetZ() * 0.3125, 1); + droppedItem.fling(direction.offsetX() * 0.3125, direction.offsetY() * 0.3125, direction.offsetZ() * 0.3125, 1); this.worldObj.entityJoinedWorld(droppedItem); } else { - this.worldObj.dropItem(this.tilePos.x, this.tilePos.y, this.tilePos.z, itemResult); + this.worldObj.dropItem(this.tilePos, itemResult); } } else if (this.carriedBlock != null) { this.carriedBlock.world.dropItem(MathHelper.floor(this.carriedBlock.holder.x), MathHelper.floor(this.carriedBlock.holder.y), MathHelper.floor(this.carriedBlock.holder.z), itemResult); @@ -371,8 +373,8 @@ public class TileEntityTrommel extends TileEntity mobSlime.zd = (float) this.random.nextGaussian() * f3; if (this.worldObj != null) { if (this.worldObj.isAirBlock(new TilePos(this.tilePos.x, this.tilePos.y, this.tilePos.z).add(direction))) { - mobSlime.moveTo(this.tilePos.x + 0.5 + direction.getOffsetX(), this.tilePos.y + 0.5 + direction.getOffsetY(), this.tilePos.z + 0.5 + direction.getOffsetZ(), this.random.nextFloat() * 360F, 0.0F); - mobSlime.fling(direction.getOffsetX() * 0.75, direction.getOffsetY() * 0.75, direction.getOffsetZ() * 0.75, 1); + mobSlime.moveTo(this.tilePos.x + 0.5 + direction.offsetX(), this.tilePos.y + 0.5 + direction.offsetY(), this.tilePos.z + 0.5 + direction.offsetZ(), this.random.nextFloat() * 360F, 0.0F); + mobSlime.fling(direction.offsetX() * 0.75, direction.offsetY() * 0.75, direction.offsetZ() * 0.75, 1); } else { mobSlime.moveTo(this.tilePos.x + (double)f, this.tilePos.y + 1D, this.tilePos.z + (double)f1, this.random.nextFloat() * 360F, 0.0F); } diff --git a/game/core/src/main/java/net/minecraft/core/block/motion/CarriedBlock.java b/game/core/src/main/java/net/minecraft/core/block/motion/CarriedBlock.java index 88391617f..f7a2ded33 100644 --- a/game/core/src/main/java/net/minecraft/core/block/motion/CarriedBlock.java +++ b/game/core/src/main/java/net/minecraft/core/block/motion/CarriedBlock.java @@ -60,9 +60,9 @@ public class CarriedBlock implements ICarriable, ICarriedBlock { if (entity != null) { return entity.tryPlace(world, holder, blockX, blockY, blockZ, side, xPlaced, yPlaced); } else { - int x = blockX + side.getOffsetX(); - int y = blockY + side.getOffsetY(); - int z = blockZ + side.getOffsetZ(); + int x = blockX + side.offsetX(); + int y = blockY + side.offsetY(); + int z = blockZ + side.offsetZ(); Block currentBlock = world.getBlock(x, y, z); if (currentBlock != null && !currentBlock.hasTag(BlockTags.PLACE_OVERWRITES)) return false; diff --git a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBase.java b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBase.java index 88cecea89..d066e7073 100644 --- a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBase.java +++ b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBase.java @@ -3,388 +3,573 @@ package net.minecraft.core.block.piston; import net.minecraft.core.block.Blocks; import net.minecraft.core.block.entity.TileEntity; import net.minecraft.core.block.material.Material; +import net.minecraft.core.Global; import net.minecraft.core.block.Block; import net.minecraft.core.block.BlockLogic; import net.minecraft.core.block.material.Materials; +import net.minecraft.core.block.piston.PistonCommon.MovingType; import net.minecraft.core.block.support.FullSupport; import net.minecraft.core.block.support.ISupport; import net.minecraft.core.block.support.PartialSupport; import net.minecraft.core.block.tag.BlockTags; -import net.minecraft.core.entity.Mob; +import net.minecraft.core.entity.EntityFallingBlock; import net.minecraft.core.entity.player.Player; import net.minecraft.core.enums.EnumDropCause; import net.minecraft.core.item.ItemStack; import net.minecraft.core.sound.SoundCategory; +import net.minecraft.core.util.PackedField; import net.minecraft.core.util.helper.Direction; import net.minecraft.core.util.helper.Side; +import net.minecraft.core.world.IVehicle; import net.minecraft.core.world.LevelListener; import net.minecraft.core.world.World; import net.minecraft.core.world.WorldSource; import net.minecraft.core.world.pos.TilePos; import net.minecraft.core.world.pos.TilePosc; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.joml.Vector3d; import org.joml.primitives.AABBd; import org.joml.primitives.AABBdc; +import static net.minecraft.core.block.piston.PistonCommon.*; + public class BlockLogicPistonBase extends BlockLogic { - public static final int MASK_DIRECTION = 0b0000_0111; - public static final int MASK_POWERED = 0b0000_1000; - - public static final int EVENT_EXTEND = 0; - public static final int EVENT_RETRACT = 1; - - public static final ISupport[] pistonSupportLookupTable = { - // Bottom - PartialSupport.INSTANCE, - FullSupport.INSTANCE, - PartialSupport.INSTANCE.center().up(), - PartialSupport.INSTANCE.center().down(), - PartialSupport.INSTANCE.center().right(), - PartialSupport.INSTANCE.center().left(), - // Top - FullSupport.INSTANCE, - PartialSupport.INSTANCE, - PartialSupport.INSTANCE.center().down(), - PartialSupport.INSTANCE.center().up(), - PartialSupport.INSTANCE.center().right(), - PartialSupport.INSTANCE.center().left(), - // North - PartialSupport.INSTANCE.center().up(), - PartialSupport.INSTANCE.center().down(), - PartialSupport.INSTANCE, - FullSupport.INSTANCE, - PartialSupport.INSTANCE.center().right(), - PartialSupport.INSTANCE.center().left(), - // South - PartialSupport.INSTANCE.center().up(), - PartialSupport.INSTANCE.center().down(), - FullSupport.INSTANCE, - PartialSupport.INSTANCE, - PartialSupport.INSTANCE.center().right(), - PartialSupport.INSTANCE.center().left(), - // West - PartialSupport.INSTANCE.center().up(), - PartialSupport.INSTANCE.center().down(), - PartialSupport.INSTANCE.center().left(), - PartialSupport.INSTANCE.center().right(), - PartialSupport.INSTANCE, - FullSupport.INSTANCE, - // East - PartialSupport.INSTANCE.center().up(), - PartialSupport.INSTANCE.center().down(), - PartialSupport.INSTANCE.center().left(), - PartialSupport.INSTANCE.center().right(), - FullSupport.INSTANCE, - PartialSupport.INSTANCE, - }; - - private final int maxPushedBlocks; - - public BlockLogicPistonBase(@NotNull Block block, int maxPushedBlocks) { + public final byte typeId; + + final byte pushLimit, crushLimit; + final @Nullable EnumDropCause crushAction; + final boolean canPull; + final double flingStrength; + + public BlockLogicPistonBase( + @NotNull Block block, + byte typeId, + byte pushLimit, byte crushLimit, + @Nullable EnumDropCause crushAction, boolean canPull, double flingStrength + ) { super(block, Materials.PISTON); - this.maxPushedBlocks = maxPushedBlocks; block.withHardness(0.5F); + this.typeId = typeId; + + assert typeId >= 0 && typeId < 3; + + this.pushLimit = pushLimit; + this.crushLimit = crushLimit; + this.crushAction = crushAction; + this.canPull = canPull; + this.flingStrength = flingStrength; } - @Override - public boolean isSolidRender() { - return false; + // Piston updates: + // ================= + + private final boolean signalUpdate(@NotNull World world, @NotNull TilePosc tilePos) { + return signalUpdate(world, tilePos, world.getBlockData(tilePos)); } - @Override - public void onPlacedByMob(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, @NotNull Mob mob, double xHit, double yHit) { - Direction placementDirection = mob.getPlacementDirection(side).getOpposite(); - world.setBlockDataNotify(tilePos, placementDirection.getId()); - if (!world.isClientSide) { - checkIfExtend(world, tilePos); - } + private final boolean signalUpdate(@NotNull World world, @NotNull TilePosc tilePos, int data) { + data = validateBaseData(data, this); + + final boolean powered = hasNeighborSignal(world, tilePos, Direction.fromId(DIRECTION.get(data))); + final boolean extended = IS_EXTENDED.bool(data); + final boolean detached = IS_DETACHED.bool(data); + + if (powered == extended) return false; + + int event = (!detached) ? EVENT_EXTEND : EVENT_DETACH_EXTEND; + event |= (powered) ? 0 : 1; + + final var lineInfo = (powered && !detached) + ? testLine(world, tilePos, Direction.fromId(DIRECTION.get(data))) + : 0; + assert (lineInfo & ~0xFF) == 0; + + if (LINE_OBSTRUCTED.bool(lineInfo)) return false; + + world.triggerEvent(tilePos, event, lineInfo); + return true; } @Override - public void onPlacedOnSide(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) { - Direction placementDirection = side.getDirection(); - world.setBlockDataNotify(tilePos, placementDirection.getId()); - if (!world.isClientSide) { - checkIfExtend(world, tilePos); + public void triggerEvent(@NotNull World world, @NotNull TilePosc tilePos, int index, int eventData) { + assert (eventData & ~0xFF) == 0; + final double x, y, z; + x = tilePos.x() + 0.5D; + y = tilePos.y() + 0.5D; + z = tilePos.z() + 0.5D; + + final int data = getValidatedBaseData(world, tilePos, this); + final boolean isOut = (index & 1) == 0; + + switch (index & ~1) { + default: + return; + case EVENT_DETACH: + break; + case EVENT_DETACH_EXTEND: + world.setBlockData(tilePos, IS_EXTENDED.set(data, isOut ? 1 : 0)); + break; + case EVENT_EXTEND: + if (isOut) { + if (!this.extend(world, tilePos, data, eventData)) return; + } else { + if (world.isClientSide) { + // serverside / singleplayer should have already fixed this + fixLegacyBaseData(world, tilePos); + } + this.retract(world, tilePos, data); + } + break; } - } - @Override - public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block block) { - checkIfExtend(world, tilePos); - } + // we let client side compute effects + if (Global.isServer) return; - @Override - public void onPlacedByWorld(@NotNull World world, @NotNull TilePosc tilePos) { - if (!world.isClientSide && world.getTileEntity(tilePos) == null) { - checkIfExtend(world, tilePos); + final @NotNull String sound; + final float volumn, pitch; + + switch (index & ~1) { + default: + assert false; + return; + case EVENT_DETACH: + world.playBlockEvent(tilePos, LevelListener.EVENT_DISPENSER_PARTICLES, DIRECTION.get(data)); + sound = (isOut) ? "tile.piston.detached" : "tile.piston.attached"; + volumn = 1.0F; + pitch = 0.6F; + break; + case EVENT_DETACH_EXTEND: + world.playBlockEvent(tilePos, LevelListener.EVENT_DISPENSER_PARTICLES, DIRECTION.get(data)); + sound = (isOut) ? "tile.piston.detached.out" : "tile.piston.detached.in"; + volumn = pitch = 1.0F; + break; + case EVENT_EXTEND: + sound = (isOut) ? "tile.piston.out" : "tile.piston.in"; + volumn = 0.5F; + pitch = world.rand.nextFloat() * 0.25F + 0.6F; + break; } + + world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, x, y, z, sound, volumn, pitch); } + + private static boolean hasNeighborSignal(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Direction dir) { + final var queryPos = new TilePos(); + for (final var search : Direction.all) { + queryPos.set(tilePos).add(search); + if (search != dir && world.hasSignal(queryPos, search.side())) return true; - private void checkIfExtend(@NotNull World world, @NotNull TilePosc tilePos) { - int data = world.getBlockData(tilePos); - Direction direction = getDirection(data); - boolean hasNeighborSignal = getNeighborSignal(world, tilePos, direction); - if (data == MASK_DIRECTION) { - return; + // QC + if (search == Direction.DOWN) continue; + if (dir == Direction.UP && search == Direction.UP) continue; + queryPos.up(); + if (world.hasSignal(queryPos, search.side())) return true; } - if (hasNeighborSignal && !isPowered(data)) { - if (canPushLine(world, tilePos, direction, this.maxPushedBlocks)) { - world.setBlockData(tilePos, direction.getId() | MASK_POWERED); - world.triggerEvent(tilePos, EVENT_EXTEND, direction.getId()); + return false; + } + + // Piston tests: + // ================= + + // only uses 8 bits since only 8 bits of PacketBlockEvent's data field + private static final PackedField LINE_LENGTH = new PackedField(0, 6); + private static final PackedField CRUSH_EOL = new PackedField(6, 1); + private static final PackedField LINE_OBSTRUCTED = new PackedField(7, 1); + + /** + * Returns line length:
+ * {@code LINE_LENGTH.get(n)} encodes length of line;
+ * if {@code LINE_OBSTRUCTED.bool(n)}, line can't be pushed;
+ * if {@code CRUSH_EOL.bool(n)}, end of line should be crushed;
+ */ + public int testLine(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Direction dir) { + final var pos = new TilePos(tilePos).add(dir); + final int maxY = world.getHeightBlocks(); + final int pushLimit = LINE_LENGTH.get(this.pushLimit); + + if (pushLimit == 0) return 0; + for (int i = 0; i <= pushLimit; i++, pos.add(dir)) { + final int nope = LINE_OBSTRUCTED.mask | i; + + if (pos.y < 0 || pos.y >= maxY) return nope; + + switch (Movability.test(world, pos)) { + case BREAKS: + return i; + case MOVES: + if (i >= pushLimit) return nope; + continue; + case CRUSHES: + if (this.crushAction == null) return nope; + if (i == 0) return nope; + if (i > this.crushLimit) return nope; + return CRUSH_EOL.mask | i - 1; + case OBSTRUCTED: + return nope; } - } else if (!hasNeighborSignal && isPowered(data)) { - world.setBlockData(tilePos, direction.getId()); - world.triggerEvent(tilePos, EVENT_RETRACT, direction.getId()); + assert false : "unreachable"; } + assert false : "unreachable"; return 0; } - private boolean getNeighborSignal(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Direction direction) { - TilePos queryPos = new TilePos(); - if (direction != Direction.DOWN && world.hasSignal(tilePos.add(0, -1, 0, queryPos), Side.BOTTOM)) { - return true; - } - if (direction != Direction.UP && world.hasSignal(tilePos.add(0, 1, 0, queryPos), Side.TOP)) { - return true; - } - if (direction != Direction.NORTH && world.hasSignal(tilePos.add(0, 0, -1, queryPos), Side.NORTH)) { - return true; - } - if (direction != Direction.SOUTH && world.hasSignal(tilePos.add(0, 0, 1, queryPos), Side.SOUTH)) { - return true; - } - if (direction != Direction.EAST && world.hasSignal(tilePos.add(1, 0, 0, queryPos), Side.EAST)) { - return true; - } - if (direction != Direction.WEST && world.hasSignal(tilePos.add(-1, 0, 0, queryPos), Side.WEST)) { - return true; - } - if (world.hasSignal(tilePos, Side.BOTTOM)) { - return true; - } - // QC - if (direction != Direction.UP && world.hasSignal(tilePos.add(0, 2, 0, queryPos), Side.TOP)) { - return true; + public static enum Movability { + OBSTRUCTED, MOVES, BREAKS, CRUSHES; + + public static @NotNull Movability test(@NotNull World world, @NotNull TilePosc tilePos) { + final var block = world.getBlockType(tilePos); + if (block == Blocks.AIR) return BREAKS; + if (block.hasTag(BlockTags.PISTON_CRUSHING)) return CRUSHES; + switch (block.getPistonPushReaction(world, tilePos)) { + case Material.PISTON_DESTROY_ON_PUSH: return BREAKS; + case Material.PISTON_CANT_PUSH: return OBSTRUCTED; + } + if (block.getImmovable() || block.getHardness() == -1F) return OBSTRUCTED; + return MOVES; } - if (world.hasSignal(tilePos.add(0, 1, -1, queryPos), Side.NORTH)) { - return true; + } + + // Piston Events: + // ================== + // ├─ extend + // │ ├─ push + // │ ├─ destroy (breakTail) + // │ ├─ ?crush (breakTail) + // │ ├─ ?flingEntity + // │ └─ ?flingBlock + // └─ retract + // └─ ?pull + // + + private boolean extend(@NotNull World world, @NotNull TilePosc tilePos, int data, int lineInfo) { + data = validateBaseData(data, this); + final var dir = Direction.fromId(DIRECTION.get(data)); + final var headPos = new TilePos(tilePos).add(dir); + + world.setBlockData(tilePos, IS_EXTENDED.set(data, 1)); + world.markBlockNeedsUpdate(tilePos); + + final boolean canFling = !Double.isNaN(this.flingStrength); + if (canFling) flingEntity(world, headPos, dir); + + final int len = LINE_LENGTH.get(lineInfo); + final boolean shouldCrush = CRUSH_EOL.bool(lineInfo); + final boolean shouldFling = !shouldCrush && canFling && len == 1; + if (shouldFling) { + flingBlock(world, headPos, dir); + } else { + final var tailAction = (shouldCrush) ? this.crushAction : EnumDropCause.WORLD; + breakTail(tailAction, world, headPos, dir, len); + push(world, headPos, dir, len); } - if (world.hasSignal(tilePos.add(0, 1, 1, queryPos), Side.SOUTH)) { - return true; + + final var headData = DIRECTION.set(0, dir.id) | TYPE.getNoShift(data); + final var headMoving = new TileEntityMovingPistonBlock( + MovingType.EXTENDING_PISTON, + HEAD_BLOCK_MAP[TYPE.get(data)], headData, null, dir); + + world.setBlockTypeDataEntity(headPos, Blocks.PISTON_MOVING, headData, headMoving); + + // extension updates base immediately, and head 3 ticks after + world.notifyBlocksOfNeighborChange(tilePos, this.block); + + return true; + } + + private static void push(@NotNull World world, @NotNull TilePosc headPos, @NotNull Direction dir, int len) { + final var src = new TilePos(); + final var tar = new TilePos(); + + for (int i = len - 1; i >= 0; i--) { + src.set(headPos); + dir.offsetScaled(src, i); + tar.set(src); + dir.offset(tar); + + final @NotNull Block block; + final int data; + var entity = world.getTileEntity(src); + + if (entity instanceof TileEntityMovingPistonBlock moving && !moving.isSourcePiston) { + assert world.getBlockType(src) == Blocks.PISTON_MOVING; + block = moving.movingBlock; + data = moving.movingBlockData; + entity = moving.movingTileEntity; + } else { + block = world.getBlockType(src); + data = world.getBlockData(src); + } + + world.removeTileEntity(src); + final var moving = new TileEntityMovingPistonBlock( + MovingType.EXTENDING, + block, data, entity, dir); + world.setBlockTypeDataEntity(tar, Blocks.PISTON_MOVING, data, moving); + + if (i >= 1) world.setBlockTypeRaw(src, Blocks.AIR); } - if (world.hasSignal(tilePos.add(-1, 1, 0, queryPos), Side.WEST)) { - return true; + } + + private void breakTail( + @NotNull EnumDropCause cause, @NotNull World world, @NotNull TilePosc headPos, + @NotNull Direction dir, int off + ) { + final var target = dir.offsetScaled(new TilePos(headPos), off); + + final var block = world.getBlockType(target); + if (block.id() > 0) { + world.playBlockEvent(null, target, LevelListener.EVENT_BLOCK_BREAK, block.id()); } - return world.hasSignal(tilePos.add(1, 1, 0, queryPos), Side.EAST); + + block.dropWithCause(world, cause, target, world.getBlockData(target), world.getTileEntity(target), null); + world.setBlockType(target, Blocks.AIR); } - @Override - public void triggerEvent(@NotNull World world, @NotNull TilePosc tilePos, int index, int data) { - Direction direction = getDirection(data); - if (direction == Direction.NONE) return; - if (index == EVENT_EXTEND) { - extendEvent(world, tilePos, data, direction); - } else if (index == EVENT_RETRACT) { - retractEvent(world, tilePos, data, direction); + private void flingEntity(@NotNull World world, @NotNull TilePosc headPos, @NotNull Direction dir) { + if (world.isClientSide) return; + final double vx = dir.offsetX() * this.flingStrength; + final double vy = dir.offsetY() * this.flingStrength; + final double vz = dir.offsetZ() * this.flingStrength; + final var entities = world.getEntitiesWithinAABBExcludingEntity(null, + new AABBd(new Vector3d(headPos.vec()), new Vector3d(headPos.vec()).add(1, 1, 1))); + // note that flingEntity is performed before flingBlock, therefore no need to + // check for flingBlock + for (final var entity : entities) { + entity.fling(vx, vy, vz, 1f); } } - public void extendEvent(@NotNull World world, @NotNull TilePosc tilePos, int data, @NotNull Direction direction) { - if (tryExtend(world, tilePos, direction, this.maxPushedBlocks)) { - world.setBlockDataNotify(tilePos, direction.getId() | MASK_POWERED); - world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, (double) tilePos.x() + 0.5D, (double) tilePos.y() + 0.5D, (double) tilePos.z() + 0.5D, "tile.piston.out", 0.5F, world.rand.nextFloat() * 0.25F + 0.6F); + private void flingBlock(@NotNull World world, @NotNull TilePosc headPos, @NotNull Direction dir) { + final double vx = dir.offsetX() * this.flingStrength; + final double vy = dir.offsetY() * this.flingStrength; + final double vz = dir.offsetZ() * this.flingStrength; + + final var block = world.getBlockType(headPos); + if (block == Blocks.AIR) return; + + final int blockMeta = world.getBlockData(headPos); + final var tileEntity = world.getTileEntity(headPos); + world.removeTileEntity(headPos); + world.setBlockTypeNotify(headPos, Blocks.AIR); + + if (world.isClientSide) return; + + var flungBlock = new EntityFallingBlock(world, + headPos.x() + 0.5, headPos.y() + 0.5, headPos.z() + 0.5, + block.id(), blockMeta, tileEntity); + flungBlock.hasRemovedBlock = true; + + if (tileEntity instanceof IVehicle vehicle) { + var rider = vehicle.ejectRider(); + if (rider != null) rider.startRiding(flungBlock); // TODO: ride packet after entity packet } + + world.entityJoinedWorld(flungBlock); + flungBlock.fling(vx, vy, vz, 1f); } - public void retractEvent(@NotNull World world, @NotNull TilePosc tilePos, int data, @NotNull Direction direction) { - TilePos shiftedPos = tilePos.add(direction, new TilePos()); - TileEntity tileEntity = world.getTileEntity(shiftedPos); - if ((tileEntity instanceof TileEntityMovingPistonBlock moving)) { - if (!moving.isExtending()) { + private void retract(@NotNull World world, @NotNull TilePosc tilePos, int data) { + data = validateBaseData(data, this); + final var dir = Direction.fromId(DIRECTION.get(data)); + final var headPos = new TilePos(tilePos).add(dir); + + if (world.getTileEntity(headPos) instanceof TileEntityMovingPistonBlock moving) { + if (!moving.isExtending) { moving.finalTick(); } else { - world.setBlockType(shiftedPos, Blocks.AIR); + world.setBlockType(headPos, Blocks.AIR); } } - world.setBlockTypeData(tilePos, Blocks.PISTON_MOVING, direction.getId()); - world.replaceTileEntity(tilePos, BlockLogicPistonMoving.createTileEntity(this.block, direction.getId(), null, direction, false, true)); - world.setBlockTypeNotify(shiftedPos, Blocks.AIR); - world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, (double) tilePos.x() + 0.5D, (double) tilePos.y() + 0.5D, (double) tilePos.z() + 0.5D, "tile.piston.in", 0.5F, world.rand.nextFloat() * 0.15F + 0.6F); - } - @Override - public @NotNull AABBdc getBoundsFromState(@NotNull WorldSource source, @NotNull TilePosc tilePos) { - int data = source.getBlockData(tilePos); - if (isPowered(data)) { - return switch (getDirection(data)) { - case DOWN -> new AABBd(0.0F, 0.25F, 0.0F, 1.0F, 1.0F, 1.0F); - case UP -> new AABBd(0.0F, 0.0F, 0.0F, 1.0F, 0.75F, 1.0F); - case NORTH -> new AABBd(0.0F, 0.0F, 0.25F, 1.0F, 1.0F, 1.0F); - case SOUTH -> new AABBd(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.75F); - case WEST -> new AABBd(0.25F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); - default -> new AABBd(0.0F, 0.0F, 0.0F, 0.75F, 1.0F, 1.0F); - }; + final var moving = new TileEntityMovingPistonBlock( + MovingType.RETRACTING_PISTON, + this.block, dir.id, null, dir); + world.setBlockTypeDataEntity(tilePos, Blocks.PISTON_MOVING, data, moving); + + if (this.canPull) { + pull(world, headPos, dir); } else { - return new AABBd(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + world.setBlockType(headPos, Blocks.AIR); + world.removeTileEntity(headPos); } + + // logically, retraction should only update head immediately, and base 3 ticks after + // but this emulates the old behavior + world.notifyBlocksOfNeighborChange(tilePos, this.block); + world.notifyBlocksOfNeighborChange(headPos, Blocks.AIR); + } + + private static void pull(@NotNull World world, @NotNull TilePosc headPos, @NotNull Direction dir) { + final var tar = headPos; + final var src = new TilePos(tar).add(dir); + + final var entity = world.getTileEntity(src); + + if (entity instanceof TileEntityMovingPistonBlock moving) position_moving: { + if (moving.direction != dir) break position_moving; + if (!moving.isExtending) break position_moving; + assert world.getBlockType(src) == Blocks.PISTON_MOVING; + + // 0t + moving.finalTick(); + return; + } + + if (Movability.test(world, src) != Movability.MOVES) { + world.removeTileEntity(tar); + return; + } + + final var block = world.getBlockType(src); + final var data = world.getBlockData(src); + + world.removeTileEntity(src); + final var moving = new TileEntityMovingPistonBlock( + MovingType.RETRACTING, + block, data, entity, dir); + world.setBlockTypeDataEntity(tar, Blocks.PISTON_MOVING, data, moving); + + world.setBlockTypeNotify(src, Blocks.AIR); } + // BlockLogic impl: + // ==================== + @Override - public boolean isCubeShaped() { + public boolean isSolidRender() { return false; } - + @Override - public @NotNull ISupport getSupport(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side) { - int meta = world.getBlockData(tilePos); - if ((meta & MASK_POWERED) == 0) return FullSupport.INSTANCE; - Direction dir = getDirection(meta); - return pistonSupportLookupTable[side.getId() * 6 + dir.getId()]; + public int getPlacedData( + @Nullable Player player, @NotNull ItemStack itemStack, @NotNull World world, + @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit + ) { + int meta = 0; + meta |= TYPE.set(meta, this.typeId); + meta |= NEW_FORMAT_SIGNATURE.mask; + + meta |= IS_DETACHED_OR_EXTENDED.setNoShift(meta, itemStack.getMetadata()); + final var dir = (player != null) + ? player.getPlacementDirection(side).opposite().id + : side.id; + meta |= DIRECTION.set(meta, dir); + + return meta; } - public static Direction getDirection(int data) { - return Direction.getDirectionById(data & MASK_DIRECTION); + @Override + public void onPlacedByWorld(@NotNull World world, @NotNull TilePosc tilePos) { + if (world.isClientSide) return; + final var d = NEW_FORMAT_SIGNATURE.set(world.getBlockData(tilePos), 1); + world.setBlockData(tilePos, d); + this.signalUpdate(world, tilePos); } - public static boolean isPowered(int data) { - return (data & MASK_POWERED) != 0; + @Override + public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block block) { + if (world.isClientSide) return; + final var data = fixLegacyBaseData(world, tilePos); + this.signalUpdate(world, tilePos, data); } - protected boolean isPushable(final @NotNull Block block, @NotNull World world, @NotNull TilePos tilePos, boolean canDestroy) { - int pushReaction = block.getPistonPushReaction(world, tilePos); - return !block.hasTag(BlockTags.PISTON_CRUSHING) && - !block.getImmovable() && - pushReaction != Material.PISTON_CANT_PUSH && - (canDestroy || pushReaction != Material.PISTON_DESTROY_ON_PUSH) && - block.getHardness() != -1F; + @Override + public @NotNull AABBdc getBoundsFromState(@NotNull WorldSource source, @NotNull TilePosc tilePos) { + int data = getValidatedBaseData(source, tilePos, this); + if (!IS_DETACHED_OR_EXTENDED.bool(data)) return new AABBd(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + + final var dir = Direction.fromId(DIRECTION.get(data)); + final var thickness = HEAD_BLOCK_MAP[this.typeId].getLogic().headThickness; + + final var min = new Vector3d(0); + final var max = new Vector3d(1); + + dir.offsetScaled(dir.isPositive() ? max : min, (dir.isNegative()) ? thickness : -thickness); + return new AABBd(min, max); } @Override - public int getPistonPushReaction(@NotNull World world, @NotNull TilePosc tilePos) { - if (isPowered(world.getBlockData(tilePos))) { - return Material.PISTON_CANT_PUSH; - } - return super.getPistonPushReaction(world, tilePos); + public boolean isCubeShaped() { + return false; } - protected boolean canPushLine(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Direction direction, int maxPushedBlocks) { - TilePos posO = tilePos.add(direction, new TilePos()); - int blocks = 0; - while (true) { - if (blocks >= maxPushedBlocks + 1) { - break; - } - if (posO.y < 0 || posO.y >= world.getHeightBlocks()) { - return false; - } - final @NotNull Block block = world.getBlockType(posO); - if (block == Blocks.AIR) { - break; - } - if (!isPushable(block, world, posO, true)) { - if (blocks == 1 && block.hasTag(BlockTags.PISTON_CRUSHING) && tryCrush(world, tilePos, direction)) { - break; - } - return false; - } - if (block.getPistonPushReaction(world, posO) == Material.PISTON_DESTROY_ON_PUSH) { - break; - } - if (blocks == maxPushedBlocks) { - return false; - } - posO.x += direction.getOffsetX(); - posO.y += direction.getOffsetY(); - posO.z += direction.getOffsetZ(); - blocks++; - } - return true; + private static final ISupport[] SUPPORT_LUT; + static { + final var F = FullSupport.INSTANCE; + final var P = PartialSupport.INSTANCE; + final PartialSupport U,D,L,R; + U = P.center().up(); + D = P.center().down(); + L = P.center().left(); + R = P.center().right(); + + SUPPORT_LUT = new ISupport[] { + P,F, U,D, R,L, // Bottom + F,P, D,U, R,L, // Top + U,D, P,F, R,L, // North + U,D, F,P, R,L, // South + U,D, L,R, P,F, // West + U,D, L,R, F,P, // East + }; } - public boolean tryCrush(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Direction direction) { - TilePos pos2 = tilePos.add(direction, new TilePos()); - Block block = world.getBlockType(pos2); - world.playBlockEvent(null, pos2, LevelListener.EVENT_BLOCK_BREAK, world.getBlockType(pos2).id()); - block.dropWithCause(world, EnumDropCause.SILK_TOUCH, pos2, world.getBlockData(pos2), null, null); - world.setBlockTypeNotify(pos2, Blocks.AIR); - return true; + @Override + public @NotNull ISupport getSupport(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side) { + final int data = getValidatedBaseData(world, tilePos, this); + final int dir = Direction.fromId(DIRECTION.get(data)).id; // ensures < 6 + + return (!IS_DETACHED_OR_EXTENDED.bool(data)) + ? FullSupport.INSTANCE + : SUPPORT_LUT[side.id * 6 + dir]; } - protected boolean tryExtend(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Direction direction, int maxPushedBlocks) { - int data = world.getBlockData(tilePos); - TilePos posO = tilePos.add(direction, new TilePos()); - int blocks = 0; - while (true) { - if (blocks >= maxPushedBlocks + 1) { - break; - } - if (posO.y < 0 || posO.y >= world.getHeightBlocks()) { - return false; - } - final @NotNull Block block = world.getBlockType(posO); - if (block == Blocks.AIR) { - break; - } - if (!isPushable(block, world, posO, true)) { - return false; - } - if (block.getPistonPushReaction(world, posO) == Material.PISTON_DESTROY_ON_PUSH) { - block.dropWithCause(world, EnumDropCause.WORLD, posO, world.getBlockData(posO), world.getTileEntity(posO), null); - break; - } - if (blocks == maxPushedBlocks) { - return false; - } - posO.x += direction.getOffsetX(); - posO.y += direction.getOffsetY(); - posO.z += direction.getOffsetZ(); - blocks++; - } - TilePos posP = new TilePos(posO); - while (!posO.equals(tilePos)) { - posP.set(posO.x - direction.getOffsetX(), posO.y - direction.getOffsetY(), posO.z - direction.getOffsetZ()); - @NotNull Block pushBlock = world.getBlockType(posP); - int pushMeta = world.getBlockData(posP); - TileEntity pushEntity = world.getTileEntity(posP); - if (pushEntity instanceof TileEntityMovingPistonBlock && posP.equals(tilePos)) { - break; - } - if (pushBlock == this.block && posP.equals(tilePos)) { - createPistonHeadAt(world, posO, data, direction); - } else if (pushBlock == Blocks.PISTON_MOVING) { - TileEntity old = world.getTileEntity(posP); - if (old instanceof TileEntityMovingPistonBlock moving) { - if (!moving.isSourcePiston()) { - pushBlock = moving.getMovedBlock(); - pushMeta = moving.getMovedData(); - pushEntity = moving.getMovedEntity(); - } - } - world.removeTileEntity(posP); - world.setBlockTypeData(posO, Blocks.PISTON_MOVING, pushMeta); - world.replaceTileEntity(posO, BlockLogicPistonMoving.createTileEntity(pushBlock, pushMeta, pushEntity, direction, true, false)); - } else { - world.removeTileEntity(posP); - world.setBlockTypeData(posO, Blocks.PISTON_MOVING, pushMeta); - world.replaceTileEntity(posO, BlockLogicPistonMoving.createTileEntity(pushBlock, pushMeta, pushEntity, direction, true, false)); - } - if (!posP.equals(tilePos)) { - world.setBlockTypeRaw(posP, Blocks.AIR); - } - posO.set(posP.x, posP.y, posP.z); - } + @Override + public int getPistonPushReaction(@NotNull World world, @NotNull TilePosc tilePos) { + final var data = fixLegacyBaseData(world, tilePos); - return true; + return (IS_DETACHED_OR_EXTENDED.bool(data)) + ? Material.PISTON_CANT_PUSH + : super.getPistonPushReaction(world, tilePos); } - public void createPistonHeadAt(@NotNull World world, @NotNull TilePos tilePos, int data, @NotNull Direction direction) { - world.setBlockTypeData(tilePos, Blocks.PISTON_MOVING, BlockLogicPistonHead.setPistonType(BlockLogicPistonHead.TYPE_NORMAL, direction.getId())); - world.replaceTileEntity(tilePos, BlockLogicPistonMoving.createTileEntity(Blocks.PISTON_HEAD, BlockLogicPistonHead.setPistonType(BlockLogicPistonHead.TYPE_NORMAL, direction.getId()), null, direction, true, false)); + @Override + public void onRemoved(@NotNull World world, @NotNull TilePosc tilePos, int data) { + data = validateBaseData(data, this); + if (IS_DETACHED.bool(data)) return; + + final var dir = Direction.fromId(DIRECTION.get(data)); + final var hpos = new TilePos(tilePos).add(dir); + final var head = world.getBlockType(hpos).getLogic(); + + if (head instanceof BlockLogicPistonHead) { + final int hdat = getValidatedHeadData(world, hpos); + if (hdat == DATA_INVALID) return; + if (PAIR_COMPARISON.get(data ^ hdat) != 0) return; + world.setBlockTypeNotify(hpos, Blocks.AIR); + } + else if (head instanceof BlockLogicPistonMoving) { + if (!(world.getTileEntity(hpos) instanceof TileEntityMovingPistonBlock moving)) return; + if (!moving.isSourcePiston) return; + if (moving.direction != dir) return; + world.removeTileEntity(hpos); + world.setBlockTypeNotify(hpos, Blocks.AIR); + } } @Override - public int getPlacedData(@Nullable Player player, @NotNull ItemStack itemStack, @NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) { - return MASK_DIRECTION; + public @NotNull ItemStack @Nullable [] getBreakResult( + @NotNull World world, @NotNull EnumDropCause dropCause, + int data, @Nullable TileEntity tileEntity + ) { + class ctx { + static final ItemStack[] buf = new ItemStack[1]; + } + + data = validateBaseData(data, this); + data = DIRECTION.set(data, 0) & IS_EXTENDED.set(data, 0); + + ctx.buf[0] = new ItemStack(this.block, 1, data); + return ctx.buf; } } diff --git a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBaseSteel.java b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBaseSteel.java deleted file mode 100644 index 6a9281cf1..000000000 --- a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBaseSteel.java +++ /dev/null @@ -1,197 +0,0 @@ -package net.minecraft.core.block.piston; - -import net.minecraft.core.block.Blocks; -import net.minecraft.core.block.entity.TileEntity; -import net.minecraft.core.block.material.Material; -import net.minecraft.core.block.Block; -import net.minecraft.core.block.tag.BlockTags; -import net.minecraft.core.entity.Entity; -import net.minecraft.core.entity.EntityFallingBlock; -import net.minecraft.core.entity.player.Player; -import net.minecraft.core.enums.EnumDropCause; -import net.minecraft.core.util.helper.Direction; -import net.minecraft.core.world.IVehicle; -import net.minecraft.core.world.LevelListener; -import net.minecraft.core.world.World; -import net.minecraft.core.world.WorldSource; -import net.minecraft.core.world.pos.TilePos; -import net.minecraft.core.world.pos.TilePosc; -import org.jetbrains.annotations.NotNull; -import org.joml.primitives.AABBd; -import org.joml.primitives.AABBdc; - -import java.util.ArrayList; -import java.util.List; - -public class BlockLogicPistonBaseSteel extends BlockLogicPistonBase { - public static final double HEAD_THICKNESS_STEEL = 6 / 16d; - - private Entity flungBlock = null; - - public BlockLogicPistonBaseSteel(@NotNull Block container, int maxPushedBlocks) { - super(container, maxPushedBlocks); - } - - @Override - public @NotNull AABBdc getBoundsFromState(@NotNull WorldSource source, @NotNull TilePosc tilePos) { - int data = source.getBlockData(tilePos); - if (isPowered(data)) { - return switch (getDirection(data)) { - case DOWN -> new AABBd(0.0F, HEAD_THICKNESS_STEEL, 0.0F, 1.0F, 1.0F, 1.0F); - case UP -> new AABBd(0.0F, 0.0F, 0.0F, 1.0F, 1 - HEAD_THICKNESS_STEEL, 1.0F); - case NORTH -> new AABBd(0.0F, 0.0F, HEAD_THICKNESS_STEEL, 1.0F, 1.0F, 1.0F); - case SOUTH -> new AABBd(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1 - HEAD_THICKNESS_STEEL); - case WEST -> new AABBd(HEAD_THICKNESS_STEEL, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); - default -> new AABBd(0.0F, 0.0F, 0.0F, 1 - HEAD_THICKNESS_STEEL, 1.0F, 1.0F); - }; - } else { - return new AABBd(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); - } - } - - @Override - protected boolean canPushLine(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Direction direction, int maxPushedBlocks) { - TilePos posO = tilePos.add(direction, new TilePos()); - int blocks = 0; - boolean didCrush = false; - while (true) { - if (blocks >= maxPushedBlocks + 1) { - break; - } - if (posO.y < 0 || posO.y >= world.getHeightBlocks()) { - return false; - } - final @NotNull Block block = world.getBlockType(posO); - if (block == Blocks.AIR) { - break; - } - if (!isPushable(block, world, posO, true)) { - if (blocks == 1 && block.hasTag(BlockTags.PISTON_CRUSHING) && tryCrush(world, tilePos, direction)) { - didCrush = true; - break; - } - return false; - } - if (block.getPistonPushReaction(world, posO) == Material.PISTON_DESTROY_ON_PUSH) { - break; - } - if (blocks == maxPushedBlocks) { - return false; - } - posO.x += direction.getOffsetX(); - posO.y += direction.getOffsetY(); - posO.z += direction.getOffsetZ(); - blocks++; - } - if (!didCrush && blocks == 1) { // Block Flinging - tilePos.add(direction, posO); - Block block = world.getBlockType(posO); - if (block == null) return true; - int blockMeta = world.getBlockData(posO); - TileEntity tileEntity = world.getTileEntity(posO); - world.removeTileEntity(posO); - world.setBlockTypeNotify(posO, Blocks.AIR); - if (!world.isClientSide) { - EntityFallingBlock entityFallingBlock = new EntityFallingBlock(world, posO.x + 0.5, posO.y + 0.5, posO.z + 0.5, block.id(), blockMeta, tileEntity); - entityFallingBlock.hasRemovedBlock = true; - if (tileEntity instanceof IVehicle) { - Entity rider = ((IVehicle) tileEntity).getPassenger(); - ((IVehicle) tileEntity).ejectRider(); - if (rider != null) rider.startRiding(entityFallingBlock); - } - world.entityJoinedWorld(entityFallingBlock); - final double speed = 2; - entityFallingBlock.fling(direction.getOffsetX() * speed, direction.getOffsetY() * speed, direction.getOffsetZ() * speed, 1f); - this.flungBlock = entityFallingBlock; - } - } - return true; - } - - @Override - public boolean tryCrush(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Direction direction) { - TilePos pos2 = tilePos.add(direction, new TilePos()); - Block block = world.getBlockType(pos2); - world.playBlockEvent(null, pos2, LevelListener.EVENT_BLOCK_BREAK, world.getBlockType(pos2).id()); - block.dropWithCause(world, EnumDropCause.PISTON_CRUSH, pos2, world.getBlockData(pos2), null, null); - world.setBlockTypeNotify(pos2, Blocks.AIR); - return true; - } - - @Override - protected boolean tryExtend(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Direction direction, int maxPushedBlocks) { - if (world.isClientSide) { // "Fixes" steel pistons appearing to push the block they just flung - int data = world.getBlockData(tilePos); - TilePos posO = tilePos.add(direction, new TilePos()); - int blocks = 0; - while (true) { - if (blocks >= maxPushedBlocks + 1) { - break; - } - if (posO.y < 0 || posO.y >= world.getHeightBlocks()) { - return false; - } - final @NotNull Block block = world.getBlockType(posO); - if (block == Blocks.AIR) { - break; - } - if (!isPushable(block, world, posO, true)) { - return false; - } - if (block.getPistonPushReaction(world, posO) == Material.PISTON_DESTROY_ON_PUSH) { - block.dropWithCause(world, EnumDropCause.WORLD, posO, world.getBlockData(posO), world.getTileEntity(posO), null); - break; - } - if (blocks == maxPushedBlocks) { - return false; - } - posO.x += direction.getOffsetX(); - posO.y += direction.getOffsetY(); - posO.z += direction.getOffsetZ(); - blocks++; - } - if (blocks == 1) { - TilePos posP = new TilePos(posO); - while (!posO.equals(tilePos)) { - posP.set(posO.x - direction.getOffsetX(), posO.y - direction.getOffsetY(), posO.z - direction.getOffsetZ()); - @NotNull Block pushBlock = world.getBlockType(posP); - TileEntity pushEntity = world.getTileEntity(posP); - if (pushEntity instanceof TileEntityMovingPistonBlock && posP.equals(tilePos)) { - break; - } - if (pushBlock == this.block && posP.equals(tilePos)) { - createPistonHeadAt(world, posO, data, direction); - } - if (!posP.equals(tilePos)) - world.setBlockTypeRaw(posP, Blocks.AIR); - posO.x = posP.x; - posO.y = posP.y; - posO.z = posP.z; - } - return true; - } - } - return super.tryExtend(world, tilePos, direction, maxPushedBlocks); - } - - @Override - public void extendEvent(@NotNull World world, @NotNull TilePosc tilePos, int data, @NotNull Direction direction) { - List entityList = new ArrayList<>(world.getEntitiesWithinAABBExcludingEntity(null, new AABBd((double) tilePos.x() + direction.getOffsetX(), (double) tilePos.y() + direction.getOffsetY(), (double) tilePos.z() + direction.getOffsetZ(), (double) tilePos.x() + direction.getOffsetX() + 1, (double) tilePos.y() + direction.getOffsetY() + 1, (double) tilePos.z() + direction.getOffsetZ() + 1))); - for (Entity entity : entityList) { - /*Fix for 1 tick extensions not working properly*/ - if (entity == null || entity.noPhysics || entity == this.flungBlock || entity.world.isClientSide && entity instanceof Player) - continue; - final double speed = 2; - entity.fling(direction.getOffsetX() * speed, direction.getOffsetY() * speed, direction.getOffsetZ() * speed, 1f); - } - this.flungBlock = null; - super.extendEvent(world, tilePos, data, direction); - } - - @Override - public void createPistonHeadAt(@NotNull World world, @NotNull TilePos tilePos, int data, @NotNull Direction direction) { - world.setBlockTypeData(tilePos, Blocks.PISTON_MOVING, BlockLogicPistonHead.setPistonType(BlockLogicPistonHead.TYPE_STEEL, direction.getId())); - world.replaceTileEntity(tilePos, BlockLogicPistonMoving.createTileEntity(Blocks.PISTON_HEAD_STEEL, BlockLogicPistonHead.setPistonType(BlockLogicPistonHead.TYPE_STEEL, direction.getId()), null, direction, true, false)); - } - -} diff --git a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBaseSticky.java b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBaseSticky.java deleted file mode 100644 index 890266124..000000000 --- a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBaseSticky.java +++ /dev/null @@ -1,75 +0,0 @@ -package net.minecraft.core.block.piston; - -import net.minecraft.core.block.Blocks; -import net.minecraft.core.block.entity.TileEntity; -import net.minecraft.core.block.material.Material; -import net.minecraft.core.block.Block; -import net.minecraft.core.sound.SoundCategory; -import net.minecraft.core.util.helper.Direction; -import net.minecraft.core.world.World; -import net.minecraft.core.world.pos.TilePos; -import net.minecraft.core.world.pos.TilePosc; -import org.jetbrains.annotations.NotNull; - -import java.util.Objects; - -public class BlockLogicPistonBaseSticky extends BlockLogicPistonBase { - public BlockLogicPistonBaseSticky(@NotNull Block block, int maxPushedBlocks) { - super(block, maxPushedBlocks); - } - - @Override - public void retractEvent(@NotNull World world, @NotNull TilePosc tilePos, int data, @NotNull Direction direction) { - TilePos posDir = tilePos.add(direction, new TilePos()); - TileEntity tileEntity = world.getTileEntity(posDir); - if ((tileEntity instanceof TileEntityMovingPistonBlock moving)) { - if (!moving.isExtending()) { - moving.finalTick(); - } else { - world.setBlockType(posDir, Blocks.AIR); - } - } - world.setBlockTypeData(tilePos, Blocks.PISTON_MOVING, direction.getId()); - world.replaceTileEntity(tilePos, BlockLogicPistonMoving.createTileEntity(this.block, direction.getId(), null, direction, false, true)); - TilePos pos1 = new TilePos(tilePos.x() + direction.getOffsetX() * 2, tilePos.y() + direction.getOffsetY() * 2, tilePos.z() + direction.getOffsetZ() * 2); - @NotNull Block retractBlock = world.getBlockType(pos1); - int retactMeta = world.getBlockData(pos1); - TileEntity retractEntity = world.getTileEntity(pos1); - boolean pulledMoving = false; - if (retractBlock == Blocks.PISTON_MOVING) { - if ((world.getTileEntity(pos1) instanceof TileEntityMovingPistonBlock movingPistonBlock)) { - if (movingPistonBlock.getDirection() == direction && movingPistonBlock.isExtending()) { - movingPistonBlock.finalTick(); - retractBlock = movingPistonBlock.getMovedBlock(); - retactMeta = movingPistonBlock.getMovedData(); - retractEntity = movingPistonBlock.getMovedEntity(); - pulledMoving = true; - } - } - } - TilePos pos2 = new TilePos(tilePos); - if (!pulledMoving && - isPushable(retractBlock, world, pos1, false) && - (retractBlock.getPistonPushReaction(world, pos1) == Material.PISTON_PUSHABLE || (retractBlock.getLogic() instanceof BlockLogicPistonBase))) { - if (!(retractEntity instanceof TileEntityMovingPistonBlock)) { - world.removeTileEntity(pos1); - } - world.setBlockType(pos1, Blocks.AIR); - pos2.x += direction.getOffsetX(); - pos2.y += direction.getOffsetY(); - pos2.z += direction.getOffsetZ(); - world.setBlockTypeData(pos2, Blocks.PISTON_MOVING, retactMeta); - world.replaceTileEntity(pos2, BlockLogicPistonMoving.createTileEntity(retractBlock, retactMeta, retractEntity, direction, false, false)); - world.notifyBlockChange(pos1, Blocks.AIR); - } else if (!pulledMoving) { - world.setBlockTypeNotify(posDir, Blocks.AIR); - } - world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, (double) pos2.x + 0.5D, (double) pos2.y + 0.5D, (double) pos2.z + 0.5D, "tile.piston.in", 0.5F, world.rand.nextFloat() * 0.15F + 0.6F); - } - - @Override - public void createPistonHeadAt(@NotNull World world, @NotNull TilePos tilePos, int data, @NotNull Direction direction) { - world.setBlockTypeData(tilePos, Blocks.PISTON_MOVING, BlockLogicPistonHead.setPistonType(BlockLogicPistonHead.TYPE_STICKY, direction.getId())); - world.replaceTileEntity(tilePos, BlockLogicPistonMoving.createTileEntity(Blocks.PISTON_HEAD, BlockLogicPistonHead.setPistonType(BlockLogicPistonHead.TYPE_STICKY, direction.getId()), null, direction, true, false)); - } -} diff --git a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonHead.java b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonHead.java index a1ee5acc8..95d6d5b68 100644 --- a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonHead.java +++ b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonHead.java @@ -11,28 +11,32 @@ import net.minecraft.core.block.material.Materials; import net.minecraft.core.block.support.FullSupport; import net.minecraft.core.block.support.ISupport; import net.minecraft.core.block.support.PartialSupport; +import net.minecraft.core.entity.Entity; +import net.minecraft.core.entity.player.Player; import net.minecraft.core.enums.EnumDropCause; +import net.minecraft.core.item.Item; import net.minecraft.core.item.ItemStack; +import net.minecraft.core.item.Items; import net.minecraft.core.util.helper.Direction; import net.minecraft.core.util.helper.Side; +import net.minecraft.core.world.ICarriable; +import net.minecraft.core.world.ICarrySource; import net.minecraft.core.world.World; import net.minecraft.core.world.WorldSource; import net.minecraft.core.world.pos.TilePos; import net.minecraft.core.world.pos.TilePosc; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.joml.Vector3d; import org.joml.primitives.AABBd; import org.joml.primitives.AABBdc; -public class BlockLogicPistonHead extends BlockLogic { - public static final int MASK_DIRECTION = 0b0000_0111; - public static final int MASK_TYPE = 0b1111_1000; - public static final int TYPE_NORMAL = 0; - public static final int TYPE_STICKY = 1; - public static final int TYPE_STEEL = 2; +import static net.minecraft.core.block.piston.PistonCommon.*; - private final double headThickness; - private final double shaftThickness; +public class BlockLogicPistonHead extends BlockLogic implements ICarrySource { + + // "Good lord. This really is our most NSFW update" -- Jonk + final double headThickness, shaftThickness; public BlockLogicPistonHead(final Block block, final double headThickness, final double shaftThickness) { super(block, Materials.PISTON); @@ -41,25 +45,6 @@ public class BlockLogicPistonHead extends BlockLogic { this.shaftThickness = shaftThickness; } - @Override - public void onRemoved(@NotNull World world, @NotNull TilePosc tilePos, int data) { - super.onRemoved(world, tilePos, data); - Direction direction = getDirectionFromMeta(data); - if (direction == Direction.NONE) { - return; - } - Direction orientation = direction.getOpposite(); - TilePos nextPos = tilePos.add(orientation, new TilePos()); - Block block = world.getBlockType(nextPos); - if (block != null && block.getLogic() instanceof BlockLogicPistonBase) { - int data2 = world.getBlockData(nextPos); - if (BlockLogicPistonBase.isPowered(data2)) { - block.dropWithCause(world, EnumDropCause.PROPER_TOOL, nextPos, data2, null, null); - world.setBlockTypeNotify(nextPos, Blocks.AIR); - } - } - } - @Override public boolean isSolidRender() { return false; @@ -72,106 +57,174 @@ public class BlockLogicPistonHead extends BlockLogic { @Override public @NotNull ISupport getSupport(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side) { - int meta = world.getBlockData(tilePos); - return getDirectionFromMeta(meta).getSide() == side ? FullSupport.INSTANCE : PartialSupport.INSTANCE; + int data = getValidatedHeadData(world, tilePos); + return (DIRECTION.get(data) == side.id) + ? FullSupport.INSTANCE + : PartialSupport.INSTANCE; } @Override public boolean canPlaceAt(@NotNull World world, @NotNull TilePosc tilePos) { return false; } - + @Override public boolean canPlaceOnSide(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side) { return false; } - - + @Override public void getCollisionAABBs(@NotNull World world, @NotNull TilePosc tilePos, @NotNull AABBdc aabb, @NotNull List<@NotNull AABBdc> aabbList) { - switch (getDirectionFromMeta(world.getBlockData(tilePos))) { - case DOWN -> { - addIntersectingBoundingBox(aabb, new AABBd(0.0F, 0.0F, 0.0F, 1.0F, this.headThickness, 1.0F).translate(tilePos.x(), tilePos.y(), tilePos.z()), aabbList); - addIntersectingBoundingBox(aabb, new AABBd(0.5 - this.shaftThickness / 2, this.headThickness, 0.5 - this.shaftThickness / 2, 0.5 + this.shaftThickness / 2, 1 + this.headThickness, 0.5 + this.shaftThickness / 2).translate(tilePos.x(), tilePos.y(), tilePos.z()), aabbList); - } - case UP -> { - addIntersectingBoundingBox(aabb, new AABBd(0.0F, 1 - this.headThickness, 0.0F, 1.0F, 1.0F, 1.0F).translate(tilePos.x(), tilePos.y(), tilePos.z()), aabbList); - addIntersectingBoundingBox(aabb, new AABBd(0.5 - this.shaftThickness / 2, -this.headThickness, 0.5 - this.shaftThickness / 2, 0.5 + this.shaftThickness / 2, 1 - this.headThickness, 0.5 + this.shaftThickness / 2).translate(tilePos.x(), tilePos.y(), tilePos.z()), aabbList); - } - case NORTH -> { - addIntersectingBoundingBox(aabb, new AABBd(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, this.headThickness).translate(tilePos.x(), tilePos.y(), tilePos.z()), aabbList); - addIntersectingBoundingBox(aabb, new AABBd(0.5 - this.shaftThickness / 2, 0.5 - this.shaftThickness / 2, this.headThickness, 0.5 + this.shaftThickness / 2, 0.5 + this.shaftThickness / 2, 1 + this.headThickness).translate(tilePos.x(), tilePos.y(), tilePos.z()), aabbList); - } - case SOUTH -> { - addIntersectingBoundingBox(aabb, new AABBd(0.0F, 0.0F, 1 - this.headThickness, 1.0F, 1.0F, 1.0F).translate(tilePos.x(), tilePos.y(), tilePos.z()), aabbList); - addIntersectingBoundingBox(aabb, new AABBd(0.5 - this.shaftThickness / 2, 0.5 - this.shaftThickness / 2, -this.headThickness, 0.5 + this.shaftThickness / 2, 0.5 + this.shaftThickness / 2, 1 - this.headThickness).translate(tilePos.x(), tilePos.y(), tilePos.z()), aabbList); - } - case WEST -> { - addIntersectingBoundingBox(aabb, new AABBd(0.0F, 0.0F, 0.0F, this.headThickness, 1.0F, 1.0F).translate(tilePos.x(), tilePos.y(), tilePos.z()), aabbList); - addIntersectingBoundingBox(aabb, new AABBd(this.headThickness, 0.5 - this.shaftThickness / 2, 0.5 - this.shaftThickness / 2, 1 + this.headThickness, 0.5 + this.shaftThickness / 2, 0.5 + this.shaftThickness / 2).translate(tilePos.x(), tilePos.y(), tilePos.z()), aabbList); - } - case EAST -> { - addIntersectingBoundingBox(aabb, new AABBd(1 - this.headThickness, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F).translate(tilePos.x(), tilePos.y(), tilePos.z()), aabbList); - addIntersectingBoundingBox(aabb, new AABBd(-this.headThickness, 0.5 - this.shaftThickness / 2, 0.5 - this.shaftThickness / 2, 1 - this.headThickness, 0.5 + this.shaftThickness / 2, 0.5 + this.shaftThickness / 2).translate(tilePos.x(), tilePos.y(), tilePos.z()), aabbList); - } - } + final var halvedShaft = shaftThickness / 2; + + final Vector3d hmin = new Vector3d(0), hmax = new Vector3d(1); + final Vector3d smin = new Vector3d(0.5 - halvedShaft), smax = new Vector3d(0.5 + halvedShaft); + + final var dir = Direction.fromId(DIRECTION.get(getValidatedHeadData(world, tilePos))); + final int cidx = dir.componentIndex(); + final boolean neg = dir.isNegative(); + + if (neg) hmax.setComponent(cidx, headThickness); + else hmin.setComponent(cidx, 1 - headThickness); + + final var sstart = (neg) ? this.headThickness : -this.headThickness; + smin.setComponent(cidx, sstart); + smax.setComponent(cidx, sstart + 1); + + final var pos = new Vector3d(tilePos.vec()); + addIntersectingBoundingBox(aabb, new AABBd(hmin, hmax).translate(pos), aabbList); + addIntersectingBoundingBox(aabb, new AABBd(smin, smax).translate(pos), aabbList); + } + + @Override + public @NotNull AABBdc getSelectionAABB(@NotNull WorldSource source, @NotNull TilePosc tilePos) { + final Vector3d min = new Vector3d(0), max = new Vector3d(1); + // if (!isBaseless(source.getBlockData(tilePos))) { + // final int i = getDirectionFromMeta(source.getBlockData(tilePos)).getId(); + // final int j = (i/2 + 1) % 3; + // final boolean n = (i & 1) == 0; + // if (n) max.setComponent(j, 1 + headThickness); + // else min.setComponent(j, 0 - headThickness); + // } + return new AABBd(min, max).translate(new Vector3d(tilePos.vec())); } @Override public @NotNull AABBdc getBoundsFromState(@NotNull WorldSource source, @NotNull TilePosc tilePos) { - return switch (getDirectionFromMeta(source.getBlockData(tilePos))) { - case DOWN -> new AABBd(0.0F, 0.0F, 0.0F, 1.0F, this.headThickness, 1.0F); - case UP -> new AABBd(0.0F, 1 - this.headThickness, 0.0F, 1.0F, 1.0F, 1.0F); - case NORTH -> new AABBd(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, this.headThickness); - case SOUTH -> new AABBd(0.0F, 0.0F, 1 - this.headThickness, 1.0F, 1.0F, 1.0F); - case WEST -> new AABBd(0.0F, 0.0F, 0.0F, this.headThickness, 1.0F, 1.0F); - case EAST -> new AABBd(1 - this.headThickness, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); - default -> super.getBoundsFromState(source, tilePos); - }; + final Vector3d min = new Vector3d(0), max = new Vector3d(1); + + final var dir = Direction.fromId(DIRECTION.get(getValidatedHeadData(source, tilePos))); + final int cidx = dir.componentIndex(); + final boolean neg = dir.isNegative(); + + if (neg) max.setComponent(cidx, headThickness); + else min.setComponent(cidx, 1 - headThickness); + + return new AABBd(min, max); } @Override public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block block) { - Direction direction = getDirectionFromMeta(world.getBlockData(tilePos)); - if (direction == Direction.NONE) { - return; - } - TilePos posOffset = tilePos.sub(direction, new TilePos()); - Block offsetBlock = world.getBlockType(posOffset); - if (offsetBlock.getLogic() instanceof BlockLogicPistonBase) { - offsetBlock.onNeighborChanged(world, posOffset, block); - } else { - world.setBlockTypeNotify(tilePos, Blocks.AIR); - } + final var data = getValidatedHeadData(world, tilePos); + if (IS_DETACHED.bool(data)) return; + + final var bpos = new TilePos(tilePos).sub(Direction.fromId(DIRECTION.get(data))); + if (!(world.getBlockType(bpos).getLogic() instanceof BlockLogicPistonBase)) return; + int bdat = fixLegacyBaseData(world, bpos); + if (PAIR_COMPARISON.get(data ^ bdat) != 0) return; + + world.getBlockType(bpos).onNeighborChanged(world, bpos, block); } @Override public int getPistonPushReaction(@NotNull World world, @NotNull TilePosc tilePos) { - return Material.PISTON_CANT_PUSH; - } - - public static Direction getDirectionFromMeta(int meta) { - return Direction.getDirectionById(meta & MASK_DIRECTION); + return (IS_DETACHED.bool(getValidatedHeadData(world, tilePos))) + ? Material.PISTON_PUSHABLE + : Material.PISTON_CANT_PUSH; } - public static int getPistonType(int data) { - return ((data & 0xFF) & MASK_TYPE) >> 3; + @Override + public void onRemoved(@NotNull World world, @NotNull TilePosc tilePos, int data) { + data = validateHeadData(data); + if (IS_DETACHED.bool(data)) return; + + final var bpos = new TilePos(tilePos).sub(Direction.fromId(DIRECTION.get(data))); + if (!(world.getBlockType(bpos).getLogic() instanceof BlockLogicPistonBase)) return; + int bdat = fixLegacyBaseData(world, bpos); + if (PAIR_COMPARISON.get(data ^ bdat) != 0) return; + bdat = IS_DETACHED.set(bdat, 1); + if (TYPE.get(bdat) == TYPE_STICKY) { + bdat = TYPE.set(bdat, TYPE_NORMAL); + world.setBlockTypeData(bpos, Blocks.PISTON_BASE, bdat); + } else { + world.setBlockData(bpos, bdat); + } + world.markBlockDirty(bpos); + world.triggerEvent(bpos, EVENT_DETACH, 0); } - public static int setPistonType(int type, int data) { - return ((data & ~MASK_TYPE) | (type << 3)) & 0xFF; + @Override + public void onDestroyedByPlayer( + @NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, int data, + @NotNull Player player, @Nullable Item item + ) { + data = validateHeadData(data); + if (IS_DETACHED.bool(data)) return; + + final var bpos = new TilePos(tilePos).sub(Direction.fromId(DIRECTION.get(data))); + if (!(world.getBlockType(bpos).getLogic() instanceof BlockLogicPistonBase)) return; + int bdat = fixLegacyBaseData(world, bpos); + bdat = IS_DETACHED.set(bdat, 0); + if (PAIR_COMPARISON.get(data ^ bdat) != 0) return; + + final var b = world.getBlockType(bpos).getLogic(); + world.setBlockTypeNotify(bpos, Blocks.AIR); // onRemoved + + if (player.gamemode.hasItemDrops()) { + b.dropWithCause(world, EnumDropCause.WORLD, bpos, bdat, null, null); + } } @Override - public ItemStack[] getBreakResult(@NotNull World world, @NotNull EnumDropCause dropCause, int data, @Nullable TileEntity tileEntity) { + public @NotNull ItemStack @Nullable [] getBreakResult( + @NotNull World world, @NotNull EnumDropCause dropCause, @NotNull TilePosc tilePos, + int data, @Nullable TileEntity tileEntity + ) { + // handle middle click pick block properly if (dropCause == EnumDropCause.PICK_BLOCK) { - return switch (getPistonType(data)) { - case TYPE_NORMAL -> new ItemStack[]{new ItemStack(Blocks.PISTON_BASE)}; - case TYPE_STICKY -> new ItemStack[]{new ItemStack(Blocks.PISTON_BASE_STICKY)}; - case TYPE_STEEL -> new ItemStack[]{new ItemStack(Blocks.PISTON_BASE_STEEL)}; - default -> null; - }; + if (IS_DETACHED.bool(data)) return null; + + // we assume head is attached to an actual matching base without performing tilepos lookup + int baseData = IS_EXTENDED.set(data, 1); + return BASE_BLOCK_MAP[TYPE.get(data)].getBreakResult(world, dropCause, baseData, null); } - return null; + + return this.getBreakResult(world, dropCause, data, tileEntity); + } + + @Override + public @NotNull ItemStack @Nullable [] getBreakResult( + @NotNull World world, @NotNull EnumDropCause dropCause, + int data, @Nullable TileEntity tileEntity + ) { + class Result { final static ItemStack[][] LUT = { + { new ItemStack(Blocks.PLANKS_OAK, 3) }, + { new ItemStack(Blocks.PLANKS_OAK, 3), new ItemStack(Items.SLIMEBALL) }, + { new ItemStack(Items.INGOT_STEEL_CRUDE, 3) }, + }; } + + if (dropCause == EnumDropCause.PICK_BLOCK) return null; + if (!IS_DETACHED.bool(data)) return null; + return Result.LUT[TYPE.get(data)]; + } + + @Override + public @NotNull ICarriable pickup(@NotNull World world, @NotNull Entity holder, @NotNull TilePosc tilePos) { + final var hdat = getValidatedHeadData(world, tilePos); + + world.setBlockType(tilePos, Blocks.AIR); // onRemoved + world.notifyBlockChange(tilePos, this.block); + + return new CarriedPistonHead((byte)TYPE.get(hdat)); } } diff --git a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonMoving.java b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonMoving.java index 192fc82fd..9cf4d026d 100644 --- a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonMoving.java +++ b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonMoving.java @@ -8,11 +8,13 @@ import net.minecraft.core.block.material.Materials; import net.minecraft.core.entity.player.Player; import net.minecraft.core.enums.EnumDropCause; import net.minecraft.core.item.ItemStack; -import net.minecraft.core.util.helper.Direction; import net.minecraft.core.util.helper.Side; import net.minecraft.core.world.WorldSource; import net.minecraft.core.world.World; import net.minecraft.core.world.pos.TilePosc; + +import java.util.List; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.joml.primitives.AABBd; @@ -54,20 +56,6 @@ public class BlockLogicPistonMoving extends BlockLogic { return false; } - @Override - public boolean onInteracted(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Player player, @Nullable Side side, double xHit, double yHit) { - if (!world.isClientSide && world.getTileEntity(tilePos) == null) { - @NotNull Block block = Blocks.AIR; - if (world.getTileEntity(tilePos) instanceof TileEntityMovingPistonBlock piston) { - block = piston.getMovedBlock(); - } - world.setBlockTypeNotify(tilePos, block); - return true; - } else { - return false; - } - } - @Override public ItemStack[] getBreakResult(@NotNull World world, @NotNull EnumDropCause dropCause, int data, @Nullable TileEntity tileEntity) { return null; @@ -75,62 +63,52 @@ public class BlockLogicPistonMoving extends BlockLogic { @Override public void dropWithCause(@NotNull World world, @NotNull EnumDropCause dropCause, @NotNull TilePosc tilePos, int data, @Nullable TileEntity tileEntity, @Nullable Player player) { - if (world.isClientSide) { - return; - } + if (world.isClientSide) return; if (world.getTileEntity(tilePos) instanceof TileEntityMovingPistonBlock piston) { - piston.getMovedBlock().dropWithCause(world, EnumDropCause.WORLD, tilePos, data, null, null); + piston.movingBlock().dropWithCause(world, EnumDropCause.WORLD, tilePos, data, null, null); } } - + @Override public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block block) { - if (!world.isClientSide) { - world.getTileEntity(tilePos); // Im not sure if this actually does anything anymore?? + if (world.isClientSide) return; + if (!(world.getTileEntity(tilePos) instanceof TileEntityMovingPistonBlock)) { + world.setBlockType(tilePos, Blocks.AIR); } } - public static TileEntity createTileEntity(final @NotNull Block movedBlock, int movedData, @Nullable TileEntity movedEntity, @NotNull Direction direction, boolean extending, boolean isSourcePiston) { - assert !(movedEntity instanceof TileEntityMovingPistonBlock) : "Moving piston entity should not be able to be put into another moving piston!"; - return new TileEntityMovingPistonBlock(movedBlock, movedData, movedEntity, direction, extending, isSourcePiston); + @Override + public void getCollisionAABBs( + @NotNull World world, @NotNull TilePosc tilePos, + @NotNull AABBdc aabb, @NotNull List<@NotNull AABBdc> aabbList + ) { + if (!(world.getTileEntity(tilePos) instanceof TileEntityMovingPistonBlock moving)) { + super.getCollisionAABBs(world, tilePos, aabb, aabbList); + return; + } + if (moving.isExtending || !moving.isSourcePiston) { + super.getCollisionAABBs(world, tilePos, aabb, aabbList); + return; + } + aabbList.add(this.getCollisionAABB(world, tilePos)); + // prevents entities from phasing into piston base + aabbList.add(new AABBd(0, 0, 0, 1, 1, 1).translate(tilePos.x(), tilePos.y(), tilePos.z())); + return; } @Override public @Nullable AABBdc getCollisionAABB(@NotNull WorldSource source, @NotNull TilePosc tilePos) { - if (source.getTileEntity(tilePos) instanceof TileEntityMovingPistonBlock piston) { - float progress = piston.getProgress(0.0F); - if (piston.isExtending()) { - progress = 1.0F - progress; - } - return getCollisionShapeFromTileEntity(source, tilePos, piston.getMovedBlock(), progress, piston.getDirection()); + if (!(source.getTileEntity(tilePos) instanceof TileEntityMovingPistonBlock moving)) { + return null; } - return null; + return moving.collision; } @Override public @NotNull AABBdc getBoundsFromState(@NotNull WorldSource source, @NotNull TilePosc tilePos) { if (source.getTileEntity(tilePos) instanceof TileEntityMovingPistonBlock piston) { - Block block = piston.getMovedBlock(); - if (block == this.block) { - return super.getBoundsFromState(source, tilePos); - } - float directionStretch = piston.getProgress(0.0F); - if (piston.isExtending()) { - directionStretch = 1.0F - directionStretch; - } - Direction direction = piston.getDirection(); - AABBdc otherBounds = block.getBoundsFromState(source, tilePos); - return otherBounds.translate(-direction.getOffsetX() * directionStretch, -direction.getOffsetY() * directionStretch, -direction.getOffsetZ() * directionStretch, new AABBd()); + return piston.bounds; } return super.getBoundsFromState(source, tilePos); } - - public @Nullable AABBdc getCollisionShapeFromTileEntity(@NotNull WorldSource source, @NotNull TilePosc tilePos, final @NotNull Block block, float directionStretch, @NotNull Direction direction) { - AABBdc aabb = block.getCollisionAABB(source, tilePos); - if (aabb == null) { - return null; - } else { - return aabb.translate(-direction.getOffsetX() * directionStretch, -direction.getOffsetY() * directionStretch, -direction.getOffsetZ() * directionStretch, new AABBd()); - } - } } diff --git a/game/core/src/main/java/net/minecraft/core/block/piston/CarriedPistonHead.java b/game/core/src/main/java/net/minecraft/core/block/piston/CarriedPistonHead.java new file mode 100644 index 000000000..a67feeed1 --- /dev/null +++ b/game/core/src/main/java/net/minecraft/core/block/piston/CarriedPistonHead.java @@ -0,0 +1,107 @@ +package net.minecraft.core.block.piston; + +import org.jetbrains.annotations.NotNull; + +import com.mojang.nbt.tags.CompoundTag; + +import net.minecraft.core.block.Block; +import net.minecraft.core.block.motion.ICarriedBlock; +import net.minecraft.core.entity.Entity; +import net.minecraft.core.entity.Mob; +import net.minecraft.core.enums.PlacementMode; +import net.minecraft.core.util.helper.Direction; +import net.minecraft.core.util.helper.Side; +import net.minecraft.core.world.ICarriable; +import net.minecraft.core.world.World; +import net.minecraft.core.world.pos.TilePos; + +import static net.minecraft.core.block.piston.PistonCommon.*; + +public class CarriedPistonHead implements ICarriable, ICarriedBlock { + private @NotNull byte type; + + public CarriedPistonHead(byte type) { + this.type = type; + } + + @Override + public @NotNull Block block() { + return PistonCommon.HEAD_BLOCK_MAP[type]; + } + + @Override + public int metadata() { + return metadata(Direction.UP.id); + } + + private int metadata(int dir) { + int d = 0; + d = IS_DETACHED.set(d, 1); + d = TYPE.set(d, this.type); + d = DIRECTION.set(d, dir); + d = validateHeadData(d); + return d; + } + + @Override + public boolean tryPlace(World world, Entity holder, int blockX, int blockY, int blockZ, + Side side, double xPlaced, double yPlaced + ) { + final var hpos = new TilePos(blockX, blockY, blockZ).add(side.direction()); + if (!world.canPlaceInsideBlock(hpos)) return false; + + final int dir = (holder instanceof Mob mob) + ? mob.getPlacementDirection(side.opposite(), PlacementMode.SIDE).opposite().id + : Direction.UP.id; + + int hdat = metadata(dir); + world.setBlockType(hpos, block()); + + sync_base: { + final var bpos = new TilePos(); + int bdat = headGetBase(hdat, bpos, world, hpos); + if (bdat == DATA_INVALID) break sync_base; + if (!IS_DETACHED_OR_EXTENDED.bool(bdat)) break sync_base; + if (PAIR_COMPARISON.get(hdat ^ bdat) != 0) break sync_base; + + hdat = IS_DETACHED.set(hdat, 0); + bdat = IS_DETACHED.set(bdat, 0); + bdat = IS_EXTENDED.set(hdat, 1); + + if (IS_STEEL.bool(hdat)) { + world.setBlockData(bpos, bdat); + } else { + bdat = TYPE.setNoShift(bdat, hdat); + world.setBlockTypeDataRaw(bpos, BASE_BLOCK_MAP[TYPE.get(hdat)], bdat); + } + world.triggerEvent(bpos, EVENT_ATTACH, 0); + } + + world.setBlockDataNotify(hpos, hdat); + return true; + } + + @Override + public void drop(World world, Entity holder) { + } + + @Override + public void writeToNBT(CompoundTag tag) { + tag.putByte("head_type", type); + tag.putString("type", TYPE_PISTON_HEAD); + } + + @Override + public void readFromNBT(CompoundTag tag) { + type = tag.getByte("head_type"); + } + + public static CarriedPistonHead createAndLoad(CompoundTag tag) { + final var carriedBlock = new CarriedPistonHead((byte)0); + carriedBlock.readFromNBT(tag); + return carriedBlock; + } + + @Override + public void heldTick(World world, Entity holder) {} +} diff --git a/game/core/src/main/java/net/minecraft/core/block/piston/PistonCommon.java b/game/core/src/main/java/net/minecraft/core/block/piston/PistonCommon.java new file mode 100644 index 000000000..ebf72e971 --- /dev/null +++ b/game/core/src/main/java/net/minecraft/core/block/piston/PistonCommon.java @@ -0,0 +1,186 @@ +package net.minecraft.core.block.piston; + +import org.jetbrains.annotations.NotNull; + +import net.minecraft.core.block.Block; +import net.minecraft.core.block.Blocks; +import net.minecraft.core.item.ItemStack; +import net.minecraft.core.util.PackedField; +import net.minecraft.core.util.helper.Direction; +import net.minecraft.core.world.World; +import net.minecraft.core.world.WorldSource; +import net.minecraft.core.world.pos.TilePos; +import net.minecraft.core.world.pos.TilePosc; + +/** + * NOTE: this class should only be accessed after the Blocks clinit logic is complete, i.e. + * not from within BlockLogic constructors! + */ +public abstract class PistonCommon { + private PistonCommon() {} + + public static final PackedField DIRECTION = new PackedField(0, 3); + public static final PackedField TYPE = new PackedField(3, 2); + public static final PackedField IS_DETACHED = new PackedField(5, 1); + public static final PackedField IS_EXTENDED = new PackedField(6, 1); + + public static final PackedField NEW_FORMAT_SIGNATURE = new PackedField(7, 1); + + public static final PackedField IS_STICKY = new PackedField(4, 1); + public static final PackedField IS_STEEL = new PackedField(5, 1); + + public static final PackedField IS_DETACHED_OR_EXTENDED = new PackedField( + IS_DETACHED.mask | IS_EXTENDED.mask + ); + + public static final PackedField PAIR_COMPARISON = new PackedField( + DIRECTION.mask | IS_DETACHED.mask | IS_STEEL.mask + ); + + // TODO using type id is poorly extensible, + // TODO in the future we should probably just represent piston types with separate Blocks + public static final byte TYPE_NORMAL = 0b00; + public static final byte TYPE_STICKY = 0b01; + public static final byte TYPE_STEEL = 0b10; + + /** + * Event data encodes line length. + * @see BlockLogicPistonBase#testLine(World, TilePosc, int) + */ + public static final byte EVENT_EXTEND = 0b00_0; + public static final byte EVENT_RETRACT = 0b00_1; + public static final byte EVENT_DETACH = 0b01_0; + public static final byte EVENT_ATTACH = 0b01_1; + public static final byte EVENT_DETACH_EXTEND = 0b10_0; + public static final byte EVENT_DETACH_RETRACT = 0b10_1; + + public static final @NotNull Block[] + BASE_BLOCK_MAP = (Block[]) new Block[] { + Blocks.PISTON_BASE, + Blocks.PISTON_BASE_STICKY, + Blocks.PISTON_BASE_STEEL, + }; + + public static final @NotNull Block[] + HEAD_BLOCK_MAP = (Block[]) new Block[] { + Blocks.PISTON_HEAD, + Blocks.PISTON_HEAD, // TODO this here is the only reason why we need typeid in block metadata + Blocks.PISTON_HEAD_STEEL, + }; + + public static final int DATA_INVALID = ~0; + + public static int fixLegacyBaseData(@NotNull World world, @NotNull TilePosc basePos) { + final var baseBlock = world.getBlockType(basePos); + final BlockLogicPistonBase base; + assert baseBlock.getLogic() instanceof BlockLogicPistonBase; + base = (BlockLogicPistonBase) baseBlock.getLogic(); + + int baseData = world.getBlockData(basePos); + if (NEW_FORMAT_SIGNATURE.bool(baseData)) return baseData; + + baseData = TYPE.set(baseData, base.typeId); + baseData = NEW_FORMAT_SIGNATURE.set(baseData, 1); + + // Direction bit address is the same as before + var baseDir = Direction.fromIdLenient(DIRECTION.get(baseData)); + + // on a healthy world this shouldn't happen + if (baseDir == Direction.NONE) return DIRECTION.set(baseData, 0); + + // old data format should not have set those bits + if (!IS_DETACHED_OR_EXTENDED.bool(baseData)) set_extended_if_head_matches: { + final var headPos = new TilePos(basePos).add(baseDir); + final var headBlock = world.getBlockType(headPos); + final var headData = world.getBlockData(headPos); + + final boolean isMovingHead = headBlock.getLogic() instanceof BlockLogicPistonMoving; + + if (isMovingHead) { + if (!(world.getTileEntity(headPos) instanceof TileEntityMovingPistonBlock moving)) { + break set_extended_if_head_matches; + } + if (!moving.isSourcePiston) break set_extended_if_head_matches; + if (moving.direction != baseDir) break set_extended_if_head_matches; + } else if (!(headBlock.getLogic() instanceof BlockLogicPistonHead)) { + break set_extended_if_head_matches; + } + + // old head data format should not have set this bit + if (IS_DETACHED.bool(headData)) break set_extended_if_head_matches; + if (DIRECTION.get(headData) != baseDir.id) break set_extended_if_head_matches; + + if (TYPE.get(headData) != base.typeId) break set_extended_if_head_matches; + + baseData = IS_EXTENDED.set(baseData, 1); + } + + world.setBlockData(basePos, baseData); + return baseData; + } + + public static int validateBaseData(int data, @NotNull BlockLogicPistonBase base) { + data = TYPE.set(data, base.typeId); + if (DIRECTION.get(data) > 5) data = DIRECTION.set(data, 0); + // if (IS_DETACHED.bool(data)) data = IS_EXTENDED.set(data, 1); + return data; + } + + public static int getValidatedBaseData(@NotNull WorldSource world, @NotNull TilePosc pos, @NotNull BlockLogicPistonBase base) { + return validateBaseData(world.getBlockData(pos), base); + } + + public static int validateHeadData(int data) { + data = IS_EXTENDED.set(data, 0); + if (DIRECTION.get(data) > 5) data = DIRECTION.set(data, 0); + return data; + } + + public static int getValidatedHeadData(@NotNull WorldSource world, @NotNull TilePosc pos) { + return validateHeadData(world.getBlockData(pos)); + } + + public static int baseGetHead(int bdata, @NotNull TilePos hpos, @NotNull World world, @NotNull TilePosc bpos) { + hpos.set(bpos).add(Direction.fromId(DIRECTION.get(bdata))); + return (world.getBlockType(hpos).getLogic() instanceof BlockLogicPistonHead) + ? getValidatedHeadData(world, hpos) + : DATA_INVALID; + } + + public static int headGetBase(int hdata, @NotNull TilePos bpos, @NotNull World world, @NotNull TilePosc hpos) { + bpos.set(hpos).sub(Direction.fromId(DIRECTION.get(hdata))); + return (world.getBlockType(bpos).getLogic() instanceof BlockLogicPistonBase base) + ? getValidatedBaseData(world, bpos, base) + : DATA_INVALID; + } + + public static enum MovingType { + EXTENDING(true, false), + EXTENDING_PISTON(true, true), + RETRACTING(false, false), + RETRACTING_PISTON(false, true); + + private MovingType(boolean isExtending, boolean isSourcePiston) { + this.isExtending = isExtending; + this.isSourcePiston = isSourcePiston; + } + + public final boolean isExtending; + public final boolean isSourcePiston; + } + + public static @NotNull ItemStack baseItem(int type, boolean isExteneded, boolean isDetached) { + int data = 0; + data |= TYPE.set(data, type); + data |= IS_EXTENDED.set(data, isExteneded ? 1 : 0); + data |= IS_DETACHED.set(data, isDetached ? 1 : 0); + return new ItemStack(BASE_BLOCK_MAP[type], 1, data); + } + + public static @NotNull ItemStack headItem(int type, boolean isDetached) { + int data = 0; + data |= TYPE.set(data, type); + data |= IS_DETACHED.set(data, isDetached ? 1 : 0); + return new ItemStack(BASE_BLOCK_MAP[type], 1, data); + } +} diff --git a/game/core/src/main/java/net/minecraft/core/block/piston/TileEntityMovingPistonBlock.java b/game/core/src/main/java/net/minecraft/core/block/piston/TileEntityMovingPistonBlock.java index 0b7d5745b..8822b3578 100644 --- a/game/core/src/main/java/net/minecraft/core/block/piston/TileEntityMovingPistonBlock.java +++ b/game/core/src/main/java/net/minecraft/core/block/piston/TileEntityMovingPistonBlock.java @@ -3,217 +3,210 @@ package net.minecraft.core.block.piston; import net.minecraft.core.block.entity.TileEntity; import net.minecraft.core.block.entity.TileEntityDispatcher; import net.minecraft.core.block.Block; -import net.minecraft.core.entity.Entity; import net.minecraft.core.block.Blocks; import net.minecraft.core.util.helper.Direction; import com.mojang.nbt.tags.CompoundTag; -import net.minecraft.core.world.World; import net.minecraft.core.world.pos.TilePos; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.joml.primitives.AABBd; import org.joml.primitives.AABBdc; import java.util.*; +import static net.minecraft.core.block.piston.PistonCommon.*; public class TileEntityMovingPistonBlock extends TileEntity { public static final int TICKS_TO_EXTEND = 2; - private static final List entityBuffer = new ArrayList<>(); - - private @NotNull Block movedBlock; - private int movedData; - private @Nullable TileEntity movedEntity; - private Direction direction; - private boolean extending; - private boolean isSourcePiston; - private float progress; - private float progressO; - - @SuppressWarnings("unused") - public TileEntityMovingPistonBlock() - { - } - - public TileEntityMovingPistonBlock(final @NotNull Block movedBlock, int movedData, @Nullable TileEntity movedEntity, Direction direction, boolean extending, boolean isSourcePiston) - { - this.movedBlock = movedBlock; - this.movedData = movedData; - this.movedEntity = movedEntity; + private static final float PROGRESS_DELTA = 1f / TICKS_TO_EXTEND; + + @NotNull Block movingBlock; + int movingBlockData; + @Nullable TileEntity movingTileEntity; + + @NotNull Direction direction; + boolean isExtending; + boolean isSourcePiston; + float progressCur = 0F, progressPrev = 0F; + + // these would otherwise be reallocated each tick, might as well store them here + @NotNull AABBd collision = new AABBd(); + @NotNull AABBd bounds = new AABBd(); + + + public @NotNull Block movingBlock() { return this.movingBlock; } + public int movingBlockData() { return this.movingBlockData; } + public @Nullable TileEntity movingTileEntity() { return this.movingTileEntity; } + + public @NotNull Direction direction() { return this.direction; } + public @NotNull Direction movingDirection() { + return (this.isExtending) ? this.direction : this.direction.opposite(); + } + + public boolean isExtending() { return this.isExtending; } + public boolean isSourcePiston() { return this.isSourcePiston; } + + public @NotNull AABBdc collision() { return this.collision; } + public @NotNull AABBdc bounds() { return this.bounds; } + + + // @SuppressWarnings("unused") + public TileEntityMovingPistonBlock() {} + + public TileEntityMovingPistonBlock( + @NotNull MovingType type, + @NotNull Block movingBlock, int movingData, @Nullable TileEntity movingEntity, + @NotNull Direction direction + ) { + assert movingBlock != Blocks.PISTON_MOVING; + this.movingBlock = movingBlock; + this.movingBlockData = movingData; + this.movingTileEntity = movingEntity; this.direction = direction; - this.extending = extending; - this.isSourcePiston = isSourcePiston; - this.progress = this.progressO = 0.0F; + this.isExtending = type.isExtending; + this.isSourcePiston = type.isSourcePiston; } - public @NotNull Block getMovedBlock() - { - return this.movedBlock; - } + private final void initAABBs() { + double dx,dy,dz; + final var sign = (this.isExtending) ? -1 : 1; + dx = sign * this.direction.offsetX(); + dy = sign * this.direction.offsetY(); + dz = sign * this.direction.offsetZ(); - public int getMovedData() - { - return this.movedData; - } + this.bounds + .set(this.movingBlock.getBoundsFromState(this.worldObj, tilePos)) + .translate(dx, dy, dz); - public @Nullable TileEntity getMovedEntity() { - return this.movedEntity; - } + var collision = this.movingBlock.getCollisionAABB(this.worldObj, this.tilePos); + if (collision == null) collision = new AABBd(0,0,0,0,0,0); - public boolean isExtending() - { - return this.extending; + this.collision + .set(collision) + .translate(dx, dy, dz); } - public Direction getDirection() - { - return this.direction; + private final void translateAABBs(float scale) { + final float dx,dy,dz; + scale = (this.isExtending) ? scale : -scale; + dx = scale * this.direction.offsetX(); + dy = scale * this.direction.offsetY(); + dz = scale * this.direction.offsetZ(); + this.bounds.translate(dx, dy, dz); + this.collision.translate(dx, dy, dz); } - public boolean isSourcePiston() - { - return this.isSourcePiston; + @Override + public void tick() { + this.progressPrev = this.progressCur; + if (this.progressCur == 0.0f) this.initAABBs(); + if (this.progressCur > (1.0F - 0x1p-12F)) { + this.finalTick(); + } else { + this.progressCur += PROGRESS_DELTA; + this.translateAABBs(PROGRESS_DELTA); + this.moveCollidedEntities(PROGRESS_DELTA + 0x1p-7F); + } } - public float getProgress(float partialTick) - { - if(partialTick > 1.0F) - { - partialTick = 1.0F; + private final void moveCollidedEntities(float scale) { + assert this.worldObj != null; + + final var dir = this.movingDirection(); + final float dx,dy,dz; + dx = dir.offsetX() * scale; + dy = dir.offsetY() * scale; + dz = dir.offsetZ() * scale; + + final int axis = dir.id >> 1; // y z x + final boolean neg = (dir.id & 1) == 0; + final double lim = 0x1p-4; + + final var entities = this.worldObj.getEntitiesWithinAABBExcludingEntity(null, this.collision); + for (final @NotNull var e : entities) { + if (e.noPhysics) continue; + e.move(dx, dy, dz); + switch (axis) { + case 2 -> e.xd = (neg) ? Math.min(e.xd, -lim) : Math.max(e.xd, lim); + case 0 -> e.yd = (neg) ? Math.min(e.yd, -lim) : Math.max(e.yd, lim); + case 1 -> e.zd = (neg) ? Math.min(e.zd, -lim) : Math.max(e.zd, lim); + } } - return this.progressO + (this.progress - this.progressO) * partialTick; } - public float getXOff(float partialTick) - { - if(this.extending) - { - return (getProgress(partialTick) - 1.0F) * (float) this.direction.getOffsetX(); - } else - { - return (1.0F - getProgress(partialTick)) * (float) this.direction.getOffsetX(); - } + public float progress(float partialTick) { + partialTick = Math.min(partialTick, 1.0F); + return this.progressPrev + (this.progressCur - this.progressPrev) * partialTick; } - public float getYOff(float partialTick) - { - if(this.extending) - { - return (getProgress(partialTick) - 1.0F) * (float) this.direction.getOffsetY(); - } else - { - return (1.0F - getProgress(partialTick)) * (float) this.direction.getOffsetY(); - } + public float progressSigned(float partialTick) { + final var p = this.progress(partialTick); + return (this.isExtending) + ? p - 1.0F + : 1.0F - p; } - public float getZOff(float partialTick) - { - if(this.extending) - { - return (getProgress(partialTick) - 1.0F) * (float) this.direction.getOffsetZ(); - } else - { - return (1.0F - getProgress(partialTick)) * (float) this.direction.getOffsetZ(); - } + public float xOffset(float partialTick) { + return this.progressSigned(partialTick) * (float) this.direction.offsetX(); } - private void moveCollidedEntities(float stretch, float force) { - assert this.worldObj != null; - if(!this.extending) { - stretch--; - } else { - stretch = 1.0F - stretch; - } - AABBdc aabb = Blocks.PISTON_MOVING.getLogic().getCollisionShapeFromTileEntity(this.worldObj, new TilePos(this.tilePos.x, this.tilePos.y, this.tilePos.z), this.movedBlock, stretch, this.direction); - if (aabb == null) return; - - List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(null, aabb); - if(!list.isEmpty()) - { - entityBuffer.addAll(list); - for (Entity entity : entityBuffer) { - if (entity == null || entity.noPhysics) continue; - entity.move(force * (float) this.direction.getOffsetX(), force * (float) this.direction.getOffsetY(), force * (float) this.direction.getOffsetZ()); - } - entityBuffer.clear(); - } + public float yOffset(float partialTick) { + return this.progressSigned(partialTick) * (float) this.direction.offsetY(); + } + + public float zOffset(float partialTick) { + return this.progressSigned(partialTick) * (float) this.direction.offsetZ(); } public void finalTick() { - TilePos selfPos = new TilePos(this.tilePos.x, this.tilePos.y, this.tilePos.z); + final var selfPos = new TilePos(this.tilePos); assert this.worldObj != null; - this.progressO = this.progress = 1.0F; + this.progressPrev = this.progressCur = 1.0F; this.worldObj.removeTileEntity(selfPos); invalidate(); - if(this.worldObj.getBlockType(selfPos) == Blocks.PISTON_MOVING) { - this.worldObj.setBlockTypeDataRaw(selfPos, this.movedBlock, this.movedData); - if (this.movedEntity != null) { - TileEntity oldEnt = this.worldObj.getTileEntity(selfPos); - if (oldEnt != null) { - oldEnt.invalidate(); - } - this.movedEntity.validate(); - this.movedEntity.tilePos.x = this.tilePos.x; - this.movedEntity.tilePos.y = this.tilePos.y; - this.movedEntity.tilePos.z = this.tilePos.z; - this.worldObj.replaceTileEntity(selfPos, this.movedEntity); - } + if (this.worldObj.getBlockType(selfPos) != Blocks.PISTON_MOVING) return; + this.worldObj.setBlockTypeDataRaw(selfPos, this.movingBlock, this.movingBlockData); - Block.disableNormalEntityLogic = true; - this.movedBlock.onPlacedByWorld(this.worldObj, selfPos); - Block.disableNormalEntityLogic = false; - - assert this.movedEntity == null || this.worldObj.getTileEntity(selfPos) == this.movedEntity : "Piston failed to actually move entity!"; - this.worldObj.notifyBlockChange(selfPos, this.movedBlock); + if (this.movingTileEntity != null) { + this.movingTileEntity.validate(); + this.worldObj.replaceTileEntity(selfPos, this.movingTileEntity); } - } + + Block.disableNormalEntityLogic = true; + this.movingBlock.onPlacedByWorld(this.worldObj, selfPos); + Block.disableNormalEntityLogic = false; - @Override - public void tick() - { - this.progressO = this.progress; - if(this.progressO >= 1.0F) - { - moveCollidedEntities(1.0F, 0.25F); - finalTick(); - return; - } - this.progress += 1f/TICKS_TO_EXTEND; - if(this.progress >= 0.999F) - { - this.progress = 1.0F; - } - if(this.extending) - { - moveCollidedEntities(this.progress, (this.progress - this.progressO) + 0.0625F); - } + assert this.movingTileEntity == null || this.worldObj.getTileEntity(selfPos) == this.movingTileEntity + : "Piston failed to actually move entity!"; + + this.worldObj.notifyBlockChange(selfPos, this.movingBlock); } @Override public void readAdditionalData(@NotNull CompoundTag compoundTag) { - this.movedBlock = Objects.requireNonNullElse(Blocks.getBlock(compoundTag.getInteger("blockId")), Blocks.AIR); - this.movedData = compoundTag.getInteger("blockData"); + this.movingBlock = Objects.requireNonNullElse(Blocks.getBlock(compoundTag.getInteger("blockId")), Blocks.AIR); + this.movingBlockData = compoundTag.getInteger("blockData"); if (compoundTag.containsKey("tileEntity")) { CompoundTag entityTag = compoundTag.getCompound("tileEntity"); - this.movedEntity = TileEntityDispatcher.createAndLoadEntity(entityTag); + this.movingTileEntity = TileEntityDispatcher.createAndLoadEntity(entityTag); } - this.direction = Direction.getDirectionById(compoundTag.getInteger("facing")); - this.progressO = this.progress = compoundTag.getFloat("progress"); - this.extending = compoundTag.getBoolean("extending"); + this.direction = Direction.fromId(compoundTag.getInteger("facing")); + this.progressPrev = this.progressCur = compoundTag.getFloat("progress"); + this.isExtending = compoundTag.getBoolean("extending"); } @Override - public void writeAdditionalData(@NotNull CompoundTag compoundTag) - { - compoundTag.putInt("blockId", this.movedBlock.id()); - compoundTag.putInt("blockData", this.movedData); - if (this.movedEntity != null) { + public void writeAdditionalData(@NotNull CompoundTag compoundTag) { + compoundTag.putInt("blockId", this.movingBlock.id()); + compoundTag.putInt("blockData", this.movingBlockData); + if (this.movingTileEntity != null) { CompoundTag entityTag = new CompoundTag(); - this.movedEntity.writeToNBT(entityTag); + this.movingTileEntity.writeToNBT(entityTag); compoundTag.put("tileEntity", entityTag); } - compoundTag.putInt("facing", this.direction.getId()); - compoundTag.putFloat("progress", this.progressO); - compoundTag.putBoolean("extending", this.extending); + compoundTag.putInt("facing", this.direction.id); + compoundTag.putFloat("progress", this.progressPrev); + compoundTag.putBoolean("extending", this.isExtending); } } diff --git a/game/core/src/main/java/net/minecraft/core/block/support/ISupportable.java b/game/core/src/main/java/net/minecraft/core/block/support/ISupportable.java index 909a160f3..660fc08ea 100644 --- a/game/core/src/main/java/net/minecraft/core/block/support/ISupportable.java +++ b/game/core/src/main/java/net/minecraft/core/block/support/ISupportable.java @@ -6,19 +6,14 @@ import net.minecraft.core.world.World; import net.minecraft.core.world.pos.TilePos; import net.minecraft.core.world.pos.TilePosc; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; public interface ISupportable { @NotNull ISupport getSupportConstraint(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Side side); default boolean isSupported(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Side side) { - final @Nullable Block supportingBlock = world.getBlockType(tilePos.add(side.getDirection(), new TilePos())); - if (supportingBlock == null) { - return false; - } - - final @NotNull ISupport supporting = supportingBlock.getSupport(world, tilePos.add(side.getDirection(), new TilePos()), side.getOpposite()); + final @NotNull Block supportingBlock = world.getBlockType(tilePos.add(side.direction(), new TilePos())); + final @NotNull ISupport supporting = supportingBlock.getSupport(world, tilePos.add(side.direction(), new TilePos()), side.opposite()); final @NotNull ISupport supported = this.getSupportConstraint(world, tilePos, side); - return supporting.canSupport(supported, side.getOpposite()); + return supporting.canSupport(supported, side.opposite()); } } diff --git a/game/core/src/main/java/net/minecraft/core/block/tag/BlockTags.java b/game/core/src/main/java/net/minecraft/core/block/tag/BlockTags.java index 2a8d1432f..5f4b11937 100644 --- a/game/core/src/main/java/net/minecraft/core/block/tag/BlockTags.java +++ b/game/core/src/main/java/net/minecraft/core/block/tag/BlockTags.java @@ -178,7 +178,7 @@ public abstract class BlockTags */ public static final Tag> NETHER_MOBS_SPAWN = Tag.of("nether_mobs_spawn"); /** - * Will drop block when piston extends into it + * Will drop block when piston push blocks into it */ public static final Tag> PISTON_CRUSHING = Tag.of("piston_crushing"); /** diff --git a/game/core/src/main/java/net/minecraft/core/current/util/BlockState.java b/game/core/src/main/java/net/minecraft/core/current/util/BlockState.java index a85af8cec..044e534f0 100644 --- a/game/core/src/main/java/net/minecraft/core/current/util/BlockState.java +++ b/game/core/src/main/java/net/minecraft/core/current/util/BlockState.java @@ -62,11 +62,11 @@ public class BlockState { } public boolean hasSignal(World world, TilePosc pos, Direction dir) { - return block.isEmittingSignal(world, pos, dir.getSide()); + return block.isEmittingSignal(world, pos, dir.side()); } public boolean hasDirectSignal(World world, TilePosc pos, Direction dir) { - return block.isEmittingDirectSignal(world, pos, dir.getSide()); + return block.isEmittingDirectSignal(world, pos, dir.side()); } public boolean canSurvive(World world, TilePosc pos) { diff --git a/game/core/src/main/java/net/minecraft/core/current/wire/ConduitHandler.java b/game/core/src/main/java/net/minecraft/core/current/wire/ConduitHandler.java index 6db86a5c8..2e53c3f8d 100644 --- a/game/core/src/main/java/net/minecraft/core/current/wire/ConduitHandler.java +++ b/game/core/src/main/java/net/minecraft/core/current/wire/ConduitHandler.java @@ -89,7 +89,7 @@ public class ConduitHandler { for (Side side : BlockLogicConduit.getOpenSides(data)) { TilePos nPos = new TilePos(pos).add(side); if (world.getBlockType(nPos) == Blocks.CONDUIT && - BlockLogicConduit.isSideOpen(world.getBlockData(nPos), side.getOpposite())) { + BlockLogicConduit.isSideOpen(world.getBlockData(nPos), side.opposite())) { toSearch.add(nPos); } } @@ -162,10 +162,8 @@ public class ConduitHandler { if (oldPower != newPower) { int state = oldData & BlockLogicConduit.STATE_MASK; - //suppress recursive neighbor updates while data is being set - world.noNeighborUpdate = true; - world.setBlockDataNotify(tilePos, (newPower << BlockLogicConduit.POWER_SHIFT) | state); - world.noNeighborUpdate = false; + world.setBlockData(tilePos, (newPower << BlockLogicConduit.POWER_SHIFT) | state); + world.markBlockNeedsUpdate(tilePos); //queue updates ONLY for blocks facing the open sides that ARE NOT conduits in this network for (Side side : BlockLogicConduit.getOpenSides(state)) { diff --git a/game/core/src/main/java/net/minecraft/core/current/wire/WireHandler.java b/game/core/src/main/java/net/minecraft/core/current/wire/WireHandler.java index ec81ad39e..9565b40a6 100644 --- a/game/core/src/main/java/net/minecraft/core/current/wire/WireHandler.java +++ b/game/core/src/main/java/net/minecraft/core/current/wire/WireHandler.java @@ -808,7 +808,7 @@ public class WireHandler { default -> wireSide; }; - return wireSide.getOpposite(); + return wireSide.opposite(); } /** diff --git a/game/core/src/main/java/net/minecraft/core/current/wire/WorldHelper.java b/game/core/src/main/java/net/minecraft/core/current/wire/WorldHelper.java index 5c61fc059..efc3de215 100644 --- a/game/core/src/main/java/net/minecraft/core/current/wire/WorldHelper.java +++ b/game/core/src/main/java/net/minecraft/core/current/wire/WorldHelper.java @@ -53,10 +53,11 @@ public class WorldHelper { world.setBlockData(pos, metadata); - // notify clients of the BlockState change - world.notifyBlockChange(pos, block); - // mark the chunk for saving - world.markBlockDirty(pos); + // // notify clients of the BlockState change + // world.notifyBlockChange(pos, block); + world.markBlockNeedsUpdate(pos); + // // mark the chunk for saving // is this actually true? + // world.markBlockDirty(pos); return true; } 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 cfaba6e12..0f22991d0 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 @@ -866,7 +866,7 @@ public abstract class Entity double dx = this.x - x; double dy = this.y - y; double dz = this.z - z; - return MathHelper.sqrt(dx * dx + dy * dy + dz * dz); + return Math.sqrt(dx * dx + dy * dy + dz * dz); } public double distanceToSqr(@NotNull Entity entity) { diff --git a/game/core/src/main/java/net/minecraft/core/entity/EntityFallingBlock.java b/game/core/src/main/java/net/minecraft/core/entity/EntityFallingBlock.java index 4b483ea9f..d6577933a 100644 --- a/game/core/src/main/java/net/minecraft/core/entity/EntityFallingBlock.java +++ b/game/core/src/main/java/net/minecraft/core/entity/EntityFallingBlock.java @@ -85,17 +85,20 @@ public class EntityFallingBlock extends Entity @Override public void tick() { - if(this.carriedBlock.blockId == 0) - { + final boolean isClient = this.world.isClientSide; + + if(this.carriedBlock.blockId == 0) { remove(); return; } + this.pushesThisTick = 0; this.pushTime *= 0.98f; if (this.pushTime < 0.05f || (this.pushTime < 0.25 && this.onGround)){ this.pushTime = 0; } - if (isOnFire() && this.carriedBlock.blockId == Blocks.TNT.id()) { + + if (!isClient && this.carriedBlock.blockId == Blocks.TNT.id() && isOnFire()) { remove(); EntityPrimedTNT entityPrimedTNT = new EntityPrimedTNT(this.world, this.x, this.y, this.z); entityPrimedTNT.xd = this.xd; @@ -105,6 +108,7 @@ public class EntityFallingBlock extends Entity this.world.entityJoinedWorld(entityPrimedTNT); return; } + this.xo = this.x; this.yo = this.y; this.zo = this.z; @@ -116,12 +120,16 @@ public class EntityFallingBlock extends Entity this.xd *= 0.98D; this.yd *= 0.98D; this.zd *= 0.98D; - TilePosc blockPos = roundedPos(); - if(this.world.getBlockType(blockPos).id() == this.carriedBlock.blockId && !this.hasRemovedBlock) - { + + final TilePosc blockPos = this.tilePosApprox(); + + // TODO tbh why are we using this hacky way of removing the block, should probably + // TODO just remove directly from within block logic :\ + if (!isClient && this.world.getBlockType(blockPos).id() == this.carriedBlock.blockId && !this.hasRemovedBlock) { this.world.setBlockTypeNotify(blockPos, Blocks.AIR); this.hasRemovedBlock = true; } + if (this.onGround) { Block selfBlock = this.carriedBlock.block(); Block blockBelow = this.world.getBlockType(blockPos.down(new TilePos())); @@ -140,53 +148,70 @@ public class EntityFallingBlock extends Entity this.pushTime *= (float) friction; } - double v = Math.hypot(this.xd, this.zd); - if (v < 0.001 || isInWall()) { - if(this.onGround || isInWall()) - { - Entity rider = getPassenger(); - ejectRider(); - remove(); - if( - ( - this.fallChecker.canFallInto(this.world, this.carriedBlock, blockPos.down(new TilePos())) || - !this.world.setBlockType(blockPos, Blocks.getBlock(this.carriedBlock.blockId)) - ) && !this.world.isClientSide - ) { - if(this.hasRemovedBlock) { - drop(); - } - } else if (!this.world.isClientSide) { - this.world.setBlockData(blockPos, this.carriedBlock.metadata); - if (this.carriedBlock.entity != null) { - TileEntity oldEnt = this.world.getTileEntity(blockPos); - if (oldEnt != null) { - oldEnt.invalidate(); - } - this.carriedBlock.entity.validate(); - this.carriedBlock.entity.tilePos.x = blockPos.x(); - this.carriedBlock.entity.tilePos.y = blockPos.y(); - this.carriedBlock.entity.tilePos.z = blockPos.z(); - this.carriedBlock.entity.worldObj = this.world; - this.carriedBlock.entity.carriedBlock = null; - this.world.replaceTileEntity(blockPos, this.carriedBlock.entity); - } - this.world.notifyBlockChange(blockPos, Blocks.getBlock(this.carriedBlock.blockId)); + if (!isClient) check_removal: { + final boolean isInWall = this.isInWall(); + if (!isInWall) { + if (Math.hypot(this.xd, this.zd) >= 0x1p-4D) break check_removal; + if (!this.onGround) { + if (this.fallTime <= 600) break check_removal; + if (this.hasRemovedBlock) this.drop(); + this.ejectRider(); + this.remove(); + break check_removal; } - if (rider != null) { - TileEntity te = this.world.getTileEntity(blockPos); - if (te instanceof IVehicle vehicle) rider.startRiding(vehicle); + } + final var passenger = getPassenger(); + this.ejectRider(); + this.remove(); + + // moving .hasRemovedBlock here fixes gravity block dupe + // note that it still creates duplicated falling block entity, but it cannot be + // turned into actual block (or item) anymore + if (this.hasRemovedBlock) fall_or_drop: { + + // if can be placed at position, AND cannot replace position bellow (floored), try to place; + // otherwise drop instead. + // + // this causes the interesting behavior of falling block when falling onto + // fence(gate) / boat, where they drop if the block above the fence, or the block + // the boat is in, is air, and place even if there's a torch above the fence / in the boat. + // + // this should be changed if we want something more intuitive. + final boolean shoudPlaceHere = + !this.fallChecker.canFallInto(this.world, this.carriedBlock, blockPos.down(new TilePos())); + + final boolean isPlaced = shoudPlaceHere && + this.world.setBlockType(blockPos, Blocks.getBlock(this.carriedBlock.blockId)); + + if (!isPlaced) { + this.drop(); + break fall_or_drop; } - } else if(this.fallTime > 600 && !this.world.isClientSide) { - if(this.hasRemovedBlock) { - drop(); + + this.world.setBlockData(blockPos, this.carriedBlock.metadata); + + final var tileEntity = this.carriedBlock.entity; + if (tileEntity != null) { + tileEntity.validate(); + tileEntity.tilePos.set(blockPos); + tileEntity.worldObj = this.world; + tileEntity.carriedBlock = null; + this.world.replaceTileEntity(blockPos, tileEntity); + + if (passenger != null && tileEntity instanceof IVehicle vehicle) { + passenger.startRiding(vehicle); + } } - ejectRider(); - remove(); + + this.world.notifyBlockChange(blockPos, this.carriedBlock.block()); } - this.carriedBlock.heldTick(this.world, this); + // we used to call heldTick even after falling block is removed. + // was that _intended_? + return; } + + this.carriedBlock.heldTick(this.world, this); } public void drop() { @@ -199,10 +224,8 @@ public class EntityFallingBlock extends Entity } } } - if (this.carriedBlock.entity != null) { - TilePosc blockPos = roundedPos(); - this.carriedBlock.entity.dropContents(this.world, blockPos.x(), blockPos.y(), blockPos.z()); - } + final var bpos = this.tilePosApprox(); + if (this.carriedBlock.entity != null) this.carriedBlock.entity.dropContents(world, bpos.x(), bpos.y(), bpos.z());; } @Override @@ -272,7 +295,7 @@ public class EntityFallingBlock extends Entity return 0.0D; } - public @NotNull TilePosc roundedPos() { + public @NotNull TilePosc tilePosApprox() { return new TilePos(MathHelper.round(this.x - 0.5), MathHelper.floor(this.y), MathHelper.round(this.z - 0.5)); } } diff --git a/game/core/src/main/java/net/minecraft/core/entity/EntityPainting.java b/game/core/src/main/java/net/minecraft/core/entity/EntityPainting.java index 6cbeeb3fa..7913026e0 100644 --- a/game/core/src/main/java/net/minecraft/core/entity/EntityPainting.java +++ b/game/core/src/main/java/net/minecraft/core/entity/EntityPainting.java @@ -272,9 +272,9 @@ public class EntityPainting extends Entity { break; } } - final double x = this.x + d.getOffsetX() / 4d; - final double y = this.y + d.getOffsetY() / 4d; - final double z = this.z + d.getOffsetZ() / 4d; + final double x = this.x + d.offsetX() / 4d; + final double y = this.y + d.offsetY() / 4d; + final double z = this.z + d.offsetZ() / 4d; this.world.entityJoinedWorld(new EntityItem(this.world, x, y, z, new ItemStack(Items.PAINTING))); if (getBorderStack() != null) { this.world.entityJoinedWorld(new EntityItem(this.world, x, y, z, getBorderStack())); diff --git a/game/core/src/main/java/net/minecraft/core/entity/Mob.java b/game/core/src/main/java/net/minecraft/core/entity/Mob.java index 6b58551ce..6f73ebaa1 100644 --- a/game/core/src/main/java/net/minecraft/core/entity/Mob.java +++ b/game/core/src/main/java/net/minecraft/core/entity/Mob.java @@ -1195,9 +1195,9 @@ public abstract class Mob extends Entity { mode = this.placementModeOverride; } if (mode == PlacementMode.SIDE && side != null && side.isHorizontal()) { - return side.getDirection().getOpposite(); + return side.direction().opposite(); } - return Direction.getHorizontalDirection(this); + return Direction.getHorizontalLockable(this); } public @NotNull Direction getPlacementDirection(final @NotNull Side side) { @@ -1212,9 +1212,9 @@ public abstract class Mob extends Entity { mode = this.placementModeOverride; } if (mode == PlacementMode.SIDE && side != null) { - return side.getDirection(); + return side.direction(); } - return Direction.getDirection(this); + return Direction.getLockable(this); } public Direction getVerticalPlacementDirection(Side side, double sideHeight) { @@ -1230,7 +1230,7 @@ public abstract class Mob extends Entity { } if (mode == PlacementMode.SIDE) { if (side.isVertical()) { - return side.getDirection().getOpposite(); + return side.direction().opposite(); } else { return sideHeight > 0.5 ? Direction.UP : Direction.DOWN; } diff --git a/game/core/src/main/java/net/minecraft/core/entity/projectile/ProjectileCannonballBouncy.java b/game/core/src/main/java/net/minecraft/core/entity/projectile/ProjectileCannonballBouncy.java index 6eaeced84..94e8901d1 100644 --- a/game/core/src/main/java/net/minecraft/core/entity/projectile/ProjectileCannonballBouncy.java +++ b/game/core/src/main/java/net/minecraft/core/entity/projectile/ProjectileCannonballBouncy.java @@ -58,19 +58,19 @@ public class ProjectileCannonballBouncy extends ProjectileCannonball { this.zd = 0f; return; } - if (side.getAxis() == Axis.Y) { + if (side.axis() == Axis.Y) { this.yd = -this.yd * bounceAxisScale; this.xd *= otherAxisScale; this.zd *= otherAxisScale; this.world.playSoundAtEntity(null, this, "random.explode", 0.25f * velocity, 2.0f); } - if (side.getAxis() == Axis.X) { + if (side.axis() == Axis.X) { this.xd = -this.xd * bounceAxisScale; this.yd *= otherAxisScale; this.zd *= otherAxisScale; this.world.playSoundAtEntity(null, this, "random.explode", 0.25f * velocity, 2.0f); } - if (side.getAxis() == Axis.Z) { + if (side.axis() == Axis.Z) { this.zd = -this.zd * bounceAxisScale; this.xd *= otherAxisScale; this.yd *= otherAxisScale; diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemBed.java b/game/core/src/main/java/net/minecraft/core/item/ItemBed.java index 23cdecf3c..4f8df4f8c 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemBed.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemBed.java @@ -23,33 +23,34 @@ public class ItemBed extends Item { if (selfStack.stackSize <= 0) return false; TilePosc pos1 = blockPos; if (!world.canPlaceInsideBlock(pos1)) { - pos1 = new TilePos(pos1).add(side.getDirection()); + pos1 = new TilePos(pos1).add(side.direction()); } - Direction dir = player == null ? Direction.NORTH : player.getHorizontalPlacementDirection(null).getOpposite(); + Direction dir = player == null ? Direction.NORTH : player.getHorizontalPlacementDirection(null).opposite(); final TilePos pos2 = new TilePos(pos1).sub(dir); if (!world.canPlaceInsideBlock(pos1) || !world.canPlaceInsideBlock(pos2)) return false; - final TilePos qpos = new TilePos(); - if (!world.canPlaceOnSurfaceOfBlock(qpos.set(pos1).down())) return false; - if (!world.canPlaceOnSurfaceOfBlock(qpos.set(pos2).down())) return false; + final var bed = Blocks.BED.getLogic(); + if (!bed.isSupported(world, pos1, Side.BOTTOM)) return false; + if (!bed.isSupported(world, pos2, Side.BOTTOM)) return false; if (!world.canBlockIdBePlacedAt(Blocks.BED.id(), pos1, false, side)) return false; - // if (!world.canBlockIdBePlacedAt(Blocks.BED.id(), pos2, false, side)) return false; + if (!world.canBlockIdBePlacedAt(Blocks.BED.id(), pos2, false, side)) return false; final boolean isPlaced1 = - world.setBlockTypeData(pos1, Blocks.BED, dir.getHorizontalIndex()); + world.setBlockTypeData(pos1, Blocks.BED, dir.legacyHorizontalIndex()); final boolean isPlaced2 = isPlaced1 && - world.setBlockTypeData(pos2, Blocks.BED, dir.getHorizontalIndex() | BlockLogicBed.IS_HEAD.set(0, 1)); + world.setBlockTypeData(pos2, Blocks.BED, dir.legacyHorizontalIndex() | BlockLogicBed.IS_HEAD.set(0, 1)); if (!isPlaced2) { if (isPlaced1) world.setBlockType(pos1, Blocks.AIR); return false; } selfStack.consumeItem(player); - world.notifyBlockChange(pos1, Blocks.BED); - world.notifyBlockChange(pos2, Blocks.BED); + world.markBlockNeedsUpdate(pos1); + world.markBlockNeedsUpdate(pos2); + world.notifyBlocksInCapsuleOfNeighborChange(dir.opposite(), pos1, Blocks.BED); world.playBlockSoundEffect(player, pos1.x() + 0.5F, pos1.y() + 0.5F, pos1.z() + 0.5F, Blocks.BED, EnumBlockSoundEffectType.PLACE); return true; diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemBoat.java b/game/core/src/main/java/net/minecraft/core/item/ItemBoat.java index 95329ef10..0d0fcfcc6 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemBoat.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemBoat.java @@ -44,9 +44,9 @@ public class ItemBoat extends Item { @Override public void onUseByActivator(@NotNull ItemStack selfStack, @NotNull World world, @NotNull TileEntityActivator activator, @NotNull Random random, @NotNull TilePosc blockPos, @NotNull Direction direction, double offX, double offY, double offZ) { - double x = blockPos.x() + offX + direction.getOffsetX(); - double y = blockPos.y() + offY + direction.getOffsetY(); - double z = blockPos.z() + offZ + direction.getOffsetZ(); + double x = blockPos.x() + offX + direction.offsetX(); + double y = blockPos.y() + offY + direction.offsetY(); + double z = blockPos.z() + offZ + direction.offsetZ(); selfStack.consumeItem(null); EntityBoat boat = new EntityBoat(world, x, y, z); world.entityJoinedWorld(boat); 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 8d9bcfeb3..201bb20eb 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 @@ -248,9 +248,9 @@ public abstract class ItemBucket extends ItemFood implements IItemContainer { Block blockAtPos = world.getBlockType(rayCastPos); if (!blockAtPos.hasTag(BlockTags.PLACE_OVERWRITES) && !blockAtPos.hasTag(BlockTags.BROKEN_BY_FLUIDS)) { Side side = hitTile.side; - rayCastPos.x += side.getOffsetX(); - rayCastPos.y += side.getOffsetY(); - rayCastPos.z += side.getOffsetZ(); + rayCastPos.x += side.offsetX(); + rayCastPos.y += side.offsetY(); + rayCastPos.z += side.offsetZ(); } if (rayCastPos.y < 0 || rayCastPos.y >= world.getHeightBlocks()) return itemStack; diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemDoor.java b/game/core/src/main/java/net/minecraft/core/item/ItemDoor.java index d6fb92c73..fc9c59284 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemDoor.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemDoor.java @@ -33,22 +33,24 @@ public class ItemDoor extends Item { public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) { if (player == null) return false; if (!world.canPlaceInsideBlock(blockPos)) { - blockPos = blockPos.add(side.getDirection(), new TilePos()); + blockPos = blockPos.add(side.direction(), new TilePos()); } - Direction leftDir = player.getHorizontalPlacementDirection(side).rotate(3); - int meta = leftDir.getHorizontalIndex(); + if (!world.canBlockIdBePlacedAt(this.doorBlockBottom.id(), blockPos, false, side)) return false; + + Direction leftDir = player.getHorizontalPlacementDirection(side).rotateY(1); + int meta = leftDir.legacyHorizontalIndex(); int isSolidBlockLeft = (isSupported(world, blockPos, leftDir, false) ? 1 : 0) + (isSupported(world, blockPos.up(new TilePos()), leftDir, false) ? 1 : 0); - int isSolidBlockRight = (isSupported(world, blockPos, leftDir.getOpposite(), true) ? 1 : 0) + (isSupported(world, blockPos.up(new TilePos()), leftDir.getOpposite(), true) ? 1 : 0); + int isSolidBlockRight = (isSupported(world, blockPos, leftDir.opposite(), true) ? 1 : 0) + (isSupported(world, blockPos.up(new TilePos()), leftDir.opposite(), true) ? 1 : 0); boolean isDoorLeft = world.getBlockType(blockPos.add(leftDir, new TilePos())) == this.doorBlockBottom || world.getBlockType(blockPos.add(leftDir, new TilePos()).up(new TilePos())) == this.doorBlockTop; boolean isDoorRight = world.getBlockType(blockPos.sub(leftDir, new TilePos())) == this.doorBlockBottom || world.getBlockType(blockPos.sub(leftDir, new TilePos()).up(new TilePos())) == this.doorBlockTop; boolean isMirrored = false; if (isDoorLeft && !isDoorRight) { isMirrored = (world.getBlockData(blockPos.add(leftDir, new TilePos())) & BlockLogicDoor.MASK_HINGE) == 0; - } else if (isSolidBlockLeft <= 0 || side.getDirection() != leftDir.getOpposite()) { - if (isSolidBlockRight > 0 && side.getDirection() == leftDir) { + } else if (isSolidBlockLeft <= 0 || side.direction() != leftDir.opposite()) { + if (isSolidBlockRight > 0 && side.direction() == leftDir) { isMirrored = true; } else if (isSolidBlockRight > isSolidBlockLeft) { isMirrored = true; @@ -72,16 +74,17 @@ public class ItemDoor extends Item { this.doorBlockBottom.onPlacedByMob(world, blockPos, side, player, xHit, yHit); this.doorBlockTop.onPlacedByMob(world, blockPos.up(new TilePos()), side, player, xHit, yHit); - world.notifyBlockChange(blockPos, this.doorBlockBottom); - world.notifyBlockChange(blockPos.up(new TilePos()), this.doorBlockTop); + // this is technically incorrect as both positions are updated as bottom door, + // but does it really matter? + world.notifyBlocksInCapsuleOfNeighborChange(Direction.UP, blockPos, this.doorBlockBottom); world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, this.doorBlockBottom, EnumBlockSoundEffectType.PLACE); return true; } public boolean isSupported(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Direction direction, boolean mirrored) { - ISupport support = world.getSupport(tilePos.add(direction, new TilePos()), direction.getSide().getOpposite()); - return support.canSupport(mirrored ? PartialSupport.INSTANCE.right() : PartialSupport.INSTANCE.left(), direction.getSide()); + ISupport support = world.getSupport(tilePos.add(direction, new TilePos()), direction.opposite().side()); + return support.canSupport(mirrored ? PartialSupport.INSTANCE.right() : PartialSupport.INSTANCE.left(), direction.side()); } @Override @@ -91,18 +94,18 @@ public class ItemDoor extends Item { } if (!direction.isHorizontal()) direction = Direction.NORTH; - Direction lefDir = direction.rotate(3); - int meta = lefDir.getHorizontalIndex(); + Direction lefDir = direction.rotateY(1); + int meta = lefDir.legacyHorizontalIndex(); int isSolidBlockLeft = (isSupported(world, blockPos, lefDir, false) ? 1 : 0) + (isSupported(world, blockPos.up(new TilePos()), lefDir, false) ? 1 : 0); - int isSolidBlockRight = (isSupported(world, blockPos, lefDir.getOpposite(), true) ? 1 : 0) + (isSupported(world, blockPos.up(new TilePos()), lefDir.getOpposite(), true) ? 1 : 0); + int isSolidBlockRight = (isSupported(world, blockPos, lefDir.opposite(), true) ? 1 : 0) + (isSupported(world, blockPos.up(new TilePos()), lefDir.opposite(), true) ? 1 : 0); boolean isDoorLeft = world.getBlockType(blockPos.add(lefDir, new TilePos())) == this.doorBlockBottom || world.getBlockType(blockPos.add(lefDir, new TilePos()).up(new TilePos())) == this.doorBlockTop; boolean isDoorRight = world.getBlockType(blockPos.sub(lefDir, new TilePos())) == this.doorBlockBottom || world.getBlockType(blockPos.sub(lefDir, new TilePos()).up(new TilePos())) == this.doorBlockTop; boolean isMirrored = false; if (isDoorLeft && !isDoorRight) { isMirrored = (world.getBlockData(blockPos.add(lefDir, new TilePos())) & BlockLogicDoor.MASK_HINGE) == 0; - } else if (isSolidBlockLeft <= 0 || direction != lefDir.getOpposite()) { + } else if (isSolidBlockLeft <= 0 || direction != lefDir.opposite()) { if (isSolidBlockRight > 0 && direction == lefDir) { isMirrored = true; } else if (isSolidBlockRight > isSolidBlockLeft) { @@ -121,13 +124,15 @@ public class ItemDoor extends Item { world.setBlockTypeData(blockPos, this.doorBlockBottom, meta); world.setBlockTypeData(blockPos.up(new TilePos()), this.doorBlockTop, meta); + world.markBlockNeedsUpdate(blockPos); + world.markBlockNeedsUpdate(blockPos.up(new TilePos())); + selfStack.consumeItem(null); - this.doorBlockBottom.onPlacedOnSide(world, blockPos, direction.getSide(), 0.5, 0.5); - this.doorBlockTop.onPlacedOnSide(world, blockPos.up(new TilePos()), direction.getSide(), 0.5, 0.5); + this.doorBlockBottom.onPlacedOnSide(world, blockPos, direction.side(), 0.5, 0.5); + this.doorBlockTop.onPlacedOnSide(world, blockPos.up(new TilePos()), direction.side(), 0.5, 0.5); - world.notifyBlockChange(blockPos, this.doorBlockBottom); - world.notifyBlockChange(blockPos.up(new TilePos()), this.doorBlockTop); + world.notifyBlocksInCapsuleOfNeighborChange(Direction.UP, blockPos, this.doorBlockBottom); world.playBlockSoundEffect(null, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, this.doorBlockBottom, EnumBlockSoundEffectType.PLACE); } diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemDye.java b/game/core/src/main/java/net/minecraft/core/item/ItemDye.java index 6a748984f..fd5015b4f 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemDye.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemDye.java @@ -142,7 +142,7 @@ public class ItemDye extends Item { @Override public void onUseByActivator(@NotNull ItemStack selfStack, @NotNull World world, @NotNull TileEntityActivator activator, @NotNull Random random, @NotNull TilePosc blockPos, @NotNull Direction direction, double offX, double offY, double offZ) { - onUseOnBlock(selfStack, world, null, blockPos.add(direction, new TilePos()), direction.getSide(), 0.5, 0.5); + onUseOnBlock(selfStack, world, null, blockPos.add(direction, new TilePos()), direction.side(), 0.5, 0.5); } @Override diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemEgg.java b/game/core/src/main/java/net/minecraft/core/item/ItemEgg.java index 387d2b673..b4db79d49 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemEgg.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemEgg.java @@ -31,7 +31,7 @@ public class ItemEgg extends Item implements IDispensable { @Override public void onUseByActivator(@NotNull ItemStack selfStack, @NotNull World world, @NotNull TileEntityActivator activator, @NotNull Random random, @NotNull TilePosc blockPos, @NotNull Direction direction, double offX, double offY, double offZ) { ProjectileEgg projectileEgg = new ProjectileEgg(world, blockPos.x() + offX, blockPos.y() + offY, blockPos.z() + offZ); - projectileEgg.setHeading(direction.getOffsetX() * 0.6, direction.getOffsetY() == 0 ? 0.1 : direction.getOffsetY() * 0.6, direction.getOffsetZ() * 0.6f, 1.1F, 6F); + projectileEgg.setHeading(direction.offsetX() * 0.6, direction.offsetY() == 0 ? 0.1 : direction.offsetY() * 0.6, direction.offsetZ() * 0.6f, 1.1F, 6F); world.entityJoinedWorld(projectileEgg); selfStack.stackSize -= 1; } @@ -40,7 +40,7 @@ public class ItemEgg extends Item implements IDispensable { public void onDispensed(@NotNull ItemStack selfStack, @NotNull World world, @NotNull Random random, @NotNull Direction direction, double x, double y, double z) { if (selfStack.consumeItem(null)) { ProjectileEgg projectileEgg = new ProjectileEgg(world, x, y, z); - projectileEgg.setHeading(direction.getOffsetX(), direction.getOffsetY() + 0.1D, direction.getOffsetZ(), 1.1F, 6F); + projectileEgg.setHeading(direction.offsetX(), direction.offsetY() + 0.1D, direction.offsetZ(), 1.1F, 6F); world.entityJoinedWorld(projectileEgg); } } diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemFireStriker.java b/game/core/src/main/java/net/minecraft/core/item/ItemFireStriker.java index d4204c0b5..da56e8899 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemFireStriker.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemFireStriker.java @@ -29,7 +29,7 @@ public class ItemFireStriker extends Item { @Override public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) { - blockPos = blockPos.add(side.getDirection(), new TilePos()); + blockPos = blockPos.add(side.direction(), new TilePos()); if (world.isAirBlock(blockPos)) { if (world.setBlockTypeNotify(blockPos, Blocks.FIRE)) { world.playSoundEffect(player, SoundCategory.WORLD_SOUNDS, (double) blockPos.x() + 0.5D, (double) blockPos.y() + 0.5D, (double) blockPos.z() + 0.5D, "fire.ignite", 1.0F, itemRand.nextFloat() * 0.4F + 0.8F); @@ -43,7 +43,7 @@ public class ItemFireStriker extends Item { @Override public void onUseByActivator(@NotNull ItemStack selfStack, @NotNull World world, @NotNull TileEntityActivator activator, @NotNull Random random, @NotNull TilePosc blockPos, @NotNull Direction direction, double offX, double offY, double offZ) { - if (!onUseOnBlock(selfStack, world, null, blockPos, direction.getSide(), 0.5, 0.5)) { + if (!onUseOnBlock(selfStack, world, null, blockPos, direction.side(), 0.5, 0.5)) { blockPos = blockPos.add(direction, new TilePos()); TilePos queryPos = new TilePos(); Block b = world.getBlockType(blockPos); diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemFlag.java b/game/core/src/main/java/net/minecraft/core/item/ItemFlag.java index c00177e8f..6dfaea5f8 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemFlag.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemFlag.java @@ -57,7 +57,7 @@ public class ItemFlag extends Item { } if (!world.canPlaceInsideBlock(blockPos)) { - blockPos = blockPos.add(side.getDirection(), new TilePos()); + blockPos = blockPos.add(side.direction(), new TilePos()); } if (blockPos.y() < 0 || blockPos.y() >= world.getHeightBlocks()) { return false; diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemMinecart.java b/game/core/src/main/java/net/minecraft/core/item/ItemMinecart.java index ffa78f320..bbb77458e 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemMinecart.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemMinecart.java @@ -41,6 +41,6 @@ public class ItemMinecart extends Item { @Override public void onUseByActivator(@NotNull ItemStack selfStack, @NotNull World world, @NotNull TileEntityActivator activator, @NotNull Random random, @NotNull TilePosc blockPos, @NotNull Direction direction, double offX, double offY, double offZ) { - onUseOnBlock(selfStack, world, null, blockPos.add(direction, new TilePos()), direction.getSide(), 0.5, 0.5); + onUseOnBlock(selfStack, world, null, blockPos.add(direction, new TilePos()), direction.side(), 0.5, 0.5); } } diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemPaintBrush.java b/game/core/src/main/java/net/minecraft/core/item/ItemPaintBrush.java index 8b969fc60..4fbc6bc9b 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemPaintBrush.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemPaintBrush.java @@ -66,7 +66,7 @@ public class ItemPaintBrush extends Item { @Override public void onUseByActivator(@NotNull ItemStack selfStack, @NotNull World world, @NotNull TileEntityActivator activator, @NotNull Random random, @NotNull TilePosc blockPos, @NotNull Direction direction, double offX, double offY, double offZ) { blockPos = blockPos.add(direction, new TilePos()); - if (!onUseOnBlock(selfStack, world, null, blockPos, direction.getSide(), 0.5, 0.5)) { + if (!onUseOnBlock(selfStack, world, null, blockPos, direction.side(), 0.5, 0.5)) { AABBdc box = new AABBd(blockPos.x(), blockPos.y(), blockPos.z(), blockPos.x() + 1, blockPos.y() + 1, blockPos.z() + 1); List entities = world.getEntitiesWithinAABB(MobSheep.class, box); if (!entities.isEmpty()) { diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemPebble.java b/game/core/src/main/java/net/minecraft/core/item/ItemPebble.java index 663c88b78..1cecb614d 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemPebble.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemPebble.java @@ -53,12 +53,12 @@ public class ItemPebble extends Item implements IDispensable { return false; } + final var pebble = Blocks.OVERLAY_PEBBLES.getLogic(); + // Check if we're placing "inside" a layer if (block == Blocks.OVERLAY_PEBBLES && side == Side.TOP) { final int newMeta = meta + 1; - if (!world.canPlaceOnSurfaceOfBlock(blockPos.down(new TilePos()))) { - return false; - } + if (!pebble.isSupported(world, blockPos, Side.BOTTOM)) return false; if (newMeta < BlockLogicOverlayPebbles.MAX_PEBBLES) { world.setBlockTypeDataNotify(blockPos, Blocks.OVERLAY_PEBBLES, newMeta); @@ -70,7 +70,7 @@ public class ItemPebble extends Item implements IDispensable { // Offset position if (block != Blocks.AIR) { - blockPos = blockPos.add(side.getDirection(), new TilePos()); + blockPos = blockPos.add(side.direction(), new TilePos()); block = world.getBlockType(blockPos); meta = world.getBlockData(blockPos); } @@ -80,7 +80,7 @@ public class ItemPebble extends Item implements IDispensable { final int newMeta = meta + 1; final AABBdc bbBox = new AABBd(blockPos.x(), blockPos.y(), blockPos.z(), blockPos.x() + 1f, blockPos.y() + (2 * (newMeta + 1)) / 16.0f, blockPos.z() + 1f); - if (!world.checkIfAABBIsClear(bbBox) || !world.canPlaceOnSurfaceOfBlock(blockPos.down(new TilePos()))) { + if (!world.checkIfAABBIsClear(bbBox) || !pebble.isSupported(world, blockPos, Side.BOTTOM)) { return false; } @@ -94,7 +94,7 @@ public class ItemPebble extends Item implements IDispensable { } // Regular placement, as all else fails - if (world.canBlockIdBePlacedAt(Blocks.OVERLAY_PEBBLES.id(), blockPos, false, side) && world.canPlaceOnSurfaceOfBlock(blockPos.down(new TilePos()))) { + if (world.canBlockIdBePlacedAt(Blocks.OVERLAY_PEBBLES.id(), blockPos, false, side) && !pebble.isSupported(world, blockPos, Side.BOTTOM)) { if (world.setBlockTypeNotify(blockPos, Blocks.OVERLAY_PEBBLES)) { Blocks.OVERLAY_PEBBLES.onPlacedByMob(world, blockPos, side, player, xHit, yHit); world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, Blocks.OVERLAY_PEBBLES, EnumBlockSoundEffectType.PLACE); @@ -108,7 +108,7 @@ public class ItemPebble extends Item implements IDispensable { @Override public void onUseByActivator(@NotNull ItemStack selfStack, @NotNull World world, @NotNull TileEntityActivator activator, @NotNull Random random, @NotNull TilePosc blockPos, @NotNull Direction direction, double offX, double offY, double offZ) { ProjectilePebble projectilePebble = new ProjectilePebble(world, blockPos.x() + offX, blockPos.y() + offY, blockPos.z() + offZ); - projectilePebble.setHeading(direction.getOffsetX() * 0.6, direction.getOffsetY() == 0 ? 0.1 : direction.getOffsetY() * 0.6, direction.getOffsetZ() * 0.6f, 1.1F, 6F); + projectilePebble.setHeading(direction.offsetX() * 0.6, direction.offsetY() == 0 ? 0.1 : direction.offsetY() * 0.6, direction.offsetZ() * 0.6f, 1.1F, 6F); world.entityJoinedWorld(projectilePebble); selfStack.stackSize -= 1; } @@ -117,7 +117,7 @@ public class ItemPebble extends Item implements IDispensable { public void onDispensed(@NotNull ItemStack selfStack, @NotNull World world, @NotNull Random random, @NotNull Direction direction, double x, double y, double z) { if (selfStack.consumeItem(null)) { ProjectilePebble projectilePebble = new ProjectilePebble(world, x, y, z); - projectilePebble.setHeading(direction.getOffsetX(), direction.getOffsetY() + 0.1D, direction.getOffsetZ(), 1.1F, 6F); + projectilePebble.setHeading(direction.offsetX(), direction.offsetY() + 0.1D, direction.offsetZ(), 1.1F, 6F); world.entityJoinedWorld(projectilePebble); } } diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemPlaceable.java b/game/core/src/main/java/net/minecraft/core/item/ItemPlaceable.java index bbe148998..652c21498 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemPlaceable.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemPlaceable.java @@ -32,33 +32,48 @@ public class ItemPlaceable extends Item { return false; } if (!world.canPlaceInsideBlock(blockPos)) { - blockPos = blockPos.add(side.getDirection(), new TilePos()); + blockPos = blockPos.add(side.direction(), new TilePos()); } if (blockPos.y() < 0 || blockPos.y() >= world.getHeightBlocks()) { return false; } - if (world.canBlockIdBePlacedAt(this.blockToPlace.id(), blockPos, false, side) && selfStack.consumeItem(player)) { - if (world.setBlockType(blockPos, this.blockToPlace)) { - if (player == null) { - this.blockToPlace.onPlacedOnSide(world, blockPos, side, xHit, yHit); - } else { - this.blockToPlace.onPlacedByMob(world, blockPos, side, player, xHit, yHit); - } - if (this.blockToPlace.isEntityTile && selfStack.getData().containsKey("tileEntityData")) { - TileEntity tileEntity = world.getTileEntity(blockPos); - if (tileEntity != null) { - tileEntity.readAdditionalData(selfStack.getData().getCompound("tileEntityData")); - } - } - // notify self change after onPlacedByMob - // this should fix almost all bugs related to piston intercepting placement logic, - // with out change to individual onPlaced<_> logics. - world.notifyBlockChange(blockPos, this.blockToPlace); - world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, this.blockToPlace, EnumBlockSoundEffectType.PLACE); - return true; + if (!world.canBlockIdBePlacedAt(this.blockToPlace.id(), blockPos, false, side)) return false; + + final var data = this.blockToPlace.getPlacedData(player, selfStack, world, blockPos, side, xHit, yHit); + + final var pbloc = world.getBlockType(blockPos); + final int pdata = world.getBlockData(blockPos); + + if (!world.setBlockTypeDataRaw(blockPos, this.blockToPlace, data)) return false; + + if (pbloc != this.blockToPlace || pdata != data) { + pbloc.onRemoved(world, blockPos, pdata); + } + + selfStack.consumeItem(player); + + if (player == null) { + this.blockToPlace.onPlacedOnSide(world, blockPos, side, xHit, yHit); + } else { + this.blockToPlace.onPlacedByMob(world, blockPos, side, player, xHit, yHit); + } + + // TODO before or after tileentity? + this.blockToPlace.onPlacedByWorld(world, blockPos); + + if (this.blockToPlace.isEntityTile && selfStack.getData().containsKey("tileEntityData")) { + TileEntity tileEntity = world.getTileEntity(blockPos); + if (tileEntity != null) { + tileEntity.readAdditionalData(selfStack.getData().getCompound("tileEntityData")); } } - return false; + + // notify self change after onPlacedByMob + // this should fix almost all bugs related to piston intercepting placement logic, + // with out change to individual onPlaced<_> logics. + world.notifyBlockChange(blockPos, this.blockToPlace); + world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, this.blockToPlace, EnumBlockSoundEffectType.PLACE); + return true; } @Override @@ -66,7 +81,7 @@ public class ItemPlaceable extends Item { blockPos = blockPos.add(direction, new TilePos()); Block b = world.getBlockType(blockPos); if (b == null || BlockTags.PLACE_OVERWRITES.appliesTo(b)) { - onUseOnBlock(selfStack, world, null, blockPos, direction.getSide(), 0.5, 0.5); + onUseOnBlock(selfStack, world, null, blockPos, direction.side(), 0.5, 0.5); } } } diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemQuiver.java b/game/core/src/main/java/net/minecraft/core/item/ItemQuiver.java index be24c7702..0c863de97 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemQuiver.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemQuiver.java @@ -124,7 +124,7 @@ public class ItemQuiver extends Item implements IArmorItem, IDi int count = getArrowCount(selfStack); if (count > 0) { final @NotNull ProjectileArrow arrow = new ProjectileArrow(world, x, y, z, 0); - arrow.setHeading(direction.getOffsetX(), direction.getOffsetY() + 0.1D, direction.getOffsetZ(), 1.1F, 6F); + arrow.setHeading(direction.offsetX(), direction.offsetY() + 0.1D, direction.offsetZ(), 1.1F, 6F); arrow.setDoesArrowBelongToPlayer(true); world.entityJoinedWorld(arrow); setArrowCount(selfStack, count - 1); diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemQuiverEndless.java b/game/core/src/main/java/net/minecraft/core/item/ItemQuiverEndless.java index e1e5fa509..a7a3d2668 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemQuiverEndless.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemQuiverEndless.java @@ -40,7 +40,7 @@ public class ItemQuiverEndless extends Item implements IArmorItem= world.getHeightBlocks()) { return false; diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemSeeds.java b/game/core/src/main/java/net/minecraft/core/item/ItemSeeds.java index 37e8518f8..2340932c8 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemSeeds.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemSeeds.java @@ -29,7 +29,7 @@ public class ItemSeeds extends Item { @Override public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) { if (!world.canPlaceInsideBlock(blockPos)) { - blockPos = blockPos.add(side.getDirection(), new TilePos()); + blockPos = blockPos.add(side.direction(), new TilePos()); } if (world.getBlockType(blockPos.down(new TilePos())) == Blocks.FARMLAND_DIRT && world.canPlaceInsideBlock(blockPos)) { if (world.setBlockTypeNotify(blockPos, this.cropsBlock)) { @@ -47,7 +47,7 @@ public class ItemSeeds extends Item { Block b = world.getBlockType(blockPos); boolean isFarmland = Block.hasLogicClass(b, BlockLogicFarmland.class); if (b == null || isFarmland || BlockTags.PLACE_OVERWRITES.appliesTo(b)) { - onUseOnBlock(selfStack, world, null, blockPos.add(0, isFarmland ? 1 : 0, 0, new TilePos()), direction.getSide(), 0.5, 0.5); + onUseOnBlock(selfStack, world, null, blockPos.add(0, isFarmland ? 1 : 0, 0, new TilePos()), direction.side(), 0.5, 0.5); } } } diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemSign.java b/game/core/src/main/java/net/minecraft/core/item/ItemSign.java index 66a35f6c4..4b6c2a2eb 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemSign.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemSign.java @@ -27,7 +27,7 @@ public class ItemSign extends Item { } if (!world.canPlaceInsideBlock(blockPos)) { - blockPos = blockPos.add(side.getDirection(), new TilePos()); + blockPos = blockPos.add(side.direction(), new TilePos()); } if (blockPos.y() < 0 || blockPos.y() >= world.getHeightBlocks() || !Blocks.SIGN_POST_PLANKS_OAK.canPlaceAt(world, blockPos)) { @@ -40,7 +40,7 @@ public class ItemSign extends Item { world.setBlockTypeData(blockPos, blockPlaced, MathHelper.floor((double) (((player.yRot + 180F) * 16F) / 360F) + 0.5D) & 0xf); } else { blockPlaced = Blocks.SIGN_WALL_PLANKS_OAK; - world.setBlockTypeData(blockPos, blockPlaced, side.getId()); + world.setBlockTypeData(blockPos, blockPlaced, side.id); } selfStack.consumeItem(player); world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, blockPlaced, EnumBlockSoundEffectType.PLACE); diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemSignPainted.java b/game/core/src/main/java/net/minecraft/core/item/ItemSignPainted.java index f73ba4d5a..d92c19ad6 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemSignPainted.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemSignPainted.java @@ -26,7 +26,7 @@ public class ItemSignPainted extends ItemSign { } if (!world.canPlaceInsideBlock(blockPos)) { - blockPos = blockPos.add(side.getDirection(), new TilePos()); + blockPos = blockPos.add(side.direction(), new TilePos()); } if (blockPos.y() < 0 || blockPos.y() >= world.getHeightBlocks() || !Blocks.SIGN_POST_PLANKS_OAK_PAINTED.canPlaceAt(world, blockPos)) { @@ -40,7 +40,7 @@ public class ItemSignPainted extends ItemSign { world.setBlockTypeData(blockPos, blockPlaced, Blocks.SIGN_POST_PLANKS_OAK_PAINTED.getLogic().toMetadata(DyeColor.colorFromItemMeta(selfStack.getMetadata())) | direction); } else { blockPlaced = Blocks.SIGN_WALL_PLANKS_OAK_PAINTED; - world.setBlockTypeData(blockPos, blockPlaced, Blocks.SIGN_POST_PLANKS_OAK_PAINTED.getLogic().toMetadata(DyeColor.colorFromItemMeta(selfStack.getMetadata())) | side.getId()); + world.setBlockTypeData(blockPos, blockPlaced, Blocks.SIGN_POST_PLANKS_OAK_PAINTED.getLogic().toMetadata(DyeColor.colorFromItemMeta(selfStack.getMetadata())) | side.id); } selfStack.consumeItem(player); world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, blockPlaced, EnumBlockSoundEffectType.PLACE); diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemSlimeball.java b/game/core/src/main/java/net/minecraft/core/item/ItemSlimeball.java new file mode 100644 index 000000000..e95545d96 --- /dev/null +++ b/game/core/src/main/java/net/minecraft/core/item/ItemSlimeball.java @@ -0,0 +1,100 @@ +package net.minecraft.core.item; + +import net.minecraft.core.block.Blocks; +import net.minecraft.core.block.entity.TileEntityActivator; +import net.minecraft.core.block.piston.PistonCommon; +import net.minecraft.core.entity.player.Player; +import net.minecraft.core.util.helper.Direction; +import net.minecraft.core.util.helper.Side; +import net.minecraft.core.world.World; +import net.minecraft.core.world.pos.TilePos; +import net.minecraft.core.world.pos.TilePosc; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import static net.minecraft.core.block.piston.PistonCommon.IS_DETACHED; + +import java.util.Random; + +public class ItemSlimeball extends Item { + + public ItemSlimeball(@NotNull String name, @NotNull String namespaceId, int id) { + super(name, namespaceId, id); + this.maxStackSize = 16; + } + + private static boolean useOnBlock( + @NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, + @NotNull TilePosc blockPos, @NotNull Direction direction + ) { + if (selfStack.stackSize <= 0) return false; + final var block = world.getBlockType(blockPos); + final boolean isBase = block == Blocks.PISTON_BASE; + final boolean isHead = !isBase && block == Blocks.PISTON_HEAD; + if (!isBase && !isHead) return false; + assert isBase || isHead; + + int data = world.getBlockData(blockPos); + if (PistonCommon.TYPE.get(data) != PistonCommon.TYPE_NORMAL) return false; + + // base can only be slimed while not extended and on the correct side + if (isBase) { + if (PistonCommon.IS_EXTENDED.bool(data)) return false; + final var faceDir = Direction.fromId(PistonCommon.DIRECTION.get(data)); + if (faceDir != direction) return false; + } + + data = PistonCommon.TYPE.set(data, PistonCommon.TYPE_STICKY); + assert selfStack.consumeItem(player); + + final var baseBlock = PistonCommon.BASE_BLOCK_MAP[PistonCommon.TYPE_STICKY]; + final var headBlock = PistonCommon.HEAD_BLOCK_MAP[PistonCommon.TYPE_STICKY]; + + final var newBlock = (isBase) ? baseBlock : headBlock; + + if (isBase || IS_DETACHED.bool(data)) { + world.setBlockTypeDataNotify(blockPos, newBlock, data); + return true; + } + + // head need to update base type as well + + final TilePos bpos = new TilePos(); + int bdat = PistonCommon.headGetBase(data, bpos, world, blockPos); + + System.err.println(bpos); + System.err.println(Integer.toBinaryString(bdat)); + + final boolean isExtendedButNotDetached = + PistonCommon.IS_DETACHED_OR_EXTENDED.get(bdat) == PistonCommon.IS_EXTENDED.mask; + if (!isExtendedButNotDetached) { + world.setBlockTypeDataNotify(blockPos, newBlock, data); + return true; + } + + world.setBlockTypeDataRaw(bpos, baseBlock, bdat); + world.setBlockTypeDataRaw(blockPos, newBlock, data); + world.markBlockNeedsUpdate(bpos); + world.markBlockNeedsUpdate(blockPos); + world.notifyBlocksInCapsuleOfNeighborChange(direction.opposite(), blockPos, newBlock); + + return true; + } + + @Override + public boolean onUseOnBlock( + @NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, + @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit + ) { + return useOnBlock(selfStack, world, player, blockPos, side.direction()); + } + + @Override + public void onUseByActivator( + @NotNull ItemStack selfStack, @NotNull World world, @NotNull TileEntityActivator activator, + @NotNull Random random, @NotNull TilePosc blockPos, + @NotNull Direction direction, double offX, double offY, double offZ + ) { + useOnBlock(selfStack, world, null, blockPos, direction); + } +} diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemSnowball.java b/game/core/src/main/java/net/minecraft/core/item/ItemSnowball.java index 3a7e3922b..00f3d3262 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemSnowball.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemSnowball.java @@ -31,7 +31,7 @@ public class ItemSnowball extends Item implements IDispensable { @Override public void onUseByActivator(@NotNull ItemStack selfStack, @NotNull World world, @NotNull TileEntityActivator activator, @NotNull Random random, @NotNull TilePosc blockPos, @NotNull Direction direction, double offX, double offY, double offZ) { ProjectileSnowball snowball = new ProjectileSnowball(world, blockPos.x() + offX, blockPos.y() + offY, blockPos.z() + offZ); - snowball.setHeading(direction.getOffsetX() * 0.6, direction.getOffsetY() == 0 ? 0.1 : direction.getOffsetY() * 0.6, direction.getOffsetZ() * 0.6f, 1.1F, 6F); + snowball.setHeading(direction.offsetX() * 0.6, direction.offsetY() == 0 ? 0.1 : direction.offsetY() * 0.6, direction.offsetZ() * 0.6f, 1.1F, 6F); world.entityJoinedWorld(snowball); selfStack.stackSize -= 1; } @@ -40,7 +40,7 @@ public class ItemSnowball extends Item implements IDispensable { public void onDispensed(@NotNull ItemStack selfStack, @NotNull World world, @NotNull Random random, @NotNull Direction direction, double x, double y, double z) { if (selfStack.consumeItem(null)) { ProjectileSnowball snowball = new ProjectileSnowball(world, x, y, z); - snowball.setHeading(direction.getOffsetX(), direction.getOffsetY() + 0.1D, direction.getOffsetZ(), 1.1F, 6F); + snowball.setHeading(direction.offsetX(), direction.offsetY() + 0.1D, direction.offsetZ(), 1.1F, 6F); world.entityJoinedWorld(snowball); } } diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemStatue.java b/game/core/src/main/java/net/minecraft/core/item/ItemStatue.java index 59e3381a7..09e183355 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemStatue.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemStatue.java @@ -30,15 +30,17 @@ public class ItemStatue extends Item { @Override public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) { if (!world.canPlaceInsideBlock(blockPos)) { - blockPos = blockPos.add(side.getDirection(), new TilePos()); + blockPos = blockPos.add(side.direction(), new TilePos()); } if (!this.statueBlockBottom.canPlaceAt(world, blockPos)) { return false; } + selfStack.consumeItem(player); world.setBlockTypeData(blockPos, this.statueBlockBottom, MathHelper.floor((double) (((player.yRot + 180F) * 16F) / 360F) + 0.5D) & 0xf); world.setBlockTypeData(blockPos.up(new TilePos()), this.statueBlockTop, MathHelper.floor((double) (((player.yRot + 180F) * 16F) / 360F) + 0.5D) & 0xf); - selfStack.consumeItem(player); + world.markBlockNeedsUpdate(blockPos); + world.markBlockNeedsUpdate(blockPos.up(new TilePos())); this.statueBlockBottom.onPlacedByMob(world, blockPos, side, player, xHit, yHit); this.statueBlockTop.onPlacedByMob(world, blockPos.up(new TilePos()), side, player, xHit, yHit); @@ -49,8 +51,7 @@ public class ItemStatue extends Item { tileEntity.readAdditionalData(selfStack.getData().getCompound("tileEntityData")); } } - world.notifyBlockChange(blockPos, this.statueBlockBottom); - world.notifyBlockChange(blockPos.up(new TilePos()), this.statueBlockTop); + world.notifyBlocksInCapsuleOfNeighborChange(Direction.UP, blockPos, this.statueBlockBottom); world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, this.statueBlockBottom, EnumBlockSoundEffectType.PLACE); @@ -66,15 +67,15 @@ public class ItemStatue extends Item { return; } - world.noNeighborUpdate = true; - world.setBlockTypeNotify(blockPos, this.statueBlockBottom); - world.setBlockTypeNotify(blockPos.up(new TilePos()), this.statueBlockTop); - world.noNeighborUpdate = false; - world.notifyBlocksOfNeighborChange(blockPos, this.statueBlockBottom); - world.notifyBlocksOfNeighborChange(blockPos.up(new TilePos()), this.statueBlockTop); + world.setBlockType(blockPos, this.statueBlockBottom); + world.setBlockType(blockPos.up(new TilePos()), this.statueBlockTop); + world.markBlockNeedsUpdate(blockPos); + world.markBlockNeedsUpdate(blockPos.up(new TilePos())); + world.notifyBlocksInCapsuleOfNeighborChange(Direction.UP, blockPos, this.statueBlockBottom); + world.playBlockSoundEffect(null, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, this.statueBlockBottom, EnumBlockSoundEffectType.PLACE); - this.statueBlockBottom.onPlacedOnSide(world, blockPos, direction.getSide(), 0.5, 0.5); - this.statueBlockTop.onPlacedOnSide(world, blockPos.up(new TilePos()), direction.getSide(), 0.5, 0.5); + this.statueBlockBottom.onPlacedOnSide(world, blockPos, direction.side(), 0.5, 0.5); + this.statueBlockTop.onPlacedOnSide(world, blockPos.up(new TilePos()), direction.side(), 0.5, 0.5); if (this.statueBlockBottom.isEntityTile && selfStack.getData().containsKey("tileEntityData")) { TileEntity tileEntity = world.getTileEntity(blockPos); diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemWandSpawner.java b/game/core/src/main/java/net/minecraft/core/item/ItemWandSpawner.java index 8979d9b70..15b0765d7 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemWandSpawner.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemWandSpawner.java @@ -68,11 +68,11 @@ public class ItemWandSpawner extends Item implements IDispensable @Override public void onDispensed(@NotNull ItemStack selfStack, @NotNull World world, @NotNull Random random, @NotNull Direction direction, double x, double y, double z) { - spawnEntity(selfStack, world, x + direction.getOffsetX() * 0.5, y + direction.getOffsetY() * 0.5, z + direction.getOffsetZ() * 0.5); + spawnEntity(selfStack, world, x + direction.offsetX() * 0.5, y + direction.offsetY() * 0.5, z + direction.offsetZ() * 0.5); } @Override public void onUseByActivator(@NotNull ItemStack selfStack, @NotNull World world, @NotNull TileEntityActivator activator, @NotNull Random random, @NotNull TilePosc blockPos, @NotNull Direction direction, double offX, double offY, double offZ) { - spawnEntity(selfStack, world, blockPos.x() + offX + direction.getOffsetX() * 0.5, blockPos.y() + offY + direction.getOffsetY() * 0.5, blockPos.z() + offZ + direction.getOffsetZ() * 0.5); + spawnEntity(selfStack, world, blockPos.x() + offX + direction.offsetX() * 0.5, blockPos.y() + offY + direction.offsetY() * 0.5, blockPos.z() + offZ + direction.offsetZ() * 0.5); } } diff --git a/game/core/src/main/java/net/minecraft/core/item/Items.java b/game/core/src/main/java/net/minecraft/core/item/Items.java index 895ae1556..3141a025f 100644 --- a/game/core/src/main/java/net/minecraft/core/item/Items.java +++ b/game/core/src/main/java/net/minecraft/core/item/Items.java @@ -211,6 +211,7 @@ public final class Items { public static Item WAND_NBT; // public static Item RUBYGLASS_DUST; public static Item RUBYGLASS_CRYSTAL; + public static Item TIMER; public static Item ARMOR_WOLF_LEATHER; public static Item ARMOR_WOLF_CHAINMAIL; @@ -344,7 +345,7 @@ public final class Items { SUGARCANE = (new ItemPlaceable("sugarcane", "minecraft:item/sugarcane", 16466, Blocks.SUGARCANE)); PAPER = (new Item("paper", "minecraft:item/paper", 16467)); BOOK = (new Item("book", "minecraft:item/book", 16468)); - SLIMEBALL = (new Item("slimeball", "minecraft:item/slimeball", 16469)); + SLIMEBALL = (new ItemSlimeball("slimeball", "minecraft:item/slimeball", 16469)); MINECART_CHEST = (new ItemMinecart("minecart.chest", "minecraft:item/minecart_chest", 16470, EntityMinecart.CHEST_CART)); MINECART_FURNACE = (new ItemMinecart("minecart.furnace", "minecraft:item/minecart_furnace", 16471, EntityMinecart.FURNACE_CART)); EGG_CHICKEN = (new ItemEgg("egg.chicken", "minecraft:item/egg_chicken", 16472)); @@ -413,7 +414,7 @@ public final class Items { LANTERN_FIREFLY_BLUE = (new ItemPlaceable("lantern.firefly.blue", "minecraft:item/lantern_firefly_blue", 16521, Blocks.LANTERN_FIREFLY_BLUE)); LANTERN_FIREFLY_ORANGE = (new ItemPlaceable("lantern.firefly.orange", "minecraft:item/lantern_firefly_orange", 16522, Blocks.LANTERN_FIREFLY_ORANGE)); LANTERN_FIREFLY_RED = (new ItemPlaceable("lantern.firefly.red", "minecraft:item/lantern_firefly_red", 16523, Blocks.LANTERN_FIREFLY_RED)); - // candleSoulwax = new ItemPlaceable("candle.soulwax", 16524, Block.candleSoulwax).setIconCoord(5, 10); + TIMER = (new ItemPlaceable("timer", "minecraft:item/timer", 16524, Blocks.TIMER)); BASKET = new ItemPlaceable("basket", "minecraft:item/basket", 16525, Blocks.BASKET); FLAG = new ItemFlag("flag", "minecraft:item/flag", 16526); ARMOR_BOOTS_ICESKATES = new ItemIceSkates("armor.boots.iceskates", "minecraft:item/armor_boots_iceskates", 16527); @@ -446,6 +447,7 @@ public final class Items { // RUBYGLASS_DUST = (new Item("rubyglass.crystal.cracked", "minecraft:item/rubyglass_crystal_cracked", 16554)); RUBYGLASS_CRYSTAL = (new Item("rubyglass.crystal.pure", "minecraft:item/rubyglass_crystal_pure", 16555)); + ARMOR_WOLF_LEATHER = new ItemArmor<>("armor.wolf.leather", "minecraft:item/armor_wolf_leather", 16556, ArmorMaterial.LEATHER, WolfArmorShape.BODY); ARMOR_WOLF_CHAINMAIL = new ItemArmor<>("armor.wolf.chainmail", "minecraft:item/armor_wolf_chainmail", 16557, ArmorMaterial.CHAINMAIL, WolfArmorShape.BODY); ARMOR_WOLF_IRON = new ItemArmor<>("armor.wolf.iron", "minecraft:item/armor_wolf_iron", 16558, ArmorMaterial.IRON, WolfArmorShape.BODY); diff --git a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlock.java b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlock.java index 7169216c3..b49f0c2e6 100644 --- a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlock.java +++ b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlock.java @@ -52,12 +52,20 @@ public class ItemBlock extends Item { final boolean placeNextToExisting = !world.canPlaceInsideBlock(blockPos) || (this.block.hasTag(BlockTags.PLACE_OVERWRITES) && this.block == world.getBlockType(blockPos)); - if (placeNextToExisting) blockPos = blockPos.add(side.getDirection(), new TilePos()); + if (placeNextToExisting) blockPos = blockPos.add(side.direction(), new TilePos()); if (!world.canBlockIdBePlacedAt(this.block.id(), blockPos, false, side)) return false; - - if (!world.setBlockTypeData(blockPos, this.block, meta)) return false; - if (!selfStack.consumeItem(player)) return false; // should always be true + + final var pbloc = world.getBlockType(blockPos); + final int pdata = world.getBlockData(blockPos); + + if (!world.setBlockTypeDataRaw(blockPos, this.block, meta)) return false; + + if (pbloc != this.block || pdata != meta) { + pbloc.onRemoved(world, blockPos, pdata); + } + + selfStack.consumeItem(player); if (player == null) { this.block.onPlacedOnSide(world, blockPos, side, xHit, yHit); @@ -65,6 +73,8 @@ public class ItemBlock extends Item { this.block.onPlacedByMob(world, blockPos, side, player, xHit, yHit); } + this.block.onPlacedByWorld(world, blockPos); + if (this.block.isEntityTile && selfStack.getData().containsKey("tileEntityData")) { final TileEntity tileEntity = world.getTileEntity(blockPos); if (tileEntity != null) { @@ -86,7 +96,7 @@ public class ItemBlock extends Item { blockPos = new TilePos(blockPos).add(direction); @NotNull Block b = world.getBlockType(blockPos); if (b == Blocks.AIR || BlockTags.PLACE_OVERWRITES.appliesTo(b)) { - onUseOnBlock(selfStack, world, null, blockPos, direction.getSide(), 0.5, 0.5); + onUseOnBlock(selfStack, world, null, blockPos, direction.side(), 0.5, 0.5); } } diff --git a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLadder.java b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLadder.java index e7a7a2cca..4f2dfce00 100644 --- a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLadder.java +++ b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLadder.java @@ -24,7 +24,7 @@ public class ItemBlockLadder extends ItemBlock { final Side pside; if (player == null || player.isSneaking() || world.getBlockType(bp) != this.block) { - if (!world.canPlaceInsideBlock(bp)) bp.add(side.getDirection()); + if (!world.canPlaceInsideBlock(bp)) bp.add(side.direction()); pside = ladder.getSideForPlacement(world, bp, side); } else { xHit = 0.5; diff --git a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockSlab.java b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockSlab.java index 7ba51df41..8544fd687 100644 --- a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockSlab.java +++ b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockSlab.java @@ -49,7 +49,7 @@ public class ItemBlockSlab extends ItemBlock { }; if (canPlaceInto) break; shiftPos.add(side); - yHit -= side.getOffsetY(); + yHit -= side.offsetY(); } if (i == 2) { // for else return super.onUseOnBlock(selfStack, world, player, blockPos, side, xHit, yHit); } diff --git a/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolHoe.java b/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolHoe.java index 27389ac8b..8a48d1c90 100644 --- a/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolHoe.java +++ b/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolHoe.java @@ -39,7 +39,7 @@ public class ItemToolHoe extends ItemTool { @Override public void onUseByActivator(@NotNull ItemStack selfStack, @NotNull World world, @NotNull TileEntityActivator activator, @NotNull Random random, @NotNull TilePosc blockPos, @NotNull Direction direction, double offX, double offY, double offZ) { - till(selfStack, null, world, blockPos.add(direction, new TilePos()), direction.getSide()); + till(selfStack, null, world, blockPos.add(direction, new TilePos()), direction.side()); } public boolean till(@NotNull ItemStack selfStack, @Nullable Player player, @NotNull World world, @NotNull TilePosc blockPos, @NotNull Side side) { diff --git a/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolShovel.java b/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolShovel.java index 895b76bff..aa60ed8df 100644 --- a/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolShovel.java +++ b/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolShovel.java @@ -36,7 +36,7 @@ public class ItemToolShovel extends ItemTool { @Override public void onUseByActivator(@NotNull ItemStack selfStack, @NotNull World world, @NotNull TileEntityActivator activator, @NotNull Random random, @NotNull TilePosc blockPos, @NotNull Direction direction, double offX, double offY, double offZ) { - shovelBlock(selfStack, world, null, blockPos.add(direction, new TilePos()), direction.getSide()); + shovelBlock(selfStack, world, null, blockPos.add(direction, new TilePos()), direction.side()); } public boolean shovelBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player entityplayer, @NotNull TilePosc blockPos, @NotNull Side side) { diff --git a/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolSword.java b/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolSword.java index 3d99468b8..7bb9605f1 100644 --- a/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolSword.java +++ b/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolSword.java @@ -55,7 +55,7 @@ public class ItemToolSword extends Item blockPos = blockPos.add(direction, new TilePos()); Block b = world.getBlockType(blockPos); if (b == Blocks.PUMPKIN) { - world.setBlockTypeData(blockPos, Blocks.PUMPKIN_CARVED_IDLE, direction.getOpposite().getId()); + world.setBlockTypeData(blockPos, Blocks.PUMPKIN_CARVED_IDLE, direction.opposite().id); selfStack.damageItem(1, null); } } diff --git a/game/core/src/main/java/net/minecraft/core/net/entity/entries/NetEntryFallingBlock.java b/game/core/src/main/java/net/minecraft/core/net/entity/entries/NetEntryFallingBlock.java index 473a2dd87..2f094e98d 100644 --- a/game/core/src/main/java/net/minecraft/core/net/entity/entries/NetEntryFallingBlock.java +++ b/game/core/src/main/java/net/minecraft/core/net/entity/entries/NetEntryFallingBlock.java @@ -27,7 +27,7 @@ public class NetEntryFallingBlock implements IVehicleEntry, @Override public int getMovementPacketDelay() { - return 20; + return 3; } @Override diff --git a/game/core/src/main/java/net/minecraft/core/net/packet/PacketBlockEvent.java b/game/core/src/main/java/net/minecraft/core/net/packet/PacketBlockEvent.java index 182a0f0a8..91f0698a9 100644 --- a/game/core/src/main/java/net/minecraft/core/net/packet/PacketBlockEvent.java +++ b/game/core/src/main/java/net/minecraft/core/net/packet/PacketBlockEvent.java @@ -9,14 +9,18 @@ public class PacketBlockEvent extends Packet public int xLocation; public int yLocation; public int zLocation; - public int index; - public int data; + public byte index; + public byte data; public PacketBlockEvent() { } - public PacketBlockEvent(int x, int y, int z, int index, int data) + public PacketBlockEvent(int x, int y, int z, int index, int data) { + this(x,y,z, (byte)(0xFF & index), (byte)(0xff & data)); + } + + public PacketBlockEvent(int x, int y, int z, byte index, byte data) { xLocation = x; yLocation = y; @@ -32,8 +36,8 @@ public class PacketBlockEvent extends Packet xLocation = dis.readInt(); yLocation = dis.readShort(); zLocation = dis.readInt(); - index = dis.read(); - data = dis.read(); + index = dis.readByte(); + data = dis.readByte(); } @Override @@ -43,8 +47,8 @@ public class PacketBlockEvent extends Packet dos.writeInt(xLocation); dos.writeShort(yLocation); dos.writeInt(zLocation); - dos.write(index); - dos.write(data); + dos.writeByte(index); + dos.writeByte(data); } @Override diff --git a/game/core/src/main/java/net/minecraft/core/net/packet/PacketPlayerAction.java b/game/core/src/main/java/net/minecraft/core/net/packet/PacketPlayerAction.java index bc3288510..53a2a78da 100644 --- a/game/core/src/main/java/net/minecraft/core/net/packet/PacketPlayerAction.java +++ b/game/core/src/main/java/net/minecraft/core/net/packet/PacketPlayerAction.java @@ -50,7 +50,7 @@ public class PacketPlayerAction extends Packet xPosition = dis.readInt(); yPosition = dis.read(); zPosition = dis.readInt(); - side = Side.getSideById(dis.read()); + side = Side.fromId(dis.read()); xHit = dis.readDouble(); yHit = dis.readDouble(); } @@ -63,7 +63,7 @@ public class PacketPlayerAction extends Packet dos.writeInt(xPosition); dos.write(yPosition); dos.writeInt(zPosition); - dos.write(side.getId()); + dos.write(side.id); dos.writeDouble(xHit); dos.writeDouble(yHit); } diff --git a/game/core/src/main/java/net/minecraft/core/net/packet/PacketUseOrPlaceItemStack.java b/game/core/src/main/java/net/minecraft/core/net/packet/PacketUseOrPlaceItemStack.java index 21c0c9a58..7a21858aa 100644 --- a/game/core/src/main/java/net/minecraft/core/net/packet/PacketUseOrPlaceItemStack.java +++ b/game/core/src/main/java/net/minecraft/core/net/packet/PacketUseOrPlaceItemStack.java @@ -80,7 +80,7 @@ public class PacketUseOrPlaceItemStack extends Packet xPosition = dis.readInt(); yPosition = dis.read(); zPosition = dis.readInt(); - direction = Direction.getDirectionById(dis.read()); + direction = Direction.fromId(dis.read()); xPlaced = dis.readDouble(); yPlaced = dis.readDouble(); type = dis.readByte(); @@ -103,7 +103,7 @@ public class PacketUseOrPlaceItemStack extends Packet dos.writeInt(xPosition); dos.write(yPosition); dos.writeInt(zPosition); - dos.write(direction.getId()); + dos.write(direction.id); dos.writeDouble(xPlaced); dos.writeDouble(yPlaced); dos.writeByte(type); diff --git a/game/core/src/main/java/net/minecraft/core/util/PackedField.java b/game/core/src/main/java/net/minecraft/core/util/PackedField.java index 9b7791a95..98fc084eb 100644 --- a/game/core/src/main/java/net/minecraft/core/util/PackedField.java +++ b/game/core/src/main/java/net/minecraft/core/util/PackedField.java @@ -5,7 +5,7 @@ public final class PackedField { public final int mask; public PackedField(int offset, int size) { - assert offset >= 0 && size >= 0 && offset + size < 32; + assert offset >= 0 && size >= 0 && offset + size <= 32; this.offset = offset; this.mask = ((1 << size) - 1) << offset; } diff --git a/game/core/src/main/java/net/minecraft/core/util/helper/Axis.java b/game/core/src/main/java/net/minecraft/core/util/helper/Axis.java index 53f2d815c..c72b69aa9 100644 --- a/game/core/src/main/java/net/minecraft/core/util/helper/Axis.java +++ b/game/core/src/main/java/net/minecraft/core/util/helper/Axis.java @@ -2,10 +2,23 @@ package net.minecraft.core.util.helper; public enum Axis { - X, Y, Z, NONE; + X(0), Y(1), Z(2), + @Deprecated + NONE(-1, -1); + + private Axis(int xyzIndex) { + this(xyzIndex, (xyzIndex + 1) % 3); + } + private Axis(int xyzIndex, int yzxIndex) { + this.xyzIndex = xyzIndex; + this.yzxIndex = yzxIndex; + } + public boolean isVertical() { return this == Y; } - + + public int xyzIndex; + public int yzxIndex; } diff --git a/game/core/src/main/java/net/minecraft/core/util/helper/BlockParticleHelper.java b/game/core/src/main/java/net/minecraft/core/util/helper/BlockParticleHelper.java index 3e5f86a2f..b6b3061b1 100644 --- a/game/core/src/main/java/net/minecraft/core/util/helper/BlockParticleHelper.java +++ b/game/core/src/main/java/net/minecraft/core/util/helper/BlockParticleHelper.java @@ -2,7 +2,7 @@ package net.minecraft.core.util.helper; public class BlockParticleHelper { public static int encodeBlockData(int blockId, int meta, Side side) { - return blockId & 0x3FFF | (meta & 0xFF) << 14 | (side.getId() << 22); + return blockId & 0x3FFF | (meta & 0xFF) << 14 | (side.id << 22); } public static int decodeBlockID(int data) { @@ -14,6 +14,6 @@ public class BlockParticleHelper { } public static Side decodeBlockSide(int data) { - return Side.getSideById(data >> 22 & 0xF); + return Side.fromId(data >> 22 & 0xF); } } diff --git a/game/core/src/main/java/net/minecraft/core/util/helper/Direction.java b/game/core/src/main/java/net/minecraft/core/util/helper/Direction.java index bc8f0e509..a34f6a9d6 100644 --- a/game/core/src/main/java/net/minecraft/core/util/helper/Direction.java +++ b/game/core/src/main/java/net/minecraft/core/util/helper/Direction.java @@ -1,221 +1,600 @@ package net.minecraft.core.util.helper; -import net.minecraft.core.entity.Mob; +import java.util.Arrays; + import org.jetbrains.annotations.NotNull; +import org.joml.Vector3d; +import org.joml.Vector3f; +import org.joml.Vector3i; + +import net.minecraft.core.entity.Mob; +import net.minecraft.core.world.pos.TilePos; public enum Direction { - - NORTH(Axis.Z, 0, 0, -1, "north"), - EAST(Axis.X, 1, 0, 0, "east"), - SOUTH(Axis.Z, 0, 0, 1, "south"), - WEST(Axis.X, -1, 0, 0, "west"), - UP(Axis.Y, 0, 1, 0, "up"), - DOWN(Axis.Y, 0, -1, 0, "down"), - NONE(Axis.NONE, 0, 0, 0, "none"); - - public static final @NotNull Direction @NotNull [] directions = new Direction[6]; - public static final @NotNull Direction @NotNull [] horizontalDirections = new Direction[4]; - - static { - setId(DOWN, 0); - setId(UP, 1); - setId(NORTH, 2); - setId(SOUTH, 3); - setId(WEST, 4); - setId(EAST, 5); - NONE.id = -1; - - setHorizontal(NORTH, 0); - setHorizontal(EAST, 1); - setHorizontal(SOUTH, 2); - setHorizontal(WEST, 3); - - setOpposites(EAST, WEST); - setOpposites(UP, DOWN); - setOpposites(NORTH, SOUTH); - NONE.opposite = NONE; - - UP.side = Side.TOP; - DOWN.side = Side.BOTTOM; - NORTH.side = Side.NORTH; - EAST.side = Side.EAST; - SOUTH.side = Side.SOUTH; - WEST.side = Side.WEST; - NONE.side = Side.NONE; - - NORTH.index = 0; - EAST.index = 1; - SOUTH.index = 2; - WEST.index = 3; - UP.index = 4; - DOWN.index = 5; - } - - private static void setId(Direction side, int id) { - directions[id] = side; - side.id = id; - } - - private static void setHorizontal(Direction direction, int id) { - horizontalDirections[id] = direction; - direction.horizontalIndex = id; - } - - private static void setOpposites(Direction side1, Direction side2) { - side1.opposite = side2; - side2.opposite = side1; - } - - ///////////////////// - - public static @NotNull Direction getDirectionById(int i) { - if(i >= 0 && i < directions.length) { - return directions[i]; - }else { - return NONE; - } - } - - ///////////////////// - - private final Axis axis; - private int id; - private int horizontalIndex; - private Direction opposite; - private Side side; - - private final int offsetX; - private final int offsetY; - private final int offsetZ; - private final String translationKey; - - @Deprecated - public int index; - - Direction(Axis axis, int offsetX, int offsetY, int offsetZ, String translationKey) { - this.axis = axis; - this.offsetX = offsetX; - this.offsetY = offsetY; - this.offsetZ = offsetZ; - this.translationKey = "direction." + translationKey; - } - - public int getOffsetX() { - return offsetX; - } - - public int getOffsetY() { - return offsetY; - } - - public int getOffsetZ() { - return offsetZ; - } - - public String getTranslationKey() { - return translationKey; - } - - public @NotNull Direction getOpposite() { - return opposite; - } - - public Side getSide() { - return side; - } - - public @NotNull Axis getAxis() { - return axis; - } - - public int getId() { - return id; - } - - public boolean isVertical() { - return getAxis().isVertical(); - } - - public boolean isHorizontal() { - return !isVertical(); - } - - public Direction rotate(int amount) { - if(this == UP) return UP; - if(this == DOWN) return DOWN; - return horizontalDirections[(getHorizontalIndex() + amount) & 3]; - } - - public int getHorizontalIndex() { - return horizontalIndex; - } - - ///////////////////// - - public static Direction getVerticalDirection(double rotationPitch) { - if(rotationPitch < 0) return UP; - else return DOWN; - } - - public static Direction getVerticalDirection(Mob entity) { - if(entity.rotationLockVertical != null && entity.rotationLockVertical != NONE) return entity.rotationLockVertical; - else return getVerticalDirection(entity.xRot); - } - - public static @NotNull Direction getHorizontalDirection(final double rotationYaw) { - return horizontalDirections[(MathHelper.floor(rotationYaw / 90f + 0.5) + 2) & 3]; - } - - public static @NotNull Direction getHorizontalDirection(final @NotNull Mob mob) { - if (mob.rotationLockHorizontal != null && mob.rotationLockHorizontal != NONE) return mob.rotationLockHorizontal; - return getHorizontalDirection(mob.yRot); - } - - public static @NotNull Direction getDirection(final @NotNull Mob mob) { - if (mob.rotationLock != null && mob.rotationLock != NONE) return mob.rotationLock; - if (mob.xRot < -45) return UP; - if (mob.xRot > 45) return DOWN; - return getHorizontalDirection(mob.yRot); - } - - ////////////////// - - public static @NotNull Direction[] rotXMap = new Direction[] { - Direction.DOWN, Direction.NORTH, Direction.UP, Direction.SOUTH, - Direction.UP, Direction.SOUTH, Direction.DOWN, Direction.NORTH, - Direction.NORTH, Direction.UP, Direction.SOUTH, Direction.DOWN, - Direction.SOUTH, Direction.DOWN, Direction.NORTH, Direction.UP, - Direction.WEST, Direction.WEST, Direction.WEST, Direction.WEST, - Direction.EAST, Direction.EAST, Direction.EAST, Direction.EAST, - }; - - public static @NotNull Direction rotateX(@NotNull Direction direction, int amount) { - return rotXMap[direction.getId() * 4 + (amount & 0b11)]; - } - - public static @NotNull Direction[] rotYMap = new Direction[] { - Direction.DOWN, Direction.DOWN, Direction.DOWN, Direction.DOWN, - Direction.UP, Direction.UP, Direction.UP, Direction.UP, - Direction.NORTH, Direction.WEST, Direction.SOUTH, Direction.EAST, - Direction.SOUTH, Direction.EAST, Direction.NORTH, Direction.WEST, - Direction.WEST, Direction.SOUTH, Direction.EAST, Direction.NORTH, - Direction.EAST, Direction.NORTH, Direction.WEST, Direction.SOUTH, - }; - - public static @NotNull Direction rotateY(@NotNull Direction direction, int amount) { - return rotYMap[direction.getId() * 4 + (amount & 0b11)]; - } - - public static @NotNull Direction[] rotZMap = new Direction[] { - Direction.DOWN, Direction.EAST, Direction.UP, Direction.WEST, - Direction.UP, Direction.WEST, Direction.DOWN, Direction.EAST, - Direction.NORTH, Direction.NORTH, Direction.NORTH, Direction.NORTH, - Direction.SOUTH, Direction.SOUTH, Direction.SOUTH, Direction.SOUTH, - Direction.WEST, Direction.DOWN, Direction.EAST, Direction.UP, - Direction.EAST, Direction.UP, Direction.WEST, Direction.DOWN, - }; - - public static @NotNull Direction rotateZ(@NotNull Direction direction, int amount) { - return rotZMap[direction.getId() * 4 + (amount & 0b11)]; - } + DOWN (0b000, "north"), + UP (0b001, "east"), + NORTH (0b010, "south"), + SOUTH (0b011, "west"), + WEST (0b100, "up"), + EAST (0b101, "down"), + + /** + * Method implementations might not guarantee correct behaviour (error safety) when passed + * NONE. Prefer passing {@code null} if method accepts {@code @Nullable Direction}, + * or an acceptable default direction, or avoid calling the method entirely! + */ + @Deprecated + NONE (0b000, "none"); // NONE will always index as down to simplify things :| + + public final int id; + public final String translationKey; + + private Direction(int id, String translationKey) { + this.id = id; + this.translationKey = "direction." + translationKey; + } + + public static final int count = 6; + public static final int horizontalCount = 4; + + // Lookup: + // ============================ + + /** + * returns a valid direction when id >= 0 && < 6, otherwise NONE.

+ * NOTE: + */ + public static @NotNull Direction fromId(int id) { + return ((id & ~0b111) == 0) + ? OPTIONAL_MAP[id] // NONE if >= 6 + : NONE; + } + + public static @NotNull Direction fromIdOrDefault(int id) { + if (id >= 0 && id < 6) id = 0; + return ID_MAP[id]; + } + + public static Direction fromIdOrDefault(Direction direction, int id) { + return (id >= 0 && id < 6) + ? ID_MAP[id] + : direction; + } + + /** + * simpler lookup logic, but can yield non-NONE result for index < 0 || >= 6 + */ + public static @NotNull Direction fromIdLenient(int id) { + return OPTIONAL_MAP[id & 0b111]; + } + + /** + * Perfer using {@code fromId(id)}. + * Index directly only if you are certain that the index is in bound; + * alternatively, if you want an always valid but may be incorrest result, + * use {@code ID_MAP[id % 6]}.

+ * + * Directions follow the order [ -y, +y, -z, +z, -x, +x ] + * + * @see Direction#fromId(int) + */ + public static final @NotNull Direction @NotNull[] ID_MAP = { + DOWN, UP, + NORTH, SOUTH, + WEST, EAST, + }; + + public static final @NotNull Direction @NotNull[] all = ID_MAP; + + private static final Direction[] OPTIONAL_MAP = { + DOWN, UP, + NORTH, SOUTH, + WEST, EAST, + NONE, NONE, // [6..8] + }; + + public static final @NotNull Direction @NotNull[] horizontal = { NORTH, EAST, SOUTH, WEST }; + + @Deprecated + public int legacyIndex() { + return switch (this) { + default -> 0; + case NORTH -> 0; + case EAST -> 1; + case SOUTH -> 2; + case WEST -> 3; + case UP -> 4; + case DOWN -> 5; + }; + } + + @Deprecated + public int legacyHorizontalIndex() { + return switch (this) { + default -> 0; + case NORTH -> 0; + case EAST -> 1; + case SOUTH -> 2; + case WEST -> 3; + }; + } + + // Friends: + // ============================ + + public @NotNull Side side() { + return Side.fromId(this.id); + } + + private static final Axis[] AXIS_YZX_MAP = { Axis.Y, Axis.Z, Axis.X }; + // private static final Axis[] AXIS_XYZ_MAP = { Axis.X, Axis.Y, Axis.Z }; + + public @NotNull Axis axis() { + return AXIS_YZX_MAP[this.id >> 1]; + } + + + // Rotation: + // ============================ + + public boolean isVertical() { + if (this == NONE) return false; + return isVerticle(this.id); + } + + // we don't care about NONE in the int version + public static boolean isVerticle(int id) { + return (id & 0b110) == 0; + } + + public boolean isHorizontal() { + if (this == NONE) return false; + return isHorizontal(this.id); + } + + public static boolean isHorizontal(int id) { + return (id & 0b110) != 0; + } + + public static @NotNull Direction fromPitch(double pitch) { + return (fpSign(pitch) == 0) ? DOWN : UP; + } + + // handles +-0 correctly + // does not return meaningful output for NaN however! + private static int fpSign(double x) { + final long raw = Double.doubleToRawLongBits(x); + final int sign = (int) (raw >>> 63); + assert sign == 0 || sign == 1; + return sign; + } + + public static @NotNull Direction fromYaw(double yaw) { + final double yawRightHanded = -yaw; + final int quarterTurnsFromNegX = MathHelper.floor(yawRightHanded / 90D + 0.5f); + final int quarterTurnsFromPosX = quarterTurnsFromNegX + 2; + + return ID_MAP[ROT_MAPS[1][quarterTurnsFromPosX & 0b11]]; + } + + public static @NotNull Direction getVerticalLockable(@NotNull Mob mob) { + return (mob.rotationLockVertical != null) + ? mob.rotationLockVertical + : fromPitch(mob.xRot); + } + + public static @NotNull Direction getHorizontalLockable(@NotNull Mob mob) { + return (mob.rotationLockHorizontal != null) + ? mob.rotationLockHorizontal + : fromYaw(mob.yRot); + } + + public static @NotNull Direction getLockable(@NotNull Mob mob) { + if (mob.rotationLock != null) return mob.rotationLock; + + // both of these would be false if NaN + if (mob.xRot < -45) return UP; + if (mob.xRot > 45) return DOWN; + + return fromYaw(mob.yRot); + } + + private static final int[][] ROT_MAPS = { + // X: -y, -z, +y, +z + { DOWN.id, NORTH.id, UP.id, SOUTH.id }, + + // Y: -x, +z, +x, -z + { NORTH.id, WEST.id, SOUTH.id, EAST.id }, + + // Z: -y, +x, +y, -x + { DOWN.id, EAST.id, UP.id, WEST.id }, + }; + + private static final int[][] ROT_INDEX_MAPS = new int[3][6]; + static { + for (int axis = 0; axis < 3; axis ++) { + Arrays.fill(ROT_INDEX_MAPS[axis], -1); + for (int i = 0; i < 4; i++) { + final int dir = ROT_MAPS[axis][i]; + ROT_INDEX_MAPS[axis][dir] = i; + } + } + } + + /** + * Right-handed around the +X axis + */ + public @NotNull Direction rotateX(int quarterTurns) { + if (this == NONE) return this; + return ID_MAP[rotate(this.id, 0, quarterTurns)]; + } + + /** + * Right-handed around the +X axis + */ + public static int rotateX(int id, int quarterTurns) { + return rotate(id, 0, quarterTurns); + } + + /** + * Right-handed rotation around the +Y axis + */ + public @NotNull Direction rotateY(int quarterTurns) { + if (this == NONE) return this; + return ID_MAP[rotate(this.id, 1, quarterTurns)]; + } + + /** + * Right-handed rotation around the +Y axis + */ + public static int rotateY(int id, int quarterTurns) { + return rotate(id, 1, quarterTurns); + } + + /** + * Right-handed rotation around the +Z axis + */ + public @NotNull Direction rotateZ(int quarterTurns) { + if (this == NONE) return this; + return ID_MAP[rotate(this.id, 2, quarterTurns)]; + } + + /** + * Right-handed rotation around the +Z axis + */ + public static int rotateZ(int id, int quarterTurns) { + return rotate(id, 2, quarterTurns); + } + + /** + * Right-handed rotation around the given positive axis + */ + public @NotNull Direction rotate(@NotNull Axis axis, int quarterTurns) { + if (this == NONE) return this; + return ID_MAP[rotate(this.id, axis.xyzIndex, quarterTurns)]; + } + + /** + * Right-handed rotation around the given positive axis + */ + public static int rotate(int id, @NotNull Axis axis, int quarterTurns) { + return rotate(id, axis.xyzIndex, quarterTurns); + } + + /** + * Right-handed rotation around the given positive axis, + * where +X, +Y, +Z are represented as 0, 1, 2 respectively + */ + public static int rotate(int id, int axis, int quarterTurns) { + axis &= 0b11; assert axis < 3; + id &= 0b111; assert id < 6; + + + final int ridx = ROT_INDEX_MAPS[axis][id]; + if (ridx < 0) return id; + + return ROT_MAPS[axis][(ridx + quarterTurns) & 0b11]; + } + + + // Offset: + // ============================ + + private static final int[] CMP_MAP = { 1, 2, 0 }; + + public int componentIndex() { + if (this == NONE) return 0; // instead of -1 :| + final int res = componentIndex(this.id); + assert res >= 0; + return res; + } + + public static int componentIndex(int id) { + id = (id >>> 1) & 0b11; + assert id != 0b11; + return CMP_MAP[id]; + } + + public int sign() { + if (this == NONE) return 0; + return sign(this.id); + } + + public static int sign(int id) { + return ~id & 1; + } + + public @NotNull Direction opposite() { + if (this == NONE) return this; + final var id = opposite(this.id); + assert id >= 0 && id < 6; + return ID_MAP[id]; + } + + public static int opposite(int id) { + return id ^ 1; + } + + public boolean isPositive() { + if (this == NONE) return false; + return this.sign() == 0; + } + + public boolean isNegative() { + if (this == NONE) return false; + return this.sign() == 1; + } + + public static final int[][] OFFSETS = new int[3][6]; + static { + for (int i = 0; i < 6; i++) { + OFFSETS[componentIndex(i)][i] = 1 - (sign(i) << 1); + } + } + + public int offsetX() { + if (this == NONE) return 0; + return offsetX(this.id); + } + public int offsetY() { + if (this == NONE) return 0; + return offsetY(this.id); + } + public int offsetZ() { + if (this == NONE) return 0; + return offsetZ(this.id); + } + + public static int offsetX(int id) { + id &= 0b111; assert id < 6; + return OFFSETS[0][id]; + } + + public static int offsetY(int id) { + id &= 0b111; assert id < 6; + return OFFSETS[1][id]; + } + + public static int offsetZ(int id) { + id &= 0b111; assert id < 6; + return OFFSETS[2][id]; + } + + // --------- + + // all these api to ensure conveniency while avoid redundant allocation ... + + /** + * @param out the location where the offset is written to. + */ + public @NotNull Vector3i getOffset(@NotNull Vector3i out) { + if (this == NONE) return out.set(0,0,0); + return getOffset(this.id, out); + } + + /** + * @param out the location where the offset is written to. + */ + public @NotNull Vector3d getOffset(@NotNull Vector3d out) { + if (this == NONE) return out.set(0,0,0); + return getOffset(this.id, out); + } + + /** + * @param out the location where the offset is written to. + */ + public @NotNull Vector3i getOffsetScaled(@NotNull Vector3i out, int scale) { + if (this == NONE) return out.set(0,0,0); + return getOffsetScaled(this.id, out, scale); + } + + /** + * @param out the location where the offset is written to. + */ + public @NotNull Vector3d getOffsetScaled(@NotNull Vector3d out, double scale) { + if (this == NONE) return out.set(0,0,0); + return getOffsetScaled(this.id, out, scale); + } + + /** + * @param out the location where the offset is written to. + */ + public @NotNull Vector3f getOffsetScaled(@NotNull Vector3f out, float scale) { + if (this == NONE) return out.set(0,0,0); + return getOffsetScaled(this.id, out, scale); + } + + // --------- + + /** + * @param out the location where the offset is written to. + */ + public static @NotNull Vector3i getOffset(int id, @NotNull Vector3i out) { + id &= 0b111; assert id < 6; + return out.set(OFFSETS[0][id], OFFSETS[1][id], OFFSETS[2][id]); + } + + /** + * @param out the location where the offset is written to. + */ + public static @NotNull Vector3d getOffset(int id, @NotNull Vector3d out) { + id &= 0b111; assert id < 6; + return out.set(OFFSETS[0][id], OFFSETS[1][id], OFFSETS[2][id]); + } + + /** + * @param out the location where the offset is written to. + */ + public static @NotNull Vector3f getOffset(int id, @NotNull Vector3f out) { + id &= 0b111; assert id < 6; + return out.set(OFFSETS[0][id], OFFSETS[1][id], OFFSETS[2][id]); + } + + /** + * @param out the location where the offset is written to. + */ + public static @NotNull Vector3i getOffsetScaled(int id, @NotNull Vector3i out, int scale) { + id &= 0b111; assert id < 6; + return out.set(OFFSETS[0][id] * scale, OFFSETS[1][id] * scale, OFFSETS[2][id] * scale); + } + + /** + * @param out the location where the offset is written to. + */ + public static @NotNull Vector3d getOffsetScaled(int id, @NotNull Vector3d out, double scale) { + id &= 0b111; assert id < 6; + return out.set(OFFSETS[0][id] * scale, OFFSETS[1][id] * scale, OFFSETS[2][id] * scale); + } + + /** + * @param out the location where the offset is written to. + */ + public static @NotNull Vector3f getOffsetScaled(int id, @NotNull Vector3f out, float scale) { + id &= 0b111; assert id < 6; + return out.set(OFFSETS[0][id] * scale, OFFSETS[1][id] * scale, OFFSETS[2][id] * scale); + } + + // --------- + + /** + * @param ref the location where the offset is applied to. + */ + public @NotNull TilePos offset(@NotNull TilePos ref) { + if (this == NONE) return ref; + return offset(this.id, ref); + } + + /** + * @param ref the location where the offset is applied to. + */ + public @NotNull Vector3i offset(@NotNull Vector3i ref) { + if (this == NONE) return ref; + return offset(this.id, ref); + } + + /** + * @param ref the location where the offset is applied to. + */ + public @NotNull Vector3d offset(@NotNull Vector3d ref) { + if (this == NONE) return ref; + return offset(this.id, ref); + } + + /** + * @param ref the location where the offset is applied to. + */ + public @NotNull TilePos offsetScaled(@NotNull TilePos ref, int scale) { + if (this == NONE) return ref; + return offsetScaled(this.id, ref, scale); + } + + /** + * @param ref the location where the offset is applied to. + */ + public @NotNull Vector3i offsetScaled(@NotNull Vector3i ref, int scale) { + if (this == NONE) return ref; + return offsetScaled(this.id, ref, scale); + } + + /** + * @param ref the location where the offset is applied to. + */ + public @NotNull Vector3d offsetScaled(@NotNull Vector3d ref, double scale) { + if (this == NONE) return ref; + return offsetScaled(this.id, ref, scale); + } + + /** + * @param ref the location where the offset is applied to. + */ + public @NotNull Vector3f offsetScaled(@NotNull Vector3f ref, float scale) { + if (this == NONE) return ref; + return offsetScaled(this.id, ref, scale); + } + + // --------- + + /** + * @param ref the location where the offset is applied to. + */ + public static @NotNull TilePos offset(int id, @NotNull TilePos ref) { + id &= 0b111; assert id < 6; + return ref.add(OFFSETS[0][id], OFFSETS[1][id], OFFSETS[2][id]); + } + + /** + * @param ref the location where the offset is applied to. + */ + public static @NotNull Vector3i offset(int id, @NotNull Vector3i ref) { + id &= 0b111; assert id < 6; + return ref.add(OFFSETS[0][id], OFFSETS[1][id], OFFSETS[2][id]); + } + + /** + * @param ref the location where the offset is applied to. + */ + public static @NotNull Vector3d offset(int id, @NotNull Vector3d ref) { + id &= 0b111; assert id < 6; + return ref.add(OFFSETS[0][id], OFFSETS[1][id], OFFSETS[2][id]); + } + + /** + * @param ref the location where the offset is applied to. + */ + public static @NotNull Vector3f offset(int id, @NotNull Vector3f ref) { + id &= 0b111; assert id < 6; + return ref.add(OFFSETS[0][id], OFFSETS[1][id], OFFSETS[2][id]); + } + + /** + * @param ref the location where the offset is applied to. + */ + public static @NotNull Vector3d offsetScaled(int id, @NotNull Vector3d ref, double scale) { + id &= 0b111; assert id < 6; + return ref.add(OFFSETS[0][id] * scale, OFFSETS[1][id] * scale, OFFSETS[2][id] * scale); + } + + /** + * @param ref the location where the offset is applied to. + */ + public static @NotNull TilePos offsetScaled(int id, @NotNull TilePos ref, int scale) { + id &= 0b111; assert id < 6; + return ref.add(OFFSETS[0][id] * scale, OFFSETS[1][id] * scale, OFFSETS[2][id] * scale); + } + + /** + * @param ref the location where the offset is applied to. + */ + public static @NotNull Vector3i offsetScaled(int id, @NotNull Vector3i ref, int scale) { + id &= 0b111; assert id < 6; + return ref.add(OFFSETS[0][id] * scale, OFFSETS[1][id] * scale, OFFSETS[2][id] * scale); + } + + /** + * @param ref the location where the offset is applied to. + */ + public static @NotNull Vector3f offsetScaled(int id, @NotNull Vector3f ref, float scale) { + id &= 0b111; assert id < 6; + return ref.add(OFFSETS[0][id] * scale, OFFSETS[1][id] * scale, OFFSETS[2][id] * scale); + } } diff --git a/game/core/src/main/java/net/minecraft/core/util/helper/NeighborUpdates.java b/game/core/src/main/java/net/minecraft/core/util/helper/NeighborUpdates.java new file mode 100644 index 000000000..70b8a9291 --- /dev/null +++ b/game/core/src/main/java/net/minecraft/core/util/helper/NeighborUpdates.java @@ -0,0 +1,351 @@ +package net.minecraft.core.util.helper; + +import java.util.Set; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import net.minecraft.core.block.Block; +import net.minecraft.core.world.World; +import net.minecraft.core.world.pos.TilePos; +import net.minecraft.core.world.pos.TilePosc; + +public abstract class NeighborUpdates { + private NeighborUpdates() {} + + private static final Direction Xn = Direction.WEST; + private static final Direction Xp = Direction.EAST; + private static final Direction Yn = Direction.DOWN; + private static final Direction Yp = Direction.UP; + private static final Direction Zn = Direction.NORTH; + private static final Direction Zp = Direction.SOUTH; + + private static final @NotNull Direction[] D1_OFFSETS = { Xn, Xp, Yn, Yp, Zn, Zp }; + + /** + * updates blocks adjascent to the origin with the order -x, +x, -y, +y, -z, +z + */ + public static void diamondD1(@NotNull World world, @NotNull TilePosc pos, @Nullable Block block) { + diamondD1(null, world, pos, block); + } + + public static void diamondD1( + @Nullable Set<@NotNull TilePosc> updatedPositions, + @NotNull World world, @NotNull TilePosc pos, @Nullable Block block + ) { + final boolean dedupe = updatedPositions != null; + if (block == null) block = world.getBlockType(pos); + + final var qpos = new TilePos(); + for (var d : D1_OFFSETS) { + qpos.set(pos).add(d); + + if (dedupe) { + if (updatedPositions.contains(qpos)) continue; + updatedPositions.add(new TilePos(qpos)); + } + + final var block1 = world.getBlockType(qpos); + block1.onNeighborChanged(world, qpos, block); + } + } + + private static final @NotNull Direction[] @NotNull[] D2_OFFSETS = { + /* Xn */ { Xn, Yp, Yn, Zp, Zn }, + /* Xp */ { Xp, Yp, Yn, Zp, Zn }, + /* Yn */ { Yn, Zp, Zn }, + /* Yp */ { Yp, Zp, Zn }, + /* Zn */ { Zn }, + /* Zp */ { Zp }, + }; + + /** + * updates each block within the range |x| + |y| + |z| <= 2, excluding the origin. + * blocks in the inner shell are updated with the origin as the source, + * blocks in the outer shell are updated with block from the inner shell as the source, + * prioritizing inner shell blocks from -x, +x, -y, +y, -z, +z. + */ + public static void diamondD2(@NotNull World world, @NotNull TilePosc pos, @Nullable Block block) { + diamondD2(null, world, pos, block); + } + + public static synchronized void diamondD2( + @Nullable Set<@NotNull TilePosc> updatedPositions, + @NotNull World world, @NotNull TilePosc pos, @Nullable Block block + ) { + // class ctx { static final Block[] D1_BLOCKS = new Block[6]; }; + + final boolean dedupe = updatedPositions != null; + if (block == null) block = world.getBlockType(pos); + + final var qpos1 = new TilePos(); + for (int i = 0; i < 6; i++) { + qpos1.set(pos).add(D1_OFFSETS[i]); + // ctx.D1_BLOCKS[i] = world.getBlockType(qpos1); + + if (dedupe) { + if (updatedPositions.contains(qpos1)) continue; + updatedPositions.add(new TilePos(qpos1)); + } + + // ctx.D1_BLOCKS[i].onNeighborChanged(world, qpos1, block); + world.getBlockType(qpos1).onNeighborChanged(world, qpos1, block); + } + final var qpos2 = new TilePos(); + for (int i = 0; i < 6; i++) { + qpos1.set(pos).add(D1_OFFSETS[i]); + for (final var d : D2_OFFSETS[i]) { + qpos2.set(qpos1).add(d); + + if (dedupe) { + if (updatedPositions.contains(qpos2)) continue; + updatedPositions.add(new TilePos(qpos2)); + } + + // world.getBlockType(qpos2).onNeighborChanged(world, qpos2, ctx.D1_BLOCKS[i]); + world.getBlockType(qpos2).onNeighborChanged(world, qpos2, block); + } + } + } + + public static void diamondD2Shell( + @NotNull World world, @NotNull TilePosc pos, @Nullable Block block + ) { + diamondD2Shell(null, world, pos, block); + } + + public static synchronized void diamondD2Shell( + @Nullable Set<@NotNull TilePosc> updatedPositions, + @NotNull World world, @NotNull TilePosc pos, @Nullable Block block + ) { + // class ctx { static final Block[] D1_BLOCKS = new Block[6]; }; + + final boolean dedupe = updatedPositions != null; + if (block == null) block = world.getBlockType(pos); + + final var qpos1 = new TilePos(); + // for (int i = 0; i < 6; i++) { + // qpos1.set(pos).add(D1_OFFSETS[i]); + // // ctx.D1_BLOCKS[i] = world.getBlockType(qpos1); + + // if (dedupe) { + // if (updatedPositions.contains(qpos1)) continue; + // updatedPositions.add(new TilePos(qpos1)); + // } + // } + final var qpos2 = new TilePos(); + for (int i = 0; i < 6; i++) { + qpos1.set(pos).add(D1_OFFSETS[i]); + for (final var d : D2_OFFSETS[i]) { + qpos2.set(qpos1).add(d); + + if (dedupe) { + if (updatedPositions.contains(qpos2)) continue; + updatedPositions.add(new TilePos(qpos2)); + } + + // world.getBlockType(qpos2).onNeighborChanged(world, qpos2, ctx.D1_BLOCKS[i]); + world.getBlockType(qpos2).onNeighborChanged(world, qpos2, block); + } + } + } + + /** + * similar to diamondUpdateD2, but only the blocks from the outer shell, that are adjascent + * to the block in the inner shell on the given direction, are updated. + */ + public static void diamondD2SingleDir( + @NotNull Direction direction, + @NotNull World world, @NotNull TilePosc pos, @Nullable Block block + ) { + diamondD2SingleDir(null, direction, world, pos, block); + } + + public static void diamondD2SingleDir( + @Nullable Set<@NotNull TilePosc> updatedPositions, + @NotNull Direction direction, + @NotNull World world, @NotNull TilePosc pos, @Nullable Block block + ) { + if (direction == Direction.NONE) { + diamondD1(updatedPositions, world, pos, block); + return; + } + + final boolean dedupe = updatedPositions != null; + if (block == null) block = world.getBlockType(pos); + + final var opposite = direction.opposite(); + final var qpos = new TilePos(); + + // Block sideBlock = null; + for (int i = 0; i < 6; i++) { + final var d = D1_OFFSETS[i]; + qpos.set(pos).add(d); + + if (dedupe) { + if (updatedPositions.contains(qpos)) continue; + updatedPositions.add(new TilePos(qpos)); + } + + final var b = world.getBlockType(qpos); + // if (d == direction) sideBlock = b; + + b.onNeighborChanged(world, qpos, block); + } + + // assert sideBlock != null; + for (int i = 0; i < 6; i++) { + final var d = D1_OFFSETS[i]; + if (d == opposite) continue; + qpos.set(pos).add(direction).add(d); + + if (dedupe) { + if (updatedPositions.contains(qpos)) continue; + updatedPositions.add(new TilePos(qpos)); + } + + final var b = world.getBlockType(qpos); + b.onNeighborChanged(world, qpos, block); + // b.onNeighborChanged(world, qpos, sideBlock); + } + } + + /** + * updates blocks within the range |x| + |y| + |z| <= radius, excluding the origin. + * for every N's layer is updated with the N-1's layer as the source. + * for layers >= 3, the order no longer folows vanilla :( + */ + public static void diamondDn( + int radius, + @NotNull World world, @NotNull TilePosc pos, @Nullable Block block + ) { + diamondDn(null, radius, world, pos, block); + } + + public static void diamondDn( + @Nullable Set<@NotNull TilePosc> updatedPositions, + int radius, + @NotNull World world, @NotNull TilePosc pos, @Nullable Block block + ) { + if (radius <= 0) return; + if (block == null) block = world.getBlockType(pos); + + switch (radius) { + case 1: + diamondD1(updatedPositions, world, pos, block); + break; + case 2: + diamondD2(updatedPositions, world, pos, block); + break; + default: + diamondD2(updatedPositions, world, pos, block); + final boolean dedupe = updatedPositions != null; + for (int shell = 3; shell <= radius; shell++) { + if (dedupe) { + diamondDnShell(updatedPositions, shell, world, pos, block); + } else { + diamondDnShell(shell, world, pos, block); + } + } + break; + } + } + + public static record Diamond(@NotNull TilePos origin, int radius, @Nullable Block block) { + public @NotNull Block block(@NotNull World world) { + return (this.block != null) + ? this.block + : world.getBlockType(this.origin); + } + } + + public static synchronized void diamondDnShell( + int radius, + @NotNull World world, @NotNull TilePosc pos, @Nullable Block block + ) { + class ctx { static final ObjectOpenHashSet POS_UPDATED = new ObjectOpenHashSet<>(); } + if (radius <= 0) return; + + switch (radius) { + case 1: + diamondD1(world, pos, null); + return; + case 2: + diamondD2Shell(world, pos, null); + return; + } + + final int LEN = 3 * radius * (radius - 1); + ctx.POS_UPDATED.clear(); + ctx.POS_UPDATED.ensureCapacity(LEN); + + diamondDnShell(ctx.POS_UPDATED, radius, world, pos, block); + + ctx.POS_UPDATED.clear(); + if (LEN >= 1024) ctx.POS_UPDATED.trim(512); + } + + private static int sign(int n) { return (n == 0) ? 0 : (n < 0) ? -1 : 1; } + + // TODO now that I know diamond updates should always pass the origin block + // TODO as the update source, this can be made much more efficient + public static void diamondDnShell( + // This one cannot be null + @NotNull Set<@NotNull TilePosc> updatedPositions, + int radius, + @NotNull World world, @NotNull TilePosc pos, @Nullable Block block + ) { + switch (radius) { + case 1: + diamondD1(updatedPositions, world, pos, null); + return; + case 2: + diamondD2Shell(updatedPositions, world, pos, null); + return; + } + + radius --; + if (radius <= 0) return; + + if (block == null) block = world.getBlockType(pos); + + final TilePos s_query = new TilePos(); + final TilePos t_query = new TilePos(); + + for (int x = -radius; x <= radius; x ++) { + final int x_sign = sign(x); + final int y_radius = radius - Math.abs(x); // 0, 1, 2, ... targetR, ... 2, 1, 0 + + for (int y = -y_radius; y <= y_radius; y++) { + final int y_sign = sign(y); + final int z_radius = y_radius - Math.abs(y); + + for (int z = -z_radius; z <= z_radius; z++) { // [-1 0 1] or [0] + final int z_sign = sign(z); + + s_query.set(pos).add(x, y, z_radius); + + for (final var dir : D1_OFFSETS) { + final int dx_sign = sign(dir.offsetX()); + final int dy_sign = sign(dir.offsetY()); + final int dz_sign = sign(dir.offsetZ()); + + if (Math.abs(x_sign - dx_sign) > 1) continue; + if (Math.abs(y_sign - dy_sign) > 1) continue; + if (Math.abs(z_sign - dz_sign) > 1) continue; + + // t_query.set(s_query).add(dir); + + if (updatedPositions.contains(t_query)) continue; + updatedPositions.add(new TilePos(t_query)); + + // final var sblock = world.getBlockType(s_query); + final var tblock = world.getBlockType(t_query); + tblock.onNeighborChanged(world, t_query, block); + } + } + } + } + } +} diff --git a/game/core/src/main/java/net/minecraft/core/util/helper/Side.java b/game/core/src/main/java/net/minecraft/core/util/helper/Side.java index 84e23ab63..3c497cc9b 100644 --- a/game/core/src/main/java/net/minecraft/core/util/helper/Side.java +++ b/game/core/src/main/java/net/minecraft/core/util/helper/Side.java @@ -4,13 +4,20 @@ import org.jetbrains.annotations.NotNull; public enum Side { - TOP(Axis.Y, 0, 1, 0, "top"), - BOTTOM(Axis.Y, 0, -1, 0, "bottom"), - NORTH(Axis.Z, 0, 0, -1, "north"), - EAST(Axis.X, 1, 0, 0, "east"), - SOUTH(Axis.Z, 0, 0, 1, "south"), - WEST(Axis.X, -1, 0, 0, "west"), - NONE(Axis.NONE, 0, 0, 0, "none"); + BOTTOM(Direction.DOWN, "bottom"), + TOP(Direction.UP, "top"), + NORTH(Direction.NORTH, "north"), + SOUTH(Direction.SOUTH, "south"), + WEST(Direction.WEST, "west"), + EAST(Direction.EAST, "east"), + + /** + * Method implementations might not guarantee correct behaviour (error safety) when passed + * Side.NONE. Prefer passing {@code null} if method accepts {@code @Nullable Side}, + * or an acceptable default side, or avoid calling the method entirely! + */ + @Deprecated + NONE(Direction.NONE, "none"); public static final Side posX = EAST; public static final Side negX = WEST; @@ -19,106 +26,64 @@ public enum Side { public static final Side posZ = SOUTH; public static final Side negZ = NORTH; - public static final Side[] sides = new Side[6]; - - static { - setId(BOTTOM, 0); - setId(TOP, 1); - setId(NORTH, 2); - setId(SOUTH, 3); - setId(WEST, 4); - setId(EAST, 5); - NONE.id = -1; - - setOpposites(EAST, WEST); - setOpposites(TOP, BOTTOM); - setOpposites(NORTH, SOUTH); - NONE.opposite = NONE; - - TOP.direction = Direction.UP; - BOTTOM.direction = Direction.DOWN; - NORTH.direction = Direction.NORTH; - EAST.direction = Direction.EAST; - SOUTH.direction = Direction.SOUTH; - WEST.direction = Direction.WEST; - NONE.direction = Direction.NONE; - } - - private static void setId(Side side, int id) { - sides[id] = side; - side.id = id; - } - - private static void setOpposites(Side side1, Side side2) { - side1.opposite = side2; - side2.opposite = side1; - } + public static final Side[] sides = { + BOTTOM, TOP, + NORTH, SOUTH, + WEST, EAST, + }; ///////////////////// - public static Side getSideById(int i) { - if(i >= 0 && i < sides.length) { - return sides[i]; - }else { - return NONE; - } + public static Side fromId(int i) { + return (i >= 0 && i < 6) + ? sides[i] + : Side.NONE; } - + ///////////////////// - private final Axis axis; - private int id; - private Side opposite; - private Direction direction; - - private final int offsetX; - private final int offsetY; - private final int offsetZ; + public final int id; + public final @NotNull Direction direction; - private final String translationKey; + // Why arent we using this + private final @NotNull String translationKey; - Side(Axis axis, int offsetX, int offsetY, int offsetZ, String translationKey) { - this.axis = axis; - this.offsetX = offsetX; - this.offsetY = offsetY; - this.offsetZ = offsetZ; + Side(@NotNull Direction direction, @NotNull String translationKey) { + this.direction = direction; + this.id = direction.id; this.translationKey = translationKey; } - public int getOffsetX() { - return offsetX; + public int offsetX() { + return this.direction.offsetX(); } - public int getOffsetY() { - return offsetY; + public int offsetY() { + return this.direction.offsetY(); } - public int getOffsetZ() { - return offsetZ; + public int offsetZ() { + return this.direction.offsetZ(); } - public @NotNull Side getOpposite() { - return opposite; + public @NotNull Side opposite() { + return sides[this.id ^ 1]; } - public @NotNull Direction getDirection() { - return direction; + public @NotNull Direction direction() { + return this.direction; } - public @NotNull Axis getAxis() { - return axis; + public @NotNull Axis axis() { + return this.direction.axis(); } - public int getId() { - return id; - } - public boolean isVertical() { - return getAxis().isVertical(); + return this.direction.isVertical(); } public boolean isHorizontal() { - return !isVertical(); + return this.direction.isHorizontal(); } } diff --git a/game/core/src/main/java/net/minecraft/core/util/helper/Sides.java b/game/core/src/main/java/net/minecraft/core/util/helper/Sides.java index a282369be..98c668058 100644 --- a/game/core/src/main/java/net/minecraft/core/util/helper/Sides.java +++ b/game/core/src/main/java/net/minecraft/core/util/helper/Sides.java @@ -16,6 +16,7 @@ public class Sides public static final int negX = 4; public static final int posX = 5; + // TODO replace with Direction.rotate public static final int[] orientationLookUpHorizontal = { bottom, top, south, north, west, east, bottom, top, south, north, west, east, diff --git a/game/core/src/main/java/net/minecraft/core/world/ICarriable.java b/game/core/src/main/java/net/minecraft/core/world/ICarriable.java index d2a19fd8d..da753bdeb 100644 --- a/game/core/src/main/java/net/minecraft/core/world/ICarriable.java +++ b/game/core/src/main/java/net/minecraft/core/world/ICarriable.java @@ -3,6 +3,7 @@ package net.minecraft.core.world; import com.mojang.logging.LogUtils; import com.mojang.nbt.tags.CompoundTag; import net.minecraft.core.block.motion.CarriedBlock; +import net.minecraft.core.block.piston.CarriedPistonHead; import net.minecraft.core.entity.Entity; import net.minecraft.core.util.helper.Side; import org.slf4j.Logger; @@ -11,9 +12,10 @@ public interface ICarriable { Logger LOGGER = LogUtils.getLogger(); /** * Called every tick an entity holds this object - */ - void heldTick(World world, Entity holder); - + */ + void heldTick(World world, Entity holder); + + // TODO TilePos refactor /** * Called by the entity when trying to place the held object at some position * @return True if carried object could place, false otherwise @@ -33,13 +35,17 @@ public interface ICarriable { void readFromNBT(CompoundTag tag); - String TYPE_BLOCK = "block"; + static final String TYPE_BLOCK = "block"; + static final String TYPE_PISTON_HEAD = "block/piston_head"; static ICarriable createAndLoadCarriable(Entity holder, CompoundTag tag) { String type = tag.getString("type"); if (type.equalsIgnoreCase(TYPE_BLOCK)) { return CarriedBlock.createAndLoadCarriedBlock(holder, tag); } + if (type.equalsIgnoreCase(TYPE_PISTON_HEAD)) { + return CarriedPistonHead.createAndLoad(tag); + } LOGGER.warn("Could not identify carriable for type {}!", type); return null; } 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 96650f788..5f83f8b14 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 @@ -2,6 +2,7 @@ package net.minecraft.core.world; import com.mojang.logging.LogUtils; import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import net.minecraft.core.Global; import net.minecraft.core.NextTickListEntry; @@ -32,6 +33,7 @@ import net.minecraft.core.util.debug.Debug; import net.minecraft.core.util.helper.Direction; import net.minecraft.core.util.helper.LightIndexHelper; import net.minecraft.core.util.helper.MathHelper; +import net.minecraft.core.util.helper.NeighborUpdates; import net.minecraft.core.util.helper.Side; import net.minecraft.core.util.phys.HitResult; import net.minecraft.core.world.biome.Biome; @@ -634,6 +636,22 @@ public abstract class World implements MutableWorldSource { } } + public boolean setBlockTypeDataEntity(final @NotNull TilePosc tilePos, final @NotNull Block block, final int data, final @NotNull TileEntity entity) { + if (!tilePos.inBounds(this)) return false; + + final var c = this.getChunk(tilePos); + final var ctp = new ChunkTilePos(tilePos); + final var prevBlock = c.getBlock(ctp); + final var prevData = c.getBlockData(ctp); + if (!c.setBlockIdDataRaw(ctp, block.id(), data)) return false; + + this.replaceTileEntity(tilePos, entity); + prevBlock.getLogic().onRemoved(this, tilePos, prevData); + block.getLogic().onPlacedByWorld(this, tilePos); + + return true; + } + public boolean setBlockTypeRaw(final @NotNull TilePosc tilePos, final @NotNull Block block) { return this.setBlockTypeDataRaw(tilePos, block, this.getBlockData(tilePos)); } @@ -656,6 +674,10 @@ public abstract class World implements MutableWorldSource { return this.setBlockTypeDataRaw(new TilePos(x, y, z), Objects.requireNonNull(Blocks.getBlock(id)), metadata); } + public boolean setBlockTypeEntity(final @NotNull TilePosc tilePos, final @NotNull Block block, final @NotNull TileEntity entity) { + return this.setBlockTypeDataEntity(tilePos, block, this.getBlockData(tilePos), entity); + } + @Override public boolean setBlockType(final @NotNull TilePosc tilePos, final @NotNull Block block) { if (!tilePos.inBounds(this)) { @@ -708,6 +730,15 @@ public abstract class World implements MutableWorldSource { } } + public boolean setBlockTypeEntityNotify(final @NotNull TilePosc tilePos, final @NotNull Block block, final @NotNull TileEntity entity) { + if (this.setBlockTypeEntity(tilePos, block, entity)) { + this.notifyBlockChange(tilePos, block); + return true; + } + + return false; + } + public boolean setBlockTypeNotify(final @NotNull TilePosc tilePos, final @NotNull Block block) { if (this.setBlockType(tilePos, block)) { this.notifyBlockChange(tilePos, block); @@ -722,6 +753,15 @@ public abstract class World implements MutableWorldSource { return this.setBlockTypeNotify(new TilePos(x, y, z), Objects.requireNonNull(Blocks.getBlock(id))); } + public boolean setBlockTypeDataEntityNotify(final @NotNull TilePosc tilePos, final @NotNull Block block, final int data, final @NotNull TileEntity entity) { + if (this.setBlockTypeDataEntity(tilePos, block, data, entity)) { + this.notifyBlockChange(tilePos, block); + return true; + } + + return false; + } + public boolean setBlockTypeDataNotify(final @NotNull TilePosc tilePos, final @NotNull Block block, final int data) { if (this.setBlockTypeData(tilePos, block, data)) { this.notifyBlockChange(tilePos, block); @@ -790,27 +830,114 @@ public abstract class World implements MutableWorldSource { this.markBlocksDirty(new TilePos(minX, minY, minZ), new TilePos(maxX, maxY, maxZ)); } - public void notifyBlocksOfNeighborChange(final @NotNull TilePosc tilePos, final @NotNull Block block) { - final TilePos queryPos = new TilePos(); - this.notifyBlockOfNeighborChange(tilePos.add(Direction.WEST, queryPos), block); - this.notifyBlockOfNeighborChange(tilePos.add(Direction.EAST, queryPos), block); - this.notifyBlockOfNeighborChange(tilePos.add(Direction.DOWN, queryPos), block); - this.notifyBlockOfNeighborChange(tilePos.add(Direction.UP, queryPos), block); - this.notifyBlockOfNeighborChange(tilePos.add(Direction.NORTH, queryPos), block); - this.notifyBlockOfNeighborChange(tilePos.add(Direction.SOUTH, queryPos), block); + /** + * Notify blocks adjacent to the given position + * of neighbor update originated from the given block, + * or the block at the given position if null. + */ + public void notifyBlocksOfNeighborChange(final @NotNull TilePosc tilePos, final @Nullable Block block) { + if (this.noNeighborUpdate || this.isClientSide) return; + NeighborUpdates.diamondD1(this, tilePos, block); } - @Deprecated - public final void notifyBlocksOfNeighborChange(final int x, final int y, final int z, final int id) { - this.notifyBlocksOfNeighborChange(new TilePos(x, y, z), Objects.requireNonNull(Blocks.getBlock(id))); + /** + * Notify blocks in the provided radius -- such that (|dx| + |dy| + |dz| <= radius) -- + * from the given position of neighbor update originated from the given block, + * or the block at the given position if null. + */ + public void notifyBlocksInRadiusOfNeighborChange( + final int radius, + final @NotNull TilePosc tilePos, final @Nullable Block block + ) { + if (this.noNeighborUpdate || this.isClientSide) return; + NeighborUpdates.diamondDn(radius, this, tilePos, block); } - private void notifyBlockOfNeighborChange(final @NotNull TilePosc tilePos, final @NotNull Block block) { - if (this.noNeighborUpdate || this.isClientSide) { - return; + /** + * Notify blocks with exactly the provided radius -- such that (|dx| + |dy| + |dz| == radius) -- + * from the given position of neighbor update originated from the given block, + * or the block at the given position if null. + */ + public void notifyShellBlocksInRadiusOfNeighborChange( + final int radius, final @NotNull TilePosc tilePos, @Nullable Block block + ) { + if (this.noNeighborUpdate || this.isClientSide) return; + NeighborUpdates.diamondDnShell(radius, this, tilePos, block); + } + + /** + * Notify adjacent blocks from the given position, + * and from the adjacent position on the given direction of the position, + * of neighbor update originated from the given block, + * or the block at the given position if null (avoiding duplicated updates). + */ + public void notifyBlocksInCapsuleOfNeighborChange( + @NotNull Direction direction, final @NotNull TilePosc tilePos, + final @Nullable Block block + ) { + if (this.noNeighborUpdate || this.isClientSide) return; + NeighborUpdates.diamondD2SingleDir(direction, this, tilePos, block); + } + + /** + * Notify adjacent blocks from the given position, + * and from the position on the given side of the position, + * of neighbor update originated from the given block, + * or the block at the given position if null (avoiding duplicated updates). + */ + public void notifyBlocksInCapsuleOfNeighborChange( + @NotNull Side side, final @NotNull TilePosc tilePos, + final @Nullable Block block + ) { + this.notifyBlocksInCapsuleOfNeighborChange(side.direction(), tilePos, block); + } + + /** + * Notify blocks adjacent to every provided positions, + * of neighbor update originated from the given block, + * or the block at *each* positions if null (avoiding duplicated updates). + */ + public synchronized void notifyBlocksOfNeighborChanges( + final @NotNull TilePosc @NotNull[] tilePositions, @Nullable Block block + ) { + class ctx { static final ObjectOpenHashSet CACHE = new ObjectOpenHashSet<>(); } + if (this.noNeighborUpdate || this.isClientSide) return; + ctx.CACHE.clear(); + ctx.CACHE.ensureCapacity(tilePositions.length * (6 / 2)); + + for (var pos : tilePositions) { + NeighborUpdates.diamondD1(ctx.CACHE, this, pos, block); } - this.getBlockType(tilePos).onNeighborChanged(this, tilePos, block); + final var size = ctx.CACHE.size(); + ctx.CACHE.clear(); + if (size >= 1024) ctx.CACHE.trim(512); + } + + /** + * Notify blocks adjacent to every provided positions, + * of neighbor update originated from the given block, + * or the block at *each* positions if null (avoiding duplicated updates). + */ + public synchronized void notifyBlocksOfNeighborChanges( + final @NotNull Iterable<@NotNull T> tilePositions, @Nullable Block block + ) { + class ctx { static final ObjectOpenHashSet CACHE = new ObjectOpenHashSet<>(); } + if (this.noNeighborUpdate || this.isClientSide) return; + ctx.CACHE.clear(); + + for (var pos : tilePositions) { + NeighborUpdates.diamondD1(ctx.CACHE, this, pos, block); + } + + final var size = ctx.CACHE.size(); + ctx.CACHE.clear(); + if (size >= 1024) ctx.CACHE.trim(512); + } + + @Deprecated + public final void notifyBlocksOfNeighborChange(final int x, final int y, final int z, final int id) { + this.notifyBlocksOfNeighborChange(new TilePos(x, y, z), Objects.requireNonNull(Blocks.getBlock(id))); } public boolean canBlockSeeSky(final @NotNull TilePosc tilePos) { @@ -1824,7 +1951,7 @@ public abstract class World implements MutableWorldSource { } public void onBlockHit(final @NotNull Player player, final @NotNull TilePosc tilePos, final @NotNull Side side) { - final @NotNull TilePos offsetPos = tilePos.add(side.getDirection(), new TilePos()); + final @NotNull TilePos offsetPos = tilePos.add(side.direction(), new TilePos()); final @Nullable Block block = this.getBlockType(offsetPos); if (block == Blocks.FIRE || block == Blocks.FIRE_COLD) { @@ -1893,16 +2020,6 @@ public abstract class World implements MutableWorldSource { return block != null && block.isSolidRender(); } - public boolean canPlaceOnSurfaceOfBlock(final @NotNull TilePos tilePos) { - final @Nullable Block block = this.getBlockType(tilePos); - return block != null && block.canPlaceOnSurfaceOnCondition(this, tilePos.x, tilePos.y, tilePos.z); - } - - @Deprecated - public final boolean canPlaceOnSurfaceOfBlock(final int x, final int y, final int z) { - return this.canPlaceOnSurfaceOfBlock(new TilePos(x, y, z)); - } - public @NotNull ISupport getSupport(final @NotNull TilePos tilePos, final @NotNull Side side) { return this.getBlockType(tilePos).getSupport(this, tilePos, side); } @@ -2215,38 +2332,37 @@ public abstract class World implements MutableWorldSource { } public @NotNull List<@NotNull T> getEntitiesWithinAABB(@NotNull final Class ofClass, @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); - final List<@NotNull T> entities = new ArrayList<>(); for (int x = minX; x <= maxX; x++) { for (int z = minZ; z <= maxZ; z++) { if (this.isChunkLoaded(x, z)) { - this.getChunkFromChunkCoords(x, z).getEntitiesWithin(ofClass, aabb, entities); + this.getChunkFromChunkCoords(x, z).getEntitiesWithin(ofClass, aabb, (List)this.entityBuffer); } } - } - return entities; + return (List)this.entityBuffer; } public @NotNull List<@NotNull T> getEntitiesWithinRadius(@NotNull final Class ofClass, final double x, final double y, final double z, final double radius) { + this.entityBuffer.clear(); final int minX = MathHelper.floor(x - radius); final int minZ = MathHelper.floor(z - radius); final int maxX = MathHelper.ceil(x + radius); final int maxZ = MathHelper.ceil(z + radius); - final List<@NotNull T> entities = new ArrayList<>(); for (int bx = minX; bx <= maxX; bx++) { for (int bz = minZ; bz <= maxZ; bz++) { if (this.isChunkLoaded(bx, bz)) { - this.getChunkFromChunkCoords(bx, bz).getEntitiesWithinRadius(ofClass, x, y, z, radius, entities); + this.getChunkFromChunkCoords(bx, bz).getEntitiesWithinRadius(ofClass, x, y, z, radius, (List)this.entityBuffer); } } } - return entities; + return (List)this.entityBuffer; } public @NotNull List<@NotNull Entity> getLoadedEntityList() { @@ -2377,7 +2493,7 @@ public abstract class World implements MutableWorldSource { public boolean hasDirectSignal(final @NotNull TilePosc tilePos) { final TilePos queryPos = new TilePos(); for (final @NotNull Side side : Side.sides) { - if (this.hasDirectSignal(tilePos.add(side.getDirection(), queryPos), side)) { + if (this.hasDirectSignal(tilePos.add(side.direction(), queryPos), side)) { return true; } } @@ -2411,10 +2527,10 @@ public abstract class World implements MutableWorldSource { // Special version of hasDirectSignal that excludes the front side of the redstone lantern. private boolean pumpkinHasDirectSignal(final @NotNull TilePosc tilePos) { for (final @NotNull Side side : Side.sides) { - if (Side.getSideById(this.getBlockData(tilePos)) == side) { + if (Side.fromId(this.getBlockData(tilePos)) == side) { continue; } - if (this.hasDirectSignal(tilePos.add(side.getDirection(), new TilePos()), side)) { + if (this.hasDirectSignal(tilePos.add(side.direction(), new TilePos()), side)) { return true; } } @@ -2424,7 +2540,7 @@ public abstract class World implements MutableWorldSource { public boolean hasNeighborSignal(final @NotNull TilePosc tilePos) { for (final @NotNull Side side : Side.sides) { - if (this.hasSignal(tilePos.add(side.getDirection(), new TilePos()), side)) { + if (this.hasSignal(tilePos.add(side.direction(), new TilePos()), side)) { return true; } } @@ -2703,10 +2819,8 @@ public abstract class World implements MutableWorldSource { } public void triggerEvent(final @NotNull TilePosc tilePos, final int index, final int data) { - final @Nullable Block block = this.getBlockType(tilePos); - if (block != null) { - block.triggerEvent(this, tilePos.x(), tilePos.y(), tilePos.z(), index, data); - } + final @NotNull Block block = this.getBlockType(tilePos); + block.triggerEvent(this, tilePos, index, data); } @Deprecated diff --git a/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureGlowstone.java b/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureGlowstone.java index 3005f2033..c9e4b03e7 100644 --- a/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureGlowstone.java +++ b/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureGlowstone.java @@ -30,8 +30,7 @@ public class WorldFeatureGlowstone implements WorldFeatureInterface continue; } int adjacentGlowstone = 0; - for(int d = 0; d < Direction.directions.length; d++) { - Direction dir = Direction.getDirectionById(d); + for(final var dir : Direction.all) { if(world.getBlockType(queryPos.set(rx, ry, rz).add(dir)) == Blocks.GLOWSTONE) { adjacentGlowstone++; } diff --git a/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureMoss.java b/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureMoss.java index 5169d0125..41a5856f9 100644 --- a/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureMoss.java +++ b/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureMoss.java @@ -104,7 +104,7 @@ public class WorldFeatureMoss extends WorldFeature public boolean airExposed(@NotNull World world, int x, int y, int z) { for (int i = 0; i < Side.sides.length; i++) { Side s = Side.sides[i]; - if (world.isAirBlock(x + s.getOffsetX(), y + s.getOffsetY(), z + s.getOffsetZ())) return true; + if (world.isAirBlock(x + s.offsetX(), y + s.offsetY(), z + s.offsetZ())) return true; } return false; } diff --git a/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureTerrace.java b/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureTerrace.java index 7023836ab..20d342f65 100644 --- a/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureTerrace.java +++ b/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureTerrace.java @@ -83,7 +83,7 @@ public class WorldFeatureTerrace extends WorldFeature return false; } - for (Direction dir : Direction.directions) { + for (final var dir : Direction.all) { cursor.add(dir, query); if(dir == Direction.UP){ if (!world.isAirBlock(query)) { diff --git a/game/core/src/main/java/net/minecraft/core/world/generate/feature/tree/WorldFeatureTreePalm.java b/game/core/src/main/java/net/minecraft/core/world/generate/feature/tree/WorldFeatureTreePalm.java index 55b4711d8..a00989b78 100644 --- a/game/core/src/main/java/net/minecraft/core/world/generate/feature/tree/WorldFeatureTreePalm.java +++ b/game/core/src/main/java/net/minecraft/core/world/generate/feature/tree/WorldFeatureTreePalm.java @@ -101,7 +101,7 @@ public class WorldFeatureTreePalm extends WorldFeature { }else { bend = random.nextFloat() * 3.0f + 2.0f; } - Direction direction = Direction.horizontalDirections[random.nextInt(4)]; + Direction direction = Direction.horizontal[random.nextInt(4)]; return generateTrunkIfPossible(height, angle, bend, direction); } @@ -115,9 +115,9 @@ public class WorldFeatureTreePalm extends WorldFeature { float yFactor = i / (float) height; int offset = MathHelper.floor(Math.pow(yFactor, angle + 1.0f) * bend); - int offsetX = direction.getOffsetX() * offset; + int offsetX = direction.offsetX() * offset; int offsetY = i; - int offsetZ = direction.getOffsetZ() * offset; + int offsetZ = direction.offsetZ() * offset; intList.add(encode(offsetX, offsetY, offsetZ)); } diff --git a/game/core/src/main/java/net/minecraft/core/world/pos/ChunkPos.java b/game/core/src/main/java/net/minecraft/core/world/pos/ChunkPos.java index 102c2c9f1..b8d865082 100644 --- a/game/core/src/main/java/net/minecraft/core/world/pos/ChunkPos.java +++ b/game/core/src/main/java/net/minecraft/core/world/pos/ChunkPos.java @@ -75,7 +75,7 @@ public final class ChunkPos implements Externalizable, Cloneable, ChunkPosc { @Override public @NotNull ChunkPos add(@NotNull Direction dir, @NotNull ChunkPos dest) { - return add(dir.getOffsetX(), dir.getOffsetZ(), dest); + return add(dir.offsetX(), dir.offsetZ(), dest); } public @NotNull ChunkPos add(int x, int z) { @@ -102,7 +102,7 @@ public final class ChunkPos implements Externalizable, Cloneable, ChunkPosc { @Override public @NotNull ChunkPos sub(@NotNull Direction dir, @NotNull ChunkPos dest) { - return sub(dir.getOffsetX(), dir.getOffsetZ(), dest); + return sub(dir.offsetX(), dir.offsetZ(), dest); } public @NotNull ChunkPos sub(int x, int z) { diff --git a/game/core/src/main/java/net/minecraft/core/world/pos/ChunkSectionTilePos.java b/game/core/src/main/java/net/minecraft/core/world/pos/ChunkSectionTilePos.java index 9fd7f0933..a1b5f637b 100644 --- a/game/core/src/main/java/net/minecraft/core/world/pos/ChunkSectionTilePos.java +++ b/game/core/src/main/java/net/minecraft/core/world/pos/ChunkSectionTilePos.java @@ -94,7 +94,7 @@ public class ChunkSectionTilePos implements Externalizable, Cloneable, ChunkSect @Override public @NotNull ChunkSectionTilePos add(@NotNull Direction dir, @NotNull ChunkSectionTilePos dest) { - return add(dir.getOffsetX(), dir.getOffsetY(), dir.getOffsetZ(), dest); + return add(dir.offsetX(), dir.offsetY(), dir.offsetZ(), dest); } public @NotNull ChunkSectionTilePos add(int x, int y, int z) { @@ -106,7 +106,7 @@ public class ChunkSectionTilePos implements Externalizable, Cloneable, ChunkSect } public @NotNull ChunkSectionTilePos add(@NotNull Direction dir) { - return add(dir.getOffsetX(), dir.getOffsetY(), dir.getOffsetZ(), this); + return add(dir.offsetX(), dir.offsetY(), dir.offsetZ(), this); } @Override @@ -121,7 +121,7 @@ public class ChunkSectionTilePos implements Externalizable, Cloneable, ChunkSect @Override public @NotNull ChunkSectionTilePos sub(@NotNull Direction dir, @NotNull ChunkSectionTilePos dest) { - return sub(dir.getOffsetX(), dir.getOffsetY(), dir.getOffsetZ(), dest); + return sub(dir.offsetX(), dir.offsetY(), dir.offsetZ(), dest); } public @NotNull ChunkSectionTilePos sub(int x, int y, int z) { @@ -133,7 +133,7 @@ public class ChunkSectionTilePos implements Externalizable, Cloneable, ChunkSect } public @NotNull ChunkSectionTilePos sub(@NotNull Direction dir) { - return sub(dir.getOffsetX(), dir.getOffsetY(), dir.getOffsetZ(), this); + return sub(dir.offsetX(), dir.offsetY(), dir.offsetZ(), this); } @Override diff --git a/game/core/src/main/java/net/minecraft/core/world/pos/ChunkTilePos.java b/game/core/src/main/java/net/minecraft/core/world/pos/ChunkTilePos.java index 97182c78c..dfe28ea69 100644 --- a/game/core/src/main/java/net/minecraft/core/world/pos/ChunkTilePos.java +++ b/game/core/src/main/java/net/minecraft/core/world/pos/ChunkTilePos.java @@ -94,7 +94,7 @@ public class ChunkTilePos implements Externalizable, Cloneable, ChunkTilePosc { @Override public @NotNull ChunkTilePos add(@NotNull Direction dir, @NotNull ChunkTilePos dest) { - return add(dir.getOffsetX(), dir.getOffsetY(), dir.getOffsetZ(), dest); + return add(dir.offsetX(), dir.offsetY(), dir.offsetZ(), dest); } public @NotNull ChunkTilePos add(int x, int y, int z) { @@ -106,7 +106,7 @@ public class ChunkTilePos implements Externalizable, Cloneable, ChunkTilePosc { } public @NotNull ChunkTilePos add(@NotNull Direction dir) { - return add(dir.getOffsetX(), dir.getOffsetY(), dir.getOffsetZ(), this); + return add(dir.offsetX(), dir.offsetY(), dir.offsetZ(), this); } @Override @@ -121,7 +121,7 @@ public class ChunkTilePos implements Externalizable, Cloneable, ChunkTilePosc { @Override public @NotNull ChunkTilePos sub(@NotNull Direction dir, @NotNull ChunkTilePos dest) { - return sub(dir.getOffsetX(), dir.getOffsetY(), dir.getOffsetZ(), dest); + return sub(dir.offsetX(), dir.offsetY(), dir.offsetZ(), dest); } public @NotNull ChunkTilePos sub(int x, int y, int z) { @@ -133,7 +133,7 @@ public class ChunkTilePos implements Externalizable, Cloneable, ChunkTilePosc { } public @NotNull ChunkTilePos sub(@NotNull Direction dir) { - return sub(dir.getOffsetX(), dir.getOffsetY(), dir.getOffsetZ(), this); + return sub(dir.offsetX(), dir.offsetY(), dir.offsetZ(), this); } @Override diff --git a/game/core/src/main/java/net/minecraft/core/world/pos/TilePos.java b/game/core/src/main/java/net/minecraft/core/world/pos/TilePos.java index aedd08e22..58453ec8f 100644 --- a/game/core/src/main/java/net/minecraft/core/world/pos/TilePos.java +++ b/game/core/src/main/java/net/minecraft/core/world/pos/TilePos.java @@ -134,11 +134,11 @@ public final class TilePos implements Externalizable, Cloneable, TilePosc { @Override public @NotNull TilePos add(@NotNull Direction dir, @NotNull TilePos dest) { - return add(dir.getOffsetX(), dir.getOffsetY(), dir.getOffsetZ(), dest); + return dir.offset(dest.set(this)); } public @NotNull TilePos add(@NotNull Side side, @NotNull TilePos dest) { - return add(side.getOffsetX(), side.getOffsetY(), side.getOffsetZ(), dest); + return add(side.offsetX(), side.offsetY(), side.offsetZ(), dest); } public @NotNull TilePos add(int x, int y, int z) { @@ -169,12 +169,12 @@ public final class TilePos implements Externalizable, Cloneable, TilePosc { @Override public @NotNull TilePos sub(@NotNull Direction dir, @NotNull TilePos dest) { - return sub(dir.getOffsetX(), dir.getOffsetY(), dir.getOffsetZ(), dest); + return dir.offsetScaled(dest.set(this), -1); } @Override public @NotNull TilePos sub(@NotNull Side side, @NotNull TilePos dest) { - return sub(side.getOffsetX(), side.getOffsetY(), side.getOffsetZ(), dest); + return sub(side.offsetX(), side.offsetY(), side.offsetZ(), dest); } public @NotNull TilePos sub(int x, int y, int z) { diff --git a/game/core/src/main/java/net/minecraft/core/world/weather/WeatherSnow.java b/game/core/src/main/java/net/minecraft/core/world/weather/WeatherSnow.java index 2d3e063ba..29b900c7b 100644 --- a/game/core/src/main/java/net/minecraft/core/world/weather/WeatherSnow.java +++ b/game/core/src/main/java/net/minecraft/core/world/weather/WeatherSnow.java @@ -112,9 +112,8 @@ public class WeatherSnow } } else if (blockIdBelow == Blocks.FLUID_WATER_STILL.id() && world.getBlockMetadata(x, y - 1, z) == 0) { if (rand.nextFloat() < world.getWeatherManager().getWeatherPower() * world.getWeatherManager().getWeatherIntensity()) { - for (int i = 0; i < 4; i++) { - Direction direction = Direction.horizontalDirections[i]; - Block block = world.getBlock(x + direction.getOffsetX(), y - 1, z + direction.getOffsetZ()); + for (final var dir : Direction.horizontal) { + Block block = world.getBlock(x + dir.offsetX(), y - 1, z + dir.offsetZ()); if (block == Blocks.ICE || block != null && block.isSolidRender()) { world.setBlockWithNotify(x, y - 1, z, Blocks.ICE.id()); break; diff --git a/game/core/src/main/resources/assets/minecraft/lang/en_US/item.lang b/game/core/src/main/resources/assets/minecraft/lang/en_US/item.lang index 1783d0edc..939eabe0b 100644 --- a/game/core/src/main/resources/assets/minecraft/lang/en_US/item.lang +++ b/game/core/src/main/resources/assets/minecraft/lang/en_US/item.lang @@ -324,6 +324,8 @@ item.bed.name=Bed item.bed.desc=Take a nap overnight. item.repeater.name=Redstone Repeater item.repeater.desc=Delays a redstone signal. +item.timer.name=Redstone Timer +item.timer.desc=Continuously switches between two outputs. item.map.name=Map item.map.blank.name=Blank Map item.map.desc=Chart your land! diff --git a/game/core/src/main/resources/assets/minecraft/lang/en_US/subtitles.lang b/game/core/src/main/resources/assets/minecraft/lang/en_US/subtitles.lang index 28d05bfd8..a61904b28 100644 --- a/game/core/src/main/resources/assets/minecraft/lang/en_US/subtitles.lang +++ b/game/core/src/main/resources/assets/minecraft/lang/en_US/subtitles.lang @@ -91,6 +91,10 @@ subtitles.ambient.weather.rain=Rainfall subtitles.tile.piston.out=Piston extended subtitles.tile.piston.in=Piston retracted +subtitles.tile.piston.detached=Piston detached +subtitles.tile.piston.attached=Piston attached +subtitles.tile.piston.detached.out=Piston failed to extend +subtitles.tile.piston.detached.in=Piston failed to retract subtitles.tile.tnt.fuse=TNT lit subtitles.tile.sensor_block.sense=Mob sense diff --git a/game/core/src/main/resources/assets/minecraft/lang/en_US/tile.lang b/game/core/src/main/resources/assets/minecraft/lang/en_US/tile.lang index 58413130c..1f2511f1a 100644 --- a/game/core/src/main/resources/assets/minecraft/lang/en_US/tile.lang +++ b/game/core/src/main/resources/assets/minecraft/lang/en_US/tile.lang @@ -803,6 +803,8 @@ tile.repeater.idle.name=Redstone Repeater tile.repeater.idle.desc=Repeats redstone signals over a distance. tile.repeater.active.name=Redstone Repeater tile.repeater.active.desc=Repeats redstone signals over a distance. +tile.timer.name=Redstone Timer +tile.timer.desc=Continuously switches between two outputs. tile.piston.base.name=Piston tile.piston.base.desc=Pushes blocks but does not pull them. diff --git a/game/core/src/main/resources/assets/minecraft/sounds/sounds.json b/game/core/src/main/resources/assets/minecraft/sounds/sounds.json index bc67d6a65..0aad36ab1 100644 --- a/game/core/src/main/resources/assets/minecraft/sounds/sounds.json +++ b/game/core/src/main/resources/assets/minecraft/sounds/sounds.json @@ -704,6 +704,38 @@ "tile/piston/in.ogg" ] }, + "tile.piston.detached": { + "subtitle": "subtitles.tile.piston.detached", + "sounds": [ + "tile/piston/out.ogg" + ] + }, + "tile.piston.attached": { + "subtitle": "subtitles.tile.piston.attached", + "sounds": [ + "tile/piston/in.ogg" + ] + }, + "tile.piston.detached.in": { + "subtitle": "subtitles.tile.piston.detached.in", + "sounds": [ + { + "name": "random.click", + "type": "event", + "pitch": 0.85 + } + ] + }, + "tile.piston.detached.out": { + "subtitle": "subtitles.tile.piston.detached.out", + "sounds": [ + { + "name": "random.click", + "type": "event", + "pitch": 0.8 + } + ] + }, "mob.cow": { "subtitle": "subtitles.mob.cow", "sounds": [ diff --git a/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java b/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java index e8cf4ceeb..f537cb748 100644 --- a/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java +++ b/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java @@ -386,12 +386,12 @@ public class PacketHandlerServer extends PacketHandler j1 = i1; } if (this.hasMoved && this.playerEntity.distanceToSqr((double) x + 0.5D, (double) y + 0.5D, (double) z + 0.5D) < 64D && (j1 > this.mcServer.spawnProtectionRange || ignoreSpawnProtection)) { - this.playerEntity.playerController.useOrPlaceItemStackOnTile(this.playerEntity, worldserver, itemstack, x, y, z, direction.getSide(), xPlaced, yPlaced); + this.playerEntity.playerController.useOrPlaceItemStackOnTile(this.playerEntity, worldserver, itemstack, x, y, z, direction.side(), xPlaced, yPlaced); } this.playerEntity.playerNetServerHandler.sendPacket(new PacketBlockUpdate(x, y, z, worldserver)); - x += direction.getOffsetX(); - y += direction.getOffsetY(); - z += direction.getOffsetZ(); + x += direction.offsetX(); + y += direction.offsetY(); + z += direction.offsetZ(); this.playerEntity.playerNetServerHandler.sendPacket(new PacketBlockUpdate(x, y, z, worldserver)); break; } @@ -416,12 +416,12 @@ public class PacketHandlerServer extends PacketHandler j1 = i1; } if (this.hasMoved && this.playerEntity.distanceToSqr((double) x + 0.5D, (double) y + 0.5D, (double) z + 0.5D) < 64D && (j1 > this.mcServer.spawnProtectionRange || ignoreSpawnProtection)) { - this.playerEntity.playerController.placeItemStackOnTile(this.playerEntity, worldserver, itemstack, x, y, z, direction.getSide(), xPlaced, yPlaced); + this.playerEntity.playerController.placeItemStackOnTile(this.playerEntity, worldserver, itemstack, x, y, z, direction.side(), xPlaced, yPlaced); } this.playerEntity.playerNetServerHandler.sendPacket(new PacketBlockUpdate(x, y, z, worldserver)); - x += direction.getOffsetX(); - y += direction.getOffsetY(); - z += direction.getOffsetZ(); + x += direction.offsetX(); + y += direction.offsetY(); + z += direction.offsetZ(); this.playerEntity.playerNetServerHandler.sendPacket(new PacketBlockUpdate(x, y, z, worldserver)); break; } @@ -738,9 +738,9 @@ public class PacketHandlerServer extends PacketHandler public void handleCustomPayload(@NotNull PacketCustomPayload packetCustomPayload) { if (PacketCustomPayload.CHANNEL_ROTATION_LOCK.equals(packetCustomPayload.channel)) { if (packetCustomPayload.data.length == 4) { - this.playerEntity.rotationLock = Direction.getDirectionById(packetCustomPayload.data[0]); - this.playerEntity.rotationLockHorizontal = Direction.getDirectionById(packetCustomPayload.data[1]); - this.playerEntity.rotationLockVertical = Direction.getDirectionById(packetCustomPayload.data[2]); + this.playerEntity.rotationLock = Direction.fromId(packetCustomPayload.data[0]); + this.playerEntity.rotationLockHorizontal = Direction.fromId(packetCustomPayload.data[1]); + this.playerEntity.rotationLockVertical = Direction.fromId(packetCustomPayload.data[2]); this.playerEntity.placementModeOverride = PlacementMode.get(packetCustomPayload.data[3]); } } else if (PacketCustomPayload.CHANNEL_FLAG.equals(packetCustomPayload.channel)) { diff --git a/game/server/src/main/java/net/minecraft/server/world/WorldServer.java b/game/server/src/main/java/net/minecraft/server/world/WorldServer.java index eb17bae0a..fe99dacb7 100644 --- a/game/server/src/main/java/net/minecraft/server/world/WorldServer.java +++ b/game/server/src/main/java/net/minecraft/server/world/WorldServer.java @@ -39,7 +39,6 @@ public class WorldServer extends World { public @NotNull MinecraftServer mcServer; private long lastWeatherSend = System.currentTimeMillis(); - public WorldServer( final @NotNull MinecraftServer server, final @NotNull LevelStorage levelStorage, diff --git a/util/datagen/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java b/util/datagen/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java index 15b788c19..82a1a4cab 100644 --- a/util/datagen/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java +++ b/util/datagen/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java @@ -7,6 +7,7 @@ import net.minecraft.core.item.ItemBucket; import net.minecraft.datagen.recipeBuilders.RecipeBuilder; import net.minecraft.datagen.recipeBuilders.RecipeBuilderShaped; import net.minecraft.core.block.Blocks; +import net.minecraft.core.block.piston.PistonCommon; import net.minecraft.core.data.registry.Registries; import net.minecraft.core.data.registry.recipe.RecipeSymbol; import net.minecraft.core.item.ItemStack; @@ -1226,6 +1227,14 @@ class WorkbenchGenerator { .addInput('R', Items.DUST_REDSTONE) .create("piston", new ItemStack(Blocks.PISTON_BASE)); + RecipeBuilder.Shaped(CORE_NAMESPACE) + .setShape( + "XXX", + " B ") + .addInput('X', "minecraft:planks") + .addInput('B', PistonCommon.baseItem(PistonCommon.TYPE_NORMAL, false, true)) + .create("piston_reattach", new ItemStack(Blocks.PISTON_BASE)); + RecipeBuilder.Shaped(CORE_NAMESPACE) .setShape( "S", @@ -1236,14 +1245,32 @@ class WorkbenchGenerator { RecipeBuilder.Shaped(CORE_NAMESPACE) .setShape( + " S ", "XXX", - "#I#", - "#R#") + " B ") + .addInput('S', Items.SLIMEBALL) + .addInput('X', "minecraft:planks") + .addInput('B', PistonCommon.baseItem(PistonCommon.TYPE_STICKY, false, true)) + .create("sticky_piston_reattach", Blocks.PISTON_BASE_STICKY.getDefaultStack()); + + RecipeBuilder.Shaped(CORE_NAMESPACE) + .setShape( + "XXX", + "#I#", + "#R#") .addInput('X', Items.INGOT_STEEL_CRUDE) .addInput('#', "minecraft:stones") .addInput('I', Items.INGOT_STEEL) .addInput('R', Items.DUST_REDSTONE) .create("steel_piston", Blocks.PISTON_BASE_STEEL.getDefaultStack()); + + RecipeBuilder.Shaped(CORE_NAMESPACE) + .setShape( + "XXX", + " B ") + .addInput('X', Items.INGOT_STEEL_CRUDE) + .addInput('B', PistonCommon.baseItem(PistonCommon.TYPE_STEEL, false, true)) + .create("steel_piston_reattach", Blocks.PISTON_BASE_STEEL.getDefaultStack()); RecipeBuilder.Shaped(CORE_NAMESPACE) .setShape( @@ -1295,6 +1322,15 @@ class WorkbenchGenerator { .addInput('I', "minecraft:stones") .create("redstone_repeater", new ItemStack(Items.REPEATER, 1)); + RecipeBuilder.Shaped(CORE_NAMESPACE) + .setShape( + "#X#", + "III") + .addInput('#', Blocks.TORCH_REDSTONE_ACTIVE) + .addInput('X', Items.QUARTZ) + .addInput('I', "minecraft:stones") + .create("redstone_timer", new ItemStack(Items.TIMER, 1)); + RecipeBuilder.Shaped(CORE_NAMESPACE) .setShape( "X",