1.21.6 dev

Co-authored-by: Bjarne Koll <git@lynxplay.dev>
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
Co-authored-by: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
Co-authored-by: Noah van der Aa <ndvdaa@gmail.com>
Co-authored-by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
This commit is contained in:
Bjarne Koll
2025-05-28 13:23:32 +02:00
committed by Nassim Jahnke
parent 39203a65e0
commit a24f9b204c
788 changed files with 41006 additions and 6324 deletions

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/AbstractCauldronBlock.java
+++ b/net/minecraft/world/level/block/AbstractCauldronBlock.java
@@ -62,7 +_,7 @@
@@ -57,7 +_,7 @@
ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult
) {
CauldronInteraction cauldronInteraction = this.interactions.map().get(stack.getItem());

View File

@@ -90,7 +90,7 @@
+ // Paper end - add entity parameter
if (level.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) {
- ExperienceOrb.award(level, Vec3.atCenterOf(pos), amount);
+ ExperienceOrb.award(level, Vec3.atCenterOf(pos), amount, org.bukkit.entity.ExperienceOrb.SpawnReason.BLOCK_BREAK, entity); // Paper
+ ExperienceOrb.awardWithDirection(level, Vec3.atCenterOf(pos), net.minecraft.world.phys.Vec3.ZERO, amount, org.bukkit.entity.ExperienceOrb.SpawnReason.BLOCK_BREAK, entity, null); // Paper
}
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/CactusBlock.java
+++ b/net/minecraft/world/level/block/CactusBlock.java
@@ -58,25 +_,29 @@
@@ -58,18 +_,22 @@
int ageValue = state.getValue(AGE);
while (level.getBlockState(pos.below(i)).is(this)) {
@@ -29,14 +29,6 @@
BlockState blockState = state.setValue(AGE, 0);
level.setBlock(pos, blockState, 260);
level.neighborChanged(blockState, blockPos, this, null, false);
}
if (ageValue < 15) {
- level.setBlock(pos, state.setValue(AGE, ageValue + 1), 260);
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, state.setValue(AGE, ageValue + 1), 260); // Paper
}
}
}
@@ -124,7 +_,8 @@
@Override

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/EndPortalBlock.java
+++ b/net/minecraft/world/level/block/EndPortalBlock.java
@@ -57,8 +_,15 @@
@@ -58,8 +_,15 @@
@Override
protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier) {
@@ -16,8 +16,8 @@
serverPlayer.showEndCredits();
} else {
entity.setAsInsidePortal(this, pos);
@@ -68,7 +_,7 @@
@@ -70,7 +_,7 @@
@Nullable
@Override
public TeleportTransition getPortalDestination(ServerLevel level, Entity entity, BlockPos pos) {
- ResourceKey<Level> resourceKey = level.dimension() == Level.END ? Level.OVERWORLD : Level.END;
@@ -25,7 +25,7 @@
ServerLevel level1 = level.getServer().getLevel(resourceKey);
if (level1 == null) {
return null;
@@ -79,7 +_,7 @@
@@ -81,7 +_,7 @@
float f;
Set<Relative> set;
if (flag) {
@@ -34,8 +34,8 @@
f = Direction.WEST.toYRot();
set = Relative.union(Relative.DELTA, Set.of(Relative.X_ROT));
if (entity instanceof ServerPlayer) {
@@ -89,15 +_,23 @@
f = 0.0F;
@@ -91,15 +_,23 @@
f = level1.getSharedSpawnAngle();
set = Relative.union(Relative.DELTA, Relative.ROTATION);
if (entity instanceof ServerPlayer serverPlayer) {
- return serverPlayer.findRespawnPositionAndUseSpawnBlock(false, TeleportTransition.DO_NOTHING);

View File

@@ -1,15 +1,14 @@
--- a/net/minecraft/world/level/block/LavaCauldronBlock.java
+++ b/net/minecraft/world/level/block/LavaCauldronBlock.java
@@ -33,9 +_,10 @@
@@ -44,8 +_,10 @@
@Override
protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
if (this.isEntityInsideContent(state, pos, entity)) {
- entity.lavaIgnite();
- entity.lavaHurt();
+ entity.lavaIgnite(pos); // Paper - track lava contact
+ entity.lavaHurt(pos); // Paper - track lava contact
}
+ BlockPos savedPos = pos.immutable(); // Paper - track lava contact
effectApplier.apply(InsideBlockEffectType.LAVA_IGNITE);
- effectApplier.runAfter(InsideBlockEffectType.LAVA_IGNITE, Entity::lavaHurt);
+ effectApplier.runAfter(InsideBlockEffectType.LAVA_IGNITE, ignitedEntity -> ignitedEntity.lavaHurt(savedPos)); // Paper - track lava contact
}
@Override

View File

@@ -1,23 +1,27 @@
--- a/net/minecraft/world/level/block/LayeredCauldronBlock.java
+++ b/net/minecraft/world/level/block/LayeredCauldronBlock.java
@@ -62,35 +_,67 @@
@@ -79,39 +_,71 @@
@Override
protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
if (level instanceof ServerLevel serverLevel && entity.isOnFire() && this.isEntityInsideContent(state, pos, entity)) {
- entity.clearFire();
- if (entity.mayInteract(serverLevel, pos)) {
- this.handleEntityOnFireInside(state, level, pos);
+ // CraftBukkit start - moved down
+ // entity.clearFire();
+ if ((entity instanceof net.minecraft.world.entity.player.Player || serverLevel.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING)) && entity.mayInteract(serverLevel, pos)) { // Paper - Fixes MC-248588
+ if (this.handleEntityOnFireInside(state, level, pos, entity)) { // Paper - fix powdered snow cauldron extinguishing entities
+ entity.clearFire();
+ }
+ // CraftBukkit end
}
if (level instanceof ServerLevel serverLevel) {
BlockPos blockPos = pos.immutable();
effectApplier.runBefore(InsideBlockEffectType.EXTINGUISH, entity1 -> {
- if (entity1.isOnFire() && entity1.mayInteract(serverLevel, blockPos)) {
- this.handleEntityOnFireInside(state, level, blockPos);
+ if (entity1.isOnFire() && (entity instanceof net.minecraft.world.entity.player.Player || serverLevel.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING)) && entity1.mayInteract(serverLevel, blockPos)) { // Paper - Fixes MC-248588
+ // Paper start - cauldron level change event
+ if (this.handleEntityOnFireInside(state, level, blockPos, entity1)) { // Paper - track entity
+ InsideBlockEffectType.EXTINGUISH.effect().affect(entity1, blockPos); // apply extinguishing if event was not cancelled.
+ }
+ // Paper end - cauldron level change event
}
});
}
- effectApplier.apply(InsideBlockEffectType.EXTINGUISH);
+ // effectApplier.apply(InsideBlockEffectType.EXTINGUISH); // Paper - manually applied above - cauldron level change event - delay to not extinguish when event is cancelled
}
- private void handleEntityOnFireInside(BlockState state, Level level, BlockPos pos) {
@@ -79,7 +83,7 @@
}
}
@@ -108,8 +_,11 @@
@@ -129,8 +_,11 @@
protected void receiveStalactiteDrip(BlockState state, Level level, BlockPos pos, Fluid fluid) {
if (!this.isFull(state)) {
BlockState blockState = state.setValue(LEVEL, state.getValue(LEVEL) + 1);

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/NetherPortalBlock.java
+++ b/net/minecraft/world/level/block/NetherPortalBlock.java
@@ -70,7 +_,7 @@
@@ -65,7 +_,7 @@
@Override
protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
@@ -9,7 +9,7 @@
&& level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)
&& random.nextInt(2000) < level.getDifficulty().getId()
&& level.anyPlayerCloseEnoughForSpawning(pos)) {
@@ -79,9 +_,13 @@
@@ -74,9 +_,13 @@
}
if (level.getBlockState(pos).isValidSpawn(level, pos, EntityType.ZOMBIFIED_PIGLIN)) {
@@ -24,7 +24,7 @@
Entity vehicle = entity.getVehicle();
if (vehicle != null) {
vehicle.setPortalCooldown();
@@ -112,7 +_,13 @@
@@ -107,7 +_,13 @@
@Override
protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier) {
@@ -38,7 +38,7 @@
entity.setAsInsidePortal(this, pos);
}
}
@@ -135,22 +_,46 @@
@@ -130,22 +_,46 @@
@Nullable
@Override
public TeleportTransition getPortalDestination(ServerLevel level, Entity entity, BlockPos pos) {
@@ -90,7 +90,7 @@
BlockUtil.FoundRectangle largestRectangleAround;
TeleportTransition.PostTeleportTransition postTeleportTransition;
if (optional.isPresent()) {
@@ -165,17 +_,22 @@
@@ -160,17 +_,22 @@
blockPos1 -> level.getBlockState(blockPos1) == blockState
);
postTeleportTransition = TeleportTransition.PLAY_PORTAL_SOUND.then(entity1 -> entity1.placePortalTicket(blockPos));
@@ -116,7 +116,7 @@
return getDimensionTransitionFromExit(entity, pos, largestRectangleAround, level, postTeleportTransition);
}
@@ -221,7 +_,7 @@
@@ -216,7 +_,7 @@
boolean flag = axis1 == Direction.Axis.X;
Vec3 vec3 = new Vec3(blockPos.getX() + (flag ? d2 : d4), blockPos.getY() + d3, blockPos.getZ() + (flag ? d4 : d2));
Vec3 vec31 = PortalShape.findCollisionFreePosition(vec3, level, entity, dimensions);

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/SculkSpreader.java
+++ b/net/minecraft/world/level/block/SculkSpreader.java
@@ -45,6 +_,7 @@
@@ -46,6 +_,7 @@
private final int chargeDecayRate;
private final int additionalDecayRate;
private List<SculkSpreader.ChargeCursor> cursors = new ArrayList<>();
@@ -8,16 +8,16 @@
public SculkSpreader(
boolean isWorldGeneration, TagKey<Block> replaceableBlocks, int growthSpawnCoat, int noGrowthRadius, int chargeDecayRate, int additionalDecayRate
@@ -100,7 +_,7 @@
@@ -101,7 +_,7 @@
public void load(CompoundTag tag) {
public void load(ValueInput input) {
this.cursors.clear();
- tag.read("cursors", SculkSpreader.ChargeCursor.CODEC.sizeLimitedListOf(32)).orElse(List.of()).forEach(this::addCursor);
+ tag.read("cursors", SculkSpreader.ChargeCursor.CODEC.sizeLimitedListOf(32)).orElse(List.of()).forEach((cursor) -> this.addCursor(cursor, false)); // Paper - don't fire event for block entity loading
- input.read("cursors", SculkSpreader.ChargeCursor.CODEC.sizeLimitedListOf(32)).orElse(List.of()).forEach(this::addCursor);
+ input.read("cursors", SculkSpreader.ChargeCursor.CODEC.sizeLimitedListOf(32)).orElse(List.of()).forEach((cursor) -> this.addCursor(cursor, false)); // Paper - don't fire event for block entity loading
}
public void save(CompoundTag tag) {
@@ -110,13 +_,24 @@
public void save(ValueOutput output) {
@@ -111,13 +_,24 @@
public void addCursors(BlockPos pos, int charge) {
while (charge > 0) {
int min = Math.min(charge, 1000);

View File

@@ -1,15 +1,15 @@
--- a/net/minecraft/world/level/block/SignBlock.java
+++ b/net/minecraft/world/level/block/SignBlock.java
@@ -133,7 +_,7 @@
} else if (!this.otherPlayerIsEditingSign(player, signBlockEntity)
&& player.mayBuild()
&& this.hasEditableText(player, signBlockEntity, isFacingFrontText)) {
- this.openTextEdit(player, signBlockEntity, isFacingFrontText);
+ this.openTextEdit(player, signBlockEntity, isFacingFrontText, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.INTERACT); // Paper - Add PlayerOpenSignEvent
return InteractionResult.SUCCESS_SERVER;
} else {
return InteractionResult.PASS;
@@ -175,7 +_,34 @@
} else if (!this.otherPlayerIsEditingSign(player, signBlockEntity)
&& player.mayBuild()
&& this.hasEditableText(player, signBlockEntity, isFacingFrontText)) {
- this.openTextEdit(player, signBlockEntity, isFacingFrontText);
+ this.openTextEdit(player, signBlockEntity, isFacingFrontText, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.INTERACT); // Paper - Add PlayerOpenSignEvent
return InteractionResult.SUCCESS_SERVER;
} else {
return InteractionResult.PASS;
@@ -179,7 +_,34 @@
return woodType;
}
@@ -44,7 +44,7 @@
signEntity.setAllowedPlayerEditor(player.getUUID());
player.openTextEdit(signEntity, isFrontText);
}
@@ -188,6 +_,6 @@
@@ -192,6 +_,6 @@
@Nullable
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> blockEntityType) {

View File

@@ -10,7 +10,7 @@
pos,
6,
65,
@@ -63,8 +_,10 @@
@@ -63,16 +_,18 @@
if (blockPos.equals(pos)) {
return BlockPos.TraversalNodeStatus.ACCEPT;
} else {
@@ -23,7 +23,8 @@
if (!fluidState.is(FluidTags.WATER)) {
return BlockPos.TraversalNodeStatus.SKIP;
} else if (blockState.getBlock() instanceof BucketPickup bucketPickup
@@ -72,7 +_,7 @@
- && !bucketPickup.pickupBlock(null, level, blockPos, blockState).isEmpty()) {
+ && !bucketPickup.pickupBlock(null, blockList, blockPos, blockState).isEmpty()) { // CraftBukkit
return BlockPos.TraversalNodeStatus.ACCEPT;
} else {
if (blockState.getBlock() instanceof LiquidBlock) {
@@ -32,7 +33,7 @@
} else {
if (!blockState.is(Blocks.KELP)
&& !blockState.is(Blocks.KELP_PLANT)
@@ -81,16 +_,55 @@
@@ -81,16 +_,49 @@
return BlockPos.TraversalNodeStatus.SKIP;
}
@@ -42,7 +43,6 @@
+ // CraftBukkit start
+ // BlockEntity blockEntity = blockState.hasBlockEntity() ? level.getBlockEntity(blockPos) : null;
+ // dropResources(blockState, level, blockPos, blockEntity);
+ // level.setBlock(blockPos, Blocks.AIR.defaultBlockState(), 3);
+ blockList.setBlock(blockPos, Blocks.AIR.defaultBlockState(), 3);
+ // CraftBukkit end
}
@@ -66,22 +66,17 @@
+
+ for (org.bukkit.craftbukkit.block.CraftBlockState snapshot : snapshots) {
+ BlockPos blockPos = snapshot.getPosition();
+ BlockState state = level.getBlockState(blockPos);
+ FluidState fluid = level.getFluidState(blockPos);
+ BlockState blockState = level.getBlockState(blockPos);
+ FluidState fluidState = level.getFluidState(blockPos);
+
+ if (fluid.is(FluidTags.WATER)) {
+ if (state.getBlock() instanceof BucketPickup bucketPickup && !bucketPickup.pickupBlock(null, blockList, blockPos, state).isEmpty()) {
+ // NOP
+ } else if (state.getBlock() instanceof LiquidBlock) {
+ // NOP
+ } else if (state.is(Blocks.KELP) || state.is(Blocks.KELP_PLANT) || state.is(Blocks.SEAGRASS) || state.is(Blocks.TALL_SEAGRASS)) {
+ BlockEntity blockEntity = state.hasBlockEntity() ? level.getBlockEntity(blockPos) : null;
+ if (!fluidState.is(FluidTags.WATER)) {
+ } else if (blockState.getBlock() instanceof BucketPickup bucketPickup && !bucketPickup.pickupBlock(null, level, blockPos, blockState).isEmpty()) {
+ } else if (blockState.getBlock() instanceof LiquidBlock) {
+ } else if (blockState.is(Blocks.KELP) || blockState.is(Blocks.KELP_PLANT) || blockState.is(Blocks.SEAGRASS) || blockState.is(Blocks.TALL_SEAGRASS)) {
+ BlockEntity blockEntity = blockState.hasBlockEntity() ? level.getBlockEntity(blockPos) : null;
+
+ // Paper start - Fix SpongeAbsortEvent handling
+ if (snapshot.getHandle().isAir()) {
+ dropResources(state, level, blockPos, blockEntity);
+ }
+ // Paper end - Fix SpongeAbsortEvent handling
+ if (snapshot.getHandle().isAir()) {
+ dropResources(blockState, level, blockPos, blockEntity);
+ }
+ }
+ snapshot.place(snapshot.getFlags());

View File

@@ -52,20 +52,20 @@
private boolean isLit() {
return this.litTimeRemaining > 0;
@@ -125,6 +_,7 @@
this.litTotalTime = tag.getShortOr("lit_total_time", (short)0);
this.litTotalTime = input.getShortOr("lit_total_time", (short)0);
this.recipesUsed.clear();
this.recipesUsed.putAll(tag.read("RecipesUsed", RECIPES_USED_CODEC).orElse(Map.of()));
+ this.cookSpeedMultiplier = tag.getDoubleOr("Paper.CookSpeedMultiplier", 1); // Paper - cook speed multiplier API
this.recipesUsed.putAll(input.read("RecipesUsed", RECIPES_USED_CODEC).orElse(Map.of()));
+ this.cookSpeedMultiplier = input.getDoubleOr("Paper.CookSpeedMultiplier", 1); // Paper - cook speed multiplier API
}
@Override
@@ -134,6 +_,7 @@
tag.putShort("cooking_total_time", (short)this.cookingTotalTime);
tag.putShort("lit_time_remaining", (short)this.litTimeRemaining);
tag.putShort("lit_total_time", (short)this.litTotalTime);
+ tag.putDouble("Paper.CookSpeedMultiplier", this.cookSpeedMultiplier); // Paper - cook speed multiplier API
ContainerHelper.saveAllItems(tag, this.items, registries);
tag.store("RecipesUsed", RECIPES_USED_CODEC, this.recipesUsed);
output.putShort("cooking_total_time", (short)this.cookingTotalTime);
output.putShort("lit_time_remaining", (short)this.litTimeRemaining);
output.putShort("lit_total_time", (short)this.litTotalTime);
+ output.putDouble("Paper.CookSpeedMultiplier", this.cookSpeedMultiplier); // Paper - cook speed multiplier API
ContainerHelper.saveAllItems(output, this.items);
output.store("RecipesUsed", RECIPES_USED_CODEC, this.recipesUsed);
}
@@ -160,11 +_,22 @@
@@ -210,9 +210,9 @@
}
- public void awardUsedRecipesAndPopExperience(ServerPlayer player) {
- List<RecipeHolder<?>> recipesToAwardAndPopExperience = this.getRecipesToAwardAndPopExperience(player.serverLevel(), player.position());
- List<RecipeHolder<?>> recipesToAwardAndPopExperience = this.getRecipesToAwardAndPopExperience(player.level(), player.position());
+ public void awardUsedRecipesAndPopExperience(ServerPlayer player, ItemStack itemstack, int amount) { // CraftBukkit
+ List<RecipeHolder<?>> recipesToAwardAndPopExperience = this.getRecipesToAwardAndPopExperience(player.serverLevel(), player.position(), this.worldPosition, player, itemstack, amount); // CraftBukkit - overload for exp spawn events
+ List<RecipeHolder<?>> recipesToAwardAndPopExperience = this.getRecipesToAwardAndPopExperience(player.level(), player.position(), this.worldPosition, player, itemstack, amount); // CraftBukkit - overload for exp spawn events
player.awardRecipes(recipesToAwardAndPopExperience);
for (RecipeHolder<?> recipeHolder : recipesToAwardAndPopExperience) {
@@ -268,7 +268,7 @@
+ floor = event.getExpToDrop();
+ // CraftBukkit end
+
+ ExperienceOrb.award(level, popVec, floor, org.bukkit.entity.ExperienceOrb.SpawnReason.FURNACE, serverPlayer); // Paper
+ ExperienceOrb.awardWithDirection(level, popVec, net.minecraft.world.phys.Vec3.ZERO, floor, org.bukkit.entity.ExperienceOrb.SpawnReason.FURNACE, serverPlayer, null); // Paper
}
@Override

View File

@@ -1,24 +1,24 @@
--- a/net/minecraft/world/level/block/entity/BannerBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BannerBlockEntity.java
@@ -52,7 +_,7 @@
protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) {
super.saveAdditional(tag, registries);
RegistryOps<Tag> registryOps = registries.createSerializationContext(NbtOps.INSTANCE);
@@ -50,7 +_,7 @@
@Override
protected void saveAdditional(ValueOutput output) {
super.saveAdditional(output);
- if (!this.patterns.equals(BannerPatternLayers.EMPTY)) {
+ if (!this.patterns.equals(BannerPatternLayers.EMPTY) || serialisingForNetwork.get()) { // Paper - always send patterns to client
tag.store("patterns", BannerPatternLayers.CODEC, registryOps, this.patterns);
output.store("patterns", BannerPatternLayers.CODEC, this.patterns);
}
@@ -64,7 +_,7 @@
super.loadAdditional(tag, registries);
this.name = parseCustomNameSafe(tag.get("CustomName"), registries);
RegistryOps<Tag> registryOps = registries.createSerializationContext(NbtOps.INSTANCE);
- this.patterns = tag.read("patterns", BannerPatternLayers.CODEC, registryOps).orElse(BannerPatternLayers.EMPTY);
+ this.setPatterns(tag.read("patterns", BannerPatternLayers.CODEC, registryOps).orElse(BannerPatternLayers.EMPTY)); // CraftBukkit - apply limits
@@ -61,7 +_,7 @@
protected void loadAdditional(ValueInput input) {
super.loadAdditional(input);
this.name = parseCustomNameSafe(input, "CustomName");
- this.patterns = input.read("patterns", BannerPatternLayers.CODEC).orElse(BannerPatternLayers.EMPTY);
+ this.setPatterns(input.read("patterns", BannerPatternLayers.CODEC).orElse(BannerPatternLayers.EMPTY)); // CraftBukkit - apply limits
}
@Override
@@ -72,9 +_,18 @@
@@ -69,9 +_,18 @@
return ClientboundBlockEntityDataPacket.create(this);
}
@@ -37,7 +37,7 @@
}
public BannerPatternLayers getPatterns() {
@@ -94,7 +_,7 @@
@@ -91,7 +_,7 @@
@Override
protected void applyImplicitComponents(DataComponentGetter componentGetter) {
super.applyImplicitComponents(componentGetter);
@@ -46,9 +46,9 @@
this.name = componentGetter.get(DataComponents.CUSTOM_NAME);
}
@@ -110,4 +_,13 @@
tag.remove("patterns");
tag.remove("CustomName");
@@ -107,4 +_,13 @@
output.discard("patterns");
output.discard("CustomName");
}
+
+ // CraftBukkit start

View File

@@ -1,7 +1,7 @@
--- a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
@@ -21,6 +_,41 @@
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.storage.ValueOutput;
public class BarrelBlockEntity extends RandomizableContainerBlockEntity {
+ // CraftBukkit start - add fields and methods

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
@@ -69,17 +_,45 @@
@@ -66,17 +_,45 @@
protected abstract Component getDefaultName();
public boolean canOpen(Player player) {
@@ -48,9 +48,9 @@
}
protected abstract NonNullList<ItemStack> getItems();
@@ -167,4 +_,12 @@
tag.remove("lock");
tag.remove("Items");
@@ -164,4 +_,12 @@
output.discard("lock");
output.discard("Items");
}
+
+ // CraftBukkit start

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
@@ -109,6 +_,53 @@
@@ -110,6 +_,53 @@
return 3;
}
};
@@ -54,7 +54,7 @@
@Nullable
static Holder<MobEffect> filterEffect(@Nullable Holder<MobEffect> effect) {
@@ -166,17 +_,26 @@
@@ -167,17 +_,26 @@
blockEntity.lastCheckY++;
}
@@ -83,7 +83,7 @@
if (blockEntity.lastCheckY >= height) {
blockEntity.lastCheckY = level.getMinY() - 1;
@@ -227,35 +_,100 @@
@@ -228,35 +_,100 @@
@Override
public void setRemoved() {
@@ -202,35 +202,35 @@
public static void playSound(Level level, BlockPos pos, SoundEvent sound) {
level.playSound(null, pos, sound, SoundSource.BLOCKS, 1.0F, 1.0F);
@@ -284,7 +_,7 @@
@@ -285,7 +_,7 @@
@Nullable
private static Holder<MobEffect> loadEffect(CompoundTag tag, String key) {
- return tag.read(key, BuiltInRegistries.MOB_EFFECT.holderByNameCodec()).filter(VALID_EFFECTS::contains).orElse(null);
+ return tag.read(key, BuiltInRegistries.MOB_EFFECT.holderByNameCodec()).orElse(null); // CraftBukkit - persist manually set non-default beacon effects (SPIGOT-3598)
private static Holder<MobEffect> loadEffect(ValueInput input, String key) {
- return input.read(key, BuiltInRegistries.MOB_EFFECT.holderByNameCodec()).filter(VALID_EFFECTS::contains).orElse(null);
+ return input.read(key, BuiltInRegistries.MOB_EFFECT.holderByNameCodec()).orElse(null); // CraftBukkit - persist manually set non-default beacon effects (SPIGOT-3598)
}
@Override
@@ -292,8 +_,10 @@
super.loadAdditional(tag, registries);
this.primaryPower = loadEffect(tag, "primary_effect");
this.secondaryPower = loadEffect(tag, "secondary_effect");
+ this.levels = tag.getIntOr("Levels", 0); // CraftBukkit - SPIGOT-5053, use where available
this.name = parseCustomNameSafe(tag.get("CustomName"), registries);
this.lockKey = LockCode.fromTag(tag, registries);
+ this.effectRange = tag.getDoubleOr(PAPER_RANGE_TAG, -1); // Paper - Custom beacon ranges
@@ -293,8 +_,10 @@
super.loadAdditional(input);
this.primaryPower = loadEffect(input, "primary_effect");
this.secondaryPower = loadEffect(input, "secondary_effect");
+ this.levels = input.getIntOr("Levels", 0); // CraftBukkit - SPIGOT-5053, use where available
this.name = parseCustomNameSafe(input, "CustomName");
this.lockKey = LockCode.fromTag(input);
+ this.effectRange = input.getDoubleOr(PAPER_RANGE_TAG, -1); // Paper - Custom beacon ranges
}
@Override
@@ -304,6 +_,7 @@
tag.putInt("Levels", this.levels);
tag.storeNullable("CustomName", ComponentSerialization.CODEC, registries.createSerializationContext(NbtOps.INSTANCE), this.name);
this.lockKey.addToTag(tag, registries);
+ tag.putDouble(PAPER_RANGE_TAG, this.effectRange); // Paper - Custom beacon ranges
@@ -305,6 +_,7 @@
output.putInt("Levels", this.levels);
output.storeNullable("CustomName", ComponentSerialization.CODEC, this.name);
this.lockKey.addToTag(output);
+ output.putDouble(PAPER_RANGE_TAG, this.effectRange); // Paper - Custom beacon ranges
}
public void setCustomName(@Nullable Component name) {
@@ -319,7 +_,7 @@
@@ -320,7 +_,7 @@
@Nullable
@Override
public AbstractContainerMenu createMenu(int containerId, Inventory playerInventory, Player player) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
@@ -79,6 +_,7 @@
@@ -82,6 +_,7 @@
private List<BeehiveBlockEntity.BeeData> stored = Lists.newArrayList();
@Nullable
public BlockPos savedFlowerPos;
@@ -8,7 +8,7 @@
public BeehiveBlockEntity(BlockPos pos, BlockState blockState) {
super(BlockEntityType.BEEHIVE, pos, blockState);
@@ -112,7 +_,7 @@
@@ -115,7 +_,7 @@
}
public boolean isFull() {
@@ -17,7 +17,7 @@
}
public void emptyAllLivingFromHive(@Nullable Player player, BlockState state, BeehiveBlockEntity.BeeReleaseStatus releaseStatus) {
@@ -121,7 +_,7 @@
@@ -124,7 +_,7 @@
for (Entity entity : list) {
if (entity instanceof Bee bee && player.position().distanceToSqr(entity.position()) <= 16.0) {
if (!this.isSedated()) {
@@ -26,7 +26,7 @@
} else {
bee.setStayOutOfHiveCountdown(400);
}
@@ -131,8 +_,14 @@
@@ -134,8 +_,14 @@
}
private List<Entity> releaseAllOccupants(BlockState state, BeehiveBlockEntity.BeeReleaseStatus releaseStatus) {
@@ -42,7 +42,7 @@
if (!list.isEmpty()) {
super.setChanged();
}
@@ -145,6 +_,11 @@
@@ -148,6 +_,11 @@
return this.stored.size();
}
@@ -54,7 +54,7 @@
public static int getHoneyLevel(BlockState state) {
return state.getValue(BeehiveBlock.HONEY_LEVEL);
}
@@ -155,7 +_,16 @@
@@ -158,7 +_,16 @@
}
public void addOccupant(Bee bee) {
@@ -72,7 +72,7 @@
bee.stopRiding();
bee.ejectPassengers();
bee.dropLeash();
@@ -180,7 +_,7 @@
@@ -183,7 +_,7 @@
this.level.gameEvent(GameEvent.BLOCK_CHANGE, blockPos, GameEvent.Context.of(bee, this.getBlockState()));
}
@@ -81,7 +81,7 @@
super.setChanged();
}
}
@@ -198,7 +_,21 @@
@@ -201,7 +_,21 @@
BeehiveBlockEntity.BeeReleaseStatus releaseStatus,
@Nullable BlockPos storedFlowerPos
) {
@@ -104,7 +104,7 @@
return false;
} else {
Direction direction = state.getValue(BeehiveBlock.FACING);
@@ -209,6 +_,17 @@
@@ -212,6 +_,17 @@
} else {
Entity entity = occupant.createEntity(level, pos);
if (entity != null) {
@@ -122,7 +122,7 @@
if (entity instanceof Bee bee) {
if (storedFlowerPos != null && !bee.hasSavedFlowerPos() && level.random.nextFloat() < 0.9F) {
bee.setSavedFlowerPos(storedFlowerPos);
@@ -224,7 +_,13 @@
@@ -227,7 +_,13 @@
i--;
}
@@ -137,7 +137,7 @@
}
}
}
@@ -233,17 +_,19 @@
@@ -236,17 +_,19 @@
storedInHives.add(bee);
}
@@ -158,7 +158,7 @@
} else {
return false;
}
@@ -269,6 +_,11 @@
@@ -272,6 +_,11 @@
flag = true;
iterator.remove();
}
@@ -170,23 +170,23 @@
}
}
@@ -292,9 +_,10 @@
@@ -295,9 +_,10 @@
@Override
protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) {
super.loadAdditional(tag, registries);
protected void loadAdditional(ValueInput input) {
super.loadAdditional(input);
- this.stored.clear();
+ this.stored = Lists.newArrayList(); // CraftBukkit - SPIGOT-7790: create new copy (may be modified in physics event triggered by honey change)
tag.read("bees", BeehiveBlockEntity.Occupant.LIST_CODEC).orElse(List.of()).forEach(this::storeBee);
this.savedFlowerPos = tag.read("flower_pos", BlockPos.CODEC).orElse(null);
+ this.maxBees = tag.getIntOr("Bukkit.MaxEntities", MAX_OCCUPANTS); // Paper - persist max bukkit occupants
input.read("bees", BeehiveBlockEntity.Occupant.LIST_CODEC).orElse(List.of()).forEach(this::storeBee);
this.savedFlowerPos = input.read("flower_pos", BlockPos.CODEC).orElse(null);
+ this.maxBees = input.getIntOr("Bukkit.MaxEntities", MAX_OCCUPANTS); // Paper - persist max bukkit occupants
}
@Override
@@ -302,12 +_,13 @@
super.saveAdditional(tag, registries);
tag.store("bees", BeehiveBlockEntity.Occupant.LIST_CODEC, this.getBees());
tag.storeNullable("flower_pos", BlockPos.CODEC, this.savedFlowerPos);
+ tag.putInt("Bukkit.MaxEntities", this.maxBees); // Paper - persist max bukkit occupants
@@ -305,12 +_,13 @@
super.saveAdditional(output);
output.store("bees", BeehiveBlockEntity.Occupant.LIST_CODEC, this.getBees());
output.storeNullable("flower_pos", BlockPos.CODEC, this.savedFlowerPos);
+ output.putInt("Bukkit.MaxEntities", this.maxBees); // Paper - persist max bukkit occupants
}
@Override
@@ -197,7 +197,7 @@
List<BeehiveBlockEntity.Occupant> list = componentGetter.getOrDefault(DataComponents.BEES, Bees.EMPTY).bees();
list.forEach(this::storeBee);
}
@@ -330,15 +_,18 @@
@@ -333,15 +_,18 @@
static class BeeData {
private final BeehiveBlockEntity.Occupant occupant;
@@ -217,7 +217,7 @@
}
public BeehiveBlockEntity.Occupant toOccupant() {
@@ -409,6 +_,7 @@
@@ -418,6 +_,7 @@
}
private static void setBeeReleaseData(int ticksInHive, Bee bee) {
@@ -225,7 +225,7 @@
int age = bee.getAge();
if (age < 0) {
bee.setAge(Math.min(0, age + ticksInHive));
@@ -417,6 +_,7 @@
@@ -426,6 +_,7 @@
}
bee.setInLoveTime(Math.max(0, bee.getInLoveTime() - ticksInHive));

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/BlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BlockEntity.java
@@ -33,6 +_,10 @@
@@ -35,6 +_,10 @@
import org.slf4j.Logger;
public abstract class BlockEntity {
@@ -11,7 +11,7 @@
private static final Codec<BlockEntityType<?>> TYPE_CODEC = BuiltInRegistries.BLOCK_ENTITY_TYPE.byNameCodec();
private static final Logger LOGGER = LogUtils.getLogger();
private final BlockEntityType<?> type;
@@ -48,6 +_,7 @@
@@ -50,6 +_,7 @@
this.worldPosition = pos.immutable();
this.validateBlockState(blockState);
this.blockState = blockState;
@@ -19,7 +19,7 @@
}
private void validateBlockState(BlockState state) {
@@ -64,6 +_,7 @@
@@ -66,6 +_,7 @@
int intOr = tag.getIntOr("x", 0);
int intOr1 = tag.getIntOr("y", 0);
int intOr2 = tag.getIntOr("z", 0);
@@ -27,7 +27,7 @@
int sectionPosCoord = SectionPos.blockToSectionCoord(intOr);
int sectionPosCoord1 = SectionPos.blockToSectionCoord(intOr2);
if (sectionPosCoord != chunkPos.x || sectionPosCoord1 != chunkPos.z) {
@@ -71,6 +_,7 @@
@@ -73,6 +_,7 @@
intOr = chunkPos.getBlockX(SectionPos.sectionRelative(intOr));
intOr2 = chunkPos.getBlockZ(SectionPos.sectionRelative(intOr2));
}
@@ -35,45 +35,44 @@
return new BlockPos(intOr, intOr1, intOr2);
}
@@ -89,6 +_,14 @@
@@ -91,6 +_,12 @@
}
protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) {
protected void loadAdditional(ValueInput input) {
+ // Paper start - read persistent data container
+ this.persistentDataContainer.clear(); // Paper - clear instead of init
+
+ net.minecraft.nbt.Tag persistentDataTag = tag.get("PublicBukkitValues");
+ if (persistentDataTag instanceof CompoundTag) {
+ this.persistentDataContainer.putAll((CompoundTag) persistentDataTag);
+ }
+ input.read("PublicBukkitValues", CompoundTag.CODEC)
+ .ifPresent(this.persistentDataContainer::putAll);
+ // Paper end - read persistent data container
}
public final void loadWithComponents(CompoundTag tag, HolderLookup.Provider registries) {
@@ -120,12 +_,22 @@
CompoundTag compoundTag = new CompoundTag();
this.saveAdditional(compoundTag, registries);
compoundTag.store(BlockEntity.ComponentHelper.COMPONENTS_CODEC, registries.createSerializationContext(NbtOps.INSTANCE), this.components);
public final void loadWithComponents(ValueInput input) {
@@ -140,6 +_,11 @@
public void saveWithoutMetadata(ValueOutput output) {
this.saveAdditional(output);
output.store("components", DataComponentMap.CODEC, this.components);
+ // CraftBukkit start - store container
+ if (!this.persistentDataContainer.isEmpty()) {
+ compoundTag.put("PublicBukkitValues", this.persistentDataContainer.toTagCompound());
+ output.store("PublicBukkitValues", CompoundTag.CODEC, this.persistentDataContainer.toTagCompound());
+ }
+ // CraftBukkit end
return compoundTag;
}
public final CompoundTag saveCustomOnly(HolderLookup.Provider registries) {
CompoundTag compoundTag = new CompoundTag();
this.saveAdditional(compoundTag, registries);
@@ -155,6 +_,11 @@
public void saveCustomOnly(ValueOutput output) {
this.saveAdditional(output);
+ // Paper start - store PDC here as well
+ if (!this.persistentDataContainer.isEmpty()) {
+ compoundTag.put("PublicBukkitValues", this.persistentDataContainer.toTagCompound());
+ output.store("PublicBukkitValues", CompoundTag.CODEC, this.persistentDataContainer.toTagCompound());
+ }
+ // Paper end
return compoundTag;
}
@@ -260,6 +_,12 @@
public void saveId(ValueOutput output) {
@@ -287,6 +_,12 @@
}
public final void applyComponents(DataComponentMap components, DataComponentPatch patch) {
@@ -86,7 +85,7 @@
final Set<DataComponentType<?>> set = new HashSet<>();
set.add(DataComponents.BLOCK_ENTITY_DATA);
set.add(DataComponents.BLOCK_STATE);
@@ -280,6 +_,10 @@
@@ -307,6 +_,10 @@
});
DataComponentPatch dataComponentPatch = patch.forget(set::contains);
this.components = dataComponentPatch.split().added();
@@ -97,9 +96,9 @@
}
protected void collectImplicitComponents(DataComponentMap.Builder components) {
@@ -313,6 +_,28 @@
.resultOrPartial(string -> LOGGER.warn("Failed to parse custom name, discarding: {}", string))
.orElse(null);
@@ -339,6 +_,27 @@
public ProblemReporter.PathElement problemPath() {
return new BlockEntity.BlockEntityPathElement(this);
}
+
+ // CraftBukkit start - add method
@@ -122,7 +121,6 @@
+ return tag;
+ }
+ // Paper end - Sanitize sent data
+
static class ComponentHelper {
public static final MapCodec<DataComponentMap> COMPONENTS_CODEC = DataComponentMap.CODEC.optionalFieldOf("components", DataComponentMap.EMPTY);
record BlockEntityPathElement(BlockEntity blockEntity) implements ProblemReporter.PathElement {
@Override

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/BrushableBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BrushableBlockEntity.java
@@ -65,9 +_,26 @@
@@ -67,9 +_,26 @@
return false;
} else {
this.coolDownEndsAtTick = startTick + 10L;
@@ -29,7 +29,7 @@
this.brushingCompleted(level, brusher, stack);
return true;
} else {
@@ -75,7 +_,7 @@
@@ -77,7 +_,7 @@
int completionState1 = this.getCompletionState();
if (completionState != completionState1) {
BlockState blockState = this.getBlockState();
@@ -38,7 +38,7 @@
level.setBlock(this.getBlockPos(), blockState1, 3);
}
@@ -116,6 +_,11 @@
@@ -118,6 +_,11 @@
this.dropContent(level, brusher, stack);
BlockState blockState = this.getBlockState();
level.levelEvent(3008, this.getBlockPos(), Block.getId(blockState));
@@ -50,7 +50,7 @@
Block turnsInto;
if (this.getBlockState().getBlock() instanceof BrushableBlock brushableBlock) {
turnsInto = brushableBlock.getTurnsInto();
@@ -123,6 +_,11 @@
@@ -125,6 +_,11 @@
turnsInto = Blocks.AIR;
}
@@ -62,7 +62,7 @@
level.setBlock(this.worldPosition, turnsInto.defaultBlockState(), 3);
}
@@ -139,7 +_,12 @@
@@ -141,7 +_,12 @@
double d5 = blockPos.getZ() + 0.5 * d1 + d2;
ItemEntity itemEntity = new ItemEntity(level, d3, d4, d5, this.item.split(level.random.nextInt(21) + 10));
itemEntity.setDeltaMovement(Vec3.ZERO);

View File

@@ -6,8 +6,8 @@
}
+ // Paper start - Configurable sculk sensor listener range
+ @Override
+ protected void saveRangeOverride(final net.minecraft.nbt.CompoundTag nbt) {
+ if (this.rangeOverride != null && this.rangeOverride != 16) nbt.putInt(PAPER_LISTENER_RANGE_NBT_KEY, this.rangeOverride); // only save if it's different from the default
+ protected void saveRangeOverride(final net.minecraft.world.level.storage.ValueOutput output) {
+ if (this.rangeOverride != null && this.rangeOverride != 16) output.putInt(PAPER_LISTENER_RANGE_NBT_KEY, this.rangeOverride); // only save if it's different from the default
+ }
+ // Paper end - Configurable sculk sensor listener range

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/CampfireBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/CampfireBlockEntity.java
@@ -38,6 +_,7 @@
@@ -45,6 +_,7 @@
private final NonNullList<ItemStack> items = NonNullList.withSize(4, ItemStack.EMPTY);
public final int[] cookingProgress = new int[4];
public final int[] cookingTime = new int[4];
@@ -8,7 +8,7 @@
public CampfireBlockEntity(BlockPos pos, BlockState blockState) {
super(BlockEntityType.CAMPFIRE, pos, blockState);
@@ -56,14 +_,44 @@
@@ -63,14 +_,44 @@
ItemStack itemStack = campfire.items.get(i);
if (!itemStack.isEmpty()) {
flag = true;
@@ -55,38 +55,38 @@
campfire.items.set(i, ItemStack.EMPTY);
level.sendBlockUpdated(pos, state, state, 3);
level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(state));
@@ -135,6 +_,16 @@
@@ -142,6 +_,16 @@
.ifPresentOrElse(
ints -> System.arraycopy(ints, 0, this.cookingTime, 0, Math.min(this.cookingTime.length, ints.length)), () -> Arrays.fill(this.cookingTime, 0)
);
+
+ // Paper start - Add more Campfire API
+ tag.getByteArray("Paper.StopCooking").ifPresent(bytes -> {
+ input.read("Paper.StopCooking", com.mojang.serialization.Codec.BYTE_BUFFER).ifPresent(bytes -> {
+ final boolean[] cookingState = new boolean[4];
+ for (int index = 0; index < bytes.length; index++) {
+ cookingState[index] = bytes[index] == 1;
+ for (int index = 0; bytes.hasRemaining() && index < cookingState.length; index++) {
+ cookingState[index] = bytes.get() == 1;
+ }
+ System.arraycopy(cookingState, 0, this.stopCooking, 0, Math.min(this.stopCooking.length, bytes.length));
+ System.arraycopy(cookingState, 0, this.stopCooking, 0, Math.min(this.stopCooking.length, bytes.capacity()));
+ });
+ // Paper end - Add more Campfire API
}
@Override
@@ -143,6 +_,13 @@
ContainerHelper.saveAllItems(tag, this.items, true, registries);
tag.putIntArray("CookingTimes", this.cookingProgress);
tag.putIntArray("CookingTotalTimes", this.cookingTime);
@@ -150,6 +_,13 @@
ContainerHelper.saveAllItems(output, this.items, true);
output.putIntArray("CookingTimes", this.cookingProgress);
output.putIntArray("CookingTotalTimes", this.cookingTime);
+ // Paper start - Add more Campfire API
+ byte[] cookingState = new byte[4];
+ for (int index = 0; index < cookingState.length; index++) {
+ cookingState[index] = (byte) (this.stopCooking[index] ? 1 : 0);
+ }
+ tag.putByteArray("Paper.StopCooking", cookingState);
+ output.store("Paper.StopCooking", com.mojang.serialization.Codec.BYTE_BUFFER, java.nio.ByteBuffer.wrap(cookingState));
+ // Paper end - Add more Campfire API
}
@Override
@@ -167,7 +_,15 @@
@@ -179,7 +_,15 @@
return false;
}

View File

@@ -21,7 +21,7 @@
int x = pos.getX();
int y = pos.getY();
int z = pos.getZ();
@@ -175,13 +_,19 @@
@@ -175,20 +_,25 @@
if (!entitiesOfClass.isEmpty()) {
for (Player player : entitiesOfClass) {
if (pos.closerThan(player.blockPosition(), i) && player.isInWaterOrRain()) {
@@ -32,31 +32,21 @@
}
}
private static void updateDestroyTarget(Level level, BlockPos pos, BlockState state, List<BlockPos> positions, ConduitBlockEntity blockEntity) {
+ // CraftBukkit start - add "damageTarget" boolean
+ ConduitBlockEntity.updateDestroyTarget(level, pos, state, positions, blockEntity, true);
private static void updateAndAttackTarget(ServerLevel level, BlockPos pos, BlockState state, ConduitBlockEntity blockEntity, boolean canDestroy) {
+ // CraftBukkit start - add "damageTarget" boolean
+ updateAndAttackTarget(level, pos, state, blockEntity, canDestroy, true);
+ }
+
+ public static void updateDestroyTarget(Level level, BlockPos pos, BlockState state, List<BlockPos> positions, ConduitBlockEntity blockEntity, boolean damageTarget) {
+ // CraftBukkit end
LivingEntity livingEntity = blockEntity.destroyTarget;
int size = positions.size();
if (size < 42) {
@@ -200,7 +_,8 @@
blockEntity.destroyTarget = null;
}
- if (blockEntity.destroyTarget != null) {
+ if (damageTarget && blockEntity.destroyTarget != null) { // CraftBukkit
+ if (blockEntity.destroyTarget.hurtServer((net.minecraft.server.level.ServerLevel) level, level.damageSources().magic().eventBlockDamager(level, pos), 4.0F)) // CraftBukkit
+ public static void updateAndAttackTarget(ServerLevel level, BlockPos pos, BlockState state, ConduitBlockEntity blockEntity, boolean canDestroy, boolean damageTarget) {
+ // CraftBukkit end - add "damageTarget" boolean
EntityReference<LivingEntity> entityReference = updateDestroyTarget(blockEntity.destroyTarget, level, pos, canDestroy);
LivingEntity livingEntity = EntityReference.get(entityReference, level, LivingEntity.class);
- if (livingEntity != null) {
+ if (damageTarget && livingEntity != null) { // CraftBukkit
+ if (livingEntity.hurtServer(level, level.damageSources().magic().eventBlockDamager(level, pos), 4.0F)) // CraftBukkit - move up
level.playSound(
null,
blockEntity.destroyTarget.getX(),
@@ -211,7 +_,6 @@
1.0F,
1.0F
null, livingEntity.getX(), livingEntity.getY(), livingEntity.getZ(), SoundEvents.CONDUIT_ATTACK_TARGET, SoundSource.BLOCKS, 1.0F, 1.0F
);
- blockEntity.destroyTarget.hurt(level.damageSources().magic(), 4.0F);
- livingEntity.hurtServer(level, level.damageSources().magic(), 4.0F);
}
if (livingEntity != blockEntity.destroyTarget) {
if (!Objects.equals(entityReference, blockEntity.destroyTarget)) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/DecoratedPotBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/DecoratedPotBlockEntity.java
@@ -24,6 +_,48 @@
@@ -23,6 +_,48 @@
import net.minecraft.world.ticks.ContainerSingleItem;
public class DecoratedPotBlockEntity extends BlockEntity implements RandomizableContainer, ContainerSingleItem.BlockContainerSingleItem {
@@ -49,18 +49,18 @@
public static final String TAG_SHERDS = "sherds";
public static final String TAG_ITEM = "item";
public static final int EVENT_POT_WOBBLES = 1;
@@ -48,8 +_,8 @@
tag.store("sherds", PotDecorations.CODEC, this.decorations);
@@ -47,8 +_,8 @@
output.store("sherds", PotDecorations.CODEC, this.decorations);
}
- if (!this.trySaveLootTable(tag) && !this.item.isEmpty()) {
- tag.store("item", ItemStack.CODEC, registries.createSerializationContext(NbtOps.INSTANCE), this.item);
+ if (!this.trySaveLootTable(tag) && !this.item.isEmpty()) { // Paper - diff on change - hide unnecessary update data
+ tag.store("item", ItemStack.CODEC, registries.createSerializationContext(NbtOps.INSTANCE), this.item); // Paper - diff on change - hide unnecessary update data
- if (!this.trySaveLootTable(output) && !this.item.isEmpty()) {
- output.store("item", ItemStack.CODEC, this.item);
+ if (!this.trySaveLootTable(output) && !this.item.isEmpty()) { // Paper - diff on change - hide unnecessary update data
+ output.store("item", ItemStack.CODEC, this.item); // Paper - diff on change - hide unnecessary update data
}
}
@@ -72,7 +_,14 @@
@@ -70,7 +_,14 @@
@Override
public CompoundTag getUpdateTag(HolderLookup.Provider registries) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/JigsawBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/JigsawBlockEntity.java
@@ -138,7 +_,12 @@
@@ -140,7 +_,12 @@
public void generate(ServerLevel level, int maxDepth, boolean keepJigsaws) {
BlockPos blockPos = this.getBlockPos().relative(this.getBlockState().getValue(JigsawBlock.ORIENTATION).front());
Registry<StructureTemplatePool> registry = level.registryAccess().lookupOrThrow(Registries.TEMPLATE_POOL);

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java
@@ -23,6 +_,44 @@
@@ -20,6 +_,44 @@
import net.minecraft.world.ticks.ContainerSingleItem;
public class JukeboxBlockEntity extends BlockEntity implements ContainerSingleItem.BlockContainerSingleItem {
@@ -45,7 +45,7 @@
public static final String SONG_ITEM_TAG_ID = "RecordItem";
public static final String TICKS_SINCE_SONG_STARTED_TAG_ID = "ticks_since_song_started";
private ItemStack item = ItemStack.EMPTY;
@@ -128,7 +_,7 @@
@@ -123,7 +_,7 @@
@Override
public int getMaxStackSize() {
@@ -54,7 +54,7 @@
}
@Override
@@ -152,11 +_,16 @@
@@ -147,11 +_,16 @@
}
@VisibleForTesting

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/LecternBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/LecternBlockEntity.java
@@ -36,7 +_,53 @@
@@ -33,7 +_,53 @@
public static final int NUM_DATA = 1;
public static final int SLOT_BOOK = 0;
public static final int NUM_SLOTS = 1;
@@ -55,7 +55,7 @@
@Override
public int getContainerSize() {
return 1;
@@ -80,11 +_,19 @@
@@ -77,11 +_,19 @@
@Override
public void setItem(int slot, ItemStack stack) {
@@ -76,7 +76,7 @@
}
@Override
@@ -162,7 +_,7 @@
@@ -159,7 +_,7 @@
if (i != this.page) {
this.page = i;
this.setChanged();
@@ -85,7 +85,7 @@
}
}
@@ -183,6 +_,36 @@
@@ -180,6 +_,36 @@
return stack;
}
@@ -122,7 +122,7 @@
private CommandSourceStack createCommandSourceStack(@Nullable Player player, ServerLevel level) {
String string;
Component component;
@@ -195,7 +_,7 @@
@@ -192,7 +_,7 @@
}
Vec3 vec3 = Vec3.atCenterOf(this.worldPosition);
@@ -131,7 +131,7 @@
}
@Override
@@ -237,7 +_,7 @@
@@ -232,7 +_,7 @@
@Override
public AbstractContainerMenu createMenu(int containerId, Inventory playerInventory, Player player) {

View File

@@ -1,8 +1,8 @@
--- a/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
@@ -116,4 +_,13 @@
tag.remove("LootTable");
tag.remove("LootTableSeed");
output.discard("LootTable");
output.discard("LootTableSeed");
}
+
+ // Paper start - LootTable API

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java
@@ -24,6 +_,7 @@
@@ -21,6 +_,7 @@
private final VibrationSystem.Listener vibrationListener;
private final VibrationSystem.User vibrationUser;
public int lastVibrationFrequency = 0;
@@ -8,32 +8,31 @@
protected SculkSensorBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState blockState) {
super(type, pos, blockState);
@@ -46,15 +_,23 @@
this.lastVibrationFrequency = tag.getIntOr("last_vibration_frequency", 0);
RegistryOps<Tag> registryOps = registries.createSerializationContext(NbtOps.INSTANCE);
this.vibrationData = tag.read("listener", VibrationSystem.Data.CODEC, registryOps).orElseGet(VibrationSystem.Data::new);
+ this.rangeOverride = tag.getInt(PAPER_LISTENER_RANGE_NBT_KEY).orElse(null); // Paper start - Configurable sculk sensor listener range
@@ -42,14 +_,22 @@
super.loadAdditional(input);
this.lastVibrationFrequency = input.getIntOr("last_vibration_frequency", 0);
this.vibrationData = input.read("listener", VibrationSystem.Data.CODEC).orElseGet(VibrationSystem.Data::new);
+ this.rangeOverride = input.getInt(PAPER_LISTENER_RANGE_NBT_KEY).orElse(null); // Paper start - Configurable sculk sensor listener range
}
+ protected static final String PAPER_LISTENER_RANGE_NBT_KEY = "Paper.ListenerRange"; // Paper - Configurable sculk sensor listener range
@Override
protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) {
super.saveAdditional(tag, registries);
tag.putInt("last_vibration_frequency", this.lastVibrationFrequency);
RegistryOps<Tag> registryOps = registries.createSerializationContext(NbtOps.INSTANCE);
tag.store("listener", VibrationSystem.Data.CODEC, registryOps, this.vibrationData);
protected void saveAdditional(ValueOutput output) {
super.saveAdditional(output);
output.putInt("last_vibration_frequency", this.lastVibrationFrequency);
output.store("listener", VibrationSystem.Data.CODEC, this.vibrationData);
- }
+ this.saveRangeOverride(tag); // Paper - Configurable sculk sensor listener range
+ this.saveRangeOverride(output); // Paper - Configurable sculk sensor listener range
+ }
+ // Paper start - Configurable sculk sensor listener range
+ protected void saveRangeOverride(CompoundTag tag) {
+ if (this.rangeOverride != null && this.rangeOverride != VibrationUser.LISTENER_RANGE) tag.putInt(PAPER_LISTENER_RANGE_NBT_KEY, this.rangeOverride); // only save if it's different from the default
+ protected void saveRangeOverride(ValueOutput output) {
+ if (this.rangeOverride != null && this.rangeOverride != VibrationUser.LISTENER_RANGE) output.putInt(PAPER_LISTENER_RANGE_NBT_KEY, this.rangeOverride); // only save if it's different from the default
+ }
+ // Paper end - Configurable sculk sensor listener range
@Override
public VibrationSystem.Data getVibrationData() {
@@ -91,6 +_,7 @@
@@ -86,6 +_,7 @@
@Override
public int getListenerRadius() {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java
@@ -91,6 +_,13 @@
@@ -86,6 +_,13 @@
@Nullable
public static ServerPlayer tryGetPlayer(@Nullable Entity entity) {
@@ -14,7 +14,7 @@
if (entity instanceof ServerPlayer serverPlayer) {
return serverPlayer;
} else if (entity != null && entity.getControllingPassenger() instanceof ServerPlayer serverPlayer) {
@@ -166,7 +_,7 @@
@@ -161,7 +_,7 @@
private boolean trySummonWarden(ServerLevel level) {
return this.warningLevel >= 4
&& SpawnUtil.trySpawnMob(

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/SignBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/SignBlockEntity.java
@@ -58,10 +_,15 @@
@@ -57,10 +_,15 @@
}
public boolean isFacingFrontText(Player player) {
@@ -18,7 +18,7 @@
float yRotationDegrees = signBlock.getYRotationDegrees(this.getBlockState());
float f = (float)(Mth.atan2(d1, d) * 180.0F / (float)Math.PI) - 90.0F;
return Mth.degreesDifferenceAbs(yRotationDegrees, f) <= 90.0F;
@@ -131,11 +_,13 @@
@@ -128,11 +_,13 @@
public void updateSignText(Player player, boolean isFrontText, List<FilteredText> filteredText) {
if (!this.isWaxed() && player.getUUID().equals(this.getPlayerWhoMayEdit()) && this.level != null) {
@@ -33,7 +33,7 @@
}
}
@@ -144,18 +_,40 @@
@@ -141,19 +_,41 @@
return this.setText(updater.apply(text), isFrontText);
}
@@ -53,7 +53,7 @@
);
}
}
+
+ // CraftBukkit start
+ org.bukkit.entity.Player apiPlayer = ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity();
+ List<net.kyori.adventure.text.Component> lines = new java.util.ArrayList<>(); // Paper - adventure
@@ -74,41 +74,40 @@
+ }
+ }
+ // CraftBukkit end
+
return text;
}
@@ -193,8 +_,24 @@
for (Component component : this.getText(frontText).getMessages(player.isTextFilteringEnabled())) {
@@ -192,7 +_,23 @@
Style style = component.getStyle();
- if (style.getClickEvent() instanceof ClickEvent.RunCommand(String var14)) {
- player.getServer().getCommands().performPrefixedCommand(createCommandSourceStack(player, level, pos), var14);
+ if (style.getClickEvent() instanceof ClickEvent.RunCommand(String var14)) { final String runCommand = var14; // Paper - OBFHELPER
+ // Paper start - Fix commands from signs not firing command events
+ String command = runCommand.startsWith("/") ? runCommand : "/" + runCommand;
+ if (org.spigotmc.SpigotConfig.logCommands) {
+ LOGGER.info("{} issued server command: {}", player.getScoreboardName(), command);
+ }
+ io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent event = new io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent(
+ (org.bukkit.entity.Player) player.getBukkitEntity(),
+ command,
+ new org.bukkit.craftbukkit.util.LazyPlayerSet(player.getServer()),
+ (org.bukkit.block.Sign) org.bukkit.craftbukkit.block.CraftBlock.at(this.level, this.worldPosition).getState(),
+ frontText ? org.bukkit.block.sign.Side.FRONT : org.bukkit.block.sign.Side.BACK
+ );
+ if (!event.callEvent()) {
+ return false;
+ }
+ player.getServer().getCommands().performPrefixedCommand(createCommandSourceStack(((org.bukkit.craftbukkit.entity.CraftPlayer) event.getPlayer()).getHandle(), level, pos), event.getMessage());
+ // Paper end - Fix commands from signs not firing command events
flag = true;
}
}
@@ -202,10 +_,55 @@
switch (style.getClickEvent()) {
case ClickEvent.RunCommand runCommand:
- level.getServer().getCommands().performPrefixedCommand(createCommandSourceStack(player, level, pos), runCommand.command());
+ // Paper start - Fix commands from signs not firing command events
+ String command = runCommand.command().startsWith("/") ? runCommand.command() : "/" + runCommand.command();
+ if (org.spigotmc.SpigotConfig.logCommands) {
+ LOGGER.info("{} issued server command: {}", player.getScoreboardName(), command);
+ }
+ io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent event = new io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent(
+ (org.bukkit.entity.Player) player.getBukkitEntity(),
+ command,
+ new org.bukkit.craftbukkit.util.LazyPlayerSet(player.getServer()),
+ (org.bukkit.block.Sign) org.bukkit.craftbukkit.block.CraftBlock.at(this.level, this.worldPosition).getState(),
+ isFrontText ? org.bukkit.block.sign.Side.FRONT : org.bukkit.block.sign.Side.BACK
+ );
+ if (!event.callEvent()) {
+ return false;
+ }
+ level.getServer().getCommands().performPrefixedCommand(createCommandSourceStack(((org.bukkit.craftbukkit.entity.CraftPlayer) event.getPlayer()).getHandle(), level, pos), event.getMessage());
+ // Paper end - Fix commands from signs not firing command events
flag = true;
break;
case ClickEvent.ShowDialog showDialog:
@@ -211,10 +_,55 @@
return flag;
}
- private static CommandSourceStack createCommandSourceStack(@Nullable Player player, Level level, BlockPos pos) {
- private static CommandSourceStack createCommandSourceStack(@Nullable Player player, ServerLevel level, BlockPos pos) {
+ // CraftBukkit start
+ private final CommandSource commandSource = new CommandSource() {
+
@@ -136,11 +135,11 @@
+ }
+ };
+
+ private CommandSourceStack createCommandSourceStack(@Nullable Player player, Level level, BlockPos pos) {
+ private CommandSourceStack createCommandSourceStack(@Nullable Player player, ServerLevel level, BlockPos pos) {
+ // CraftBukkit end
String string = player == null ? "Sign" : player.getName().getString();
Component component = (Component)(player == null ? Component.literal("Sign") : player.getDisplayName());
- return new CommandSourceStack(CommandSource.NULL, Vec3.atCenterOf(pos), Vec2.ZERO, (ServerLevel)level, 2, string, component, level.getServer(), player);
- return new CommandSourceStack(CommandSource.NULL, Vec3.atCenterOf(pos), Vec2.ZERO, level, 2, string, component, level.getServer(), player);
+
+ // Paper start - Fix commands from signs not firing command events
+ CommandSource commandSource = level.paperConfig().misc.showSignClickCommandFailureMsgsToPlayer ? new io.papermc.paper.commands.DelegatingCommandSource(this.commandSource) {
@@ -158,11 +157,11 @@
+ } : this.commandSource;
+ // Paper end - Fix commands from signs not firing command events
+ // CraftBukkit - this
+ return new CommandSourceStack(commandSource, Vec3.atCenterOf(pos), Vec2.ZERO, (ServerLevel)level, 2, string, component, level.getServer(), player); // Paper - Fix commands from signs not firing command events
+ return new CommandSourceStack(commandSource, Vec3.atCenterOf(pos), Vec2.ZERO, level, 2, string, component, level.getServer(), player); // Paper - Fix commands from signs not firing command events
}
@Override
@@ -224,12 +_,17 @@
@@ -233,12 +_,17 @@
@Nullable
public UUID getPlayerWhoMayEdit() {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/SkullBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/SkullBlockEntity.java
@@ -40,7 +_,7 @@
@@ -41,7 +_,7 @@
@Nullable
private static LoadingCache<String, CompletableFuture<Optional<GameProfile>>> profileCacheByName;
@Nullable
@@ -9,7 +9,7 @@
public static final Executor CHECKED_MAIN_THREAD_EXECUTOR = runnable -> {
Executor executor = mainThreadExecutor;
if (executor != null) {
@@ -75,9 +_,9 @@
@@ -76,9 +_,9 @@
profileCacheById = CacheBuilder.newBuilder()
.expireAfterAccess(Duration.ofMinutes(10L))
.maximumSize(256L)
@@ -21,7 +21,7 @@
return SkullBlockEntity.fetchProfileById(id, services, booleanSupplier);
}
});
@@ -88,23 +_,29 @@
@@ -89,23 +_,29 @@
.getAsync(name)
.thenCompose(
optional -> {
@@ -56,7 +56,7 @@
}
public static void clear() {
@@ -188,9 +_,11 @@
@@ -189,9 +_,11 @@
: CompletableFuture.completedFuture(Optional.empty());
}

View File

@@ -1,10 +1,10 @@
--- a/net/minecraft/world/level/block/entity/TestBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/TestBlockEntity.java
@@ -36,6 +_,7 @@
@@ -38,6 +_,7 @@
@Override
public void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) {
+ super.loadAdditional(tag, registries); // Paper - load the PDC
this.mode = tag.read("mode", TestBlockMode.CODEC).orElse(TestBlockMode.FAIL);
this.message = tag.getStringOr("message", "");
this.powered = tag.getBooleanOr("powered", false);
protected void loadAdditional(ValueInput input) {
+ super.loadAdditional(input); // Paper - load the PDC
this.mode = input.read("mode", TestBlockMode.CODEC).orElse(TestBlockMode.FAIL);
this.message = input.getStringOr("message", "");
this.powered = input.getBooleanOr("powered", false);

View File

@@ -1,14 +1,14 @@
--- a/net/minecraft/world/level/block/entity/TestInstanceBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/TestInstanceBlockEntity.java
@@ -157,6 +_,7 @@
@@ -154,6 +_,7 @@
@Override
protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) {
+ super.loadAdditional(tag, registries); // Paper - load the PDC
Tag tag1 = tag.get("data");
if (tag1 != null) {
TestInstanceBlockEntity.Data.CODEC.parse(NbtOps.INSTANCE, tag1).ifSuccess(this::set);
@@ -320,7 +_,7 @@
protected void loadAdditional(ValueInput input) {
+ super.loadAdditional(input); // Paper - load the PDC
input.read("data", TestInstanceBlockEntity.Data.CODEC).ifPresent(this::set);
}
@@ -317,7 +_,7 @@
}
private void removeEntities() {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
@@ -129,7 +_,7 @@
@@ -131,7 +_,7 @@
@Nullable
public Vec3 getPortalPosition(ServerLevel level, BlockPos pos) {

View File

@@ -1,22 +1,22 @@
--- a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java
+++ b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java
@@ -238,7 +_,14 @@
nextSpawnData.getEquipment().ifPresent(mob::equip);
}
@@ -214,7 +_,14 @@
nextSpawnData.getEquipment().ifPresent(mob::equip);
}
- if (!level.tryAddFreshEntityWithPassengers(entity)) {
+ // Paper start - TrialSpawnerSpawnEvent + SpawnReason
+ entity.spawnedViaMobSpawner = true; // Mark entity as spawned via spawner
+ entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.TRIAL_SPAWNER; // Paper - Entity#getEntitySpawnReason
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callTrialSpawnerSpawnEvent(entity, pos).isCancelled()) {
+ return Optional.empty();
+ }
+ if (!level.tryAddFreshEntityWithPassengers(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.TRIAL_SPAWNER)) {
+ // Paper end - TrialSpawnerSpawnEvent + SpawnReason
return Optional.empty();
} else {
TrialSpawner.FlameParticle flameParticle = this.isOminous ? TrialSpawner.FlameParticle.OMINOUS : TrialSpawner.FlameParticle.NORMAL;
@@ -258,6 +_,19 @@
- if (!level.tryAddFreshEntityWithPassengers(entity)) {
+ // Paper start - TrialSpawnerSpawnEvent + SpawnReason
+ entity.spawnedViaMobSpawner = true; // Mark entity as spawned via spawner
+ entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.TRIAL_SPAWNER; // Paper - Entity#getEntitySpawnReason
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callTrialSpawnerSpawnEvent(entity, pos).isCancelled()) {
+ return Optional.empty();
+ }
+ if (!level.tryAddFreshEntityWithPassengers(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.TRIAL_SPAWNER)) {
+ // Paper end - TrialSpawnerSpawnEvent + SpawnReason
return Optional.empty();
}
@@ -233,6 +_,19 @@
LootParams lootParams = new LootParams.Builder(level).create(LootContextParamSets.EMPTY);
ObjectArrayList<ItemStack> randomItems = lootTable1.getRandomItems(lootParams);
if (!randomItems.isEmpty()) {
@@ -36,3 +36,39 @@
for (ItemStack itemStack : randomItems) {
DefaultDispenseItemBehavior.spawnItem(level, itemStack, 2, Direction.UP, Vec3.atBottomCenterOf(pos).relative(Direction.UP, 1.2));
}
@@ -402,6 +_,35 @@
this.requiredPlayerRange
);
}
+
+ // Paper start - trial spawner API - withers
+ public TrialSpawner.FullConfig overrideTargetCooldownLength(final int targetCooldownLength) {
+ return new TrialSpawner.FullConfig(
+ this.normal,
+ this.ominous,
+ targetCooldownLength,
+ this.requiredPlayerRange
+ );
+ }
+
+ public TrialSpawner.FullConfig overrideRequiredPlayerRange(final int requiredPlayerRange) {
+ return new TrialSpawner.FullConfig(
+ this.normal,
+ this.ominous,
+ this.targetCooldownLength,
+ requiredPlayerRange
+ );
+ }
+
+ public TrialSpawner.FullConfig overrideConfigs(final Holder<TrialSpawnerConfig> normal, final Holder<TrialSpawnerConfig> ominous) {
+ return new TrialSpawner.FullConfig(
+ normal,
+ ominous,
+ this.targetCooldownLength,
+ this.requiredPlayerRange
+ );
+ }
+ // Paper end - trial spawner API - withers
}
public interface StateAccessor {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java
+++ b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java
@@ -197,7 +_,7 @@
--- a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerStateData.java
+++ b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerStateData.java
@@ -185,7 +_,7 @@
mob.dropPreservedEquipment(level);
}
@@ -8,4 +8,4 @@
+ entity.remove(Entity.RemovalReason.DISCARDED, org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - Add bukkit remove cause;
}
});
if (!spawner.getOminousConfig().spawnPotentialsDefinition().isEmpty()) {
if (!spawner.ominousConfig().spawnPotentialsDefinition().isEmpty()) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/vault/VaultBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/vault/VaultBlockEntity.java
@@ -260,7 +_,12 @@
@@ -257,7 +_,12 @@
if (!list.isEmpty()) {
player.awardStat(Stats.ITEM_USED.get(stack.getItem()));
stack.consume(config.keyItem().getCount(), player);
@@ -14,7 +14,7 @@
serverData.addToRewardedPlayers(player);
sharedData.updateConnectedPlayersWithinRange(level, pos, serverData, config, config.deactivationRange());
}
@@ -269,8 +_,30 @@
@@ -266,8 +_,30 @@
}
static void setVaultState(ServerLevel level, BlockPos pos, BlockState oldState, BlockState newState, VaultConfig config, VaultSharedData sharedData) {
@@ -47,7 +47,7 @@
level.setBlock(pos, newState, 3);
vaultState.onTransition(level, pos, vaultState1, config, sharedData, newState.getValue(VaultBlock.OMINOUS));
}
@@ -282,6 +_,11 @@
@@ -279,6 +_,11 @@
ItemStack randomDisplayItemFromLootTable = getRandomDisplayItemFromLootTable(
level, pos, config.overrideLootTableToDisplay().orElse(config.lootTable())
);
@@ -59,7 +59,7 @@
sharedData.setDisplayItem(randomDisplayItemFromLootTable);
}
}
@@ -304,10 +_,24 @@
@@ -301,10 +_,24 @@
VaultSharedData sharedData,
List<ItemStack> itemsToEject
) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
+++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
@@ -39,7 +_,7 @@
@@ -38,7 +_,7 @@
private static final boolean DEFAULT_EXTENDING = false;
private static final boolean DEFAULT_SOURCE = false;
private BlockState movedState = DEFAULT_BLOCK_STATE;
@@ -9,7 +9,7 @@
private boolean extending = false;
private boolean isSourcePiston = false;
private static final ThreadLocal<Direction> NOCLIP = ThreadLocal.withInitial(() -> null);
@@ -310,7 +_,7 @@
@@ -309,7 +_,7 @@
if (level.getBlockState(pos).is(Blocks.MOVING_PISTON)) {
BlockState blockState = Block.updateFromNeighbourShapes(blockEntity.movedState, level, pos);
if (blockState.isAir()) {