diff --git a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenContainerAbstract.java b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenContainerAbstract.java index dcd58660a..35af4f5ae 100644 --- a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenContainerAbstract.java +++ b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenContainerAbstract.java @@ -262,6 +262,10 @@ public abstract class ScreenContainerAbstract extends Screen { if (!this.mc.thePlayer.getGamemode().hasBlockConsumption()) { // Duplicate items with middle mouse button if (buttonNum == 2) { + if (GameSettings.ENABLE_ITEM_DRAGGING.value) { + this.itemDragHandler.mouseEvent(mx, my, buttonNum, true); + return; + } Slot slot = this.inventorySlots.getSlot(getSlotId(mx, my)); if (slot != null) { if (slot.getItemStack() == null) { diff --git a/game/client/src/main/java/net/minecraft/client/player/controller/PlayerController.java b/game/client/src/main/java/net/minecraft/client/player/controller/PlayerController.java index a9a0ac06d..f3594f92a 100644 --- a/game/client/src/main/java/net/minecraft/client/player/controller/PlayerController.java +++ b/game/client/src/main/java/net/minecraft/client/player/controller/PlayerController.java @@ -58,6 +58,9 @@ public abstract class PlayerController { return; } + final @NotNull Block mineBlock = world.getBlockType(tilePos); + if (!mineBlock.canCollideCheck(world.getBlockData(tilePos), false)) return; + if (!player.getGamemode().hasBlockBreakingAnimation()) { this.swingItem(true); @@ -71,7 +74,6 @@ public abstract class PlayerController { return; } - final @NotNull Block mineBlock = world.getBlockType(tilePos); final float mineStrength = mineBlock.getStrength(world, tilePos, side, player); if (mineStrength < 1.0f) { diff --git a/game/client/src/main/java/net/minecraft/client/render/WorldRenderer.java b/game/client/src/main/java/net/minecraft/client/render/WorldRenderer.java index fd5b5ea7f..a7ea30810 100644 --- a/game/client/src/main/java/net/minecraft/client/render/WorldRenderer.java +++ b/game/client/src/main/java/net/minecraft/client/render/WorldRenderer.java @@ -22,7 +22,6 @@ import org.joml.Matrix4f; import org.joml.Vector3d; import org.joml.Vector3dc; import org.joml.primitives.AABBd; -import org.joml.primitives.AABBdc; import org.lwjgl.input.Mouse; import net.minecraft.client.Minecraft; @@ -47,10 +46,12 @@ import net.minecraft.client.render.tessellator.TessellatorGeneral; import net.minecraft.client.render.texture.stitcher.TextureRegistry; import net.minecraft.core.entity.Entity; import net.minecraft.core.entity.player.Player; +import net.minecraft.core.item.IPlaceable; import net.minecraft.core.sound.SoundCategory; import net.minecraft.core.util.debug.Debug; import net.minecraft.core.util.helper.Direction; import net.minecraft.core.util.helper.MathHelper; +import net.minecraft.core.util.helper.Side; import net.minecraft.core.util.helper.Time; import net.minecraft.core.util.phys.HitResult; import net.minecraft.core.world.World; @@ -127,23 +128,22 @@ public class WorldRenderer { } public void getMouseOver(float partialTicks) { - if (this.mc.activeCamera == null) { - return; - } - if (this.mc.currentWorld == null) { - return; - } + if (this.mc.activeCamera == null) return; + if (this.mc.currentWorld == null) return; final double blockReach = this.mc.thePlayer.getGamemode().getBlockReachDistance(); final double entityReach = this.mc.thePlayer.getGamemode().getEntityReachDistance(); - Vector3dc pos1 = this.mc.thePlayer.getPosition(partialTicks, true); - Vector3dc look = this.mc.thePlayer.getViewVector(partialTicks); + final Vector3dc pos1 = this.mc.thePlayer.getPosition(partialTicks, true); + final Vector3dc look = this.mc.thePlayer.getViewVector(partialTicks); assert look != null; - Vector3dc pos2 = pos1.add(look.x() * blockReach, look.y() * blockReach, look.z() * blockReach, new Vector3d()); + final Vector3dc pos2 = new Vector3d(look).mul(blockReach).add(pos1); + + final var playerItem = this.mc.thePlayer.inventory.getCurrentItem(); + final boolean interactsWithFluid = playerItem != null && playerItem.interactsWithFluid(); // Raytrace blocks - this.mc.objectMouseOver = this.mc.thePlayer.rayCast(blockReach, partialTicks, false, false, true); + this.mc.objectMouseOver = this.mc.thePlayer.rayCast(blockReach, partialTicks, interactsWithFluid, false, true); // mc.objectMouseOver = mc.currentWorld.checkBlockCollisionBetweenPoints(pos1, pos2, false, false, true); // Calculate again because block raytrace changes the values @@ -151,28 +151,32 @@ public class WorldRenderer { // look = mc.thePlayer.getViewVector(partialTicks); // pos2 = pos1.add(look.x * entityReach, look.y * entityReach, look.z * entityReach); - double hitBlockDistance = 1000.0; - if (this.mc.objectMouseOver != null) { - hitBlockDistance = pos1.distance(this.mc.objectMouseOver.location); - } + final double hitBlockDistance = (this.mc.objectMouseOver != null) + ? pos1.distance(this.mc.objectMouseOver.location) + : Double.POSITIVE_INFINITY; this.pointedEntity = null; - float expand = 1.0f; - AABBd entitySearchBox = MathHelper.aabbExpand(this.mc.thePlayer.bb, look.x() * entityReach, look.y() * entityReach, look.z() * entityReach, new AABBd()); + + final float expand = 1.0f; + final AABBd entitySearchBox = MathHelper.aabbExpand(this.mc.thePlayer.bb, look.x() * entityReach, look.y() * entityReach, look.z() * entityReach, new AABBd()); MathHelper.aabbGrow(entitySearchBox, expand, expand, expand, entitySearchBox); - - List entities = this.mc.currentWorld.getEntitiesWithinAABBExcludingEntity(this.mc.thePlayer, entitySearchBox); - + // Search for the closest hit entity double pointedEntityDistance = 0.0; + + final var entities = this.mc.currentWorld.getEntitiesWithinAABBExcludingEntity(this.mc.thePlayer, entitySearchBox); + final AABBd hitBox = new AABBd(); for (int i = 0; i < entities.size(); i++) { - Entity entity = entities.get(i); - if (!entity.isSelectable()) { - continue; + final Entity entity = entities.get(i); + + if (playerItem != null) { + if (!playerItem.interactsWithEntity(entity)) continue; + } else { + if (!entity.isSelectable()) continue; } - float hitRadius = entity == this.mc.thePlayer.vehicle ? 0 : entity.getPickRadius(); - AABBdc hitBox = MathHelper.aabbGrow(entity.bb, hitRadius, hitRadius, hitRadius, new AABBd()); + final float hitRadius = entity == this.mc.thePlayer.vehicle ? 0 : entity.getPickRadius(); + MathHelper.aabbGrow(entity.bb, hitRadius, hitRadius, hitRadius, hitBox); if (hitBox.containsPoint(pos1)) { this.pointedEntity = entity; @@ -180,12 +184,10 @@ public class WorldRenderer { continue; } - HitResult hitResult = MathHelper.aabbClip(hitBox, pos1, pos2); - if (hitResult == null) { - continue; - } + final HitResult hitResult = MathHelper.aabbClip(hitBox, pos1, pos2); + if (hitResult == null) continue; - double entityDistance = pos1.distance(hitResult.location); + final double entityDistance = pos1.distance(hitResult.location); if (this.pointedEntity == null || entityDistance < pointedEntityDistance) { this.pointedEntity = entity; pointedEntityDistance = entityDistance; @@ -207,7 +209,9 @@ public class WorldRenderer { if (!GameSettings.EASY_BRIDGE.value) return; if (!this.mc.thePlayer.onGround) return; if (Direction.getLockable(this.mc.thePlayer) != Direction.DOWN) return; - if (this.mc.thePlayer.inventory.getCurrentItem() == null) return; + final var item = this.mc.thePlayer.inventory.getCurrentItem(); + if (item == null) return; + if (!(item.getItem() instanceof IPlaceable placeable)) return; this.mc.bridgePos.set( MathHelper.floor(this.mc.thePlayer.x), @@ -215,7 +219,11 @@ public class WorldRenderer { MathHelper.floor(this.mc.thePlayer.z) ); - this.mc.canBridge = this.mc.thePlayer.world.canPlaceInsideBlock(this.mc.bridgePos); + if (!placeable.canPlaceDirectlyAtPosition( + item, this.mc.currentWorld, this.mc.thePlayer, this.mc.bridgePos, Side.TOP, + 0.5, 0.5)) return; + + this.mc.canBridge = true; } private float getFOVModifier(float partialTick, boolean isModifiedByFOV) { diff --git a/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererPlayer.java b/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererPlayer.java index 271270fd2..be6db2908 100644 --- a/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererPlayer.java +++ b/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererPlayer.java @@ -76,7 +76,6 @@ public class MobRendererPlayer extends MobRendererBipedArmored { final TessellatorGeneral tessellator = GLRenderer.getTessellator(); TextureRegistry.worldAtlas.bind(); GLRenderer.pushFrame(); - Lighting.disable(); GLRenderer.setBlendFunc(BlendFactor.SRC_ALPHA, BlendFactor.ONE_MINUS_SRC_ALPHA); GLRenderer.enableState(State.BLEND); diff --git a/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelBucket.java b/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelBucket.java index 6bd95d81a..b54bf5588 100644 --- a/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelBucket.java +++ b/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelBucket.java @@ -1,5 +1,6 @@ package net.minecraft.client.render.item.model; +import net.minecraft.client.Minecraft; import net.minecraft.client.render.texture.stitcher.IconCoordinate; import net.minecraft.client.render.texture.stitcher.TextureRegistry; import net.minecraft.core.entity.Entity; @@ -7,6 +8,7 @@ import net.minecraft.core.item.Item; import net.minecraft.core.item.ItemBucket; import net.minecraft.core.item.ItemStack; import net.minecraft.core.util.collection.NamespaceID; +import net.minecraft.core.world.World; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -17,12 +19,21 @@ import java.util.Set; public abstract class ItemModelBucket extends ItemModelStandard { protected final Map bucketIcons = new HashMap<>(); + private final Map textureIconCache = new HashMap<>(); + + protected String iconNamespace; + protected String iconPrefix; + protected int iconMaxCharges; public ItemModelBucket(@NotNull Item item, boolean defaultTextureLookup) { super(item, defaultTextureLookup); } protected void initializeIcons(@NotNull String namespace, @NotNull String prefix, int maxCharges, @NotNull Set<@NotNull NamespaceID> validStates) { + this.iconNamespace = namespace; + this.iconPrefix = prefix; + this.iconMaxCharges = maxCharges; + IconCoordinate[] emptyArray = new IconCoordinate[1]; emptyArray[0] = TextureRegistry.getTexture(namespace + ":item/" + prefix + "/empty"); this.bucketIcons.put(ItemBucket.STATE_EMPTY, emptyArray); @@ -41,6 +52,17 @@ public abstract class ItemModelBucket extends ItemModelStandard { } } + private @NotNull IconCoordinate[] getChargeIcons(final @NotNull String textureStateName, final int maxCharges) { + return textureIconCache.computeIfAbsent(textureStateName, name -> { + IconCoordinate[] chargesArray = new IconCoordinate[maxCharges + 1]; + for (int c = 1; c <= maxCharges; c++) { + String path = iconNamespace + ":item/" + iconPrefix + "/" + name + "_" + c; + chargesArray[c] = TextureRegistry.getTexture(path); + } + return chargesArray; + }); + } + @Override public @NotNull IconCoordinate getIcon(@Nullable Entity entity, @NotNull ItemStack itemStack) { NamespaceID state = ItemBucket.getState(itemStack); @@ -57,7 +79,24 @@ public abstract class ItemModelBucket extends ItemModelStandard { } charges = Math.max(0, Math.min(charges, maxForThisBucket)); - IconCoordinate[] iconsForState = bucketIcons.get(state); + + if (ItemBucket.STATE_EMPTY.equals(state)) { + IconCoordinate[] emptyIcons = bucketIcons.get(ItemBucket.STATE_EMPTY); + if (emptyIcons != null && charges < emptyIcons.length) { + IconCoordinate emptyIcon = emptyIcons[charges]; + if (emptyIcon != null) { + return emptyIcon; + } + } + return super.getIcon(entity, itemStack); + } + + final World world = entity != null ? entity.world : Minecraft.getMinecraft().currentWorld; + final String textureStateName = ItemBucket.getTextureStateName(entity, world, itemStack); + final String defaultTextureStateName = ItemBucket.getStateName(state); + IconCoordinate[] iconsForState = textureStateName.equals(defaultTextureStateName) + ? bucketIcons.get(state) + : getChargeIcons(textureStateName, maxForThisBucket); if (iconsForState == null || charges >= iconsForState.length) { return super.getIcon(entity, itemStack); @@ -66,4 +105,4 @@ public abstract class ItemModelBucket extends ItemModelStandard { IconCoordinate icon = iconsForState[charges]; return (icon != null) ? icon : super.getIcon(entity, itemStack); } -} \ No newline at end of file +} 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 87b3af8b0..9194db182 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 @@ -10,15 +10,15 @@ import net.minecraft.core.item.block.ItemBlock; import org.useless.dragonfly.DisplayPos; public class ItemModelDispatcher extends Dispatcher { - protected static final DisplayPos HANDHELD_FIRST_PERSON_RIGHT_HAND = new DisplayPos(1.13f/16f, 3.2f/16f, 1.13f/16f, 0, -90, 25, 0.68f, 0.68f, 0.68f); - protected static final DisplayPos HANDHELD_FIRST_PERSON_LEFT_HAND = new DisplayPos(1.13f/16f, 3.2f/16f, 1.13f/16f, 0, 90, -25, 0.68f, 0.68f, 0.68f); - protected static final DisplayPos HANDHELD_THIRD_PERSON_RIGHT_HAND = new DisplayPos(0, 4.0f/16f, 0.5f/16f, 0, -90, 55, 0.85f, 0.85f, 0.85f); - protected static final DisplayPos HANDHELD_THIRD_PERSON_LEFT_HAND = new DisplayPos(0, 4.0f/16f, 0.5f/16f, 0, 90, -55, 0.85f, 0.85f, 0.85f); - - protected static final DisplayPos HANDHELD_ROD_FIRST_PERSON_RIGHT_HAND = new DisplayPos(0/16f, 1.6f/16f, 0.8f/16f, 0, 90, 25, 0.68f, 0.68f, 0.68f); - protected static final DisplayPos HANDHELD_ROD_FIRST_PERSON_LEFT_HAND = new DisplayPos(0/16f, 1.6f/16f, 0.8f/16f, 0, -90, -25, 0.68f, 0.68f, 0.68f); - protected static final DisplayPos HANDHELD_ROD_THIRD_PERSON_RIGHT_HAND = new DisplayPos(0, 4.0f/16f, 2.5f/16f, 0, 90, 55, 0.85f, 0.85f, 0.85f); - protected static final DisplayPos HANDHELD_ROD_THIRD_PERSON_LEFT_HAND = new DisplayPos(0, 4.0f/16f, 2.5f/16f, 0, -90, -55, 0.85f, 0.85f, 0.85f); + public static final DisplayPos HANDHELD_FIRST_PERSON_RIGHT_HAND = new DisplayPos(1.13f/16f, 3.2f/16f, 1.13f/16f, 0, -90, 25, 0.68f, 0.68f, 0.68f); + public static final DisplayPos HANDHELD_FIRST_PERSON_LEFT_HAND = new DisplayPos(1.13f/16f, 3.2f/16f, 1.13f/16f, 0, 90, -25, 0.68f, 0.68f, 0.68f); + public static final DisplayPos HANDHELD_THIRD_PERSON_RIGHT_HAND = new DisplayPos(0, 4.0f/16f, 0.5f/16f, 0, -90, 55, 0.85f, 0.85f, 0.85f); + public static final DisplayPos HANDHELD_THIRD_PERSON_LEFT_HAND = new DisplayPos(0, 4.0f/16f, 0.5f/16f, 0, 90, -55, 0.85f, 0.85f, 0.85f); + + public static final DisplayPos HANDHELD_ROD_FIRST_PERSON_RIGHT_HAND = new DisplayPos(0/16f, 1.6f/16f, 0.8f/16f, 0, 90, 25, 0.68f, 0.68f, 0.68f); + public static final DisplayPos HANDHELD_ROD_FIRST_PERSON_LEFT_HAND = new DisplayPos(0/16f, 1.6f/16f, 0.8f/16f, 0, -90, -25, 0.68f, 0.68f, 0.68f); + public static final DisplayPos HANDHELD_ROD_THIRD_PERSON_RIGHT_HAND = new DisplayPos(0, 4.0f/16f, 2.5f/16f, 0, 90, 55, 0.85f, 0.85f, 0.85f); + public static final DisplayPos HANDHELD_ROD_THIRD_PERSON_LEFT_HAND = new DisplayPos(0, 4.0f/16f, 2.5f/16f, 0, -90, -55, 0.85f, 0.85f, 0.85f); private static ItemModelDispatcher instance = new ItemModelDispatcher(); public static final ItemModel emptyModel = new ItemModelNone(); diff --git a/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererJarButterfly.java b/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererJarButterfly.java index c813ce39b..0b5f21272 100644 --- a/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererJarButterfly.java +++ b/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererJarButterfly.java @@ -13,6 +13,6 @@ public class TileEntityRendererJarButterfly extends TileEntityRenderer overridePoses) { + assert this.displayPositions != null : "should only be called when this.displayPositions definitely exists!"; + if (overridePoses.containsKey(DisplayPos.FIRST_PERSON_RIGHT_HAND) && !overridePoses.containsKey(DisplayPos.FIRST_PERSON_LEFT_HAND)) { + var right = overridePoses.get(DisplayPos.FIRST_PERSON_RIGHT_HAND); + this.displayPositions.put(DisplayPos.FIRST_PERSON_LEFT_HAND, right); + } + if (overridePoses.containsKey(DisplayPos.THIRD_PERSON_RIGHT_HAND) && !overridePoses.containsKey(DisplayPos.THIRD_PERSON_LEFT_HAND)) { + var right = overridePoses.get(DisplayPos.THIRD_PERSON_RIGHT_HAND); + this.displayPositions.put(DisplayPos.THIRD_PERSON_LEFT_HAND, right); + } } @Override diff --git a/game/client/src/main/resources/assets/minecraft/models/block/activator_active.json b/game/client/src/main/resources/assets/minecraft/models/block/activator_active.json index 9c8fa7ed3..f397922f7 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/activator_active.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/activator_active.json @@ -1,11 +1,9 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable_with_bottom", "textures": { - "up": "minecraft:block/activator/top_active", - "down": "minecraft:block/activator/bottom_active", - "south": "minecraft:block/activator/side_active", - "north": "minecraft:block/activator/front_active", - "west": "minecraft:block/activator/side_active", - "east": "minecraft:block/activator/side_active" + "top": "minecraft:block/activator/top_active", + "bottom": "minecraft:block/activator/bottom_active", + "front": "minecraft:block/activator/front_active", + "side": "minecraft:block/activator/side_active" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/activator_idle.json b/game/client/src/main/resources/assets/minecraft/models/block/activator_idle.json index 27baf99d8..2887658c3 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/activator_idle.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/activator_idle.json @@ -1,11 +1,9 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable_with_bottom", "textures": { - "up": "minecraft:block/activator/top", - "down": "minecraft:block/activator/bottom", - "south": "minecraft:block/activator/side", - "north": "minecraft:block/activator/front", - "west": "minecraft:block/activator/side", - "east": "minecraft:block/activator/side" + "top": "minecraft:block/activator/top", + "bottom": "minecraft:block/activator/bottom", + "front": "minecraft:block/activator/front", + "side": "minecraft:block/activator/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/black.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/black.json index 868c24d60..9d451473a 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/black.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/black.json @@ -1,11 +1,8 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable", "textures": { - "up": "minecraft:block/chest/planks_black/top", - "down": "minecraft:block/chest/planks_black/top", - "south": "minecraft:block/chest/planks_black/side", - "north": "minecraft:block/chest/planks_black/front", - "west": "minecraft:block/chest/planks_black/side", - "east": "minecraft:block/chest/planks_black/side" + "top": "minecraft:block/chest/planks_black/top", + "front": "minecraft:block/chest/planks_black/front", + "side": "minecraft:block/chest/planks_black/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/blue.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/blue.json index 5e36ee04e..9a2d6e77c 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/blue.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/blue.json @@ -1,11 +1,8 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable", "textures": { - "up": "minecraft:block/chest/planks_blue/top", - "down": "minecraft:block/chest/planks_blue/top", - "south": "minecraft:block/chest/planks_blue/side", - "north": "minecraft:block/chest/planks_blue/front", - "west": "minecraft:block/chest/planks_blue/side", - "east": "minecraft:block/chest/planks_blue/side" + "top": "minecraft:block/chest/planks_blue/top", + "front": "minecraft:block/chest/planks_blue/front", + "side": "minecraft:block/chest/planks_blue/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/brown.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/brown.json index d64a68821..1206d0fe8 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/brown.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/brown.json @@ -1,11 +1,8 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable", "textures": { - "up": "minecraft:block/chest/planks_brown/top", - "down": "minecraft:block/chest/planks_brown/top", - "south": "minecraft:block/chest/planks_brown/side", - "north": "minecraft:block/chest/planks_brown/front", - "west": "minecraft:block/chest/planks_brown/side", - "east": "minecraft:block/chest/planks_brown/side" + "top": "minecraft:block/chest/planks_brown/top", + "front": "minecraft:block/chest/planks_brown/front", + "side": "minecraft:block/chest/planks_brown/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/cyan.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/cyan.json index 17762aa8a..fe576c3f3 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/cyan.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/cyan.json @@ -1,11 +1,8 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable", "textures": { - "up": "minecraft:block/chest/planks_cyan/top", - "down": "minecraft:block/chest/planks_cyan/top", - "south": "minecraft:block/chest/planks_cyan/side", - "north": "minecraft:block/chest/planks_cyan/front", - "west": "minecraft:block/chest/planks_cyan/side", - "east": "minecraft:block/chest/planks_cyan/side" + "top": "minecraft:block/chest/planks_cyan/top", + "front": "minecraft:block/chest/planks_cyan/front", + "side": "minecraft:block/chest/planks_cyan/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/gray.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/gray.json index 935596991..39bf24dad 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/gray.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/gray.json @@ -1,11 +1,8 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable", "textures": { - "up": "minecraft:block/chest/planks_gray/top", - "down": "minecraft:block/chest/planks_gray/top", - "south": "minecraft:block/chest/planks_gray/side", - "north": "minecraft:block/chest/planks_gray/front", - "west": "minecraft:block/chest/planks_gray/side", - "east": "minecraft:block/chest/planks_gray/side" + "top": "minecraft:block/chest/planks_gray/top", + "front": "minecraft:block/chest/planks_gray/front", + "side": "minecraft:block/chest/planks_gray/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/green.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/green.json index ea5fd9a06..70d51df78 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/green.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/green.json @@ -1,11 +1,8 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable", "textures": { - "up": "minecraft:block/chest/planks_green/top", - "down": "minecraft:block/chest/planks_green/top", - "south": "minecraft:block/chest/planks_green/side", - "north": "minecraft:block/chest/planks_green/front", - "west": "minecraft:block/chest/planks_green/side", - "east": "minecraft:block/chest/planks_green/side" + "top": "minecraft:block/chest/planks_green/top", + "front": "minecraft:block/chest/planks_green/front", + "side": "minecraft:block/chest/planks_green/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/lightblue.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/lightblue.json index fa6a3e1e2..bac6b9094 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/lightblue.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/lightblue.json @@ -1,11 +1,8 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable", "textures": { - "up": "minecraft:block/chest/planks_lightblue/top", - "down": "minecraft:block/chest/planks_lightblue/top", - "south": "minecraft:block/chest/planks_lightblue/side", - "north": "minecraft:block/chest/planks_lightblue/front", - "west": "minecraft:block/chest/planks_lightblue/side", - "east": "minecraft:block/chest/planks_lightblue/side" + "top": "minecraft:block/chest/planks_lightblue/top", + "front": "minecraft:block/chest/planks_lightblue/front", + "side": "minecraft:block/chest/planks_lightblue/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/lime.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/lime.json index fc28f69b3..2d51d40e5 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/lime.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/lime.json @@ -1,11 +1,8 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable", "textures": { - "up": "minecraft:block/chest/planks_lime/top", - "down": "minecraft:block/chest/planks_lime/top", - "south": "minecraft:block/chest/planks_lime/side", - "north": "minecraft:block/chest/planks_lime/front", - "west": "minecraft:block/chest/planks_lime/side", - "east": "minecraft:block/chest/planks_lime/side" + "top": "minecraft:block/chest/planks_lime/top", + "front": "minecraft:block/chest/planks_lime/front", + "side": "minecraft:block/chest/planks_lime/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/magenta.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/magenta.json index 43099184a..1ca4c294f 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/magenta.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/magenta.json @@ -1,11 +1,8 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable", "textures": { - "up": "minecraft:block/chest/planks_magenta/top", - "down": "minecraft:block/chest/planks_magenta/top", - "south": "minecraft:block/chest/planks_magenta/side", - "north": "minecraft:block/chest/planks_magenta/front", - "west": "minecraft:block/chest/planks_magenta/side", - "east": "minecraft:block/chest/planks_magenta/side" + "top": "minecraft:block/chest/planks_magenta/top", + "front": "minecraft:block/chest/planks_magenta/front", + "side": "minecraft:block/chest/planks_magenta/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/orange.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/orange.json index fb945d6c4..39ab0c95d 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/orange.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/orange.json @@ -1,11 +1,8 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable", "textures": { - "up": "minecraft:block/chest/planks_orange/top", - "down": "minecraft:block/chest/planks_orange/top", - "south": "minecraft:block/chest/planks_orange/side", - "north": "minecraft:block/chest/planks_orange/front", - "west": "minecraft:block/chest/planks_orange/side", - "east": "minecraft:block/chest/planks_orange/side" + "top": "minecraft:block/chest/planks_orange/top", + "front": "minecraft:block/chest/planks_orange/front", + "side": "minecraft:block/chest/planks_orange/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/pink.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/pink.json index 7b864c7e1..278750711 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/pink.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/pink.json @@ -1,11 +1,8 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable", "textures": { - "up": "minecraft:block/chest/planks_pink/top", - "down": "minecraft:block/chest/planks_pink/top", - "south": "minecraft:block/chest/planks_pink/side", - "north": "minecraft:block/chest/planks_pink/front", - "west": "minecraft:block/chest/planks_pink/side", - "east": "minecraft:block/chest/planks_pink/side" + "top": "minecraft:block/chest/planks_pink/top", + "front": "minecraft:block/chest/planks_pink/front", + "side": "minecraft:block/chest/planks_pink/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/planks.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/planks.json index fe1010a1e..11122998e 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/planks.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/planks.json @@ -1,11 +1,8 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable", "textures": { - "up": "minecraft:block/chest/planks/top", - "down": "minecraft:block/chest/planks/top", - "south": "minecraft:block/chest/planks/side", - "north": "minecraft:block/chest/planks/front", - "west": "minecraft:block/chest/planks/side", - "east": "minecraft:block/chest/planks/side" + "top": "minecraft:block/chest/planks/top", + "front": "minecraft:block/chest/planks/front", + "side": "minecraft:block/chest/planks/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/purple.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/purple.json index fe197824c..c2e6d865a 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/purple.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/purple.json @@ -1,11 +1,8 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable", "textures": { - "up": "minecraft:block/chest/planks_purple/top", - "down": "minecraft:block/chest/planks_purple/top", - "south": "minecraft:block/chest/planks_purple/side", - "north": "minecraft:block/chest/planks_purple/front", - "west": "minecraft:block/chest/planks_purple/side", - "east": "minecraft:block/chest/planks_purple/side" + "top": "minecraft:block/chest/planks_purple/top", + "front": "minecraft:block/chest/planks_purple/front", + "side": "minecraft:block/chest/planks_purple/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/red.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/red.json index bc3dc92f3..228113f74 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/red.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/red.json @@ -1,11 +1,8 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable", "textures": { - "up": "minecraft:block/chest/planks_red/top", - "down": "minecraft:block/chest/planks_red/top", - "south": "minecraft:block/chest/planks_red/side", - "north": "minecraft:block/chest/planks_red/front", - "west": "minecraft:block/chest/planks_red/side", - "east": "minecraft:block/chest/planks_red/side" + "top": "minecraft:block/chest/planks_red/top", + "front": "minecraft:block/chest/planks_red/front", + "side": "minecraft:block/chest/planks_red/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/silver.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/silver.json index 527dbbd40..a70f4ac17 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/silver.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/silver.json @@ -1,11 +1,8 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable", "textures": { - "up": "minecraft:block/chest/planks_silver/top", - "down": "minecraft:block/chest/planks_silver/top", - "south": "minecraft:block/chest/planks_silver/side", - "north": "minecraft:block/chest/planks_silver/front", - "west": "minecraft:block/chest/planks_silver/side", - "east": "minecraft:block/chest/planks_silver/side" + "top": "minecraft:block/chest/planks_silver/top", + "front": "minecraft:block/chest/planks_silver/front", + "side": "minecraft:block/chest/planks_silver/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/white.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/white.json index 0aecdff66..899047d0f 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/white.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/white.json @@ -1,11 +1,8 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable", "textures": { - "up": "minecraft:block/chest/planks_white/top", - "down": "minecraft:block/chest/planks_white/top", - "south": "minecraft:block/chest/planks_white/side", - "north": "minecraft:block/chest/planks_white/front", - "west": "minecraft:block/chest/planks_white/side", - "east": "minecraft:block/chest/planks_white/side" + "top": "minecraft:block/chest/planks_white/top", + "front": "minecraft:block/chest/planks_white/front", + "side": "minecraft:block/chest/planks_white/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/yellow.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/yellow.json index 73eee629b..1c7dfa7cc 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/yellow.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/yellow.json @@ -1,11 +1,8 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable", "textures": { - "up": "minecraft:block/chest/planks_yellow/top", - "down": "minecraft:block/chest/planks_yellow/top", - "south": "minecraft:block/chest/planks_yellow/side", - "north": "minecraft:block/chest/planks_yellow/front", - "west": "minecraft:block/chest/planks_yellow/side", - "east": "minecraft:block/chest/planks_yellow/side" + "top": "minecraft:block/chest/planks_yellow/top", + "front": "minecraft:block/chest/planks_yellow/front", + "side": "minecraft:block/chest/planks_yellow/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/dispenser.json b/game/client/src/main/resources/assets/minecraft/models/block/dispenser.json index 4a4f74842..3dd380cf0 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/dispenser.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/dispenser.json @@ -1,11 +1,9 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable_with_bottom", "textures": { - "up": "minecraft:block/dispenser/top", - "down": "minecraft:block/dispenser/bottom", - "south": "minecraft:block/dispenser/side", - "north": "minecraft:block/dispenser/front", - "west": "minecraft:block/dispenser/side", - "east": "minecraft:block/dispenser/side" + "top": "minecraft:block/dispenser/top", + "bottom": "minecraft:block/dispenser/bottom", + "front": "minecraft:block/dispenser/front", + "side": "minecraft:block/dispenser/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/template_closed.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/template_closed.json index b1a090fa3..82da95d1f 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/template_closed.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/template_closed.json @@ -5,6 +5,11 @@ "translation": [ 0, -1, 0], "scale":[ 0.8, 0.8, 0.8 ] }, + "firstperson_righthand": { + "rotation": [ 0, -45, 0 ], + "translation": [ 0, 0, 0 ], + "scale": [ 0.40, 0.40, 0.40 ] + }, "head": { "rotation": [ 0, 0, 0 ], "translation": [ 0, -3, -6], diff --git a/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/active.json b/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/active.json index f76da7d24..b8b5123eb 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/active.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/active.json @@ -1,11 +1,9 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable_with_bottom", "textures": { - "up": "minecraft:block/furnace_blast/top", - "down": "minecraft:block/furnace_blast/bottom", - "south": "minecraft:block/furnace_blast/side", - "north": "minecraft:block/furnace_blast/active_front", - "west": "minecraft:block/furnace_blast/side", - "east": "minecraft:block/furnace_blast/side" + "top": "minecraft:block/furnace_blast/top", + "bottom": "minecraft:block/furnace_blast/bottom", + "front": "minecraft:block/furnace_blast/active_front", + "side": "minecraft:block/furnace_blast/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/active_filled.json b/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/active_filled.json index 0f54ae353..f86499152 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/active_filled.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/active_filled.json @@ -1,11 +1,9 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable_with_bottom", "textures": { - "up": "minecraft:block/furnace_blast/top", - "down": "minecraft:block/furnace_blast/bottom", - "south": "minecraft:block/furnace_blast/side", - "north": "minecraft:block/furnace_blast/active_front_filled", - "west": "minecraft:block/furnace_blast/side", - "east": "minecraft:block/furnace_blast/side" + "top": "minecraft:block/furnace_blast/top", + "bottom": "minecraft:block/furnace_blast/bottom", + "front": "minecraft:block/furnace_blast/active_front_filled", + "side": "minecraft:block/furnace_blast/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/idle.json index 88cf9c1c9..a23fffb37 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/idle.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/idle.json @@ -1,11 +1,9 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable_with_bottom", "textures": { - "up": "minecraft:block/furnace_blast/top", - "down": "minecraft:block/furnace_blast/bottom", - "south": "minecraft:block/furnace_blast/side", - "north": "minecraft:block/furnace_blast/idle_front", - "west": "minecraft:block/furnace_blast/side", - "east": "minecraft:block/furnace_blast/side" + "top": "minecraft:block/furnace_blast/top", + "bottom": "minecraft:block/furnace_blast/bottom", + "front": "minecraft:block/furnace_blast/idle_front", + "side": "minecraft:block/furnace_blast/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/idle_filled.json b/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/idle_filled.json index a97a89097..faf411a0d 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/idle_filled.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/idle_filled.json @@ -1,11 +1,9 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable_with_bottom", "textures": { - "up": "minecraft:block/furnace_blast/top", - "down": "minecraft:block/furnace_blast/bottom", - "south": "minecraft:block/furnace_blast/side", - "north": "minecraft:block/furnace_blast/idle_front_filled", - "west": "minecraft:block/furnace_blast/side", - "east": "minecraft:block/furnace_blast/side" + "top": "minecraft:block/furnace_blast/top", + "bottom": "minecraft:block/furnace_blast/bottom", + "front": "minecraft:block/furnace_blast/idle_front_filled", + "side": "minecraft:block/furnace_blast/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/active.json b/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/active.json index 9ac40ef37..6930e8c1c 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/active.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/active.json @@ -1,11 +1,9 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable_with_bottom", "textures": { - "up": "minecraft:block/furnace_stone/top", - "down": "minecraft:block/furnace_stone/bottom", - "south": "minecraft:block/furnace_stone/side", - "north": "minecraft:block/furnace_stone/active_front", - "west": "minecraft:block/furnace_stone/side", - "east": "minecraft:block/furnace_stone/side" + "top": "minecraft:block/furnace_stone/top", + "bottom": "minecraft:block/furnace_stone/bottom", + "front": "minecraft:block/furnace_stone/active_front", + "side": "minecraft:block/furnace_stone/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/active_filled.json b/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/active_filled.json index c0b1fef32..2fc7e3b0d 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/active_filled.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/active_filled.json @@ -1,11 +1,9 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable_with_bottom", "textures": { - "up": "minecraft:block/furnace_stone/top", - "down": "minecraft:block/furnace_stone/bottom", - "south": "minecraft:block/furnace_stone/side", - "north": "minecraft:block/furnace_stone/active_front_filled", - "west": "minecraft:block/furnace_stone/side", - "east": "minecraft:block/furnace_stone/side" + "top": "minecraft:block/furnace_stone/top", + "bottom": "minecraft:block/furnace_stone/bottom", + "front": "minecraft:block/furnace_stone/active_front_filled", + "side": "minecraft:block/furnace_stone/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/idle.json index 6e35ed373..97bdf5c6d 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/idle.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/idle.json @@ -1,11 +1,9 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable_with_bottom", "textures": { - "up": "minecraft:block/furnace_stone/top", - "down": "minecraft:block/furnace_stone/bottom", - "south": "minecraft:block/furnace_stone/side", - "north": "minecraft:block/furnace_stone/idle_front", - "west": "minecraft:block/furnace_stone/side", - "east": "minecraft:block/furnace_stone/side" + "top": "minecraft:block/furnace_stone/top", + "bottom": "minecraft:block/furnace_stone/bottom", + "front": "minecraft:block/furnace_stone/idle_front", + "side": "minecraft:block/furnace_stone/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/idle_filled.json b/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/idle_filled.json index 4c234def2..ded30cb66 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/idle_filled.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/idle_filled.json @@ -1,11 +1,9 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable_with_bottom", "textures": { - "up": "minecraft:block/furnace_stone/top", - "down": "minecraft:block/furnace_stone/bottom", - "south": "minecraft:block/furnace_stone/side", - "north": "minecraft:block/furnace_stone/idle_front_filled", - "west": "minecraft:block/furnace_stone/side", - "east": "minecraft:block/furnace_stone/side" + "top": "minecraft:block/furnace_stone/top", + "bottom": "minecraft:block/furnace_stone/bottom", + "front": "minecraft:block/furnace_stone/idle_front_filled", + "side": "minecraft:block/furnace_stone/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/motion_sensor_active.json b/game/client/src/main/resources/assets/minecraft/models/block/motion_sensor_active.json index 688c988cd..be6bb697a 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/motion_sensor_active.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/motion_sensor_active.json @@ -1,11 +1,8 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable", "textures": { - "up": "minecraft:block/motion_sensor/side", - "down": "minecraft:block/motion_sensor/side", - "south": "minecraft:block/motion_sensor/side", - "north": "minecraft:block/motion_sensor/active_front", - "west": "minecraft:block/motion_sensor/side", - "east": "minecraft:block/motion_sensor/side" + "top": "minecraft:block/motion_sensor/side", + "front": "minecraft:block/motion_sensor/active_front", + "side": "minecraft:block/motion_sensor/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/motion_sensor_idle.json b/game/client/src/main/resources/assets/minecraft/models/block/motion_sensor_idle.json index 9923dee13..2ea7de729 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/motion_sensor_idle.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/motion_sensor_idle.json @@ -1,11 +1,8 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable", "textures": { - "up": "minecraft:block/motion_sensor/side", - "down": "minecraft:block/motion_sensor/side", - "south": "minecraft:block/motion_sensor/side", - "north": "minecraft:block/motion_sensor/idle_front", - "west": "minecraft:block/motion_sensor/side", - "east": "minecraft:block/motion_sensor/side" + "top": "minecraft:block/motion_sensor/side", + "front": "minecraft:block/motion_sensor/idle_front", + "side": "minecraft:block/motion_sensor/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/orientable_with_bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/orientable_with_bottom.json index d03a89bdb..7c1c61bf4 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/orientable_with_bottom.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/orientable_with_bottom.json @@ -1,19 +1,8 @@ { - "parent": "block/cube", - "display": { - "firstperson_righthand": { - "rotation": [ 0, 135, 0 ], - "translation": [ 0, 0, 0 ], - "scale": [ 0.40, 0.40, 0.40 ] - } - }, + "parent": "block/orientable_with_sides", "textures": { - "particle": "#front", - "down": "#bottom", - "up": "#top", - "north": "#front", - "east": "#side", - "south": "#side", - "west": "#side" + "right": "#side", + "back": "#side", + "left": "#side" } } diff --git a/game/client/src/main/resources/assets/minecraft/models/block/orientable_with_sides.json b/game/client/src/main/resources/assets/minecraft/models/block/orientable_with_sides.json new file mode 100644 index 000000000..98f1d0fcd --- /dev/null +++ b/game/client/src/main/resources/assets/minecraft/models/block/orientable_with_sides.json @@ -0,0 +1,19 @@ +{ + "parent": "block/cube", + "display": { + "firstperson_righthand": { + "rotation": [ 0, 135, 0 ], + "translation": [ 0, 0, 0 ], + "scale": [ 0.40, 0.40, 0.40 ] + } + }, + "textures": { + "particle": "#front", + "down": "#bottom", + "up": "#top", + "north": "#front", + "east": "#right", + "south": "#back", + "west": "#left" + } +} \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_carved.json b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_carved.json index 4aec1b871..c5788ae80 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_carved.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_carved.json @@ -1,11 +1,9 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable_with_bottom", "textures": { - "up": "minecraft:block/pumpkin_carved/top", - "down": "minecraft:block/pumpkin_carved/bottom", - "south": "minecraft:block/pumpkin_carved/side", - "north": "minecraft:block/pumpkin_carved/front", - "west": "minecraft:block/pumpkin_carved/side", - "east": "minecraft:block/pumpkin_carved/side" + "top": "minecraft:block/pumpkin_carved/top", + "bottom": "minecraft:block/pumpkin_carved/bottom", + "front": "minecraft:block/pumpkin_carved/front", + "side": "minecraft:block/pumpkin_carved/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_carved_lit.json b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_carved_lit.json index 512ca88b7..b38b16c8a 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_carved_lit.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_carved_lit.json @@ -1,11 +1,9 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable_with_bottom", "textures": { - "up": "minecraft:block/pumpkin_carved_lit/top", - "down": "minecraft:block/pumpkin_carved_lit/bottom", - "south": "minecraft:block/pumpkin_carved_lit/side", - "north": "minecraft:block/pumpkin_carved_lit/front", - "west": "minecraft:block/pumpkin_carved_lit/side", - "east": "minecraft:block/pumpkin_carved_lit/side" + "top": "minecraft:block/pumpkin_carved_lit/top", + "bottom": "minecraft:block/pumpkin_carved_lit/bottom", + "front": "minecraft:block/pumpkin_carved_lit/front", + "side": "minecraft:block/pumpkin_carved_lit/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_redstone.json b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_redstone.json index 3322c8129..57d5fa427 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_redstone.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_redstone.json @@ -1,11 +1,9 @@ { - "parent": "minecraft:block/cube", + "parent": "minecraft:block/orientable_with_bottom", "textures": { - "up": "minecraft:block/pumpkin_redstone/top", - "down": "minecraft:block/pumpkin_redstone/bottom", - "south": "minecraft:block/pumpkin_redstone/side", - "north": "minecraft:block/pumpkin_redstone/front", - "west": "minecraft:block/pumpkin_redstone/side", - "east": "minecraft:block/pumpkin_redstone/side" + "top": "minecraft:block/pumpkin_redstone/top", + "bottom": "minecraft:block/pumpkin_redstone/bottom", + "front": "minecraft:block/pumpkin_redstone/front", + "side": "minecraft:block/pumpkin_redstone/side" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trommel.json b/game/client/src/main/resources/assets/minecraft/models/block/trommel.json index c42392628..e103e4870 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/trommel.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/trommel.json @@ -1,11 +1,18 @@ { - "parent": "minecraft:block/cube_bottom_top", + "parent": "minecraft:block/orientable_with_sides", + "display": { + "firstperson_righthand": { + "rotation": [ 0, -45, 0 ], + "translation": [ 0, 0, 0 ], + "scale": [ 0.40, 0.40, 0.40 ] + } + }, "textures": { "top": "minecraft:block/trommel/top", "bottom": "minecraft:block/trommel/bottom", - "south": "minecraft:block/trommel/idle_back", - "north": "minecraft:block/trommel/idle_front", - "west": "minecraft:block/trommel/side", - "east": "minecraft:block/trommel/side_slot" + "back": "minecraft:block/trommel/idle_back", + "front": "minecraft:block/trommel/idle_front", + "left": "minecraft:block/trommel/side", + "right": "minecraft:block/trommel/side_slot" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trommel_active.json b/game/client/src/main/resources/assets/minecraft/models/block/trommel_active.json index 8394df71b..7daa3ee97 100644 --- a/game/client/src/main/resources/assets/minecraft/models/block/trommel_active.json +++ b/game/client/src/main/resources/assets/minecraft/models/block/trommel_active.json @@ -1,11 +1,18 @@ { - "parent": "minecraft:block/cube_bottom_top", + "parent": "minecraft:block/orientable_with_sides", + "display": { + "firstperson_righthand": { + "rotation": [ 0, -45, 0 ], + "translation": [ 0, 0, 0 ], + "scale": [ 0.40, 0.40, 0.40 ] + } + }, "textures": { "top": "minecraft:block/trommel/top", "bottom": "minecraft:block/trommel/bottom", - "south": "minecraft:block/trommel/active_back", - "north": "minecraft:block/trommel/active_front", - "west": "minecraft:block/trommel/side", - "east": "minecraft:block/trommel/side_slot" + "back": "minecraft:block/trommel/active_back", + "front": "minecraft:block/trommel/active_front", + "left": "minecraft:block/trommel/side", + "right": "minecraft:block/trommel/side_slot" } } \ No newline at end of file diff --git a/game/client/src/main/resources/assets/minecraft/textures/item/bucket_iron/waterboiling_1.png b/game/client/src/main/resources/assets/minecraft/textures/item/bucket_iron/waterboiling_1.png new file mode 100644 index 000000000..0473a1aeb Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/item/bucket_iron/waterboiling_1.png differ diff --git a/game/client/src/main/resources/assets/minecraft/textures/item/bucket_steel/waterboiling_1.png b/game/client/src/main/resources/assets/minecraft/textures/item/bucket_steel/waterboiling_1.png new file mode 100644 index 000000000..21cbc04ae Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/item/bucket_steel/waterboiling_1.png differ diff --git a/game/client/src/main/resources/assets/minecraft/textures/item/bucket_steel/waterboiling_2.png b/game/client/src/main/resources/assets/minecraft/textures/item/bucket_steel/waterboiling_2.png new file mode 100644 index 000000000..9a1589898 Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/item/bucket_steel/waterboiling_2.png differ diff --git a/game/client/src/main/resources/assets/minecraft/textures/item/bucket_steel/waterboiling_3.png b/game/client/src/main/resources/assets/minecraft/textures/item/bucket_steel/waterboiling_3.png new file mode 100644 index 000000000..3a0ac8d03 Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/item/bucket_steel/waterboiling_3.png differ diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicGrowthRubyglass.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicGrowthRubyglass.java index 1c9369df2..3045ada08 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicGrowthRubyglass.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicGrowthRubyglass.java @@ -211,16 +211,17 @@ public class BlockLogicGrowthRubyglass extends BlockLogic { @Override public ItemStack @Nullable [] getBreakResult(@NotNull World world, @NotNull EnumDropCause dropCause, int data, @Nullable TileEntity tileEntity) { - if (dropCause != EnumDropCause.SILK_TOUCH) { - return null; - } - - int shape = data & SHAPE_MASK; - - if (shape == STATE_BOTTOM) { - return new ItemStack[] { new ItemStack(this.block, 2) }; - } - - return new ItemStack[] { new ItemStack(this.block, 1) }; - } + if (dropCause == EnumDropCause.PICK_BLOCK) { + return new ItemStack[]{this.block.getDefaultStack()}; + } else if (dropCause == EnumDropCause.SILK_TOUCH) { + int shape = data & SHAPE_MASK; + + if (shape == STATE_BOTTOM) { + return new ItemStack[]{new ItemStack(this.block, 2)}; + } + + return new ItemStack[]{new ItemStack(this.block, 1)}; + } + return null; + } } \ No newline at end of file diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicJarButterfly.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicJarButterfly.java index 5e9e63706..44a97bf18 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicJarButterfly.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicJarButterfly.java @@ -135,7 +135,7 @@ public class BlockLogicJarButterfly extends BlockLogic implements ISupportable { } if (!world.isClientSide) { MobButterfly entity = new MobButterfly(world); - entity.setColor(this.color.id); + entity.setColor(this.color.id()); entity.setPos(tilePos.x() + 0.5f + (world.rand.nextFloat() - 0.5f) * 0.5f, tilePos.y() + world.rand.nextFloat() * 0.5f, tilePos.z() + 0.5f + (world.rand.nextFloat() - 0.5f) * 0.5f); world.entityJoinedWorld(entity); } 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 b09358de3..af63cfeea 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 @@ -17,7 +17,7 @@ import org.jetbrains.annotations.Nullable; public class BlockLogicLayerAsh extends BlockLogicLayerSupportable { - public BlockLogicLayerAsh(Block block, Block fullBlock, Material material) + public BlockLogicLayerAsh(@NotNull Block block, @NotNull Block fullBlock, @NotNull Material material) { super(block, fullBlock, material); setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerBase.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerBase.java index a0d8de9dc..628d9c951 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerBase.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerBase.java @@ -19,7 +19,7 @@ public abstract class BlockLogicLayerBase extends BlockLogic public final @Nullable Block fullBlock; public static final int MASK_HEIGHT = 0b111; - public BlockLogicLayerBase(@NotNull Block block, @Nullable Block fullBlock, @NotNull Material material) + public BlockLogicLayerBase(@NotNull Block block, @NotNull Block fullBlock, @NotNull Material material) { super(block, material); setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); 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 b01bf518f..c401bb588 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 @@ -19,7 +19,7 @@ import java.util.Random; public class BlockLogicLayerLeaves extends BlockLogicLayerSupportable { public static final int MASK_PERMANENT = 0b1000_0000; - public BlockLogicLayerLeaves(Block block, Block fullBlock, Material material) { + public BlockLogicLayerLeaves(@NotNull Block block, @NotNull Block fullBlock, @NotNull Material material) { super(block, fullBlock, material); setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); block.setTicking(true); diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerSlate.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerSlate.java index e8c2681f2..6bca23523 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerSlate.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerSlate.java @@ -11,7 +11,7 @@ import org.jetbrains.annotations.Nullable; public class BlockLogicLayerSlate extends BlockLogicLayerBase { - public BlockLogicLayerSlate(@NotNull Block block, @Nullable Block fullBlock, @NotNull Material material) { + public BlockLogicLayerSlate(@NotNull Block block, @NotNull Block fullBlock, @NotNull Material material) { super(block, fullBlock, material); } 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 b98471617..cf5f41b1a 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 @@ -22,7 +22,7 @@ import java.util.Random; public class BlockLogicLayerSnow extends BlockLogicLayerSupportable { - public BlockLogicLayerSnow(@NotNull Block block, @Nullable Block fullBlock, @NotNull Material material) { + public BlockLogicLayerSnow(@NotNull Block block, @NotNull Block fullBlock, @NotNull Material material) { super(block, fullBlock, material); setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); block.setTicking(true); diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerSupportable.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerSupportable.java index 23d242b52..6a98f27dc 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerSupportable.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerSupportable.java @@ -9,10 +9,9 @@ import net.minecraft.core.util.helper.Side; import net.minecraft.core.world.World; import net.minecraft.core.world.pos.TilePosc; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; public abstract class BlockLogicLayerSupportable extends BlockLogicLayerBase implements ISupportable { - public BlockLogicLayerSupportable(@NotNull Block block, @Nullable Block fullBlock, @NotNull Material material) { + public BlockLogicLayerSupportable(@NotNull Block block, @NotNull Block fullBlock, @NotNull Material material) { super(block, fullBlock, material); } diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicThermalVent.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicThermalVent.java index 8ba5af230..c04ab6df9 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicThermalVent.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicThermalVent.java @@ -38,7 +38,7 @@ public class BlockLogicThermalVent extends BlockLogic { world.spawnParticle("ventsmoke", xPos, yPos, zPos, 0.0D, 0.005D, 0.0D, 1, 1000, true); - if (state >= VENTING_STATE - 1) { + if (hasVentBelow(world, tilePos) && state >= VENTING_STATE - 1) { for (int i = 0; i < 4; i++) { world.spawnParticle("ventsmoke", xPos, yPos, zPos, 0.0D, 0.005D, 0.0D, 0, 1000.0, true); world.spawnParticle("smoke", xPos + rand.nextFloat() - 0.5D, yPos, zPos + rand.nextFloat() - 0.5D, 0.0D, 0.005D, 0.0D, 1, 1000.0, true); @@ -53,12 +53,30 @@ public class BlockLogicThermalVent extends BlockLogic { return 1; } + private static boolean hasVentBelow(final @NotNull World world, final @NotNull TilePosc tilePos) { + return Block.hasLogicClass(world.getBlockType(tilePos.down(new TilePos())), BlockLogicThermalVent.class); + } + + @Override + public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Block block) { + if (!hasVentBelow(world, tilePos) && getVentState(world.getBlockData(tilePos)) != DORMANT_STATE) { + world.setBlockDataNotify(tilePos, DORMANT_STATE); + } + } + @Override public void updateTick(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Random rand, final boolean isRandomTick) { if (world.getBlockType(tilePos.up(new TilePos())).solid()) { return; } + if (!hasVentBelow(world, tilePos)) { + if (getVentState(world.getBlockData(tilePos)) != DORMANT_STATE) { + world.setBlockDataNotify(tilePos, DORMANT_STATE); + } + return; + } + if (rand.nextInt(4) != 0) { int state = getVentState(world.getBlockData(tilePos)); if (state < VENTING_STATE) { @@ -120,7 +138,7 @@ public class BlockLogicThermalVent extends BlockLogic { super.onPlacedByWorld(world, tilePos); if (!world.isClientSide) { - world.setBlockDataNotify(tilePos, world.rand.nextInt(VENTING_STATE)); + world.setBlockDataNotify(tilePos, hasVentBelow(world, tilePos) ? world.rand.nextInt(VENTING_STATE) : DORMANT_STATE); } } diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityJarButterfly.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityJarButterfly.java index 77121d8e1..968a58315 100644 --- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityJarButterfly.java +++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityJarButterfly.java @@ -32,6 +32,6 @@ public class TileEntityJarButterfly extends TileEntity{ @Override public void writeAdditionalData(@NotNull CompoundTag compoundTag) { - compoundTag.putByte("color", (byte) color.id); + compoundTag.putByte("color", (byte) color.id()); } } diff --git a/game/core/src/main/java/net/minecraft/core/entity/ICapturable.java b/game/core/src/main/java/net/minecraft/core/entity/ICapturable.java new file mode 100644 index 000000000..92a6c4770 --- /dev/null +++ b/game/core/src/main/java/net/minecraft/core/entity/ICapturable.java @@ -0,0 +1,25 @@ +package net.minecraft.core.entity; + +import org.jetbrains.annotations.NotNull; + +import net.minecraft.core.item.Item; + +public interface ICapturable { + boolean canBeCapturedBy(@NotNull Item item); + int onCaptured(int amount, boolean acceptPartial); + + default int onCaptured() { return this.onCaptured(1, true); } + default int onCaptured(int amount) { return this.onCaptured(amount, true); } + + static interface Singular extends ICapturable { + void onSingularCaptured(); + + @Override + default int onCaptured(int amount, boolean acceptPartial) { + if (amount < 1) return 0; + if (!acceptPartial && amount > 1) return 0; + this.onSingularCaptured(); + return 1; + } + } +} 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 af4f33c56..363436919 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 @@ -4,6 +4,7 @@ import com.b100.utils.StringUtils; import com.mojang.nbt.tags.CompoundTag; import net.minecraft.core.Global; import net.minecraft.core.block.material.Materials; +import net.minecraft.core.item.Item; import net.minecraft.core.item.ItemFood; import net.minecraft.core.util.phys.HitResult; import net.minecraft.core.WeightedRandomLootObject; diff --git a/game/core/src/main/java/net/minecraft/core/entity/animal/MobButterfly.java b/game/core/src/main/java/net/minecraft/core/entity/animal/MobButterfly.java index 98a7d3ff3..1f983e42d 100644 --- a/game/core/src/main/java/net/minecraft/core/entity/animal/MobButterfly.java +++ b/game/core/src/main/java/net/minecraft/core/entity/animal/MobButterfly.java @@ -9,10 +9,12 @@ import net.minecraft.core.block.Block; import net.minecraft.core.block.Blocks; import net.minecraft.core.block.tag.BlockTags; import net.minecraft.core.entity.Entity; +import net.minecraft.core.entity.ICapturable; import net.minecraft.core.entity.MobFlying; import net.minecraft.core.entity.SkinVariantList; import net.minecraft.core.entity.player.Player; import net.minecraft.core.item.Item; +import net.minecraft.core.item.ItemJar; import net.minecraft.core.item.Items; import net.minecraft.core.util.helper.DamageType; import net.minecraft.core.util.helper.MathHelper; @@ -22,12 +24,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.joml.primitives.AABBd; -import java.util.Arrays; -import java.util.HashSet; import java.util.Set; import java.util.function.Supplier; -public class MobButterfly extends MobFlying implements AmbientCreature { +public class MobButterfly extends MobFlying implements AmbientCreature, ICapturable.Singular { public static final Int2ObjectMap colorEntries = new Int2ObjectArrayMap<>(); public static final int DATA_COLOR_ID = 16; @@ -38,8 +38,8 @@ public class MobButterfly extends MobFlying implements AmbientCreature { public static final ButterflyEntry COLOR_SILVER; public static ButterflyEntry addEntry(int id, String name, double weight, Supplier jarItem, Biome... allowedBiomes) { - assert id >= 0 && id <= 0xFF : "ID is outside valid range!"; - ButterflyEntry entry = new ButterflyEntry(id, name, weight, jarItem, allowedBiomes); + assert (id & ~0xFF) == 0 : "ID is outside valid range!"; + final var entry = new ButterflyEntry(id, name, weight, jarItem, allowedBiomes); colorEntries.put(id, entry); return entry; } @@ -284,45 +284,37 @@ public class MobButterfly extends MobFlying implements AmbientCreature { return colorEntries.get(getColor()).name + "/" + variantList.getSkinReference(this.variantJsonPath, "0", getSkinVariant()); } - public static class ButterflyEntry { - public final int id; - public final String name; - /** Biomes which the color can appear, null indicates any biome*/ - private @Nullable Set allowedBiomes; - public final Supplier jarItem; - public final double weight; - - public ButterflyEntry(int id, String name, double weight, Supplier jarItem, Biome... allowedBiomes) { - this.id = id; - this.name = name; - this.weight = weight; - this.jarItem = jarItem; - - if (allowedBiomes.length > 0) { - this.allowedBiomes = new HashSet<>(); - this.allowedBiomes.addAll(Arrays.asList(allowedBiomes)); - } + public static record ButterflyEntry( + int id, + @NotNull String name, + double weight, + @NotNull Supplier<@NotNull Item> jarItemLazy, + @Nullable Set allowedBiomes + ) { + public ButterflyEntry( + int id, + @NotNull String name, + double weight, + @NotNull Supplier<@NotNull Item> jarItemLazy, + Biome... allowedBiomes + ) { + this(id, name, weight, jarItemLazy, allowedBiomes.length == 0 ? null : Set.of(allowedBiomes)); } - public ButterflyEntry addAllowedBiome(Biome biome) { - if (this.allowedBiomes == null) this.allowedBiomes = new HashSet<>(); - this.allowedBiomes.add(biome); - return this; + public @NotNull Item jarItem() { return this.jarItemLazy.get(); } + public boolean isBiomeAllowed(Biome biome) { + return this.allowedBiomes == null || this.allowedBiomes.contains(biome); } + } - public ButterflyEntry removeAllowedBiome(Biome biome) { - if (this.allowedBiomes == null) this.allowedBiomes = new HashSet<>(); - this.allowedBiomes.remove(biome); - return this; - } - public ButterflyEntry allowAllBiomes() { - this.allowedBiomes = null; - return this; - } + @Override + public boolean canBeCapturedBy(@NotNull Item item) { + return item instanceof ItemJar; + } - public boolean isBiomeAllowed(Biome biome) { - return this.allowedBiomes == null || this.allowedBiomes.contains(biome); - } + @Override + public void onSingularCaptured() { + this.remove(); } } diff --git a/game/core/src/main/java/net/minecraft/core/entity/animal/MobFireflyCluster.java b/game/core/src/main/java/net/minecraft/core/entity/animal/MobFireflyCluster.java index 6b05f57ac..325eec7b6 100644 --- a/game/core/src/main/java/net/minecraft/core/entity/animal/MobFireflyCluster.java +++ b/game/core/src/main/java/net/minecraft/core/entity/animal/MobFireflyCluster.java @@ -6,8 +6,11 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import net.minecraft.core.block.Blocks; import net.minecraft.core.block.tag.BlockTags; import net.minecraft.core.entity.Entity; +import net.minecraft.core.entity.ICapturable; import net.minecraft.core.entity.MobFlying; import net.minecraft.core.enums.LightLayer; +import net.minecraft.core.item.Item; +import net.minecraft.core.item.ItemJar; import net.minecraft.core.util.helper.DamageType; import net.minecraft.core.util.helper.MathHelper; import net.minecraft.core.world.World; @@ -20,7 +23,7 @@ import java.util.Collection; import java.util.List; public class MobFireflyCluster extends MobFlying - implements AmbientCreature { + implements AmbientCreature, ICapturable { public static final int DATA_COLOR_ID = 16; public static final int DATA_CLUSTER_SIZE_ID = 17; public static final int DATA_COUNT_ID = 18; @@ -412,6 +415,26 @@ public class MobFireflyCluster extends MobFlying return true; } + + @Override + public boolean canBeCapturedBy(@NotNull Item item) { + return item instanceof ItemJar; + } + + @Override + public int onCaptured(int amount, boolean acceptPartial) { + if (amount < 1) return 0; + + int count = this.getFireflyCount(); + if (!acceptPartial && amount > count) return 0; + + count -= amount; + this.setFireflyCount(count); + if (count == 0) this.remove(); + + return count; + } + public static class FireflyColor { public static Int2ObjectMap fireFlyColors = new Int2ObjectArrayMap<>(); public static FireflyColor GREEN = register(new FireflyColor(0, "fireflyGreen", new Biome[]{ diff --git a/game/core/src/main/java/net/minecraft/core/entity/player/Player.java b/game/core/src/main/java/net/minecraft/core/entity/player/Player.java index bbc257449..b28e6ac3a 100644 --- a/game/core/src/main/java/net/minecraft/core/entity/player/Player.java +++ b/game/core/src/main/java/net/minecraft/core/entity/player/Player.java @@ -59,6 +59,9 @@ import net.minecraft.core.world.chunk.ChunkCoordinates; import net.minecraft.core.world.chunk.provider.ChunkProvider; import net.minecraft.core.world.pos.TilePos; import net.minecraft.core.world.pos.TilePosc; +import net.minecraft.core.world.type.WorldType; +import net.minecraft.core.world.type.WorldTypes; +import net.minecraft.core.world.type.tag.WorldTypeTags; import net.minecraft.core.world.weather.Weathers; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -1635,28 +1638,36 @@ public abstract class Player double oneFifthOfRadius = maxRadius * 0.2; double threeFifthsOfRadius = maxRadius * 0.6; + boolean isNether = player.world.getWorldType().hasTag(WorldTypeTags.NETHER); + float randomizedPitch = 0.8F + (this.world.rand.nextFloat() - this.world.rand.nextFloat()) * 0.45F; if (distance <= oneFifthOfRadius) { this.world.playSoundEffect(player, SoundCategory.WORLD_SOUNDS, ventCoordinateX, ventCoordinateY, ventCoordinateZ, "tile.crumble", 20.0F, randomizedPitch); - this.world.playSoundEffect(player, SoundCategory.WORLD_SOUNDS, - ventCoordinateX, ventCoordinateY, ventCoordinateZ, - "tile.deepboom", 20.0F, randomizedPitch); + if(isNether) { + this.world.playSoundEffect(player, SoundCategory.WORLD_SOUNDS, + ventCoordinateX, ventCoordinateY, ventCoordinateZ, + "tile.deepboom", 20.0F, randomizedPitch); + } } else if (distance <= threeFifthsOfRadius) { this.world.playSoundEffect(player, SoundCategory.WORLD_SOUNDS, ventCoordinateX, ventCoordinateY, ventCoordinateZ, "tile.deepcrumble", 20.0F, randomizedPitch); - this.world.playSoundEffect(player, SoundCategory.WORLD_SOUNDS, - ventCoordinateX, ventCoordinateY, ventCoordinateZ, - "tile.deepquietboom", 20.0F, randomizedPitch); + if(isNether) { + this.world.playSoundEffect(player, SoundCategory.WORLD_SOUNDS, + ventCoordinateX, ventCoordinateY, ventCoordinateZ, + "tile.deepquietboom", 20.0F, randomizedPitch); + } } else { - this.world.playSoundEffect(player, SoundCategory.WORLD_SOUNDS, - ventCoordinateX, ventCoordinateY, ventCoordinateZ, - "tile.deepquietboom", 20.0F, randomizedPitch); + if(isNether) { + this.world.playSoundEffect(player, SoundCategory.WORLD_SOUNDS, + ventCoordinateX, ventCoordinateY, ventCoordinateZ, + "tile.deepquietboom", 20.0F, randomizedPitch); + } } } diff --git a/game/core/src/main/java/net/minecraft/core/item/IAccumulatable.java b/game/core/src/main/java/net/minecraft/core/item/IAccumulatable.java new file mode 100644 index 000000000..37a4d2409 --- /dev/null +++ b/game/core/src/main/java/net/minecraft/core/item/IAccumulatable.java @@ -0,0 +1,181 @@ +package net.minecraft.core.item; + +import net.minecraft.core.block.Block; +import net.minecraft.core.block.BlockLogic; +import net.minecraft.core.block.Blocks; +import net.minecraft.core.block.entity.TileEntityActivator; +import net.minecraft.core.entity.player.Player; +import net.minecraft.core.enums.EnumBlockSoundEffectType; +import net.minecraft.core.util.helper.Direction; +import net.minecraft.core.util.helper.Side; +import net.minecraft.core.world.World; + +import java.util.Random; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.joml.primitives.AABBd; +import org.joml.primitives.AABBdc; + +import net.minecraft.core.world.pos.TilePos; +import net.minecraft.core.world.pos.TilePosc; + +public interface IAccumulatable extends IPlaceable.PlaceableBlock { + + boolean canAccumulateInto( + @NotNull ItemStack selfStack, + @NotNull Block block, int data, @NotNull Side side, double xHit, double yHit); + + /** + * @param result out parameter, .block and .data are by default the current block and data at position + */ + @NotNull BlockDataResult getAccumulationResult( + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc tilePos, + @NotNull Side side, double xHit, double yHit, + @NotNull BlockDataResult result); + + default void postAccumulate( + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc tilePos, + @NotNull Side side, double xHit, double yHit, + @NotNull BlockDataResult result + ) {} + + public static class BlockDataResult { + public @NotNull Block block; + public int data; + public boolean doRawPlacing; + public boolean shouldUpdateNeighbors; + public boolean shouldConsumeItem; + public boolean shouldPlaySound; + public final @NotNull AABBd bounds; + + public BlockDataResult() { + this(new AABBd().set(INVALID_BB)); + } + public BlockDataResult(@NotNull AABBd bounds) { + this.bounds = bounds; + this.reset(); + } + + public void reset() { + this.block = Blocks.AIR; + this.data = 0; + this.doRawPlacing = false; + this.shouldUpdateNeighbors = true; + this.shouldConsumeItem = true; + this.shouldPlaySound = true; + this.removeBounds(); + } + + public void removeBounds() { + this.bounds.set(INVALID_BB); + } + + private static final @NotNull AABBdc INVALID_BB = new AABBd( + Double.POSITIVE_INFINITY,Double.POSITIVE_INFINITY,Double.POSITIVE_INFINITY, + Double.NEGATIVE_INFINITY,Double.NEGATIVE_INFINITY,Double.NEGATIVE_INFINITY); + } + + @Override + default boolean placeOnBlock( + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, + @NotNull Side side, double xHit, double yHit + ) { + return this.placeOnBlockAccumulatable(true, selfStack, world, player, blockPos, side, xHit, yHit); + } + + @Override + default void placeByActivator( + @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()); + this.placeOnBlockAccumulatable(false, selfStack, world, null, blockPos, direction.opposite().side(), Double.NaN, Double.NaN); + } + + @Override + default boolean placeWithoutShift( + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, + @NotNull Side side, double xHit, double yHit + ) { + return this.placeOnBlockAccumulatable(false, selfStack, world, player, blockPos, side, xHit, yHit); + } + + static boolean defaultPlaceWithoutShift( + @NotNull IAccumulatable self, + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, + @NotNull Side side, double xHit, double yHit + ) { + if (!self.canPlaceDirectlyAtPosition(selfStack, world, player, blockPos, side, xHit, yHit)) return false; + + final int meta = self.getPlacedData(selfStack, world, player, blockPos, side, xHit, yHit); + return self.placeDirectly(selfStack, world, player, blockPos, meta, side, xHit, yHit); + } + + default boolean placeOnBlockAccumulatable( + boolean shift, + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc tilePos, + @NotNull Side side, double xHit, double yHit + ) { + if (selfStack.stackSize <= 0) return false; + + var block = world.getBlockType(tilePos); + var data = world.getBlockData(tilePos); + + if (!this.canAccumulateInto(selfStack, block, data, side, xHit, yHit)) { + if (!this.shouldShiftOutOf(selfStack, world, player, tilePos, side, xHit, yHit)) + return defaultPlaceWithoutShift(this, selfStack, world, player, tilePos, side, xHit, yHit); + if (!shift) return false; + + tilePos = tilePos.add(side, new TilePos()); + yHit -= side.offsetY(); + xHit -= side.offsetX() + side.offsetZ(); + block = world.getBlockType(tilePos); + data = world.getBlockData(tilePos); + + if (!this.canAccumulateInto(selfStack, block, data, side, xHit, yHit)) + return defaultPlaceWithoutShift(this, selfStack, world, player, tilePos, side, xHit, yHit); + } + + interface ctx { + BlockDataResult result = new BlockDataResult(); + AABBd queryBB = new AABBd(); + } + synchronized(ctx.result) { + ctx.result.reset(); + ctx.result.block = block; + ctx.result.data = data; + + final var result = this.getAccumulationResult(selfStack, world, player, tilePos, side, xHit, yHit, ctx.result); + + if (result.bounds.isValid()) { + ctx.queryBB.set(result.bounds).translate(tilePos.x(), tilePos.y(), tilePos.z()); + if (!world.checkIfAABBIsClear(ctx.queryBB)) return false; + } + + final boolean placed = (result.doRawPlacing) + ? world.setBlockTypeDataRaw(tilePos, result.block, result.data) + : world.setBlockTypeData(tilePos, result.block, result.data); + if (!placed) return false; + + if (result.shouldConsumeItem) selfStack.consumeItem(player); + + this.postAccumulate(selfStack, world, player, tilePos, side, xHit, yHit, result); + if (result.shouldUpdateNeighbors) world.notifyBlockChange(tilePos, block); + + if (result.shouldPlaySound) world.playBlockSoundEffect(player, + tilePos.x() + 0.5F, tilePos.y() + 0.5F, tilePos.z() + 0.5F, + block, EnumBlockSoundEffectType.PLACE); + + return true; + } + } +} diff --git a/game/core/src/main/java/net/minecraft/core/item/IPlaceable.java b/game/core/src/main/java/net/minecraft/core/item/IPlaceable.java new file mode 100644 index 000000000..77015e3a6 --- /dev/null +++ b/game/core/src/main/java/net/minecraft/core/item/IPlaceable.java @@ -0,0 +1,162 @@ +package net.minecraft.core.item; + +import java.util.Random; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.core.block.Block; +import net.minecraft.core.block.BlockLogic; +import net.minecraft.core.block.entity.TileEntityActivator; +import net.minecraft.core.block.tag.BlockTags; +import net.minecraft.core.entity.player.Player; +import net.minecraft.core.enums.EnumBlockSoundEffectType; +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; + +public interface IPlaceable { + boolean shouldShiftOutOf( + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, + @NotNull Side side, double xHit, double yHit + ); + + boolean canPlaceDirectlyAtPosition( + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, + @NotNull Side side, double xHit, double yHit + ); + + public static boolean shouldShiftBlockOutOf( + @NotNull Block block, @NotNull World world, @NotNull TilePosc blockPos + ) { + if (!world.canPlaceInsideBlock(blockPos)) return true; + return block.hasTag(BlockTags.PLACE_OVERWRITES) && + block == world.getBlockType(blockPos); + } + + public static boolean canPlaceBlockDirectlyAtPosition( + @NotNull Block block, @NotNull World world, + @NotNull TilePosc blockPos, @NotNull Side side + ) { + return world.canBlockIdBePlacedAt(block.id(), blockPos, false, side); + } + + boolean placeWithoutShift( + @NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, + @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit + ); + + default boolean placeOnBlock( + @NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, + @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit + ) { + if (this.shouldShiftOutOf(selfStack, world, player, blockPos, side, xHit, yHit)) blockPos = blockPos.add(side.direction(), new TilePos()); + return this.placeWithoutShift(selfStack, world, player, blockPos, side, xHit, yHit); + } + + default void placeByActivator( + @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 = new TilePos(blockPos).add(direction); + this.placeWithoutShift(selfStack, world, null, blockPos, direction.side().opposite(), 0.5f, 0.5f); + } + + public static interface PlaceableBlock extends IPlaceable { + @NotNull Block getBlock(); + + @Override + default boolean shouldShiftOutOf( + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, + @NotNull Side side, double xHit, double yHit + ) { + return shouldShiftBlockOutOf(this.getBlock(), world, blockPos); + } + + @Override + default boolean canPlaceDirectlyAtPosition( + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, + @NotNull Side side, double xHit, double yHit + ) { + return canPlaceBlockDirectlyAtPosition(this.getBlock(), world, blockPos, side); + } + + default boolean placeWithMeta( + @NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, + @NotNull TilePosc blockPos, int meta, @NotNull Side side, double xHit, double yHit + ) { + if (this.shouldShiftOutOf(selfStack, world, player, blockPos, side, xHit, yHit)) blockPos = blockPos.add(side.direction(), new TilePos()); + if (!this.canPlaceDirectlyAtPosition(selfStack, world, player, blockPos, side, xHit, yHit)) return false; + + return this.placeDirectly(selfStack, world, player, blockPos, meta, side, xHit, yHit); + } + + default int getPlacedData( + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, + @NotNull Side side, double xHit, double yHit + ) { + return this.getBlock().getPlacedData(player, selfStack, world, blockPos, side, xHit, yHit); + } + + @Override + default boolean placeWithoutShift( + @NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, + @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit + ) { + if (!this.canPlaceDirectlyAtPosition(selfStack, world, player, blockPos, side, xHit, yHit)) return false; + + final int meta = this.getPlacedData(selfStack, world, player, blockPos, side, xHit, yHit); + return this.placeDirectly(selfStack, world, player, blockPos, meta, side, xHit, yHit); + } + + default boolean placeDirectly( + @NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, + @NotNull TilePosc blockPos, int meta, @NotNull Side side, double xHit, double yHit + ) { + if (selfStack.stackSize <= 0) return false; + final var pbloc = world.getBlockType(blockPos); + final int pdata = world.getBlockData(blockPos); + + final var selfBlock = this.getBlock(); + + if (!world.setBlockTypeDataRaw(blockPos, selfBlock, meta)) return false; + + if (pbloc != selfBlock || pdata != meta) { + pbloc.onRemoved(world, blockPos, pdata); + } + + selfStack.consumeItem(player); + + if (player == null) { + selfBlock.onPlacedOnSide(world, blockPos, side, xHit, yHit); + } else { + selfBlock.onPlacedByMob(world, blockPos, side, player, xHit, yHit); + } + + selfBlock.onPlacedByWorld(world, blockPos); + + if (selfBlock.isEntityTile && selfStack.getData().containsKey("tileEntityData")) { + final var tileEntity = world.getTileEntity(blockPos); + if (tileEntity != null) { + tileEntity.readAdditionalData(selfStack.getData().getCompound("tileEntityData")); + } + } + + world.notifyBlockChange(blockPos, selfBlock); + world.playBlockSoundEffect( + player, + blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, + selfBlock, EnumBlockSoundEffectType.PLACE + ); + return true; + } + } +} diff --git a/game/core/src/main/java/net/minecraft/core/item/Item.java b/game/core/src/main/java/net/minecraft/core/item/Item.java index 5434bbcdd..1ff7f6a8c 100644 --- a/game/core/src/main/java/net/minecraft/core/item/Item.java +++ b/game/core/src/main/java/net/minecraft/core/item/Item.java @@ -216,6 +216,14 @@ public class Item implements ITaggable, IItemConvertible { return this.maxDamage; } + public boolean interactsWithFluid(@NotNull ItemStack selfStack) { + return false; + } + + public boolean interactsWithEntity(@NotNull ItemStack selfStack, @NotNull Entity entity) { + return entity.isSelectable(); + } + @Deprecated public final boolean onUseItemOnBlock(@NotNull final ItemStack selfStack, @Nullable final Player player, @NotNull final World world, final int blockX, final int blockY, final int blockZ, @NotNull final Side side, final double xPlaced, final double yPlaced) { return onUseOnBlock(selfStack, world, player, new TilePos(blockX, blockY, blockZ), side, xPlaced, yPlaced); 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 04610b5b2..6387080f1 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 @@ -3,7 +3,6 @@ package net.minecraft.core.item; import net.minecraft.core.block.BlockLogicBed; import net.minecraft.core.block.Blocks; import net.minecraft.core.entity.player.Player; -import net.minecraft.core.enums.EnumBlockSoundEffectType; import net.minecraft.core.util.helper.Direction; import net.minecraft.core.util.helper.Side; import net.minecraft.core.world.World; @@ -12,47 +11,41 @@ import net.minecraft.core.world.pos.TilePosc; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class ItemBed extends Item { - +public class ItemBed extends ItemPlaceablePair { public ItemBed(@NotNull String name, @NotNull String namespaceId, int id) { - super(name, namespaceId, id); + super(name, namespaceId, id, Blocks.BED, Blocks.BED); } - @Override - public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) { - if (selfStack.stackSize <= 0) return false; - TilePosc pos1 = blockPos; - if (!world.canPlaceInsideBlock(pos1)) { - pos1 = new TilePos(pos1).add(side.direction()); - } - final 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 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; - - - final boolean isPlaced1 = - world.setBlockTypeData(pos1, Blocks.BED, dir.legacyIndex()); - final boolean isPlaced2 = isPlaced1 && - world.setBlockTypeData(pos2, Blocks.BED, dir.legacyIndex() | BlockLogicBed.IS_HEAD.set(0, 1)); - if (!isPlaced2) { - if (isPlaced1) world.setBlockType(pos1, Blocks.AIR); - return false; - } - selfStack.consumeItem(player); + public static @NotNull Direction getDirection(@Nullable Player player, @NotNull Side side) { + return (player != null) + ? player.getHorizontalPlacementDirection(null).opposite() + : (side.isHorizontal()) ? side.direction : Direction.NORTH; + } - world.markBlockNeedsUpdate(pos1); - world.markBlockNeedsUpdate(pos2); - world.notifyBlocksInCapsuleOfNeighborChange(dir.opposite(), pos1, Blocks.BED); + @Override + protected @NotNull PlacementResult getPlacement( + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, + @NotNull Side side, double xHit, double yHit, + @NotNull PlacementResult result + ) { + final var dir = getDirection(player, side); + result.dataA = result.dataB = dir.legacyIndex(); + result.dataB = BlockLogicBed.IS_HEAD.set(result.dataB, 1); + dir.getOffset(result.offsetB); + result.offsetB.mul(-1); + return result; + } - world.playBlockSoundEffect(player, pos1.x() + 0.5F, pos1.y() + 0.5F, pos1.z() + 0.5F, Blocks.BED, EnumBlockSoundEffectType.PLACE); - return true; + @Override + public boolean canPlaceDirectlyAtPosition( + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, + @NotNull Side side, double xHit, double yHit + ) { + final var dir = getDirection(player, side); + return + IPlaceable.canPlaceBlockDirectlyAtPosition(blockA, world, blockPos, side) && + IPlaceable.canPlaceBlockDirectlyAtPosition(blockB, world, blockPos.sub(dir, new TilePos()), side); } } 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 2d2785f6e..3dbc3b892 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 @@ -7,6 +7,8 @@ import net.minecraft.core.block.Blocks; import net.minecraft.core.block.entity.TileEntityActivator; import net.minecraft.core.block.tag.BlockTags; import net.minecraft.core.data.tag.Tag; +import net.minecraft.core.entity.Entity; +import net.minecraft.core.entity.Mob; import net.minecraft.core.entity.animal.MobCow; import net.minecraft.core.entity.player.Player; import net.minecraft.core.enums.EnumDropCause; @@ -18,6 +20,7 @@ import net.minecraft.core.util.helper.Side; import net.minecraft.core.util.phys.HitResult; import net.minecraft.core.world.LevelListener; import net.minecraft.core.world.World; +import net.minecraft.core.world.type.tag.WorldTypeTags; import net.minecraft.core.world.pos.TilePos; import net.minecraft.core.world.pos.TilePosc; import org.jetbrains.annotations.NotNull; @@ -29,6 +32,15 @@ import java.util.function.BiConsumer; public abstract class ItemBucket extends ItemFood implements IItemContainer { + /** + * Resolves the item texture basename for a bucket state (e.g. {@code water} vs {@code waterboiling}). + * Return {@code defaultName} to use the state's default texture. + */ + @FunctionalInterface + public interface TextureStateName { + @NotNull String resolve(@Nullable Entity entity, @Nullable World world, @NotNull ItemStack stack, @NotNull String defaultName); + } + public record BucketState( String name, boolean isEdible, @@ -38,39 +50,52 @@ public abstract class ItemBucket extends ItemFood implements IItemContainer { @Nullable Tag> pickupTag, boolean canPlace, @Nullable String soundPath, - @Nullable BiConsumer placementAction + @Nullable BiConsumer placementAction, + @Nullable TextureStateName textureStateName ) { /** * Constructor for Empty/Placeholder states */ public BucketState(String name) { - this(name, false, 0, 0, null, null, false, null, null); + this(name, false, 0, 0, null, null, false, null, null, null); } /** * Constructor for Food/Edible Buckets (Non-placeable) */ public BucketState(String name, int healAmount, int ticksPerHeal) { - this(name, true, healAmount, ticksPerHeal, null, null, false, null, null); + this(name, true, healAmount, ticksPerHeal, null, null, false, null, null, null); } /** * Constructor for Fluids */ public BucketState(String name, Block fluidBlock, Tag> pickupTag, String soundPath) { - this(name, false, 0, 0, fluidBlock, pickupTag, true, soundPath, null); + this(name, false, 0, 0, fluidBlock, pickupTag, true, soundPath, null, null); + } + /** + * Constructor for Fluids with a conditional item texture + */ + public BucketState(String name, Block fluidBlock, Tag> pickupTag, String soundPath, @Nullable TextureStateName textureStateName) { + this(name, false, 0, 0, fluidBlock, pickupTag, true, soundPath, null, textureStateName); } /** * Constructor for Fluids with custom action */ - public BucketState(String name, Block fluidBlock, Tag> pickupTag, String soundPath, BiConsumer placementAction) { - this(name, false, 0, 0, fluidBlock, pickupTag, true, soundPath, placementAction); + public BucketState(String name, Block fluidBlock, Tag> pickupTag, String soundPath, BiConsumer placementAction) { + this(name, false, 0, 0, fluidBlock, pickupTag, true, soundPath, placementAction, null); + } + /** + * Constructor for Fluids with custom action and conditional item texture + */ + public BucketState(String name, Block fluidBlock, Tag> pickupTag, String soundPath, BiConsumer placementAction, @Nullable TextureStateName textureStateName) { + this(name, false, 0, 0, fluidBlock, pickupTag, true, soundPath, placementAction, textureStateName); } /** * Constructor for Edible and Placeable Buckets */ public BucketState(String name, int healAmount, int ticksPerHeal, Block fluidBlock, Tag> pickupTag, String soundPath) { - this(name, true, healAmount, ticksPerHeal, fluidBlock, pickupTag, true, soundPath, null); + this(name, true, healAmount, ticksPerHeal, fluidBlock, pickupTag, true, soundPath, null, null); } } @@ -91,7 +116,8 @@ public abstract class ItemBucket extends ItemFood implements IItemContainer { "water", Blocks.FLUID_WATER_FLOWING, BlockTags.IS_WATER, - "liquid.splash" + "liquid.splash", + ItemBucket::resolveWaterTextureStateName )); registerState(STATE_LAVA, new BucketState( @@ -141,6 +167,28 @@ public abstract class ItemBucket extends ItemFood implements IItemContainer { return id.value(); } + private static @NotNull String resolveWaterTextureStateName(final @Nullable Entity entity, final @Nullable World world, final @NotNull ItemStack stack, final @NotNull String defaultName) { + final World context = entity != null ? entity.world : world; + if (context != null && context.getWorldType().hasTag(WorldTypeTags.NETHER)) { + return "waterboiling"; + } + return defaultName; + } + + public static @NotNull String getTextureStateName(final @Nullable Entity entity, final @NotNull ItemStack stack) { + return getTextureStateName(entity, entity != null ? entity.world : null, stack); + } + + public static @NotNull String getTextureStateName(final @Nullable Entity entity, final @Nullable World world, final @NotNull ItemStack stack) { + final NamespaceID stateId = getState(stack); + final BucketState state = getBucketState(stateId); + final String defaultName = getStateName(stateId); + if (state.textureStateName() != null) { + return state.textureStateName().resolve(entity, world, stack, defaultName); + } + return defaultName; + } + public static Set getRegisteredStateIds() { return STATE_REGISTRY.keySet(); } @@ -188,49 +236,83 @@ public abstract class ItemBucket extends ItemFood implements IItemContainer { } @Override - public ItemStack onUse(@NotNull ItemStack itemStack, @NotNull World world, @NotNull Player player) { - NamespaceID currentStateId = getState(itemStack); - BucketState currentState = getBucketState(currentStateId); + public boolean interactsWithFluid(@NotNull ItemStack selfStack) { + final NamespaceID currentStateId = getState(selfStack); + final BucketState currentState = getBucketState(currentStateId); + if (!currentState.canPlace() && currentState.isEdible()) return false; + return STATE_EMPTY.equals(currentStateId) || getCharges(selfStack) < this.maxCharges; + } - if (currentState.isEdible() && !currentState.canPlace()) { - return handleAirClick(itemStack, world, player); - } + @Override + public boolean interactsWithEntity(@NotNull ItemStack selfStack, @NotNull Entity entity) { + if (!super.interactsWithEntity(selfStack, entity)) return false; + final NamespaceID currentStateId = getState(selfStack); + final BucketState currentState = getBucketState(currentStateId); + return currentState.canPlace() || !currentState.isEdible(); + } - double reachDistance = player.getGamemode().getBlockReachDistance(); - HitResult hitResultFluid = player.rayCast(reachDistance, 1f, true, false, false); + @Override + public boolean useOnEntity(@NotNull ItemStack selfStack, @NotNull Player player, @NotNull Mob mob) { + NamespaceID currentStateId = getState(selfStack); + BucketState currentState = getBucketState(currentStateId); - if (hitResultFluid == null) { - return handleAirClick(itemStack, world, player); - } else if (hitResultFluid instanceof HitResult.Entity) { - return handleEntityClick(itemStack, world, player); - } else if (hitResultFluid instanceof HitResult.Tile hitTileFluid) { - TilePosc tilePos = hitTileFluid.tilePos; - boolean isSourceBlock = world.getBlockData(tilePos) == 0; + if (currentState.isEdible() && !currentState.canPlace()) return false; - if (isSourceBlock) { - NamespaceID targetStateId = getFluidStateAt(world, tilePos); + final int oldSize = selfStack.stackSize; + var newStack = handleEntityClick(selfStack, mob.world, player, mob); + if (newStack.stackSize <= 0) newStack = null; - boolean isEmptyScoop = STATE_EMPTY.equals(currentStateId); - boolean isRefillScoop = currentStateId.equals(targetStateId) && getCharges(itemStack) < this.maxCharges; + final boolean isDifferent = oldSize != newStack.stackSize || newStack != selfStack; + if (isDifferent) player.inventory.setItem(player.inventory.getCurrentSlot(), newStack); + return isDifferent; + } + + @Override + public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) { + final NamespaceID currentStateId = getState(selfStack); + final BucketState currentState = getBucketState(currentStateId); + + if (currentState.isEdible() && !currentState.canPlace()) return false; + + final int oldSize = selfStack.stackSize; + @Nullable ItemStack newStack; + + interact: { + if (world.getBlockData(tilePos) == 0) { + final NamespaceID targetStateId = getFluidStateAt(world, tilePos); + + final boolean isEmptyScoop = STATE_EMPTY.equals(currentStateId); + final boolean isRefillScoop = !isEmptyScoop && + currentStateId.equals(targetStateId) && getCharges(selfStack) < this.maxCharges; + if (targetStateId != null && (isEmptyScoop || isRefillScoop)) { - return tryPickupFluid(itemStack, world, player, tilePos, targetStateId); + newStack = tryPickupFluid(selfStack, world, player, tilePos, targetStateId); + break interact; } } - + if (currentState.canPlace()) { - NamespaceID aimedFluid = getFluidStateAt(world, tilePos); - if (currentStateId.equals(aimedFluid) && getCharges(itemStack) < this.maxCharges) { - return itemStack; + final NamespaceID aimedFluid = getFluidStateAt(world, tilePos); + if (currentStateId.equals(aimedFluid) && getCharges(selfStack) < this.maxCharges) { + newStack = selfStack; + break interact; } - HitResult hitResultNoFluid = player.rayCast(reachDistance, 1f, false, false, false); - if (hitResultNoFluid instanceof HitResult.Tile hitTileNoFluid) { - return tryPlaceFluid(itemStack, world, player, hitTileNoFluid); - } + newStack = tryPlaceFluid(selfStack, world, player, tilePos, side); + break interact; } + return false; } + final boolean isDifferent = oldSize != newStack.stackSize || newStack != selfStack; + if (isDifferent) player.inventory.setItem(player.inventory.getCurrentSlot(), newStack); + + return isDifferent; + } + + @Override + public ItemStack onUse(@NotNull ItemStack itemStack, @NotNull World world, @NotNull Player player) { return handleAirClick(itemStack, world, player); } @@ -255,50 +337,38 @@ public abstract class ItemBucket extends ItemFood implements IItemContainer { } } - protected ItemStack tryPlaceFluid(ItemStack itemStack, World world, Player player, HitResult.Tile hitTile) { - TilePos rayCastPos = new TilePos(hitTile.tilePos); - if (!world.canMineBlock(player, rayCastPos)) return itemStack; + protected ItemStack tryPlaceFluid(@NotNull ItemStack itemStack, @NotNull World world, @NotNull Player player, @NotNull TilePosc tilePos, @NotNull Side side) { + if (!world.canMineBlock(player, tilePos)) return itemStack; + + final NamespaceID stateId = getState(itemStack); + final BucketState bucketState = getBucketState(stateId); + if (bucketState.fluidBlock() == null) return itemStack; - Block blockAtPos = world.getBlockType(rayCastPos); + final var blockAtPos = world.getBlockType(tilePos); if (!blockAtPos.hasTag(BlockTags.PLACE_OVERWRITES) && !blockAtPos.hasTag(BlockTags.BROKEN_BY_FLUIDS)) { - Side side = hitTile.side; - rayCastPos.x += side.offsetX(); - rayCastPos.y += side.offsetY(); - rayCastPos.z += side.offsetZ(); + tilePos = tilePos.add(side, new TilePos()); } - if (rayCastPos.y < 0 || rayCastPos.y >= world.getHeightBlocks()) return itemStack; - - if (world.isAirBlock(rayCastPos) || !world.getBlockMaterial(rayCastPos).isSolid()) { - NamespaceID stateId = getState(itemStack); - BucketState bucketState = getBucketState(stateId); - - if (bucketState.fluidBlock() != null) { - if (bucketState.soundPath() != null) { - world.playSoundEffect(player, SoundCategory.WORLD_SOUNDS, rayCastPos.x + 0.5F, rayCastPos.y + 0.5F, rayCastPos.z + 0.5F, bucketState.soundPath(), 1f, 1f); - } + if (!world.canBlockIdBePlacedAt(bucketState.fluidBlock().id(), tilePos, true, side)) return itemStack; - if (bucketState.placementAction() != null) { - bucketState.placementAction().accept(world, rayCastPos); - } + if (bucketState.placementAction() != null) bucketState.placementAction().accept(world, tilePos); - final Block replacedBlock = world.getBlockType(rayCastPos); - final int replacedData = world.getBlockData(rayCastPos); + final Block replacedBlock = world.getBlockType(tilePos); + final int replacedData = world.getBlockData(tilePos); - world.setBlockTypeNotify(rayCastPos, bucketState.fluidBlock()); + if (!world.setBlockTypeNotify(tilePos, bucketState.fluidBlock())) return itemStack; - if (!(replacedBlock == Blocks.AIR)) { - replacedBlock.dropWithCause(world, EnumDropCause.WORLD, rayCastPos, replacedData, null, null); - } + replacedBlock.dropWithCause(world, EnumDropCause.WORLD, tilePos, replacedData, null, null); - player.swingItem(); + if (player.getGamemode().hasBlockConsumption()) { + setCharges(itemStack, getCharges(itemStack) - 1); + if (getCharges(itemStack) == 0) setState(itemStack, STATE_EMPTY); + } - if (player.getGamemode().hasBlockConsumption()) { - setCharges(itemStack, getCharges(itemStack) - 1); - if (getCharges(itemStack) == 0) setState(itemStack, STATE_EMPTY); - } - } + if (bucketState.soundPath() != null) { + world.playSoundEffect(player, SoundCategory.WORLD_SOUNDS, tilePos.x() + 0.5F, tilePos.y() + 0.5F, tilePos.z() + 0.5F, bucketState.soundPath(), 1f, 1f); } + return itemStack; } @@ -310,7 +380,7 @@ public abstract class ItemBucket extends ItemFood implements IItemContainer { return itemStack; } - protected ItemStack handleEntityClick(ItemStack itemStack, World world, Player player) { + protected ItemStack handleEntityClick(@NotNull ItemStack itemStack, @NotNull World world, @NotNull Player player, @NotNull Entity mob) { return handleAirClick(itemStack, world, player); } 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 c12f48bc1..73777cce1 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 @@ -18,126 +18,76 @@ import org.jetbrains.annotations.Nullable; import java.util.Random; -public class ItemDoor extends Item { - protected final @NotNull Block doorBlockBottom; - protected final @NotNull Block doorBlockTop; - +public class ItemDoor extends ItemPlaceablePair { public ItemDoor(@NotNull String name, @NotNull String namespaceId, int id, @NotNull Block doorBlockBottom, @NotNull Block doorBlockTop) { - super(name, namespaceId, id); - this.maxStackSize = 64; - this.doorBlockBottom = doorBlockBottom; - this.doorBlockTop = doorBlockTop; + super(name, namespaceId, id, doorBlockBottom, doorBlockTop); } @Override - 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.direction(), new TilePos()); - } - - if (!world.canBlockIdBePlacedAt(this.doorBlockBottom.id(), blockPos, false, side)) return false; - - Direction leftDir = player.getHorizontalPlacementDirection(side).rotateY(1); - int meta = leftDir.legacyIndex(); - + protected @NotNull PlacementResult getPlacement(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit, @NotNull PlacementResult result) { final var upperPos = blockPos.up(new TilePos()); - int isSolidBlockLeft = (isSupported(world, blockPos, leftDir, false) ? 1 : 0) + (isSupported(world, upperPos, leftDir, false) ? 1 : 0); - int isSolidBlockRight = (isSupported(world, blockPos, leftDir.opposite(), true) ? 1 : 0) + (isSupported(world, upperPos, 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; + final Direction leftDir; + if (player != null) leftDir = player.getHorizontalPlacementDirection(side).rotateY(1); + else { + var dir = side.direction.opposite(); + if (!dir.isHorizontal()) dir = Direction.NORTH; + leftDir = dir.rotateY(1); + } + final int isSolidBlockLeft = + (isSupported(world, blockPos, leftDir, false) ? 1 : 0) + + (isSupported(world, upperPos, leftDir, false) ? 1 : 0); + final int isSolidBlockRight = + (isSupported(world, blockPos, leftDir.opposite(), true) ? 1 : 0) + + (isSupported(world, upperPos, leftDir.opposite(), true) ? 1 : 0); + + final var query = new TilePos(); + final boolean isDoorLeft = + world.getBlockType(blockPos.add(leftDir, query)) == this.blockA || + world.getBlockType(blockPos.add(leftDir, query).up()) == this.blockB; + final boolean isDoorRight = + world.getBlockType(blockPos.sub(leftDir, query)) == this.blockA || + world.getBlockType(blockPos.sub(leftDir, query).up()) == this.blockB; + + final boolean isMirrored; if (isDoorLeft && !isDoorRight) { isMirrored = (world.getBlockData(blockPos.add(leftDir, new TilePos())) & BlockLogicDoor.MASK_HINGE) == 0; } else if (isSolidBlockLeft <= 0 || side.direction() != leftDir.opposite()) { - if (isSolidBlockRight > 0 && side.direction() == leftDir) { - isMirrored = true; - } else if (isSolidBlockRight > isSolidBlockLeft) { - isMirrored = true; - } - } + isMirrored = + (isSolidBlockRight > 0 && side.direction() == leftDir) || + (isSolidBlockRight > isSolidBlockLeft); + } else isMirrored = false; + + int meta = leftDir.legacyIndex(); if (isMirrored) { - meta = meta - 1 & 0b11; - meta |= 0b100; - meta |= 0b1000; + meta -= 1; + meta &= 0b0011; + meta |= 0b1100; } meta |= (DyeColor.colorFromItemMeta(selfStack.getMetadata()).blockMeta) << 4 & 0xF0; - if (!this.doorBlockBottom.getLogic().canPlaceAt(world, blockPos, meta)) { - return false; + if (!((BlockLogicDoor)this.blockA.getLogic()).canPlaceAt(world, blockPos, meta)) { + result.cannotPlace = true; + return result; } - world.setBlockTypeData(blockPos, this.doorBlockBottom, meta); - world.setBlockTypeData(upperPos, this.doorBlockTop, meta); - selfStack.consumeItem(player); - - this.doorBlockBottom.onPlacedByMob(world, blockPos, side, player, xHit, yHit); - this.doorBlockTop.onPlacedByMob(world, upperPos, side, player, xHit, yHit); - - // 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.markBlockNeedsUpdate(blockPos); - world.markBlockNeedsUpdate(upperPos); - - world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, this.doorBlockBottom, EnumBlockSoundEffectType.PLACE); - return true; + result.dataA = result.dataB = meta; + result.offsetB.set(0, 1, 0); + return result; } public boolean isSupported(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Direction direction, boolean mirrored) { - ISupport support = world.getSupport(tilePos.add(direction, new TilePos()), direction.opposite().side()); - return support.canSupport(mirrored ? PartialSupport.INSTANCE.right() : PartialSupport.INSTANCE.left(), direction.side()); + return world + .getSupport(tilePos.add(direction, new TilePos()), direction.opposite().side()) + .canSupport(mirrored ? PartialSupport.INSTANCE.right() : PartialSupport.INSTANCE.left(), direction.side()); } @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 (!world.canPlaceInsideBlock(blockPos)) { - blockPos = blockPos.add(direction, new TilePos()); - } - - if (!direction.isHorizontal()) direction = Direction.NORTH; - Direction lefDir = direction.rotateY(1); - int meta = lefDir.legacyIndex(); - - 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.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.opposite()) { - if (isSolidBlockRight > 0 && direction == lefDir) { - isMirrored = true; - } else if (isSolidBlockRight > isSolidBlockLeft) { - isMirrored = true; - } - } - if (isMirrored) { - meta = meta - 1 & 0b11; - meta |= 0b100; - meta |= 0b1000; - } - meta |= (DyeColor.colorFromItemMeta(selfStack.getMetadata()).blockMeta) << 4 & 0xF0; - if (!this.doorBlockBottom.getLogic().canPlaceAt(world, blockPos, meta)) { - return; - } - - 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.side(), 0.5, 0.5); - this.doorBlockTop.onPlacedOnSide(world, blockPos.up(new TilePos()), direction.side(), 0.5, 0.5); - - 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); + public boolean canPlaceDirectlyAtPosition(@NotNull ItemStack selfStack, @NotNull World world, + @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) { + return + IPlaceable.canPlaceBlockDirectlyAtPosition(this.blockA, world, blockPos, side) && + IPlaceable.canPlaceBlockDirectlyAtPosition(this.blockA, world, blockPos, side); } } diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemJar.java b/game/core/src/main/java/net/minecraft/core/item/ItemJar.java index b2ec41d87..86da7cdc2 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemJar.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemJar.java @@ -1,20 +1,25 @@ package net.minecraft.core.item; import net.minecraft.core.block.Blocks; +import net.minecraft.core.block.entity.TileEntityActivator; import net.minecraft.core.entity.Entity; +import net.minecraft.core.entity.ICapturable; +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.util.helper.MathHelper; -import net.minecraft.core.util.helper.Side; +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 java.util.List; +import java.util.Random; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.joml.primitives.AABBd; -import java.util.List; - public class ItemJar extends ItemPlaceable { protected ItemJar(@NotNull String name, @NotNull String namespaceId, int id) { @@ -23,77 +28,83 @@ public class ItemJar extends ItemPlaceable { } @Override - 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 && player.isSneaking()) { - return super.onUseOnBlock(selfStack, world, player, blockPos, side, xHit, yHit); - } - if (player != null) { - int count = selfStack.stackSize; - ItemStack used = onUse(selfStack, world, player); - if (used != null && used.stackSize != count) { - return true; - } - } - return super.onUseOnBlock(selfStack, world, player, blockPos, side, xHit, yHit); + public boolean interactsWithEntity(@NotNull ItemStack selfStack, @NotNull Entity entity) { + return super.interactsWithEntity(selfStack, entity) || ( + entity instanceof ICapturable pokemon && pokemon.canBeCapturedBy(this) + ); } @Override - public @Nullable ItemStack onUse(@NotNull ItemStack selfStack, @NotNull World world, @NotNull Player player) { - if (player.isSneaking()) { - return selfStack; - } - List list = world.getEntitiesWithinAABBExcludingEntity(player, MathHelper.aabbGrow(player.bb, 2, 2, 2, new AABBd())); + public boolean useOnEntity(@NotNull ItemStack selfStack, @NotNull Player player, @NotNull Mob mob) { + final var captured = this.tryCaptureEntity(selfStack, player, mob); + if (captured == null) return false; + player.inventory.insertItem(captured, true); + if (captured.stackSize <= 0) return true; + player.world.dropItem(player.x, player.y + player.bbHeight, player.z, captured, 0.0); + return true; + } - for (Entity entity : list) { - if (entity instanceof MobFireflyCluster fireflyCluster) { - MobFireflyCluster.FireflyColor colour = fireflyCluster.getColor(); + @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 + ) { + final var pos = blockPos.add(direction, new TilePos()); + final @NotNull List entities; - boolean didFillJar; - if (colour == MobFireflyCluster.FireflyColor.BLUE) { - didFillJar = fillJar(player, new ItemStack(Items.LANTERN_FIREFLY_BLUE, 1)); - } else if (colour == MobFireflyCluster.FireflyColor.ORANGE) { - didFillJar = fillJar(player, new ItemStack(Items.LANTERN_FIREFLY_ORANGE, 1)); - } else if (colour == MobFireflyCluster.FireflyColor.RED) { - didFillJar = fillJar(player, new ItemStack(Items.LANTERN_FIREFLY_RED, 1)); - } else { - didFillJar = fillJar(player, new ItemStack(Items.LANTERN_FIREFLY_GREEN, 1)); - } + interface ctx { AABBd bb = new AABBd(); } + synchronized(ctx.bb) { + ctx.bb.setMin(0,0,0).setMax(1,1,1).translate(pos.x(), pos.y(), pos.z()); + entities = world.getEntitiesWithinAABBExcludingEntity(null, ctx.bb); + } - if (!world.isClientSide && didFillJar) { - fireflyCluster.setFireflyCount(fireflyCluster.getFireflyCount() - 1); - if (fireflyCluster.getFireflyCount() <= 0) { - fireflyCluster.remove(); - } - } + boolean hasEntity = false; + for (final var entity : entities) { + if (entity instanceof ICapturable pokemon && pokemon.canBeCapturedBy(this)) { + final var captured = this.tryCaptureEntity(selfStack, null, entity); + if (captured == null) continue; + world.dropItem(pos, captured); + return; + } + if (entity.isSelectable()) hasEntity = true; + } + if (hasEntity) return; + super.placeWithoutShift(selfStack, world, null, pos, direction.opposite().side(), 0.5, 0.5); + } - return selfStack; - } else if (entity instanceof MobButterfly butterfly) { - MobButterfly.ButterflyEntry color = MobButterfly.colorEntries.get(butterfly.getColor()); + public @Nullable ItemStack tryCaptureEntity( + @NotNull ItemStack selfStack, + @Nullable Player player, @NotNull Entity entity + ) { + if (selfStack.stackSize <= 0) return null; + if (entity instanceof ICapturable pokemon); else return null; + if (!pokemon.canBeCapturedBy(this)) return null; - boolean didFillJar = fillJar(player, new ItemStack(color.jarItem.get(), 1)); + final int count = pokemon.onCaptured(); + if (count == 0) return null; - if (!world.isClientSide && didFillJar) { - butterfly.remove(); - } + final Item resultingItem; + if (pokemon instanceof MobFireflyCluster firefly) resultingItem = captureFirefly(firefly); + else if (pokemon instanceof MobButterfly butterfly) resultingItem = captureButterfly(butterfly); + else return null; - return selfStack; - } - } - return selfStack; + return new ItemStack(resultingItem); } - public static boolean fillJar(@NotNull Player player, @NotNull ItemStack itemToGive) { - ItemStack currentItem = player.inventory.getCurrentItem(); - if (currentItem == null || currentItem.stackSize <= 1) { - player.inventory.setItem(player.inventory.getCurrentSlot(), itemToGive); - } else { - player.inventory.insertItem(itemToGive, true); - } - if (itemToGive.stackSize < 1) { - player.swingItem(); - player.inventory.getCurrentItem().consumeItem(player); - return true; - } - return false; + // TODO extensibility + private static @NotNull Item captureFirefly(@NotNull MobFireflyCluster firefly) { + final var colour = firefly.getColor(); + if (colour == MobFireflyCluster.FireflyColor.BLUE) return Items.LANTERN_FIREFLY_BLUE; + if (colour == MobFireflyCluster.FireflyColor.ORANGE) return Items.LANTERN_FIREFLY_ORANGE; + if (colour == MobFireflyCluster.FireflyColor.RED) return Items.LANTERN_FIREFLY_RED; + if (colour == MobFireflyCluster.FireflyColor.GREEN) return Items.LANTERN_FIREFLY_GREEN; + throw new AssertionError("unreachable"); + } + private static @NotNull Item captureButterfly(@NotNull MobButterfly butterfly) { + final var color = MobButterfly.colorEntries.get(butterfly.getColor()); + assert color != null; + return color.jarItem(); } } 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 2625ad6ef..c9f1cd304 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 @@ -4,27 +4,20 @@ import net.minecraft.core.block.Block; import net.minecraft.core.block.BlockLogicOverlayPebbles; import net.minecraft.core.block.Blocks; import net.minecraft.core.block.entity.TileEntityActivator; -import net.minecraft.core.block.tag.BlockTags; import net.minecraft.core.entity.player.Player; import net.minecraft.core.entity.projectile.ProjectilePebble; -import net.minecraft.core.enums.EnumBlockSoundEffectType; 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 org.joml.primitives.AABBd; -import org.joml.primitives.AABBdc; import java.util.Random; -public class ItemPebble extends Item implements IDispensable { - +public class ItemPebble extends Item implements IDispensable, IAccumulatable { public ItemPebble(String name, String namespaceId, int id) { super(name, namespaceId, id); - this.maxStackSize = 64; } @Override @@ -38,87 +31,50 @@ public class ItemPebble extends Item implements IDispensable { } @Override - 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; - @NotNull Block block = world.getBlockType(blockPos); - int meta = world.getBlockData(blockPos); - if (block != Blocks.OVERLAY_PEBBLES && block.hasTag(BlockTags.PLACE_OVERWRITES)) { - block = Blocks.AIR; - meta = 0; - } - if (selfStack.stackSize <= 0) { - return false; - } - if (blockPos.y() == world.getHeightBlocks() - 1 && Blocks.OVERLAY_PEBBLES.getMaterial().isSolid()) { - 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 (!pebble.isSupported(world, blockPos, Side.BOTTOM)) return false; - - if (newMeta < BlockLogicOverlayPebbles.MAX_PEBBLES) { - world.setBlockTypeDataNotify(blockPos, Blocks.OVERLAY_PEBBLES, newMeta); - world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, Blocks.OVERLAY_PEBBLES, EnumBlockSoundEffectType.PLACE); - selfStack.consumeItem(player); - return true; - } - } - - // Offset position - if (block != Blocks.AIR) { - blockPos = blockPos.add(side.direction(), new TilePos()); - block = world.getBlockType(blockPos); - meta = world.getBlockData(blockPos); - } - - // Check if the block we're placing into is a layer - if (block == Blocks.OVERLAY_PEBBLES) { - 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) || !pebble.isSupported(world, blockPos, Side.BOTTOM)) { - return false; - } + public @NotNull Block getBlock() { + return Blocks.OVERLAY_PEBBLES; + } - if (newMeta < BlockLogicOverlayPebbles.MAX_PEBBLES) { - world.setBlockTypeDataNotify(blockPos, Blocks.OVERLAY_PEBBLES, newMeta); - world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, Blocks.OVERLAY_PEBBLES, EnumBlockSoundEffectType.PLACE); - selfStack.consumeItem(player); - 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 this.placeOnBlock(selfStack, world, player, blockPos, side, xHit, yHit); + } - } + @Override + public boolean canAccumulateInto( + @NotNull ItemStack selfStack, + @NotNull Block block, int data, @NotNull Side side, double xHit, double yHit + ) { + return block == Blocks.OVERLAY_PEBBLES && data < BlockLogicOverlayPebbles.MAX_PEBBLES - 1; + } - // Regular placement, as all else fails - 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); - selfStack.consumeItem(player); - return true; - } - } - return false; + @Override + public @NotNull BlockDataResult getAccumulationResult( + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc tilePos, + @NotNull Side side, double xHit, double yHit, + @NotNull BlockDataResult result + ) { + result.data += 1; + return result; } @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.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; + if (!selfStack.consumeItem(null)) return; + final var pebble = new ProjectilePebble(world, blockPos.x() + offX, blockPos.y() + offY, blockPos.z() + offZ); + pebble.setHeading(direction.offsetX() * 0.6, direction.offsetY() == 0 ? 0.1 : direction.offsetY() * 0.6, direction.offsetZ() * 0.6f, 1.1F, 6F); + world.entityJoinedWorld(pebble); } @Override 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.offsetX(), direction.offsetY() + 0.1D, direction.offsetZ(), 1.1F, 6F); - world.entityJoinedWorld(projectilePebble); - } + if (!selfStack.consumeItem(null)) return; + final var pebble = new ProjectilePebble(world, x, y, z); + pebble.setHeading(direction.offsetX(), direction.offsetY() + 0.1D, direction.offsetZ(), 1.1F, 6F); + world.entityJoinedWorld(pebble); } } 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 0d190171a..c9a939d64 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 @@ -1,88 +1,51 @@ package net.minecraft.core.item; import net.minecraft.core.block.Block; -import net.minecraft.core.block.entity.TileEntity; +import net.minecraft.core.block.BlockLogic; import net.minecraft.core.block.entity.TileEntityActivator; -import net.minecraft.core.block.tag.BlockTags; import net.minecraft.core.entity.player.Player; -import net.minecraft.core.enums.EnumBlockSoundEffectType; -import net.minecraft.core.item.block.ItemBlock; +import net.minecraft.core.util.collection.NamespaceID; import net.minecraft.core.util.helper.Direction; import net.minecraft.core.util.helper.Side; import net.minecraft.core.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 java.util.Random; -public class ItemPlaceable extends Item { +public class ItemPlaceable extends Item implements IPlaceable.PlaceableBlock { - public final @NotNull Block blockToPlace; + public final @NotNull Block block; - public ItemPlaceable(@NotNull String name, @NotNull String namespaceId, int id, @NotNull Block blockToPlace) { - super(name, namespaceId, id); + public ItemPlaceable(@NotNull NamespaceID namespaceId, @NotNull String translationKey, int id, @NotNull Block blockToPlace) { + super(namespaceId, translationKey, id); - this.blockToPlace = blockToPlace; + this.block = blockToPlace; } - @Override - public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) { - if (selfStack.stackSize <= 0) { - return false; - } - if (ItemBlock.shouldShift(world, blockPos, this.blockToPlace)) { - 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)) 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); + public ItemPlaceable(@NotNull String translationKey, @NotNull String namespaceId, int id, @NotNull Block blockToPlace) { + super(translationKey, namespaceId, id); - 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); + this.block = blockToPlace; + } - if (this.blockToPlace.isEntityTile && selfStack.getData().containsKey("tileEntityData")) { - TileEntity tileEntity = world.getTileEntity(blockPos); - if (tileEntity != null) { - tileEntity.readAdditionalData(selfStack.getData().getCompound("tileEntityData")); - } - } + @Override + @SuppressWarnings("unchecked") + public @NotNull Block getBlock() { + return (Block)this.block; + } - // 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 + public boolean onUseOnBlock( + @NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, + @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit + ) { + return this.placeOnBlock(selfStack, world, player, blockPos, side, xHit, yHit); } @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()); - Block b = world.getBlockType(blockPos); - if (b == null || BlockTags.PLACE_OVERWRITES.appliesTo(b)) { - onUseOnBlock(selfStack, world, null, blockPos, direction.side(), 0.5, 0.5); - } + this.placeByActivator(selfStack, world, activator, random, blockPos, direction, offX, offY, offZ); } } diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemPlaceablePair.java b/game/core/src/main/java/net/minecraft/core/item/ItemPlaceablePair.java new file mode 100644 index 000000000..3827f3647 --- /dev/null +++ b/game/core/src/main/java/net/minecraft/core/item/ItemPlaceablePair.java @@ -0,0 +1,157 @@ +package net.minecraft.core.item; + +import net.minecraft.core.block.Block; +import net.minecraft.core.block.Blocks; +import net.minecraft.core.block.entity.TileEntityActivator; +import net.minecraft.core.entity.player.Player; +import net.minecraft.core.enums.EnumBlockSoundEffectType; +import net.minecraft.core.util.collection.NamespaceID; +import net.minecraft.core.util.helper.Direction; +import net.minecraft.core.util.helper.Side; +import net.minecraft.core.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 org.joml.Vector3i; + +import java.util.Random; + +public abstract class ItemPlaceablePair extends Item implements IPlaceable { + + protected final @NotNull Block blockA; + protected final @NotNull Block blockB; + + private static final PlacementResult resultBuffer = new PlacementResult(); + + public ItemPlaceablePair( + @NotNull NamespaceID namespaceId, @NotNull String translationKey, int id, + @NotNull Block blockA, @NotNull Block blockB + ) { + super(namespaceId, translationKey, id); + this.blockA = blockA; + this.blockB = blockB; + } + + public ItemPlaceablePair( + @NotNull String translationKey,@NotNull String namespaceId, int id, + @NotNull Block blockA, @NotNull Block blockB + ) { + super(translationKey, namespaceId, id); + this.blockA = blockA; + this.blockB = blockB; + } + + protected static class PlacementResult { + public int dataA; + public int dataB; + public final @NotNull Vector3i offsetB = new Vector3i(); + public boolean cannotPlace; + } + + protected abstract @NotNull PlacementResult getPlacement( + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, + @NotNull Side side, double xHit, double yHit, + @NotNull PlacementResult result + ); + + @Override + public boolean shouldShiftOutOf( + @NotNull ItemStack selfStack, + @NotNull World world, @NotNull Player player, @NotNull TilePosc blockPos, + @NotNull Side side, double xHit, double yHit + ) { + return IPlaceable.shouldShiftBlockOutOf(blockA, world, blockPos); + } + + @Override + public boolean onUseOnBlock( + @NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, + @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit + ) { + return this.placeOnBlock(selfStack, world, player, blockPos, side, xHit, yHit); + } + + @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) { + this.placeByActivator(selfStack, world, activator, random, blockPos, direction, offX, offY, offZ); + } + + @Override + public boolean placeWithoutShift( + @NotNull ItemStack selfStack, @NotNull World world, + @Nullable Player player, @NotNull TilePosc blockPos, + @NotNull Side side, double xHit, double yHit + ) { + if (selfStack.stackSize <= 0) return false; + if (!this.canPlaceDirectlyAtPosition(selfStack, world, player, blockPos, side, xHit, yHit)) return false; + + final TilePosc posA, posB; + final int dataA, dataB; + + synchronized (resultBuffer) { + resultBuffer.dataA = resultBuffer.dataB = 0; + resultBuffer.offsetB.set(0,0,0); + resultBuffer.cannotPlace = false; + final var result = this.getPlacement(selfStack, world, player, blockPos, side, xHit, yHit, resultBuffer); + + if (result.cannotPlace) return false; + + dataA = result.dataA; + dataB = result.dataB; + posA = blockPos; + posB = blockPos.add(result.offsetB, new TilePos()); + } + + final @Nullable Block prevBlockA, prevBlockB; + final int prevDataA, prevDataB; + final boolean isAIdentical, isBIdentical; + + prevBlockA = world.getBlockType(posA); + prevDataA = world.getBlockData(posA); + + prevBlockB = world.getBlockType(posB); + prevDataB = world.getBlockData(posB); + + isAIdentical = prevBlockA == this.blockA && prevDataA == dataA; + isBIdentical = prevBlockB == this.blockB && prevDataB == dataB; + + if (!isAIdentical) world.setBlockTypeDataRaw(posA, this.blockA, dataA); + if (!isBIdentical) world.setBlockTypeDataRaw(posB, this.blockB, dataB); + if (!isAIdentical) world.markBlockNeedsUpdate(posA); + if (!isBIdentical) world.markBlockNeedsUpdate(posB); + + if (!isAIdentical) prevBlockA.onRemoved(world, posA, prevDataA); + if (!isBIdentical) prevBlockB.onRemoved(world, posB, prevDataB); + if (player == null) { + if (!isAIdentical) this.blockA.onPlacedOnSide(world, posA, side, xHit, yHit); + if (!isBIdentical) this.blockB.onPlacedOnSide(world, posB, side, xHit, yHit); + } else { + if (!isAIdentical) this.blockA.onPlacedByMob(world, posA, side, player, xHit, yHit); + if (!isBIdentical) this.blockB.onPlacedByMob(world, posB, side, player, xHit, yHit); + } + if (!isAIdentical) this.blockA.onPlacedByWorld(world, posA); + if (!isBIdentical) this.blockB.onPlacedByWorld(world, posB); + + if (this.blockA.isEntityTile && selfStack.getData().containsKey("tileEntityData")) { + final var tileEntity = world.getTileEntity(blockPos); + if (tileEntity != null) { + tileEntity.readAdditionalData(selfStack.getData().getCompound("tileEntityData")); + } + } + if (isAIdentical != isBIdentical) { + if (isAIdentical) world.notifyBlocksOfNeighborChange(posB, this.blockB); + else world.notifyBlocksOfNeighborChange(posA, this.blockA); + } else if (isAIdentical) { + assert isBIdentical; + world.notifyBlocksOfNeighborChanges(new TilePosc[] { posA, posB }, null); + } + world.playBlockSoundEffect( + player, + posA.x() + 0.5F, posA.y() + 0.5F, posA.z() + 0.5F, + this.blockA, EnumBlockSoundEffectType.PLACE + ); + return true; + } +} diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemRope.java b/game/core/src/main/java/net/minecraft/core/item/ItemRope.java index fc0c9432c..c5d2c7c3e 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemRope.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemRope.java @@ -2,63 +2,48 @@ package net.minecraft.core.item; import net.minecraft.core.block.Block; import net.minecraft.core.block.BlockLogicRope; +import net.minecraft.core.block.entity.TileEntityActivator; import net.minecraft.core.entity.player.Player; -import net.minecraft.core.enums.EnumBlockSoundEffectType; +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 java.util.Random; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class ItemRope extends ItemPlaceable { - public ItemRope(@NotNull String name, @NotNull String namespaceId, int id, @NotNull Block blockToPlace) { + public ItemRope(@NotNull String name, @NotNull String namespaceId, int id, @NotNull Block blockToPlace) { super(name, namespaceId, id, blockToPlace); } @Override public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) { - if (selfStack.stackSize <= 0) { - return false; - } - TilePos bp = new TilePos(blockPos); - boolean placeOnSide = true; - if (world.getBlockType(bp) == this.blockToPlace && player != null && !player.isSneaking()) { - placeOnSide = false; - TilePos tempPos = new TilePos(bp); - while (tempPos.y > 0) { - tempPos.y--; - if (world.canBlockIdBePlacedAt(this.blockToPlace.id(), tempPos, false, side)) { - bp.y = tempPos.y; - break; - } else if (world.getBlockType(tempPos) != this.blockToPlace) { - if (side == Side.TOP) { - tempPos.y++; - break; - } - return true; - } - } - bp.set(tempPos); - } - if (!world.canPlaceInsideBlock(bp)) { - bp = bp.add(side.direction(), new TilePos()); - } - if (bp.y < 0 || bp.y >= world.getHeightBlocks()) { - return false; - } - if (world.canBlockIdBePlacedAt(this.blockToPlace.id(), bp, false, side) && selfStack.consumeItem(player)) { - if (world.setBlockTypeData(bp, this.blockToPlace, placeOnSide ? BlockLogicRope.MASK_ROPE_CONNECT : 0)) { - if (player == null) { - this.blockToPlace.onPlacedOnSide(world, bp, side, xHit, yHit); - } else { - this.blockToPlace.onPlacedByMob(world, bp, side, player, xHit, yHit); - } - world.notifyBlockChange(bp, this.blockToPlace); - world.playBlockSoundEffect(player, bp.x + 0.5F, bp.y + 0.5F, bp.z + 0.5F, this.blockToPlace, EnumBlockSoundEffectType.PLACE); - return true; - } + if (selfStack.stackSize <= 0) return false; + + final var placePos = new TilePos(blockPos); + final boolean placeOnSide = + side != Side.TOP && + (player == null || !player.isSneaking()) && + world.getBlockType(placePos) == this.block; + + if (placeOnSide) while (placePos.y-- > 0) { + if (world.getBlockType(placePos) == this.block) continue; + if (world.canBlockIdBePlacedAt(this.block.id(), placePos, false, side)) break; + else return false; } - return false; + if (super.shouldShiftOutOf(selfStack, world, player, placePos, side, xHit, yHit)) placePos.add(side); + + final int meta = (placeOnSide) ? BlockLogicRope.MASK_ROPE_CONNECT : 0; + return super.placeDirectly(selfStack, world, player, placePos, meta, side, xHit, yHit); + } + + @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()); + this.onUseOnBlock(selfStack, world, null, blockPos, direction.opposite().side(), Double.NaN, Double.NaN); } } diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemStack.java b/game/core/src/main/java/net/minecraft/core/item/ItemStack.java index d8e53be79..998e08a73 100644 --- a/game/core/src/main/java/net/minecraft/core/item/ItemStack.java +++ b/game/core/src/main/java/net/minecraft/core/item/ItemStack.java @@ -526,4 +526,12 @@ public final class ItemStack { this.tag.putInt(key, value); return this; } + + public boolean interactsWithFluid() { + return this.getItem().interactsWithFluid(this); + } + + public boolean interactsWithEntity(@NotNull Entity entity) { + return this.getItem().interactsWithEntity(this, entity); + } } 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 6c6cab39d..c759d0ed2 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 @@ -1,11 +1,7 @@ package net.minecraft.core.item; import net.minecraft.core.block.Block; -import net.minecraft.core.block.entity.TileEntity; -import net.minecraft.core.block.entity.TileEntityActivator; import net.minecraft.core.entity.player.Player; -import net.minecraft.core.enums.EnumBlockSoundEffectType; -import net.minecraft.core.util.helper.Direction; import net.minecraft.core.util.helper.MathHelper; import net.minecraft.core.util.helper.Side; import net.minecraft.core.world.World; @@ -13,82 +9,38 @@ 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.primitives.AABBd; -import java.util.Random; - -public class ItemStatue extends Item { - protected final @NotNull Block statueBlockBottom; - protected final @NotNull Block statueBlockTop; - +public class ItemStatue extends ItemPlaceablePair { public ItemStatue(@NotNull String name, @NotNull String namespaceId, int id, @NotNull Block statueBlockBottom, @NotNull Block statueBlockTop) { - super(name, namespaceId, id); - this.maxStackSize = 64; - this.statueBlockBottom = statueBlockBottom; - this.statueBlockTop = statueBlockTop; + super(name, namespaceId, id, statueBlockBottom, statueBlockTop); } @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.direction(), new TilePos()); - } - if (!this.statueBlockBottom.canPlaceAt(world, blockPos)) { - return false; - } - - final var bb = statueBlockBottom.getCollisionAABB(world, blockPos); - if (bb != null && !world.checkIfAABBIsClear(bb)) { - 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); - 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); - - if (this.statueBlockBottom.isEntityTile && selfStack.getData().containsKey("tileEntityData")) { - TileEntity tileEntity = world.getTileEntity(blockPos); - if (tileEntity != null) { - tileEntity.readAdditionalData(selfStack.getData().getCompound("tileEntityData")); - } - } - 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); - - return true; + protected @NotNull PlacementResult getPlacement( + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, + @NotNull Side side, double xHit, double yHit, + @NotNull PlacementResult result + ) { + final double yRot; + if (player == null) yRot = side.direction.opposite().yaw(); + else if (player.rotationLockHorizontal != null) yRot = player.rotationLockHorizontal.yaw(); + else yRot = player.yRot; + + result.dataA = result.dataB = MathHelper.floor(((yRot + 180D) * (16D / 360D)) + 0.5D) & 0xF; + result.offsetB.set(0,1,0); + return result; } @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 (!world.canPlaceInsideBlock(blockPos)) { - blockPos = blockPos.add(direction, new TilePos()); - } - if (!this.statueBlockBottom.canPlaceAt(world, blockPos)) { - return; - } - - 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.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); - if (tileEntity != null) { - tileEntity.readAdditionalData(selfStack.getData().getCompound("tileEntityData")); - } - } - - selfStack.consumeItem(null); + public boolean canPlaceDirectlyAtPosition( + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, + @NotNull Side side, double xHit, double yHit + ) { + return + IPlaceable.canPlaceBlockDirectlyAtPosition(blockA, world, blockPos, side) && + IPlaceable.canPlaceBlockDirectlyAtPosition(blockB, world, blockPos.up(new TilePos()), side); } } 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 deb28011a..7f2228482 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 @@ -2,124 +2,58 @@ package net.minecraft.core.item.block; import net.minecraft.core.block.Block; import net.minecraft.core.block.BlockLogic; -import net.minecraft.core.block.Blocks; -import net.minecraft.core.block.entity.TileEntity; import net.minecraft.core.block.entity.TileEntityActivator; -import net.minecraft.core.block.tag.BlockTags; import net.minecraft.core.entity.player.Player; -import net.minecraft.core.enums.EnumBlockSoundEffectType; +import net.minecraft.core.item.IPlaceable; import net.minecraft.core.item.Item; 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.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 java.util.Objects; import java.util.Random; -public class ItemBlock extends Item { - protected @NotNull Block block; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class ItemBlock extends Item implements IPlaceable.PlaceableBlock { + protected final @NotNull Block block; public ItemBlock(@NotNull Block block) { super(block.namespaceId(), block.getKey(), block.id()); - this.block = Objects.requireNonNull(block); - } - - public @NotNull Block getBlock() { - return this.block; + this.block = block; } @Override - public boolean onUseOnBlock( - @NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, - @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit - ) { - if (shouldShift(world, blockPos, this.block)) blockPos = blockPos.add(side.direction(), new TilePos()); - if (!world.canBlockIdBePlacedAt(this.block.id(), blockPos, false, side)) return false; - - final int meta = getPlacedData(selfStack, world, player, blockPos, side, xHit, yHit); - return this.placeDirectly(selfStack, world, player, blockPos, meta, side, xHit, yHit); - } - - public static boolean shouldShift(@NotNull World world, @NotNull TilePosc blockPos, @NotNull Block block) { - if (!world.canPlaceInsideBlock(blockPos)) return true; - return block.hasTag(BlockTags.PLACE_OVERWRITES) && block == world.getBlockType(blockPos); - } - - protected final boolean placeWithMeta( - @NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, - @NotNull TilePosc blockPos, int meta, @NotNull Side side, double xHit, double yHit - ) { - if (shouldShift(world, blockPos, this.block)) blockPos = blockPos.add(side.direction(), new TilePos()); - if (!world.canBlockIdBePlacedAt(this.block.id(), blockPos, false, side)) return false; - - return this.placeDirectly(selfStack, world, player, blockPos, meta, side, xHit, yHit); - } - - protected final boolean placeDirectly( - @NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, - @NotNull TilePosc blockPos, int meta, @NotNull Side side, double xHit, double yHit - ) { - if (selfStack.stackSize <= 0) return false; - 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); - } else { - 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) { - tileEntity.readAdditionalData(selfStack.getData().getCompound("tileEntityData")); - } - } - - world.notifyBlockChange(blockPos, this.block); - world.playBlockSoundEffect( - player, - blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, - this.block, EnumBlockSoundEffectType.PLACE - ); - return true; + public @NotNull String getKey() { + return this.block.getKey(); } @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 = new TilePos(blockPos).add(direction); - @NotNull Block b = world.getBlockType(blockPos); - if (b == Blocks.AIR || BlockTags.PLACE_OVERWRITES.appliesTo(b)) { - this.onUseOnBlock(selfStack, world, null, blockPos, direction.side(), 0.5, 0.5); - } + public @NotNull String getLanguageKey(@NotNull ItemStack selfStack) { + return this.block.getLanguageKey(selfStack.getMetadata()); } - public int getPlacedData(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) { - return this.block.getPlacedData(player, selfStack, world, blockPos, side, xHit, yHit); + @Override + public @NotNull Block getBlock() { + return this.block; } @Override - public @NotNull String getLanguageKey(@NotNull ItemStack selfStack) { - return this.block.getLanguageKey(selfStack.getMetadata()); + public boolean onUseOnBlock( + @NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, + @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit + ) { + return this.placeOnBlock(selfStack, world, player, blockPos, side, xHit, yHit); } @Override - public @NotNull String getKey() { - return this.block.getKey(); + 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 + ) { + this.placeByActivator(selfStack, world, activator, random, blockPos, direction, offX, offY, offZ); } } diff --git a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockAlgae.java b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockAlgae.java index 829a4db67..5ffc9a08d 100644 --- a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockAlgae.java +++ b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockAlgae.java @@ -3,14 +3,12 @@ package net.minecraft.core.item.block; import net.minecraft.core.block.Block; import net.minecraft.core.block.BlockLogic; import net.minecraft.core.block.BlockLogicFluid; -import net.minecraft.core.block.Blocks; import net.minecraft.core.block.FluidWater; import net.minecraft.core.block.entity.TileEntityActivator; import net.minecraft.core.entity.player.Player; import net.minecraft.core.item.ItemStack; import net.minecraft.core.util.helper.Direction; import net.minecraft.core.util.helper.Side; -import net.minecraft.core.util.phys.HitResult; import net.minecraft.core.world.World; import net.minecraft.core.world.pos.TilePos; import net.minecraft.core.world.pos.TilePosc; @@ -28,45 +26,33 @@ public class ItemBlockAlgae extends ItemBlock { } @Override - public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) { - return false; + public boolean interactsWithFluid(@NotNull ItemStack selfStack) { + return true; } @Override - public @Nullable ItemStack onUse(@NotNull ItemStack selfStack, @NotNull World world, @NotNull Player player) { - final double reachDistance = player.getGamemode().getBlockReachDistance(); - final HitResult rayCast = player.rayCast(reachDistance, 1f, true, false, false); - if (!(rayCast instanceof HitResult.Tile hitTile)) return selfStack; - - final var pos = new TilePos(hitTile.tilePos); - if (!testPlace(world, pos)) return selfStack; - - super.onUseOnBlock(selfStack, world, player, pos, Side.NONE, 0.5, 0.5); - return selfStack; + public boolean onUseOnBlock( + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc tilePos, + @NotNull Side side, double xHit, double yHit + ) { + if (!this.isWaterSource(world, tilePos)) return false; + return super.placeWithoutShift(selfStack, world, player, tilePos.up(new TilePos()), Side.TOP, 0.5, 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) { final var pos = new TilePos(blockPos).add(direction); - if (!testPlace(world, pos)) return; + if (!this.isWaterSource(world, pos)) return; - if (!world.setBlockType(pos, this.block)) return; - selfStack.consumeItem(null); - - this.block.onPlacedOnSide(world, pos, Side.NONE, 0.5, 0.5); - world.notifyBlockChange(pos, this.block); + super.placeWithoutShift(selfStack, world, null, pos.up(), Side.TOP, 0.5, 0.5); } - private static final boolean testPlace(@NotNull World world, @NotNull TilePos toMove) { - final TilePos origin = new TilePos(toMove); - - @NotNull Block up = world.getBlockType(toMove.up()); - if (up != Blocks.AIR) return false; - - if (!(world.getBlockType(origin).getLogic() instanceof BlockLogicFluid fluid)) return false; + private final boolean isWaterSource(@NotNull World world, @NotNull TilePosc pos) { + if (!(world.getBlockType(pos).getLogic() instanceof BlockLogicFluid fluid)) return false; if (!(fluid.fluid instanceof FluidWater)) return false; - if (fluid.getDepth(world, origin) != 0) return false; + if (fluid.getDepth(world, pos) != 0) return false; return true; } } 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 02ec02e26..4ba690e00 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 @@ -2,12 +2,17 @@ package net.minecraft.core.item.block; import net.minecraft.core.block.Block; import net.minecraft.core.block.BlockLogicLadder; +import net.minecraft.core.block.entity.TileEntityActivator; import net.minecraft.core.entity.player.Player; 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.World; import net.minecraft.core.world.pos.TilePos; import net.minecraft.core.world.pos.TilePosc; + +import java.util.Random; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -23,8 +28,8 @@ public class ItemBlockLadder extends ItemBlock { final @NotNull BlockLogicLadder ladder = this.block.getLogic(); final Side pside; - if (player == null || player.isSneaking() || world.getBlockType(bp) != this.block) { - if (shouldShift(world, bp, this.block)) bp.add(side.direction()); + if ((player != null && player.isSneaking()) || world.getBlockType(bp) != this.block) { + if (super.shouldShiftOutOf(selfStack, world, player, bp, side, xHit, yHit)) bp.add(side.direction()); pside = ladder.getSideForPlacement(world, bp, side); } else { xHit = 0.5; @@ -39,4 +44,14 @@ public class ItemBlockLadder extends ItemBlock { if (!ladder.canExistAt(world, bp, meta)) return false; return super.placeDirectly(selfStack, world, player, bp, meta, pside, xHit, yHit); } + + @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()); + this.onUseOnBlock(selfStack, world, null, blockPos, direction.opposite().side(), Double.NaN, Double.NaN); + } } diff --git a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLayer.java b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLayer.java index 0d4f4bf49..29df0de45 100644 --- a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLayer.java +++ b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLayer.java @@ -3,68 +3,44 @@ package net.minecraft.core.item.block; import net.minecraft.core.block.Block; import net.minecraft.core.block.BlockLogicLayerBase; import net.minecraft.core.entity.player.Player; -import net.minecraft.core.enums.EnumBlockSoundEffectType; +import net.minecraft.core.item.IAccumulatable; import net.minecraft.core.item.ItemStack; 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 org.joml.Vector3d; -import org.joml.primitives.AABBd; -public class ItemBlockLayer extends ItemBlock { +public class ItemBlockLayer extends ItemBlock + implements IAccumulatable +{ public ItemBlockLayer(@NotNull Block block) { super(block); } - // TODO: sideways placement into layer @Override - public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) { - if (selfStack.stackSize <= 0) return false; - if (tilePos.y() == world.getHeightBlocks() - 1 && this.block.getMaterial().isSolid()) { - return false; - } - final var targetBlock = world.getBlockType(tilePos); - if (targetBlock != this.block || side != Side.TOP) { - // you can no longer stack layers by placing on - // the top face of a partial block under the layers :3 - return super.placeWithMeta(selfStack, world, player, tilePos, 0, side, xHit, yHit); - } - - final @NotNull BlockLogicLayerBase blockLayer = this.block.getLogic(); - final int meta = world.getBlockData(tilePos) + 1; - - final var bbmin = new Vector3d(tilePos.vec()); - final var bbmax = new Vector3d(bbmin).add(1, (meta + 1) / 8.0f, 1); - if (!world.checkIfAABBIsClear(new AABBd(bbmin, bbmax))) return false; - - final boolean placed; - final @NotNull Block placedBlock; - final var placedPos = new TilePos(tilePos); + public boolean canAccumulateInto( + @NotNull ItemStack selfStack, + @NotNull Block block, int data, @NotNull Side side, double xHit, double yHit + ) { + return block == this.block && !(yHit - ((data + 1) * 0.125) <= -0x1p-12); + } - if (meta < 7) { - placedBlock = this.block; - placed = world.setBlockTypeData(placedPos, placedBlock, meta); - } else if (blockLayer.fullBlock != null) { - placedBlock = blockLayer.fullBlock; - placed = world.setBlockType(placedPos, placedBlock); + @Override + public @NotNull BlockDataResult getAccumulationResult( + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc tilePos, + @NotNull Side side, double xHit, double yHit, + @NotNull BlockDataResult result + ) { + if (result.data < 6) { + result.data += 1; } else { - placedBlock = this.block; - // TODO this can place inside entities - placed = world.setBlockType(placedPos.up(), placedBlock); + result.block = this.block.getLogic().fullBlock; + result.data = 0; } - if (!placed) return false; - selfStack.consumeItem(player); - - placedBlock.onPlacedByMob(world, tilePos, side, player, xHit, yHit); - world.notifyBlockChange(placedPos, placedBlock); - - world.playBlockSoundEffect(player, - placedPos.x() + 0.5F, placedPos.y() + 0.5F, placedPos.z() + 0.5F, - this.block, EnumBlockSoundEffectType.PLACE); - return true; + return result; } } diff --git a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLayerLeaves.java b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLayerLeaves.java index 160c93803..030a7e430 100644 --- a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLayerLeaves.java +++ b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLayerLeaves.java @@ -1,71 +1,42 @@ package net.minecraft.core.item.block; import net.minecraft.core.block.Block; -import net.minecraft.core.block.BlockLogicLayerBase; import net.minecraft.core.block.BlockLogicLayerLeaves; import net.minecraft.core.entity.player.Player; -import net.minecraft.core.enums.EnumBlockSoundEffectType; import net.minecraft.core.item.ItemStack; 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 org.joml.Vector3d; -import org.joml.primitives.AABBd; -public class ItemBlockLayerLeaves extends ItemBlock { +public class ItemBlockLayerLeaves extends ItemBlockLayer { public ItemBlockLayerLeaves(@NotNull Block block) { super(block); } - // TODO: refactor to reuse ItemBlockLayer? @Override - public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) { - if (selfStack.stackSize <= 0) return false; - if (tilePos.y() == world.getHeightBlocks() - 1 && this.block.getMaterial().isSolid()) { - return false; - } - final var targetBlock = world.getBlockType(tilePos); - if (targetBlock != this.block || side != Side.TOP) { - // you can no longer stack layers by placing on - // the top face of a partial block under the layers :3 - return super.placeWithMeta(selfStack, world, player, tilePos, - BlockLogicLayerLeaves.setPermanent(0, true), side, xHit, yHit); - } - - final @NotNull BlockLogicLayerBase blockLayer = this.block.getLogic(); - final int meta = world.getBlockData(tilePos) + 1; - - final var bbmin = new Vector3d(tilePos.vec()); - final var bbmax = new Vector3d(bbmin).add(1, (meta + 1) / 8.0f, 1); - if (!world.checkIfAABBIsClear(new AABBd(bbmin, bbmax))) return false; - - final boolean placed; - final @NotNull Block placedBlock; - final var placedPos = new TilePos(tilePos); + public boolean canAccumulateInto( + @NotNull ItemStack selfStack, + @NotNull Block block, int data, @NotNull Side side, double xHit, double yHit + ) { + return block == this.block && !(yHit - (((data&0xF) + 1) * 0.125) <= -0x1p-12); + } - if ((meta & 0x0F) < 7) { - placedBlock = this.block; - placed = world.setBlockTypeData(placedPos, placedBlock, BlockLogicLayerLeaves.setPermanent(meta, true)); - } else if (blockLayer.fullBlock != null) { - placedBlock = blockLayer.fullBlock; - placed = world.setBlockTypeData(placedPos, placedBlock, BlockLogicLayerLeaves.setPermanent(0, true)); + @Override + public @NotNull BlockDataResult getAccumulationResult( + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc tilePos, + @NotNull Side side, double xHit, double yHit, + @NotNull BlockDataResult result + ) { + result.data |= BlockLogicLayerLeaves.MASK_PERMANENT; + if ((result.data & 0xF) < 6) { + result.data += 1; } else { - placedBlock = this.block; - // TODO this can place inside entities - placed = world.setBlockTypeData(placedPos.up(), placedBlock, BlockLogicLayerLeaves.setPermanent(0, true)); + result.block = this.block.getLogic().fullBlock; + result.data &= ~0xF; } - if (!placed) return false; - selfStack.consumeItem(player); - - placedBlock.onPlacedByMob(world, tilePos, side, player, xHit, yHit); - world.notifyBlockChange(placedPos, placedBlock); - - world.playBlockSoundEffect(player, - placedPos.x() + 0.5F, placedPos.y() + 0.5F, placedPos.z() + 0.5F, - this.block, EnumBlockSoundEffectType.PLACE); - return true; + return result; } } 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 6075de3e5..953a53c21 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 @@ -2,73 +2,55 @@ package net.minecraft.core.item.block; import net.minecraft.core.block.Block; import net.minecraft.core.block.BlockLogic; -import net.minecraft.core.block.tag.BlockTags; import net.minecraft.core.entity.player.Player; -import net.minecraft.core.enums.EnumBlockSoundEffectType; +import net.minecraft.core.item.IAccumulatable; import net.minecraft.core.item.ItemStack; 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 org.joml.Vector3d; -import org.joml.primitives.AABBd; -public class ItemBlockSlab extends ItemBlock { +public class ItemBlockSlab extends ItemBlock + implements IAccumulatable +{ public ItemBlockSlab(@NotNull Block block) { super(block); } @Override - public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) { - if (selfStack.stackSize <= 0) return false; - if (blockPos.y() == world.getHeightBlocks() - 1 && this.block.getMaterial().isSolid()) { - return false; - } - - var block = world.getBlockType(blockPos); - if (block.hasTag(BlockTags.PLACE_OVERWRITES)) { - return super.onUseOnBlock(selfStack, world, player, blockPos, side, xHit, yHit); - } - - final int selfMeta = selfStack.getMetadata(); - final var shiftPos = new TilePos(blockPos); - - int i; - for (i = 0; i < 2; i++) { - block = world.getBlockType(shiftPos); - final var blockMeta = world.getBlockData(shiftPos); - final boolean canPlaceInto = - block == this.block && - (blockMeta & ~0b11) == selfMeta && - switch (blockMeta & 0b11) { - default -> false; - case 0 -> yHit >= 0.5f; - case 2 -> yHit <= 0.5f; - }; - if (canPlaceInto) break; - shiftPos.add(side); - yHit -= side.offsetY(); - } if (i == 2) { // for else - return super.onUseOnBlock(selfStack, world, player, blockPos, side, xHit, yHit); - } - - final var bbmin = new Vector3d(shiftPos.vec()); - final var bbmax = new Vector3d(bbmin).add(1,1,1); - if (!world.checkIfAABBIsClear(new AABBd(bbmin, bbmax))) return false; - - if (!world.setBlockData(shiftPos, 1 | selfStack.getMetadata())) return false; - selfStack.consumeItem(player); + public boolean canAccumulateInto( + @NotNull ItemStack selfStack, + @NotNull Block block, int data, @NotNull Side side, double xHit, double yHit + ) { + return this.block == block && (data & ~0b11) == selfStack.getMetadata() && + switch (data & 0b11) { + default -> false; + case 0 -> !(yHit - 0.5f <= -0x1p-12); + case 2 -> !(yHit - 0.5f >= +0x1p-12); + }; + } - // this invokes modelBlock's on place logic. is this a good idea? - this.block.onPlacedByWorld(world, shiftPos); + @Override + public @NotNull BlockDataResult getAccumulationResult( + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc tilePos, + @NotNull Side side, double xHit, double yHit, + @NotNull BlockDataResult result + ) { + result.data = 1 | selfStack.getMetadata(); + result.bounds.setMin(0,0,0).setMax(1,1,1); + return result; + } - world.notifyBlockChange(shiftPos, block); - world.playBlockSoundEffect(player, - shiftPos.x() + 0.5F, shiftPos.y() + 0.5F, shiftPos.z() + 0.5F, - this.block, EnumBlockSoundEffectType.PLACE); - - return true; + @Override + public void postAccumulate( + @NotNull ItemStack selfStack, + @NotNull World world, @Nullable Player player, @NotNull TilePosc tilePos, + @NotNull Side side, double xHit, double yHit, + @NotNull BlockDataResult result + ) { + this.block.onPlacedByWorld(world, tilePos); } -} \ No newline at end of file +} diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/CreativeMenuContents.java b/game/core/src/main/java/net/minecraft/core/player/inventory/CreativeMenuContents.java index 8dc5e25ad..53766556e 100644 --- a/game/core/src/main/java/net/minecraft/core/player/inventory/CreativeMenuContents.java +++ b/game/core/src/main/java/net/minecraft/core/player/inventory/CreativeMenuContents.java @@ -17,7 +17,7 @@ import static net.minecraft.core.player.inventory.menu.MenuInventoryCreative.CRE import static net.minecraft.core.player.inventory.menu.MenuInventoryCreative.CREATIVE_PAGE_SIZE; public final class CreativeMenuContents { - public static boolean ADD_GAPS = false; // Disabled for now, need to discuss full creative gui rework for 8.1 + public static boolean ADD_GAPS = true; // Disabled for now, need to discuss full creative gui rework for 8.1 private static final DyeColor[] RAINBOW_ORDER = { DyeColor.RED, @@ -90,6 +90,8 @@ public final class CreativeMenuContents { addLogTypes(list); newLine(list); + addWorkstationsAndGlass(list); + newLine(list); addWoodTypes(list); newPage(list); @@ -98,9 +100,6 @@ public final class CreativeMenuContents { addOrganicTypes(list); newPage(list); - addWorkstationsAndGlass(list); - newPage(list); - addTools(list); newPage(list); @@ -180,6 +179,9 @@ public final class CreativeMenuContents { list.add(new ItemStack(Items.TOOL_SHEARS)); list.add(new ItemStack(Items.TOOL_SHEARS_STEEL)); + + list.add(new ItemStack(Items.MAP)); + list.add(new ItemStack(Items.LABEL)); newLine(list); addBucketVariants(list, Items.BUCKET_IRON); @@ -191,25 +193,23 @@ public final class CreativeMenuContents { list.add(new ItemStack(Items.WAND_MONSTER_SPAWNER)); list.add(new ItemStack(Items.WAND_NBT)); list.add(new ItemStack(Items.TOOL_FISHINGROD)); + addGap(list, 1); + list.add(new ItemStack(Items.TOOL_COMPASS)); newLine(list); list.add(new ItemStack(Items.TOOL_BOW)); list.add(new ItemStack(Items.AMMO_ARROW)); list.add(new ItemStack(Items.AMMO_ARROW_GOLD)); list.add(new ItemStack(Items.AMMO_ARROW_FLAMING)); + addGap(list, 1); + list.add(new ItemStack(Items.TOOL_CLOCK)); newLine(list); list.add(new ItemStack(Items.HANDCANNON_UNLOADED)); list.add(new ItemStack(Items.AMMO_CHARGE_EXPLOSIVE)); list.add(new ItemStack(Items.AMMO_FIREBALL)); - newLine(list); - - list.add(new ItemStack(Items.TOOL_COMPASS)); - list.add(new ItemStack(Items.TOOL_CLOCK)); + addGap(list, 2); list.add(new ItemStack(Items.TOOL_CALENDAR)); - list.add(new ItemStack(Items.MAP)); - list.add(new ItemStack(Items.ROPE)); - list.add(new ItemStack(Items.LABEL)); newLine(list); } @@ -236,8 +236,21 @@ public final class CreativeMenuContents { addBlock(list, Blocks.BUTTON_STONE); addBlock(list, Blocks.PRESSURE_PLATE_STONE); addBlock(list, Blocks.PRESSURE_PLATE_COBBLE_STONE); + newLine(list); + + addBlock(list, Blocks.SLATE); + addBlock(list, Blocks.LAYER_SLATE); + + addBlock(list, Blocks.BRICK_SLATE); + addBlock(list, Blocks.STAIRS_BRICK_SLATE); + addBlock(list, Blocks.SLAB_BRICK_SLATE); + + addBlock(list, Blocks.SLATE_POLISHED); + addBlock(list, Blocks.SLAB_SLATE_POLISHED); + list.add(new ItemStack(Items.STATUE_SLATE)); newPage(list); + addBlock(list, Blocks.BASALT); addBlock(list, Blocks.MOSS_BASALT); @@ -256,7 +269,7 @@ public final class CreativeMenuContents { addBlock(list, Blocks.BUTTON_BASALT); addBlock(list, Blocks.PRESSURE_PLATE_BASALT); addBlock(list, Blocks.PRESSURE_PLATE_COBBLE_BASALT); - newPage(list); + newLine(list); addBlock(list, Blocks.LIMESTONE); addBlock(list, Blocks.MOSS_LIMESTONE); @@ -296,7 +309,7 @@ public final class CreativeMenuContents { addBlock(list, Blocks.BUTTON_GRANITE); addBlock(list, Blocks.PRESSURE_PLATE_GRANITE); addBlock(list, Blocks.PRESSURE_PLATE_COBBLE_GRANITE); - newPage(list); + newLine(list); addBlock(list, Blocks.PERMAFROST); @@ -333,7 +346,7 @@ public final class CreativeMenuContents { addBlock(list, Blocks.BUTTON_NETHERRACK); addBlock(list, Blocks.PRESSURE_PLATE_NETHERRACK); addBlock(list, Blocks.PRESSURE_PLATE_COBBLE_NETHERRACK); - newPage(list); + newLine(list); addBlock(list, Blocks.GLOOMSTONE); @@ -371,7 +384,7 @@ public final class CreativeMenuContents { addBlock(list, Blocks.SLAB_BRICK_BRIMSTONE); addBlock(list, Blocks.BUTTON_BRIMSTONE); addBlock(list, Blocks.PRESSURE_PLATE_BRIMSTONE); - newPage(list); + newLine(list); addBlock(list, Blocks.MARBLE); @@ -384,18 +397,8 @@ public final class CreativeMenuContents { addBlock(list, Blocks.SLAB_CAPSTONE_MARBLE); list.add(new ItemStack(Items.STATUE_MARBLE)); list.add(new ItemStack(Items.STATUE_PIGMAN)); - newLine(list); - - addBlock(list, Blocks.SLATE); - addBlock(list, Blocks.LAYER_SLATE); - addBlock(list, Blocks.BRICK_SLATE); - addBlock(list, Blocks.STAIRS_BRICK_SLATE); - addBlock(list, Blocks.SLAB_BRICK_SLATE); - addBlock(list, Blocks.SLATE_POLISHED); - addBlock(list, Blocks.SLAB_SLATE_POLISHED); - list.add(new ItemStack(Items.STATUE_SLATE)); newPage(list); } @@ -409,7 +412,6 @@ public final class CreativeMenuContents { addBlock(list, Blocks.LOG_THORN); addBlock(list, Blocks.LOG_PALM); addBlock(list, Blocks.LOG_SCORCHED); - newPage(list); } private static void addWoodTypes(List list) { @@ -451,7 +453,7 @@ public final class CreativeMenuContents { list.add(new ItemStack(Items.SIGN_PAINTED, 1, color.itemMeta)); } - private static void addPaintedWoodBlock(List list, Block block, DyeColor color) { + private static void addPaintedWoodBlock(@NotNull List list, Block block, DyeColor color) { list.add(new ItemStack(block, 1, painted(block).toMetadata(color))); } @@ -864,6 +866,7 @@ public final class CreativeMenuContents { addBlock(list, Blocks.FENCE_STEEL); list.add(new ItemStack(Items.PAINTING)); + list.add(new ItemStack(Items.ROPE)); newLine(list); list.add(new ItemStack(Items.DOOR_GLASS)); 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 2ad48ff04..e4d61e392 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 @@ -210,6 +210,20 @@ public enum Direction { } } + public static @NotNull double[] YAW_MAP = new double[6]; + static { + for (int i = 0; i < 4; i++) { + final double yaw = i * 90D; + final var dir = Direction.fromYaw(yaw); + YAW_MAP[dir.id] = yaw; + } + YAW_MAP[UP.id] = YAW_MAP[DOWN.id] = Double.NaN; + } + + public double yaw() { + return YAW_MAP[this.id]; + } + /** * Right-handed around the +X axis */ 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 27a143f3f..5546e3925 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 @@ -2986,18 +2986,21 @@ public abstract class World implements MutableWorldSource { return this.dimensionData.getWorldType(); } - public @NotNull EntityItem dropItem(final @NotNull TilePosc tilePos, final @NotNull ItemStack itemStack) { - final float radius = 0.7f; - final double x = (this.rand.nextFloat() * radius) + (1.0F - radius) * 0.5D; - final double y = (this.rand.nextFloat() * radius) + (1.0F - radius) * 0.5D; - final double z = (this.rand.nextFloat() * radius) + (1.0F - radius) * 0.5D; + public @NotNull EntityItem dropItem(double x, double y, double z, final @NotNull ItemStack itemStack, double radius) { + x += this.rand.nextFloat() * radius; + y += this.rand.nextFloat() * radius; + z += this.rand.nextFloat() * radius; - final @NotNull EntityItem item = new EntityItem(this, tilePos.x() + x, tilePos.y() + y, tilePos.z() + z, itemStack); + final @NotNull EntityItem item = new EntityItem(this, x, y, z, itemStack); item.pickupDelay = 10; this.entityJoinedWorld(item); return item; } + public @NotNull EntityItem dropItem(final @NotNull TilePosc tilePos, final @NotNull ItemStack itemStack) { + return this.dropItem(tilePos.x(), tilePos.y(), tilePos.z(), itemStack, 0.7); + } + @Deprecated public final @NotNull EntityItem dropItem(final int x, final int y, final int z, final @NotNull ItemStack itemStack) { return this.dropItem(new TilePos(x, y, z), itemStack);