net.minecraft.world.level.block.state

This commit is contained in:
Jake Potrebic
2024-12-13 15:50:44 -08:00
parent f252b67a97
commit f0e7d7e5f7
2 changed files with 63 additions and 73 deletions

View File

@@ -0,0 +1,182 @@
--- a/net/minecraft/world/level/block/state/BlockBehaviour.java
+++ b/net/minecraft/world/level/block/state/BlockBehaviour.java
@@ -46,6 +_,7 @@
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
+import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.EmptyBlockGetter;
import net.minecraft.world.level.Explosion;
@@ -167,16 +_,24 @@
}
protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean movedByPiston) {
- }
+ org.spigotmc.AsyncCatcher.catchOp("block onPlace"); // Spigot
+ }
+
+ // CraftBukkit start
+ protected void onPlace(BlockState iblockdata, Level world, BlockPos blockposition, BlockState iblockdata1, boolean flag, @Nullable UseOnContext context) {
+ this.onPlace(iblockdata, world, blockposition, iblockdata1, flag);
+ }
+ // CraftBukkit end
protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
+ org.spigotmc.AsyncCatcher.catchOp("block remove"); // Spigot
if (state.hasBlockEntity() && !state.is(newState.getBlock())) {
level.removeBlockEntity(pos);
}
}
protected void onExplosionHit(BlockState state, ServerLevel level, BlockPos pos, Explosion explosion, BiConsumer<ItemStack, BlockPos> dropConsumer) {
- if (!state.isAir() && explosion.getBlockInteraction() != Explosion.BlockInteraction.TRIGGER_BLOCK) {
+ if (!state.isAir() && explosion.getBlockInteraction() != Explosion.BlockInteraction.TRIGGER_BLOCK && state.isDestroyable()) { // Paper - Protect Bedrock and End Portal/Frames from being destroyed
Block block = state.getBlock();
boolean flag = explosion.getIndirectSourceEntity() instanceof Player;
if (block.dropFromExplosion(explosion)) {
@@ -186,8 +_,10 @@
.withParameter(LootContextParams.TOOL, ItemStack.EMPTY)
.withOptionalParameter(LootContextParams.BLOCK_ENTITY, blockEntity)
.withOptionalParameter(LootContextParams.THIS_ENTITY, explosion.getDirectSourceEntity());
- if (explosion.getBlockInteraction() == Explosion.BlockInteraction.DESTROY_WITH_DECAY) {
- builder.withParameter(LootContextParams.EXPLOSION_RADIUS, explosion.radius());
+ // CraftBukkit start - add yield
+ if (explosion instanceof net.minecraft.world.level.ServerExplosion serverExplosion && serverExplosion.yield < 1.0F) {
+ builder.withParameter(LootContextParams.EXPLOSION_RADIUS, 1.0F / serverExplosion.yield);
+ // CraftBukkit end
}
state.spawnAfterBreak(level, pos, ItemStack.EMPTY, flag);
@@ -255,7 +_,7 @@
}
protected boolean canBeReplaced(BlockState state, BlockPlaceContext useContext) {
- return state.canBeReplaced() && (useContext.getItemInHand().isEmpty() || !useContext.getItemInHand().is(this.asItem()));
+ return state.canBeReplaced() && (useContext.getItemInHand().isEmpty() || !useContext.getItemInHand().is(this.asItem()))&& (state.isDestroyable() || (useContext.getPlayer() != null && useContext.getPlayer().getAbilities().instabuild)); // Paper - Protect Bedrock and End Portal/Frames from being destroyed
}
protected boolean canBeReplaced(BlockState state, Fluid fluid) {
@@ -468,6 +_,16 @@
this.instrument = properties.instrument;
this.replaceable = properties.replaceable;
}
+ // Paper start - Perf: impl cached craft block data, lazy load to fix issue with loading at the wrong time
+ @Nullable
+ private org.bukkit.craftbukkit.block.data.CraftBlockData cachedCraftBlockData;
+
+ public org.bukkit.craftbukkit.block.data.CraftBlockData createCraftBlockData() {
+ if (this.cachedCraftBlockData == null) this.cachedCraftBlockData = org.bukkit.craftbukkit.block.data.CraftBlockData.createData(this.asState());
+ return (org.bukkit.craftbukkit.block.data.CraftBlockData) this.cachedCraftBlockData.clone();
+ }
+ // Paper end - Perf: impl cached craft block data, lazy load to fix issue with loading at the wrong time
+
private boolean calculateSolid() {
if (this.owner.properties.forceSolidOn) {
@@ -487,12 +_,14 @@
}
}
+ protected boolean shapeExceedsCube = true; // Paper - moved from actual method to here
public void initCache() {
this.fluidState = this.owner.getFluidState(this.asState());
this.isRandomlyTicking = this.owner.isRandomlyTicking(this.asState());
if (!this.getBlock().hasDynamicShape()) {
this.cache = new BlockBehaviour.BlockStateBase.Cache(this.asState());
}
+ this.shapeExceedsCube = this.cache == null || this.cache.largeCollisionShape; // Paper - moved from actual method to here
this.legacySolid = this.calculateSolid();
this.occlusionShape = this.canOcclude ? this.owner.getOcclusionShape(this.asState()) : Shapes.empty();
@@ -531,6 +_,11 @@
public boolean isSolid() {
return this.legacySolid;
}
+ // Paper start - Protect Bedrock and End Portal/Frames from being destroyed
+ public final boolean isDestroyable() {
+ return getBlock().isDestroyable();
+ }
+ // Paper end - Protect Bedrock and End Portal/Frames from being destroyed
public boolean isValidSpawn(BlockGetter level, BlockPos pos, EntityType<?> entityType) {
return this.getBlock().properties.isValidSpawn.test(this.asState(), level, pos, entityType);
@@ -552,19 +_,19 @@
return this.occlusionShape;
}
- public boolean hasLargeCollisionShape() {
- return this.cache == null || this.cache.largeCollisionShape;
+ public final boolean hasLargeCollisionShape() { // Paper
+ return this.shapeExceedsCube; // Paper - moved into shape cache init
}
- public boolean useShapeForLightOcclusion() {
+ public final boolean useShapeForLightOcclusion() { // Paper - Perf: Final for inlining
return this.useShapeForLightOcclusion;
}
- public int getLightEmission() {
+ public final int getLightEmission() { // Paper - Perf: Final for inlining
return this.lightEmission;
}
- public boolean isAir() {
+ public final boolean isAir() { // Paper - Perf: Final for inlining
return this.isAir;
}
@@ -634,14 +_,14 @@
}
public PushReaction getPistonPushReaction() {
- return this.pushReaction;
+ return !this.isDestroyable() ? PushReaction.BLOCK : this.pushReaction; // Paper - Protect Bedrock and End Portal/Frames from being destroyed
}
public boolean isSolidRender() {
return this.solidRender;
}
- public boolean canOcclude() {
+ public final boolean canOcclude() { // Paper - Perf: Final for inlining
return this.canOcclude;
}
@@ -725,7 +_,13 @@
}
public void onPlace(Level level, BlockPos pos, BlockState oldState, boolean movedByPiston) {
- this.getBlock().onPlace(this.asState(), level, pos, oldState, movedByPiston);
+ // CraftBukkit start
+ this.onPlace(level, pos, oldState, movedByPiston, null);
+ }
+
+ public void onPlace(Level level, BlockPos pos, BlockState oldState, boolean movedByPiston, @Nullable UseOnContext context) {
+ this.getBlock().onPlace(this.asState(), level, pos, oldState, movedByPiston, context);
+ // CraftBukkit end
}
public void onRemove(Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
@@ -754,6 +_,7 @@
public void spawnAfterBreak(ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) {
this.getBlock().spawnAfterBreak(this.asState(), level, pos, stack, dropExperience);
+ if (dropExperience) {this.getBlock().popExperience(level, pos, this.getBlock().getExpDrop(this.asState(), level, pos, stack, true));} // Paper - Properly handle xp dropping
}
public List<ItemStack> getDrops(LootParams.Builder lootParams) {
@@ -858,11 +_,11 @@
return this.getBlock().builtInRegistryHolder().is(block);
}
- public FluidState getFluidState() {
+ public final FluidState getFluidState() { // Paper - Perf: Final for inlining
return this.fluidState;
}
- public boolean isRandomlyTicking() {
+ public final boolean isRandomlyTicking() { // Paper - Perf: Final for inlining
return this.isRandomlyTicking;
}

View File

@@ -0,0 +1,20 @@
--- a/net/minecraft/world/level/block/state/BlockState.java
+++ b/net/minecraft/world/level/block/state/BlockState.java
@@ -10,6 +_,17 @@
public class BlockState extends BlockBehaviour.BlockStateBase {
public static final Codec<BlockState> CODEC = codec(BuiltInRegistries.BLOCK.byNameCodec(), Block::defaultBlockState).stable();
+ // Paper start - optimise getType calls
+ org.bukkit.@org.jspecify.annotations.Nullable Material cachedMaterial;
+
+ public final org.bukkit.Material getBukkitMaterial() {
+ if (this.cachedMaterial == null) {
+ this.cachedMaterial = org.bukkit.craftbukkit.block.CraftBlockType.minecraftToBukkit(this.getBlock());
+ }
+ return this.cachedMaterial;
+ }
+ // Paper end - optimise getType calls
+
public BlockState(Block owner, Reference2ObjectArrayMap<Property<?>, Comparable<?>> values, MapCodec<BlockState> propertiesCodec) {
super(owner, values, propertiesCodec);
}