diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..9b6d6732a --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,39 @@ +# Changelog + +## [8.1] +### Features + +### Fixes + +## [8.0.2] +### Features + +### Fixes +- Properly masked axis bits when calculating axis in BlockLogicAxisAligned +- Fixed an NPE with item entities +- Fixed firefly capture returning current count instead of captured amount +- Fixed guidebook index not un-hiding mob entries +- Fixed statue swap deleting armor +- Fixed fog not being applied in font shaders +- Fixed fire extinguish removing the wrong block +- Fixed incorrect indexing in font renderer +- Fixed cocoa beans not growing +- Fixed cocoa beans being harvestable when not fully grown +- Fixed NPE in EntityCameraThirdPersonRear +- Fixed ghast, pigman and wolf attacking player in creative mode +- Fixed being able to pick blocks while holding an object +- Fixed autosave timer using float and defaulting to OFF when reset +- Fixed shading applying to map render +- Fixed sign consuming glowstone dust twice +- Fixed off-by-one error in findTopSolidBlock +- Fixed carried block/tile entity placement behavior +- Fixed cacao leaves dropping 2 cocoa beans at growth stage 3 +- Fixed a credits screen crash +- Fixed some tile entities wiping item NBT when broken + - These tile entities no longer wipe item nbt when broken: + - Furnaces + - Blast Furnaces + - Trommels + - Dispensers +- Fix unban command banning player instead +- Fix fence bounding box not being offset \ No newline at end of file diff --git a/game/client/src/main/java/net/minecraft/client/Minecraft.java b/game/client/src/main/java/net/minecraft/client/Minecraft.java index 66b997a24..b90454d22 100644 --- a/game/client/src/main/java/net/minecraft/client/Minecraft.java +++ b/game/client/src/main/java/net/minecraft/client/Minecraft.java @@ -2618,9 +2618,13 @@ public class Minecraft return GameSettings.SHOW_DEBUG_SCREEN.value && this.thePlayer != null && this.thePlayer.getGamemode() == Gamemodes.CREATIVE; } + + /** + * @return The time between auto saves in seconds. + */ public int getAutosaveTimer() { - return (int) (GameSettings.AUTOSAVE_TIMER.value * 24) * 5; + return GameSettings.AUTOSAVE_TIMER.value * 5; } @Override diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenCredits.java b/game/client/src/main/java/net/minecraft/client/gui/ScreenCredits.java index 723b1c19a..cfa5c71b0 100644 --- a/game/client/src/main/java/net/minecraft/client/gui/ScreenCredits.java +++ b/game/client/src/main/java/net/minecraft/client/gui/ScreenCredits.java @@ -18,6 +18,7 @@ import org.jetbrains.annotations.Nullable; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; import org.slf4j.Logger; +import paulscode.sound.SoundSystem; import java.awt.*; import java.io.BufferedReader; @@ -132,6 +133,7 @@ public class ScreenCredits extends Screen { @Override public void tick() { + if (!SoundSystem.initialized()) return; if (!this.playing || !SoundEngine.getSoundSystem().playing(SoundEngine.STREAMING)) { this.mc.sndManager.playMusic(SONGS[(int) (Math.random() * SONGS.length)], 0, 0, 0, 1.0f, 1.0f); this.playing = true; diff --git a/game/client/src/main/java/net/minecraft/client/gui/guidebook/mobs/GuidebookSectionMob.java b/game/client/src/main/java/net/minecraft/client/gui/guidebook/mobs/GuidebookSectionMob.java index 20ab809d3..3a64cd0a5 100644 --- a/game/client/src/main/java/net/minecraft/client/gui/guidebook/mobs/GuidebookSectionMob.java +++ b/game/client/src/main/java/net/minecraft/client/gui/guidebook/mobs/GuidebookSectionMob.java @@ -4,6 +4,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.guidebook.GuidebookPage; import net.minecraft.client.gui.guidebook.GuidebookSection; import net.minecraft.client.gui.guidebook.SearchableGuidebookSection; +import net.minecraft.client.option.GameSettings; import net.minecraft.core.data.registry.recipe.SearchQuery; import net.minecraft.core.achievement.stat.StatList; import net.minecraft.core.entity.EntityDispatcher; @@ -92,7 +93,7 @@ public class GuidebookSectionMob boolean discovered = mc.statsCounter.readStat(StatList.mobEncounterStats.get(entry != null ? entry.namespaceID : null)) > 0; if (mc.thePlayer.getGamemode() == Gamemodes.CREATIVE) discovered = true; - if (discovered) { + if (discovered || !GameSettings.HIDE_UNDISCOVERED_ITEMS.value) { return I18n.getInstance().translateKey(mobInfo.getNameTranslationKey()); } else { return unknownName; diff --git a/game/client/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java b/game/client/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java index a31e8bfa7..90f30cf3f 100644 --- a/game/client/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java +++ b/game/client/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java @@ -103,7 +103,7 @@ public abstract class OptionsPages { .withComponent(new OptionsCategory("gui.options.page.general.category.miscellaneous") .withComponent(new BooleanOptionComponent(GameSettings.DISCORD_RICH_PRESENCE)) .withComponent(new BooleanOptionComponent(GameSettings.ENABLE_ITEM_CLUMPING)) - .withComponent(new FloatOptionComponent(GameSettings.AUTOSAVE_TIMER)) + .withComponent(new ToggleableOptionComponent<>(GameSettings.AUTOSAVE_TIMER)) ) .withComponent(new ShortcutComponent("gui.options.page.general.button.open_worlds_folder", () -> FileOpener.open(new File(mc.getMinecraftDir(), "saves")))) .withComponent(new ShortcutComponent("gui.options.page.general.button.open_screenshots_folder", () -> { diff --git a/game/client/src/main/java/net/minecraft/client/option/GameSettings.java b/game/client/src/main/java/net/minecraft/client/option/GameSettings.java index 74705fb43..03761aeb1 100644 --- a/game/client/src/main/java/net/minecraft/client/option/GameSettings.java +++ b/game/client/src/main/java/net/minecraft/client/option/GameSettings.java @@ -303,17 +303,13 @@ public final class GameSettings { public static final @NotNull OptionFloat COLOR_CORRECTION_OVERWORLD = register(new OptionFloat("colorCorrectionOverworld", 0.5f)); public static final @NotNull OptionFloat COLOR_CORRECTION_NETHER = register(new OptionFloat("colorCorrectionNether", 0.5f)); public static final @NotNull OptionBoolean SNEAK_TOGGLE = register(new OptionBoolean("sneakToggle", false)); - public static final @NotNull OptionFloat AUTOSAVE_TIMER = register(new OptionFloat("autosaveTimer", 0.04166666666F) - .addOnChangeCallback((mc, option) -> { - int max = 24; - option.value = (option.value + max) % max; - }) + public static final @NotNull OptionRange AUTOSAVE_TIMER = register(new OptionRange("autosaveTimer", 1, 25) .withDisplayStringProvider((mc, i18n, option) -> { - int timer = (int) (option.value * 24); - if (timer == 0) { + final int value = option.value; + if (value == 0) { return i18n.translateKey("options.autosaveTimer.off"); } else { - return (timer * 5) + " seconds"; + return (value * 5) + " seconds"; } })); public static final @NotNull OptionBoolean ENABLE_ITEM_DRAGGING = register(new OptionBoolean("enableItemDragging", true)); diff --git a/game/client/src/main/java/net/minecraft/client/render/camera/EntityCameraThirdPersonRear.java b/game/client/src/main/java/net/minecraft/client/render/camera/EntityCameraThirdPersonRear.java index ae0757a95..0acb9e21d 100644 --- a/game/client/src/main/java/net/minecraft/client/render/camera/EntityCameraThirdPersonRear.java +++ b/game/client/src/main/java/net/minecraft/client/render/camera/EntityCameraThirdPersonRear.java @@ -43,6 +43,7 @@ public class EntityCameraThirdPersonRear Vector3dc start = new Vector3d(x, y, z); double cameraDistance = start.distance(x - numSteps * dx, y - numSteps * dy, z - numSteps * dz) - offset; + if (this.mc.currentWorld == null) return cameraDistance; for (int i = 0; i <= numSteps; i++) { HitResult hitResult = this.mc.currentWorld.checkBlockCollisionBetweenPoints( diff --git a/game/client/src/main/java/net/minecraft/client/render/font/FontRendererDefault.java b/game/client/src/main/java/net/minecraft/client/render/font/FontRendererDefault.java index 1033abc2b..1e89a348f 100644 --- a/game/client/src/main/java/net/minecraft/client/render/font/FontRendererDefault.java +++ b/game/client/src/main/java/net/minecraft/client/render/font/FontRendererDefault.java @@ -94,9 +94,9 @@ public class FontRendererDefault extends FontRenderer { this.renderStringInternal_colorValue.setLength(0); boolean ended = false; if (i + 2 < charLength) { - for (int j = 0, end = Math.min(charLength - 2, 8); j < end; j++) { // Maximum of 8 chars allowed in argb color code + for (int j = i + 2, end = Math.min(charLength, i + 10); j < end; j++) { // Maximum of 8 chars allowed in argb color code offAmount++; - final char pChar = chars.charAt(i + 2 + j); + final char pChar = chars.charAt(j); if (pChar == '>'){ ended = true; break; @@ -438,9 +438,9 @@ public class FontRendererDefault extends FontRenderer { if (cN == '<') { int offAmount = 1; boolean ended = false; - for (int j = 0; j < 8; j++) { // Maximum of 8 chars allowed in argb color code + for (int j = i + 2; j < Math.min(length, i + 10); j++) { // Maximum of 8 chars allowed in argb color code offAmount++; - if (line.charAt(j + i + 2) == '>'){ + if (line.charAt(j) == '>'){ ended = true; break; } diff --git a/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelMap.java b/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelMap.java index b69ecdb1f..349645142 100644 --- a/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelMap.java +++ b/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelMap.java @@ -102,6 +102,8 @@ public class ItemModelMap extends ItemModelStandard { final float scale2 = 0.015625F; GLRenderer.modelM4f().scale(scale2, scale2, scale2); + // Disable shading of map + GLRenderer.globalSetLightEnabled(false); // Render paper background of map this.mc.textureManager.bindTexture(this.mc.textureManager.loadTexture("/assets/minecraft/textures/misc/mapbg.png")); tessellator.startDrawingQuads(); diff --git a/game/client/src/main/resources/shaders/font.fsh b/game/client/src/main/resources/shaders/font.fsh index ead383197..ee302af81 100644 --- a/game/client/src/main/resources/shaders/font.fsh +++ b/game/client/src/main/resources/shaders/font.fsh @@ -25,9 +25,62 @@ uniform float uAlphaTest; uniform float uLightMapStrength; uniform vec4 uColor; +uniform vec2 uViewPortSize; +layout (std140) uniform FogState { + vec4 color; + int mode; + float start; + float end; + float density; +} fogState; + +layout (std140) uniform Matrices { + mat4 projection; + mat4 projectionInv; + mat4 view; + mat4 viewInv; +} matrices; + uniform sampler2D colortex; uniform sampler2D lighttex; +float distance() { + vec4 fragPos = matrices.projectionInv * vec4((gl_FragCoord.xy / uViewPortSize) * 2.0 - 1.0, gl_FragCoord.z * 2.0 - 1.0, 1.0); + fragPos /= fragPos.w; + + return length(fragPos.xyz); +} + +// Taken from https://github.com/hughsk/glsl-fog +float fogFactorLinear() { + return 1.0 - clamp(((fogState.end - (distance())) / (fogState.end - fogState.start)), 0.0, 1.0); +} + +float fogFactorExp() { + return 1.0 - clamp(exp(-fogState.density * (distance())), 0.0, 1.0); +} + +float fogFactorExp2() { + float LOG2 = -1.442695; + float d = fogState.density * (distance()); + return 1.0 - clamp(exp2(d * d * LOG2), 0.0, 1.0); +} + + +vec4 computeFog(vec4 color) { + float f = 0; + if (fogState.mode == 0) { // Linear + f = fogFactorLinear(); + } + else if (fogState.mode == 1) { // EXP + f = fogFactorExp(); + } + else if (fogState.mode == 2) { // EXP2 + f = fogFactorExp2(); + } + return vec4(mix(color.rgb, fogState.color.rgb, f), color.a); +} + // min limit is a bandaid solution for unicode or other similar x256 fonts that arent double thick so that it actually works with bold and outline -PedroThePanda64 ivec2 r = max(ivec2(512), textureSize(colortex, 0)); ivec2 rh = r / 2; @@ -105,6 +158,9 @@ void main() { } } } + + FragColor = computeFog(FragColor); + if (FragColor.a < uAlphaTest) { discard; } diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicAxisAligned.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicAxisAligned.java index ec2265d18..fc19d76c8 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicAxisAligned.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicAxisAligned.java @@ -32,14 +32,18 @@ public class BlockLogicAxisAligned } public static int axisToMeta(final @NotNull Axis axis) { - if (axis == Axis.X) return 2; - if (axis == Axis.Z) return 1; - return 0; + return switch (axis) { + case X -> 2; + case Z -> 1; + default -> 0; + }; } public static @NotNull Axis metaToAxis(final int meta) { - if (meta == 2) return Axis.X; - if (meta == 1) return Axis.Z; - return Axis.Y; + return switch (meta & 0b11) { + case 2 -> Axis.X; + case 1 -> Axis.Z; + default -> Axis.Y; + }; } } diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFence.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFence.java index 4525dde8e..4c9f96156 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFence.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFence.java @@ -37,7 +37,7 @@ public class BlockLogicFence @Override public @Nullable AABBdc getCollisionAABB(final @NotNull WorldSource source, final @NotNull TilePosc tilePos) { - return MathHelper.aabbExpand(super.getBoundsFromState(source, tilePos), 0, 0.5, 0, new AABBd()); + return MathHelper.aabbExpand(this.getBoundsFromState(source, tilePos), 0, 0.5, 0, new AABBd()).translate(tilePos.x(), tilePos.y(), tilePos.z()); } @Override diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLeavesCacao.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLeavesCacao.java index e672a9731..09c4e73a6 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLeavesCacao.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLeavesCacao.java @@ -26,6 +26,7 @@ public class BlockLogicLeavesCacao extends BlockLogicLeavesBase implements IBone public static final int MASK_GROWTH_DATA = 0b1111_0000; public static final int MAX_GROWTH_STATE = 4; static final int BEAN_GROWTH_RATE = 50; + private static final int MIN_GROWTH_HARVESTABLE = 2; public BlockLogicLeavesCacao(@NotNull Block block) { super(block, Materials.LEAVES, Blocks.SAPLING_CACAO); @@ -34,9 +35,9 @@ public class BlockLogicLeavesCacao extends BlockLogicLeavesBase implements IBone public boolean canBeansGrow(@NotNull World world, @NotNull TilePosc tilePos) { TilePos queryPos = new TilePos(tilePos); - for (int x = tilePos.x() - 1; x < tilePos.x() + 1; x++) { - for (int z = tilePos.z() - 1; z < tilePos.z() + 1; z++) { - if (world.getBlockType(queryPos.set(x, tilePos.y(), z)) == null) { + for (int x = tilePos.x() - 1; x <= tilePos.x() + 1; x++) { + for (int z = tilePos.z() - 1; z <= tilePos.z() + 1; z++) { + if (world.getBlockType(queryPos.set(x, tilePos.y(), z)) == Blocks.AIR) { return true; } } @@ -50,8 +51,8 @@ public class BlockLogicLeavesCacao extends BlockLogicLeavesBase implements IBone return new ItemStack[]{new ItemStack(this)}; int growthRate = getGrowthRate(data); - if (growthRate > 1) { - return new ItemStack[]{new ItemStack(Items.DYE, MathHelper.ceil((double) growthRate / 2), DyeColor.BROWN.itemMeta)}; + if (growthRate >= MIN_GROWTH_HARVESTABLE) { + return new ItemStack[]{new ItemStack(Items.DYE, MathHelper.ceil(growthRate / 3.0F), DyeColor.BROWN.itemMeta)}; } return super.getBreakResult(world, dropCause, data, tileEntity); @@ -75,7 +76,7 @@ public class BlockLogicLeavesCacao extends BlockLogicLeavesBase implements IBone public boolean harvest(@NotNull World world, @NotNull TilePosc tilePos, @Nullable Player player) { int meta = world.getBlockData(tilePos); int growthRate = getGrowthRate(meta); - if (growthRate > 0) { + if (growthRate >= MIN_GROWTH_HARVESTABLE) { if (player != null) { world.playSoundAtEntity(player, player, "item.pickup", 1, 1); } diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSign.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSign.java index 8bcc92e0d..6a1a58549 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSign.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSign.java @@ -167,9 +167,6 @@ implements ItemStack heldItem = player.getHeldItem(); if (heldItem != null && heldItem.itemID == Items.DUST_GLOWSTONE.id && !signEntity.isGlowing() && heldItem.consumeItem(player)) { signEntity.setGlowing(true); - if (player.getGamemode().hasBlockConsumption()) { - heldItem.stackSize--; - } player.addStat(Achievements.LIGHT_SIGN, 1); return true; } else if (heldItem != null && heldItem.itemID == Items.SLIMEBALL.id && heldItem.consumeItem(player)) { diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicStatue.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicStatue.java index 6b542f61f..e0a12173d 100644 --- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicStatue.java +++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicStatue.java @@ -92,7 +92,7 @@ public class BlockLogicStatue extends BlockLogic implements BlockLogic.MatcherEn final boolean shouldTakeItem = !isStatueHandEmpty && !isPlayerHoldingArmor; final boolean shouldInsertItem = !isPlayerHandEmpty && !isPlayerHoldingArmor; final boolean shouldTakeArmor = interactSlot != null && !isStatueArmorEmpty && isStatueHandEmpty; - final boolean shouldInsertArmor = interactSlot != null && isPlayerHoldingArmor; + final boolean shouldInsertArmor = interactSlot != null && (isStatueArmorEmpty || shouldTakeArmor) && isPlayerHoldingArmor; // Handle item interaction if (shouldTakeItem && shouldInsertItem) { 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 bd6f2b385..8c0ce33e2 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 @@ -25,7 +25,7 @@ public abstract class TileEntity implements ICarriable { public @Nullable World worldObj; // Null when loading data from nbt and null when held by entity public @Nullable CarriedBlock carriedBlock; - public TilePos tilePos = new TilePos(); + public final @NotNull TilePos tilePos = new TilePos(); protected boolean tileEntityInvalid; public TileEntity() @@ -135,26 +135,26 @@ public abstract class TileEntity implements ICarriable @Override public boolean tryPlace(World world, Entity holder, int blockX, int blockY, int blockZ, Side side, double xPlaced, double yPlaced) { - CarriedBlock carriedBlock = this.carriedBlock; - tilePos.x = blockX + side.offsetX(); - tilePos.y = blockY + side.offsetY(); - tilePos.z = blockZ + side.offsetZ(); - - Block currentBlock = world.getBlockType(tilePos); - if (currentBlock != null && !currentBlock.hasTag(BlockTags.PLACE_OVERWRITES)) return false; - world.setBlockTypeData(tilePos, carriedBlock.block(), carriedBlock.metadata); - world.markBlockNeedsUpdate(tilePos); - - worldObj = world; + final TilePos blockPosCopy = new TilePos(blockX, blockY, blockZ); + final Block directBlock = world.getBlockType(blockPosCopy); + if (!directBlock.hasTag(BlockTags.PLACE_OVERWRITES)) blockPosCopy.add(side); + // directBlock is irrelevant past this point and blockPosCopy is properly mutated + + if (this.carriedBlock == null + || !world.canBlockIdBePlacedAt(this.carriedBlock.block().id(), blockPosCopy, false, Side.NONE)) return false; + final Block placedBlock = this.carriedBlock.block(); + this.tilePos.set(blockPosCopy); + this.worldObj = world; + + world.setBlockTypeDataNotify(this.tilePos, placedBlock, this.carriedBlock.metadata); this.validate(); - world.removeTileEntity(tilePos); - world.setTileEntity(tilePos, this); - Block b = world.getBlockType(tilePos); - if (b != null && holder instanceof Mob mob) { - b.onPlacedByMob(world, tilePos, side, mob, xPlaced, yPlaced); + world.removeTileEntity(this.tilePos); + world.setTileEntity(this.tilePos, this); + if (holder instanceof Mob mob) { + placedBlock.onPlacedByMob(world, this.tilePos, side, mob, xPlaced, yPlaced); } - final boolean isSignal = carriedBlock.block().isSignalSource(); - world.notifyBlocksInRadiusOfNeighborChange((isSignal) ? 2 : 1, tilePos, currentBlock); + final boolean isSignal = placedBlock.isSignalSource(); + world.notifyBlocksInRadiusOfNeighborChange((isSignal) ? 2 : 1, this.tilePos, placedBlock); return true; } diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityDispenser.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityDispenser.java index 4cfc1c4f7..17493d8fe 100644 --- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityDispenser.java +++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityDispenser.java @@ -208,7 +208,9 @@ public class TileEntityDispenser extends TileEntity i1 = itemstack.stackSize; } itemstack.stackSize -= i1; - EntityItem entityitem = new EntityItem(world, (float) x + f, (float) y + f1, (float) z + f2, new ItemStack(itemstack.itemID, i1, itemstack.getMetadata())); + var dropStack = new ItemStack(itemstack); + dropStack.stackSize = i1; + EntityItem entityitem = new EntityItem(world, (float) x + f, (float) y + f1, (float) z + f2, dropStack); float f3 = 0.05F; entityitem.xd = (float) random.nextGaussian() * f3; entityitem.yd = (float) random.nextGaussian() * f3 + 0.2F; diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFurnace.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFurnace.java index 23006d561..e1321a6b4 100644 --- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFurnace.java +++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFurnace.java @@ -358,7 +358,9 @@ public class TileEntityFurnace extends TileEntity i1 = itemstack.stackSize; } itemstack.stackSize -= i1; - EntityItem entityItem = new EntityItem(world, (float) x + f, (float) y + f1, (float) z + f2, new ItemStack(itemstack.itemID, i1, itemstack.getMetadata())); + var dropStack = new ItemStack(itemstack); + dropStack.stackSize = i1; + EntityItem entityItem = new EntityItem(world, (float) x + f, (float) y + f1, (float) z + f2, dropStack); float f3 = 0.05F; entityItem.xd = (float)random.nextGaussian() * f3; entityItem.yd = (float)random.nextGaussian() * f3 + 0.2F; diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFurnaceBlast.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFurnaceBlast.java index e2bb6252c..f3612cbc6 100644 --- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFurnaceBlast.java +++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFurnaceBlast.java @@ -316,7 +316,9 @@ public class TileEntityFurnaceBlast extends TileEntity stackSize = item.stackSize; } item.stackSize -= stackSize; - final EntityItem entityItem = new EntityItem(world, (float) x + rx, (float) y + ry, (float) z + rz, new ItemStack(item.itemID, stackSize, item.getMetadata())); + var dropStack = new ItemStack(item); + item.stackSize = stackSize; + final EntityItem entityItem = new EntityItem(world, (float) x + rx, (float) y + ry, (float) z + rz, dropStack); final float velocityScale = 0.05F; entityItem.xd = (float) this.random.nextGaussian() * velocityScale; entityItem.yd = (float) this.random.nextGaussian() * velocityScale + 0.2F; diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTrommel.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTrommel.java index d29136e9a..7a79b911f 100644 --- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTrommel.java +++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTrommel.java @@ -457,7 +457,9 @@ public class TileEntityTrommel extends TileEntity i1 = itemstack.stackSize; } itemstack.stackSize -= i1; - EntityItem item = new EntityItem(world, (float) x + f, (float) y + f1, (float) z + f2, new ItemStack(itemstack.itemID, i1, itemstack.getMetadata())); + var dropStack = new ItemStack(itemstack); + dropStack.stackSize = i1; + EntityItem item = new EntityItem(world, (float) x + f, (float) y + f1, (float) z + f2, dropStack); float f3 = 0.05F; item.xd = (float) this.random.nextGaussian() * f3; item.yd = (float) this.random.nextGaussian() * f3 + 0.2F; diff --git a/game/core/src/main/java/net/minecraft/core/block/motion/CarriedBlock.java b/game/core/src/main/java/net/minecraft/core/block/motion/CarriedBlock.java index 66612a564..e442d6bb6 100644 --- a/game/core/src/main/java/net/minecraft/core/block/motion/CarriedBlock.java +++ b/game/core/src/main/java/net/minecraft/core/block/motion/CarriedBlock.java @@ -14,6 +14,7 @@ import net.minecraft.core.util.helper.Side; import net.minecraft.core.world.ICarriable; import net.minecraft.core.world.World; +import net.minecraft.core.world.pos.TilePos; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -59,19 +60,19 @@ public class CarriedBlock implements ICarriable, ICarriedBlock { if (entity != null) { return entity.tryPlace(world, holder, blockX, blockY, blockZ, side, xPlaced, yPlaced); } else { - int x = blockX + side.offsetX(); - int y = blockY + side.offsetY(); - int z = blockZ + side.offsetZ(); + final TilePos blockPosCopy = new TilePos(blockX, blockY, blockZ); + final Block directBlock = world.getBlockType(blockPosCopy); + if (!directBlock.hasTag(BlockTags.PLACE_OVERWRITES)) blockPosCopy.add(side); + // directBlock is irrelevant past this point and blockPosCopy is properly mutated - Block currentBlock = world.getBlock(x, y, z); - if (currentBlock != null && !currentBlock.hasTag(BlockTags.PLACE_OVERWRITES)) return false; - world.setBlockAndMetadata(x, y, z, blockId, metadata); + final Block placedBlock = Blocks.getBlock(blockId); + if (!world.canBlockIdBePlacedAt(placedBlock.id(), blockPosCopy, false, Side.NONE)) return false; - Block b = world.getBlock(x, y, z); - if (b != null && holder instanceof Mob) { - b.onBlockPlacedByMob(world, x, y, z, side, (Mob) holder, xPlaced, yPlaced); + world.setBlockTypeData(blockPosCopy, placedBlock, metadata); + if (holder instanceof Mob mob) { + placedBlock.onPlacedByMob(world, blockPosCopy, side, mob, xPlaced, yPlaced); } - world.notifyBlockChange(x, y, z, blockId); + world.notifyBlockChange(blockPosCopy, placedBlock); return true; } } diff --git a/game/core/src/main/java/net/minecraft/core/entity/EntityItem.java b/game/core/src/main/java/net/minecraft/core/entity/EntityItem.java index e4b4dd745..06c2c4f2f 100644 --- a/game/core/src/main/java/net/minecraft/core/entity/EntityItem.java +++ b/game/core/src/main/java/net/minecraft/core/entity/EntityItem.java @@ -33,7 +33,7 @@ import org.joml.primitives.AABBd; public class EntityItem extends Entity { - public ItemStack item; + public @Nullable ItemStack item; public int lifetime; public int age; public @Nullable Direction siphonDirection = null; @@ -187,7 +187,7 @@ public class EntityItem extends Entity @Override protected void burn(int damage) { - if (!this.item.getItem().hasTag(ItemTags.IS_FIRE_PROOF)) { + if (this.item != null && !this.item.getItem().hasTag(ItemTags.IS_FIRE_PROOF)) { hurt(null, damage, DamageType.FIRE); } } @@ -199,13 +199,14 @@ public class EntityItem extends Entity @Override public boolean hurt(Entity entity, int i, DamageType type) { - if (this.item.getItem().hasTag(ItemTags.IS_INDESTRUCTIBLE)) { - return false; - } - else if (type == DamageType.FIRE && this.item.getItem().hasTag(ItemTags.IS_FIRE_PROOF)) { - return false; - } else if (type == DamageType.BLAST && this.item.getItem().hasTag(ItemTags.IS_BLAST_PROOF)) { - return false; + if (this.item != null) { + if (this.item.getItem().hasTag(ItemTags.IS_INDESTRUCTIBLE)) { + return false; + } else if (type == DamageType.FIRE && this.item.getItem().hasTag(ItemTags.IS_FIRE_PROOF)) { + return false; + } else if (type == DamageType.BLAST && this.item.getItem().hasTag(ItemTags.IS_BLAST_PROOF)) { + return false; + } } markHurt(); this.health -= i; @@ -240,7 +241,7 @@ public class EntityItem extends Entity @Override public void playerTouch(Player player) { - if(this.world.isClientSide) { + if(this.world.isClientSide || this.item == null) { return; } if(this.pickupDelay == 0) { @@ -322,6 +323,8 @@ public class EntityItem extends Entity } public void clumpToNearbyStack() { + if (this.item == null) return; + AABBd boundingBox = MathHelper.aabbGrow(this.bb, 0.5, 0.0, 0.5, new AABBd()); List<@NotNull EntityItem> entities = this.world.getEntitiesWithinAABB(EntityItem.class, boundingBox); @@ -332,6 +335,7 @@ public class EntityItem extends Entity ItemStack thisItemStack = this.item; ItemStack otherItemStack = otherEntity.item; + if (otherItemStack == null) continue; if(this.item.canStackWith(otherEntity.item)) { if(thisItemStack.stackSize + otherItemStack.stackSize > 64) { @@ -423,7 +427,7 @@ public class EntityItem extends Entity { ItemStack filterItem = ((TileEntityMeshGold) Objects.requireNonNull(world.getTileEntity(tilePosUnderItem))).filterItem; if(filterItem != null){ - if (this.item.getItem() == filterItem.getItem() && this.item.getMetadata() == filterItem.getMetadata()){ + if (this.item != null && this.item.getItem() == filterItem.getItem() && this.item.getMetadata() == filterItem.getMetadata()){ this.yd -= 0.02D; } } @@ -485,6 +489,8 @@ public class EntityItem extends Entity } private static void combineItems(EntityItem entityItem1, EntityItem entityItem2) { + if (entityItem1.item == null || entityItem2.item == null) return; + entityItem1.item.stackSize += entityItem2.item.stackSize; entityItem2.item.stackSize = 0; entityItem1.age = Math.min(entityItem1.age, entityItem2.age); 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 325eec7b6..a67cf515c 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 @@ -427,12 +427,13 @@ public class MobFireflyCluster extends MobFlying int count = this.getFireflyCount(); if (!acceptPartial && amount > count) return 0; - - count -= amount; - this.setFireflyCount(count); - if (count == 0) this.remove(); - return count; + final int capturedAmount = Math.min(amount, count); + final int newCount = count - capturedAmount; + this.setFireflyCount(newCount); + if (newCount == 0) this.remove(); + + return capturedAmount; } public static class FireflyColor { diff --git a/game/core/src/main/java/net/minecraft/core/entity/animal/MobWolf.java b/game/core/src/main/java/net/minecraft/core/entity/animal/MobWolf.java index 0cab7a6ba..822c41ae6 100644 --- a/game/core/src/main/java/net/minecraft/core/entity/animal/MobWolf.java +++ b/game/core/src/main/java/net/minecraft/core/entity/animal/MobWolf.java @@ -524,6 +524,8 @@ public class MobWolf @Override public boolean hurt(Entity attacker, int i, DamageType type) { setWolfSitting(false); + if (attacker instanceof Player p && !p.getGamemode().hasHostileMobs()) return super.hurt(attacker, i, type); + if (attacker != null && !(attacker instanceof Player) && !(attacker instanceof ProjectileArrow)) { i = (i + 1) / 2; } diff --git a/game/core/src/main/java/net/minecraft/core/entity/monster/MobGhast.java b/game/core/src/main/java/net/minecraft/core/entity/monster/MobGhast.java index fffb18866..37c4b8f6c 100644 --- a/game/core/src/main/java/net/minecraft/core/entity/monster/MobGhast.java +++ b/game/core/src/main/java/net/minecraft/core/entity/monster/MobGhast.java @@ -125,7 +125,7 @@ public class MobGhast extends MobFlying implements Enemy { if (this.targetedEntity == null || this.aggroCooldown-- <= 0) { Entity potentialTarget = this.world.getClosestPlayerToEntity(this, 100.0D); - if (potentialTarget instanceof Player p && p.gamemode != Gamemodes.CREATIVE && p.gamemode != Gamemodes.SPECTATOR) { + if (potentialTarget instanceof Player p && p.getGamemode().hasHostileMobs()) { this.targetedEntity = potentialTarget; } @@ -211,7 +211,7 @@ public class MobGhast extends MobFlying implements Enemy { if (this.passenger == attacker || this.vehicle == attacker) { return true; } - if (attacker != this) { + if (attacker != this && !(attacker instanceof Player p && !p.getGamemode().hasHostileMobs())) { this.targetedEntity = attacker; this.aggroCooldown = 60; } diff --git a/game/core/src/main/java/net/minecraft/core/entity/monster/MobZombiePig.java b/game/core/src/main/java/net/minecraft/core/entity/monster/MobZombiePig.java index 795fc27fd..70764d6d1 100644 --- a/game/core/src/main/java/net/minecraft/core/entity/monster/MobZombiePig.java +++ b/game/core/src/main/java/net/minecraft/core/entity/monster/MobZombiePig.java @@ -101,7 +101,7 @@ public class MobZombiePig extends MobZombie { if (type == DamageType.FIRE) { return false; } - if (attacker instanceof Player) { + if (attacker instanceof Player p && p.getGamemode().hasHostileMobs()) { List list = this.world.getEntitiesWithinAABBExcludingEntity(this, MathHelper.aabbGrow(this.bb, 32D, 32D, 32D, new AABBd())); for (int j = 0; j < list.size(); j++) { Entity e = list.get(j); 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 d77fea5ab..3efdef043 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 @@ -1754,12 +1754,12 @@ public abstract class Player } public void pickBlock(int x, int y, int z, boolean pickFully) { + if (this.heldObject != null) return; + Block block = this.world.getBlock(x, y, z); int meta = this.world.getBlockMetadata(x, y, z); - if (block == null) { - return; - } + if (block == Blocks.AIR) return; TileEntity tileEntity = this.world.getTileEntity(x, y, z); ItemStack[] result = block.getBreakResult(this.world, EnumDropCause.PICK_BLOCK, x, y, z, meta, tileEntity); 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 8c866a257..6386362a1 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 @@ -1523,7 +1523,7 @@ public abstract class World implements MutableWorldSource { int y = this.getHeightBlocks() - 1; x &= (Chunk.CHUNK_SIZE_X - 1); z &= (Chunk.CHUNK_SIZE_Z - 1); - while (y > 0) { + while (y >= 0) { final int id = chunk.getBlockID(x, y, z); final Material material = id != 0 ? Blocks.blocksList[id].getMaterial() : Materials.AIR; if (!material.blocksMotion() && !material.isLiquid()) { @@ -1978,7 +1978,7 @@ public abstract class World implements MutableWorldSource { if (block == Blocks.FIRE || block == Blocks.FIRE_COLD) { this.playBlockEvent(player, offsetPos, LevelListener.EVENT_FIRE_EXTINGUISH, 0); - this.setBlockTypeNotify(tilePos, Blocks.AIR); + this.setBlockTypeNotify(offsetPos, Blocks.AIR); } } @@ -2468,6 +2468,7 @@ public abstract class World implements MutableWorldSource { } public boolean canBlockIdBePlacedAt(final int id, final @NotNull TilePosc tilePos, final boolean ignoreCollision, final @NotNull Side side) { + // TODO Rework this method to accept Block and make side nullable if (tilePos.y() < 0 || tilePos.y() >= this.getHeightBlocks()) { return false; } diff --git a/game/server/src/main/java/net/minecraft/server/net/command/commands/CommandUnban.java b/game/server/src/main/java/net/minecraft/server/net/command/commands/CommandUnban.java index 07a382de5..175ffc8cf 100644 --- a/game/server/src/main/java/net/minecraft/server/net/command/commands/CommandUnban.java +++ b/game/server/src/main/java/net/minecraft/server/net/command/commands/CommandUnban.java @@ -33,7 +33,7 @@ public class CommandUnban implements CommandManager.CommandRegistry { String nameToUnban = c.getArgument("name", String.class); UUIDHelper.runConversionAction(nameToUnban, (uuid) -> { - server.playerList.banPlayer(uuid); + server.playerList.pardonPlayer(uuid); c.getSource().sendTranslatableMessage("command.commands.unban.username.success", nameToUnban); }, (username) -> { c.getSource().sendTranslatableMessage("command.commands.unban.username.fail.wrong_name", nameToUnban);