diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntity.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntity.java index 535d28847..5deb76c64 100644 --- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntity.java +++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntity.java @@ -30,7 +30,6 @@ public abstract class TileEntity implements ICarriable public TileEntity() { } - public void tick() { } @@ -159,29 +158,24 @@ public abstract class TileEntity implements ICarriable @Override public void drop(World world, Entity holder) { + if (world.isClientSide) return; + if (ICarriable.tryPlaceAroundHolder(this, world, holder)) return; + final int holderX = MathHelper.floor(holder.x); final int holderY = MathHelper.floor(holder.y); final int holderZ = MathHelper.floor(holder.z); - for (int _y = holderY - 1; _y <= holderY + 1; _y++) { - for (int _x = holderX - 1; _x <= holderX + 1; _x++) { - for (int _z = holderZ - 1; _z <= holderZ + 1; _z++) { - if (tryPlace(world, holder, _x, _y - 1, _z, Side.TOP, 0, 0)) { - return; - } - } - } - } - if (world.isClientSide) return; - dropContents(world, holderX, holderY, holderZ); + this.dropContents(world, holderX, holderY, holderZ); assert carriedBlock != null; carriedBlock.block().dropBlockWithCause(world, EnumDropCause.WORLD, holderX, holderY, holderZ, carriedBlock.metadata, this, null); // TODO this might be scuffed since the position won't have correlated to a real block } + // TODO: clean this up in the future tileEntity refactor protected @NotNull ICarriable pickup(@NotNull World world, @NotNull Entity holder, @NotNull TilePosc tilePos_) { Block currentBlock = world.getBlock(tilePos.x, tilePos.y, tilePos.z); int currentMeta = world.getBlockMetadata(tilePos.x, tilePos.y, tilePos.z); world.removeBlockTileEntity(tilePos.x, tilePos.y, tilePos.z); world.setBlockRaw(tilePos.x, tilePos.y, tilePos.z, 0); + world.markBlockDirty(tilePos); final boolean isSignal = this.getBlock().isSignalSource(); world.notifyBlocksInRadiusOfNeighborChange((isSignal) ? 2 : 1, tilePos, currentBlock); this.worldObj = null; diff --git a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBase.java b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBase.java index d066e7073..762cb1c4d 100644 --- a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBase.java +++ b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBase.java @@ -109,7 +109,7 @@ public class BlockLogicPistonBase extends BlockLogic { case EVENT_DETACH: break; case EVENT_DETACH_EXTEND: - world.setBlockData(tilePos, IS_EXTENDED.set(data, isOut ? 1 : 0)); + world.setBlockDataNotify(tilePos, IS_EXTENDED.set(data, isOut ? 1 : 0)); break; case EVENT_EXTEND: if (isOut) { @@ -135,15 +135,16 @@ public class BlockLogicPistonBase extends BlockLogic { assert false; return; case EVENT_DETACH: - world.playBlockEvent(tilePos, LevelListener.EVENT_DISPENSER_PARTICLES, DIRECTION.get(data)); + this.emitParticles(world, tilePos, Direction.fromId(DIRECTION.get(data))); sound = (isOut) ? "tile.piston.detached" : "tile.piston.attached"; - volumn = 1.0F; + volumn = 0.5F; pitch = 0.6F; break; case EVENT_DETACH_EXTEND: - world.playBlockEvent(tilePos, LevelListener.EVENT_DISPENSER_PARTICLES, DIRECTION.get(data)); + this.emitParticles(world, tilePos, Direction.fromId(DIRECTION.get(data))); sound = (isOut) ? "tile.piston.detached.out" : "tile.piston.detached.in"; - volumn = pitch = 1.0F; + volumn = 0.2F; + pitch = 0.5F; break; case EVENT_EXTEND: sound = (isOut) ? "tile.piston.out" : "tile.piston.in"; @@ -154,7 +155,7 @@ public class BlockLogicPistonBase extends BlockLogic { world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, x, y, z, sound, volumn, pitch); } - + private static boolean hasNeighborSignal(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Direction dir) { final var queryPos = new TilePos(); for (final var search : Direction.all) { @@ -170,6 +171,37 @@ public class BlockLogicPistonBase extends BlockLogic { return false; } + private void emitParticles(@NotNull World world, @NotNull TilePosc pos, @NotNull Direction direction) { + final var random = world.rand; + + var thickness = HEAD_BLOCK_MAP[this.typeId].getLogic().headThickness; + + final double dx,dy,dz; + dx = direction.offsetX(); + dy = direction.offsetY(); + dz = direction.offsetZ(); + + final double ox,oy,oz; + ox = pos.x() + 0.5 + dx * (0.5-thickness); + oy = pos.y() + 0.5 + dy * (0.5-thickness); + oz = pos.z() + 0.5 + dz * (0.5-thickness); + + for (int i = 0; i < 8; i++) { + final double v = random.nextDouble() * 0x1p-5; + + final double x,y,z; + x = ox + random.nextDouble() * 0x1p-2 * dx + random.nextDouble() * 0x1p-4 * (dy + dz); + y = oy + random.nextDouble() * 0x1p-2 * dy + random.nextDouble() * 0x1p-4 * (dx + dz); + z = oz + random.nextDouble() * 0x1p-2 * dz + random.nextDouble() * 0x1p-4 * (dx + dy); + + final double vx,vy,vz; + vx = dx * v + random.nextGaussian() * 0x1p-7; + vy = dy * v + random.nextGaussian() * 0x1p-7; + vz = dz * v + random.nextGaussian() * 0x1p-7; + world.spawnParticle("smoke", x,y,z, vx, vy, vz, 0, 16.0, false); + } + } + // Piston tests: // ================= @@ -385,6 +417,7 @@ public class BlockLogicPistonBase extends BlockLogic { final var moving = new TileEntityMovingPistonBlock( MovingType.RETRACTING_PISTON, this.block, dir.id, null, dir); + world.setBlockTypeRaw(tilePos, Blocks.AIR); world.setBlockTypeDataEntity(tilePos, Blocks.PISTON_MOVING, data, moving); if (this.canPull) { @@ -397,7 +430,7 @@ public class BlockLogicPistonBase extends BlockLogic { // logically, retraction should only update head immediately, and base 3 ticks after // but this emulates the old behavior world.notifyBlocksOfNeighborChange(tilePos, this.block); - world.notifyBlocksOfNeighborChange(headPos, Blocks.AIR); + world.notifyBlocksOfNeighborChange(headPos, null); } private static void pull(@NotNull World world, @NotNull TilePosc headPos, @NotNull Direction dir) { @@ -418,6 +451,7 @@ public class BlockLogicPistonBase extends BlockLogic { if (Movability.test(world, src) != Movability.MOVES) { world.removeTileEntity(tar); + world.setBlockType(tar, Blocks.AIR); return; } @@ -477,16 +511,11 @@ public class BlockLogicPistonBase extends BlockLogic { @Override public @NotNull AABBdc getBoundsFromState(@NotNull WorldSource source, @NotNull TilePosc tilePos) { int data = getValidatedBaseData(source, tilePos, this); - if (!IS_DETACHED_OR_EXTENDED.bool(data)) return new AABBd(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + if (!IS_DETACHED_OR_EXTENDED.bool(data)) return this.bounds; final var dir = Direction.fromId(DIRECTION.get(data)); final var thickness = HEAD_BLOCK_MAP[this.typeId].getLogic().headThickness; - - final var min = new Vector3d(0); - final var max = new Vector3d(1); - - dir.offsetScaled(dir.isPositive() ? max : min, (dir.isNegative()) ? thickness : -thickness); - return new AABBd(min, max); + return getBaseCollision(dir, thickness); } @Override @@ -494,6 +523,12 @@ public class BlockLogicPistonBase extends BlockLogic { return false; } + @Override + public boolean renderAsNormalBlockOnCondition(@NotNull WorldSource source, @NotNull TilePosc tilePos) { + int data = getValidatedBaseData(source, tilePos, this); + return !IS_DETACHED_OR_EXTENDED.bool(data); + } + private static final ISupport[] SUPPORT_LUT; static { final var F = FullSupport.INSTANCE; diff --git a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonMoving.java b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonMoving.java index 9cf4d026d..67f43c127 100644 --- a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonMoving.java +++ b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonMoving.java @@ -4,6 +4,7 @@ import net.minecraft.core.block.Blocks; import net.minecraft.core.block.entity.TileEntity; import net.minecraft.core.block.Block; import net.minecraft.core.block.BlockLogic; +import net.minecraft.core.block.material.Material; import net.minecraft.core.block.material.Materials; import net.minecraft.core.entity.player.Player; import net.minecraft.core.enums.EnumDropCause; @@ -13,6 +14,9 @@ import net.minecraft.core.world.WorldSource; import net.minecraft.core.world.World; import net.minecraft.core.world.pos.TilePosc; +import static net.minecraft.core.block.piston.PistonCommon.HEAD_BLOCK_MAP; +import static net.minecraft.core.block.piston.PistonCommon.getBaseCollision; + import java.util.List; import org.jetbrains.annotations.NotNull; @@ -82,17 +86,15 @@ public class BlockLogicPistonMoving extends BlockLogic { @NotNull World world, @NotNull TilePosc tilePos, @NotNull AABBdc aabb, @NotNull List<@NotNull AABBdc> aabbList ) { - if (!(world.getTileEntity(tilePos) instanceof TileEntityMovingPistonBlock moving)) { - super.getCollisionAABBs(world, tilePos, aabb, aabbList); - return; - } - if (moving.isExtending || !moving.isSourcePiston) { - super.getCollisionAABBs(world, tilePos, aabb, aabbList); - return; - } aabbList.add(this.getCollisionAABB(world, tilePos)); - // prevents entities from phasing into piston base - aabbList.add(new AABBd(0, 0, 0, 1, 1, 1).translate(tilePos.x(), tilePos.y(), tilePos.z())); + + if (!(world.getTileEntity(tilePos) instanceof TileEntityMovingPistonBlock moving)) return; + + final boolean isRetractingPiston = !moving.isExtending && moving.isSourcePiston; + if (!isRetractingPiston || !(moving.movingBlock.getLogic() instanceof BlockLogicPistonBase base)) return; + + final var thickness = HEAD_BLOCK_MAP[base.typeId].getLogic().headThickness; + aabbList.add(getBaseCollision(moving.direction, thickness).translate(tilePos.x(), tilePos.y(), tilePos.z())); return; } @@ -111,4 +113,9 @@ public class BlockLogicPistonMoving extends BlockLogic { } return super.getBoundsFromState(source, tilePos); } + + @Override + public int getPistonPushReaction(@NotNull World world, @NotNull TilePosc tilePos) { + return Material.PISTON_CANT_PUSH; + } } diff --git a/game/core/src/main/java/net/minecraft/core/block/piston/CarriedPistonHead.java b/game/core/src/main/java/net/minecraft/core/block/piston/CarriedPistonHead.java index a67feeed1..51abfd297 100644 --- a/game/core/src/main/java/net/minecraft/core/block/piston/CarriedPistonHead.java +++ b/game/core/src/main/java/net/minecraft/core/block/piston/CarriedPistonHead.java @@ -8,8 +8,10 @@ import net.minecraft.core.block.Block; import net.minecraft.core.block.motion.ICarriedBlock; import net.minecraft.core.entity.Entity; import net.minecraft.core.entity.Mob; +import net.minecraft.core.enums.EnumDropCause; import net.minecraft.core.enums.PlacementMode; 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.ICarriable; import net.minecraft.core.world.World; @@ -83,6 +85,16 @@ public class CarriedPistonHead implements ICarriable, ICarriedBlock { @Override public void drop(World world, Entity holder) { + if (world.isClientSide) return; + if (ICarriable.tryPlaceAroundHolder(this, world, holder)) return; + + final int holderX = MathHelper.floor(holder.x); + final int holderY = MathHelper.floor(holder.y); + final int holderZ = MathHelper.floor(holder.z); + + this.block().dropWithCause( + world, EnumDropCause.WORLD, new TilePos(holderX, holderY, holderZ), + this.metadata(), null, null); } @Override diff --git a/game/core/src/main/java/net/minecraft/core/block/piston/PistonCommon.java b/game/core/src/main/java/net/minecraft/core/block/piston/PistonCommon.java index ebf72e971..568e7f29c 100644 --- a/game/core/src/main/java/net/minecraft/core/block/piston/PistonCommon.java +++ b/game/core/src/main/java/net/minecraft/core/block/piston/PistonCommon.java @@ -1,6 +1,8 @@ package net.minecraft.core.block.piston; import org.jetbrains.annotations.NotNull; +import org.joml.Vector3d; +import org.joml.primitives.AABBd; import net.minecraft.core.block.Block; import net.minecraft.core.block.Blocks; @@ -26,8 +28,8 @@ public abstract class PistonCommon { public static final PackedField NEW_FORMAT_SIGNATURE = new PackedField(7, 1); - public static final PackedField IS_STICKY = new PackedField(4, 1); - public static final PackedField IS_STEEL = new PackedField(5, 1); + public static final PackedField IS_STICKY = new PackedField(3, 1); + public static final PackedField IS_STEEL = new PackedField(4, 1); public static final PackedField IS_DETACHED_OR_EXTENDED = new PackedField( IS_DETACHED.mask | IS_EXTENDED.mask @@ -153,6 +155,13 @@ public abstract class PistonCommon { ? getValidatedBaseData(world, bpos, base) : DATA_INVALID; } + + public static @NotNull AABBd getBaseCollision(@NotNull Direction dir, double headThickness) { + final var min = new Vector3d(0); + final var max = new Vector3d(1); + dir.offsetScaled(dir.isPositive() ? max : min, -headThickness); + return new AABBd(min, max); + } public static enum MovingType { EXTENDING(true, false), diff --git a/game/core/src/main/java/net/minecraft/core/block/piston/TileEntityMovingPistonBlock.java b/game/core/src/main/java/net/minecraft/core/block/piston/TileEntityMovingPistonBlock.java index 8822b3578..cdde69de5 100644 --- a/game/core/src/main/java/net/minecraft/core/block/piston/TileEntityMovingPistonBlock.java +++ b/game/core/src/main/java/net/minecraft/core/block/piston/TileEntityMovingPistonBlock.java @@ -6,9 +6,13 @@ import net.minecraft.core.block.Block; import net.minecraft.core.block.Blocks; import net.minecraft.core.util.helper.Direction; import com.mojang.nbt.tags.CompoundTag; + +import net.minecraft.core.world.pos.ChunkPos; import net.minecraft.core.world.pos.TilePos; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.joml.Vector3d; import org.joml.primitives.AABBd; import org.joml.primitives.AABBdc; @@ -30,10 +34,16 @@ public class TileEntityMovingPistonBlock extends TileEntity float progressCur = 0F, progressPrev = 0F; // these would otherwise be reallocated each tick, might as well store them here - @NotNull AABBd collision = new AABBd(); - @NotNull AABBd bounds = new AABBd(); + final @NotNull AABBd bounds = new AABBd(); + final @NotNull AABBd collision = new AABBd(); + final @NotNull AABBd sweptCollision = new AABBd(); + final @NotNull Vector3d directionScaled = new Vector3d(); + + // awkward + // TODO provide an actual initiallization event that is guaranteed to be called after + // TODO tile entity is valid (i.e. not .validate()) + private boolean isCollisionInited = false; - public @NotNull Block movingBlock() { return this.movingBlock; } public int movingBlockData() { return this.movingBlockData; } public @Nullable TileEntity movingTileEntity() { return this.movingTileEntity; } @@ -65,72 +75,63 @@ public class TileEntityMovingPistonBlock extends TileEntity this.direction = direction; this.isExtending = type.isExtending; this.isSourcePiston = type.isSourcePiston; + + this.movingDirection().getOffsetScaled(this.directionScaled, PROGRESS_DELTA); } - private final void initAABBs() { - double dx,dy,dz; - final var sign = (this.isExtending) ? -1 : 1; - dx = sign * this.direction.offsetX(); - dy = sign * this.direction.offsetY(); - dz = sign * this.direction.offsetZ(); + @Override + public void validate() { + super.validate(); + + if (this.worldObj == null) return; + if (!this.worldObj.isChunkLoaded(new ChunkPos(this.tilePos))) return; + + this.initCollision(); + } + + private final void initCollision() { + assert this.worldObj != null; + assert this.worldObj.isChunkLoaded(new ChunkPos(this.tilePos)); + final var dir = this.movingDirection(); + + final var off = dir.opposite().getOffset(new Vector3d()); this.bounds - .set(this.movingBlock.getBoundsFromState(this.worldObj, tilePos)) - .translate(dx, dy, dz); + .set(this.movingBlock.getBoundsFromState(this.worldObj, this.tilePos)) + .translate(off); var collision = this.movingBlock.getCollisionAABB(this.worldObj, this.tilePos); if (collision == null) collision = new AABBd(0,0,0,0,0,0); - this.collision .set(collision) - .translate(dx, dy, dz); - } + .translate(off); - private final void translateAABBs(float scale) { - final float dx,dy,dz; - scale = (this.isExtending) ? scale : -scale; - dx = scale * this.direction.offsetX(); - dy = scale * this.direction.offsetY(); - dz = scale * this.direction.offsetZ(); - this.bounds.translate(dx, dy, dz); - this.collision.translate(dx, dy, dz); + this.isCollisionInited = true; } + @Override public void tick() { + if (!this.isCollisionInited) this.initCollision(); this.progressPrev = this.progressCur; - if (this.progressCur == 0.0f) this.initAABBs(); if (this.progressCur > (1.0F - 0x1p-12F)) { this.finalTick(); } else { this.progressCur += PROGRESS_DELTA; - this.translateAABBs(PROGRESS_DELTA); - this.moveCollidedEntities(PROGRESS_DELTA + 0x1p-7F); - } - } - private final void moveCollidedEntities(float scale) { - assert this.worldObj != null; + this.sweptCollision.set(this.collision); + this.sweptCollision.translate(this.directionScaled); + this.sweptCollision.union(this.collision); - final var dir = this.movingDirection(); - final float dx,dy,dz; - dx = dir.offsetX() * scale; - dy = dir.offsetY() * scale; - dz = dir.offsetZ() * scale; - - final int axis = dir.id >> 1; // y z x - final boolean neg = (dir.id & 1) == 0; - final double lim = 0x1p-4; - - final var entities = this.worldObj.getEntitiesWithinAABBExcludingEntity(null, this.collision); - for (final @NotNull var e : entities) { - if (e.noPhysics) continue; - e.move(dx, dy, dz); - switch (axis) { - case 2 -> e.xd = (neg) ? Math.min(e.xd, -lim) : Math.max(e.xd, lim); - case 0 -> e.yd = (neg) ? Math.min(e.yd, -lim) : Math.max(e.yd, lim); - case 1 -> e.zd = (neg) ? Math.min(e.zd, -lim) : Math.max(e.zd, lim); + final var entities = this.worldObj.getEntitiesWithinAABBExcludingEntity(null, this.sweptCollision); + for (final var e : entities) { + if (e.noPhysics) continue; + e.move(this.directionScaled.x, this.directionScaled.y, this.directionScaled.z); } + + // translate block collision after entities are moved + this.collision.translate(this.directionScaled); + this.bounds.translate(this.directionScaled); } } 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 fc9c59284..453204786 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 @@ -41,8 +41,10 @@ public class ItemDoor extends Item { Direction leftDir = player.getHorizontalPlacementDirection(side).rotateY(1); int meta = leftDir.legacyHorizontalIndex(); - int isSolidBlockLeft = (isSupported(world, blockPos, leftDir, false) ? 1 : 0) + (isSupported(world, blockPos.up(new TilePos()), leftDir, false) ? 1 : 0); - int isSolidBlockRight = (isSupported(world, blockPos, leftDir.opposite(), true) ? 1 : 0) + (isSupported(world, blockPos.up(new TilePos()), leftDir.opposite(), true) ? 1 : 0); + 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; @@ -68,15 +70,17 @@ public class ItemDoor extends Item { } world.setBlockTypeData(blockPos, this.doorBlockBottom, meta); - world.setBlockTypeData(blockPos.up(new TilePos()), this.doorBlockTop, meta); + world.setBlockTypeData(upperPos, this.doorBlockTop, meta); selfStack.consumeItem(player); this.doorBlockBottom.onPlacedByMob(world, blockPos, side, player, xHit, yHit); - this.doorBlockTop.onPlacedByMob(world, blockPos.up(new TilePos()), 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; 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 a34f6a9d6..ea3aacaa6 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 @@ -11,12 +11,12 @@ import net.minecraft.core.entity.Mob; import net.minecraft.core.world.pos.TilePos; public enum Direction { - DOWN (0b000, "north"), - UP (0b001, "east"), - NORTH (0b010, "south"), - SOUTH (0b011, "west"), - WEST (0b100, "up"), - EAST (0b101, "down"), + DOWN (0b000, "down"), + UP (0b001, "up"), + NORTH (0b010, "north"), + SOUTH (0b011, "south"), + WEST (0b100, "west"), + EAST (0b101, "east"), /** * Method implementations might not guarantee correct behaviour (error safety) when passed diff --git a/game/core/src/main/java/net/minecraft/core/world/ICarriable.java b/game/core/src/main/java/net/minecraft/core/world/ICarriable.java index da753bdeb..d1b45581e 100644 --- a/game/core/src/main/java/net/minecraft/core/world/ICarriable.java +++ b/game/core/src/main/java/net/minecraft/core/world/ICarriable.java @@ -5,15 +5,21 @@ import com.mojang.nbt.tags.CompoundTag; import net.minecraft.core.block.motion.CarriedBlock; import net.minecraft.core.block.piston.CarriedPistonHead; import net.minecraft.core.entity.Entity; +import net.minecraft.core.enums.EnumDropCause; +import net.minecraft.core.util.helper.MathHelper; import net.minecraft.core.util.helper.Side; +import net.minecraft.core.world.pos.TilePosc; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; public interface ICarriable { Logger LOGGER = LogUtils.getLogger(); /** * Called every tick an entity holds this object - */ - void heldTick(World world, Entity holder); + */ + void heldTick(World world, Entity holder); // TODO TilePos refactor /** @@ -27,6 +33,25 @@ public interface ICarriable { */ void drop(World world, Entity holder); + static boolean tryPlaceAroundHolder( + @NotNull ICarriable self, + @NotNull World world, @NotNull Entity holder + ) { + final int holderX = MathHelper.floor(holder.x); + final int holderY = MathHelper.floor(holder.y); + final int holderZ = MathHelper.floor(holder.z); + for (int y = holderY - 1; y <= holderY + 1; y++) { + for (int x = holderX - 1; x <= holderX + 1; x++) { + for (int z = holderZ - 1; z <= holderZ + 1; z++) { + if (self.tryPlace(world, holder, x, y - 1, z, Side.TOP, 0, 0)) { + return true; + } + } + } + } + return false; + } + // moved to ICarriableSource // boolean canBeCarried(World world, Entity potentialHolder); // ICarriable pickup(World world, Entity holder, TilePosc tilePos); diff --git a/game/core/src/main/resources/assets/minecraft/lang/en_US/tile.lang b/game/core/src/main/resources/assets/minecraft/lang/en_US/tile.lang index 0d97b30e8..f337b2865 100644 --- a/game/core/src/main/resources/assets/minecraft/lang/en_US/tile.lang +++ b/game/core/src/main/resources/assets/minecraft/lang/en_US/tile.lang @@ -1539,7 +1539,7 @@ tile.boulder.sulfuric.name=Sulfuric Boulder tile.boulder.sulfuric.desc=A large sulfuric rock. tile.brimthaw.name=Brimthaw -tile.brimthaw.desc=Brimstone laced with glowing rock. +tile.brimthaw.desc=Acid that's been partially cooled. Melts in corrosive liquid. tile.ember.name=Ember tile.ember.desc=Smoldering, explosive remnants of a forgotten world. diff --git a/game/core/src/main/resources/assets/minecraft/sounds/sounds.json b/game/core/src/main/resources/assets/minecraft/sounds/sounds.json index 5181f4807..a431e1e15 100644 --- a/game/core/src/main/resources/assets/minecraft/sounds/sounds.json +++ b/game/core/src/main/resources/assets/minecraft/sounds/sounds.json @@ -716,24 +716,16 @@ "tile/piston/in.ogg" ] }, - "tile.piston.detached.in": { - "subtitle": "subtitles.tile.piston.detached.in", + "tile.piston.detached.out": { + "subtitle": "subtitles.tile.piston.detached.out", "sounds": [ - { - "name": "random.click", - "type": "event", - "pitch": 0.85 - } + "tile/piston/out.ogg" ] }, - "tile.piston.detached.out": { - "subtitle": "subtitles.tile.piston.detached.out", + "tile.piston.detached.in": { + "subtitle": "subtitles.tile.piston.detached.in", "sounds": [ - { - "name": "random.click", - "type": "event", - "pitch": 0.8 - } + "tile/piston/in.ogg" ] }, "mob.cow": {