From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Samsuik <40902469+Samsuik@users.noreply.github.com> Date: Wed, 15 Nov 2023 23:18:38 +0000 Subject: [PATCH] Explosion Durable Blocks diff --git a/src/main/java/me/samsuik/sakura/explosion/durable/DurableBlockManager.java b/src/main/java/me/samsuik/sakura/explosion/durable/DurableBlockManager.java new file mode 100644 index 0000000000000000000000000000000000000000..e52cae27c2bbf4fa02d49d1c69d8e1240fddfb81 --- /dev/null +++ b/src/main/java/me/samsuik/sakura/explosion/durable/DurableBlockManager.java @@ -0,0 +1,43 @@ +package me.samsuik.sakura.explosion.durable; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import net.minecraft.core.BlockPos; + +import java.util.concurrent.TimeUnit; + +public final class DurableBlockManager { + private final Cache durableBlocks = CacheBuilder.newBuilder() + .expireAfterAccess(1, TimeUnit.MINUTES) + .maximumSize(65534) + .build(); + + public boolean damage(BlockPos pos, DurableMaterial material) { + DurableBlock block = this.durableBlocks.getIfPresent(pos); + if (block == null) { + this.durableBlocks.put(pos, block = new DurableBlock(material.durability())); + } + return block.damage(); + } + + public int durability(BlockPos pos, DurableMaterial material) { + final DurableBlock block = this.durableBlocks.getIfPresent(pos); + return block != null ? block.durability() : material.durability(); + } + + private static final class DurableBlock { + private int durability; + + public DurableBlock(int durability) { + this.durability = durability; + } + + public int durability() { + return this.durability; + } + + public boolean damage() { + return --this.durability <= 0; + } + } +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 8041737aa751bec1c51ee3d9dacd6dfb2b845265..7073914cfd5759bea92ce098ad36a86afee5dd37 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1824,6 +1824,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop resistance = !calculateResistance ? Optional.empty() : this.damageCalculator.getBlockExplosionResistance((Explosion)(Object)this, this.level, pos, blockState, fluidState); + Optional resistance = !calculateResistance ? Optional.empty() : this.calculateBlockResistance(blockState, fluidState, pos); // Sakura - explosion durable blocks ret = new ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache( key, pos, blockState, fluidState, @@ -159,6 +159,21 @@ public class Explosion { return ret; } + // Sakura start - explosion durable blocks + private Optional calculateBlockResistance(BlockState blockState, FluidState fluidState, BlockPos pos) { + if (!blockState.isAir()) { + Block block = blockState.getBlock(); + me.samsuik.sakura.explosion.durable.DurableMaterial material = this.level.localConfig().config(pos).durableMaterials.get(block); + + if (material != null && material.resistance() >= 0.0f && (this.level.sakuraConfig().cannons.explosion.allowNonTntBreakingDurableBlocks || this.source instanceof net.minecraft.world.entity.item.PrimedTnt)) { + return Optional.of(material.resistance()); + } + } + + return this.damageCalculator.getBlockExplosionResistance((Explosion)(Object)this, this.level, pos, blockState, fluidState); + } + // Sakura end - explosion durable blocks + private boolean clipsAnything(final Vec3 from, final Vec3 to, final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext context, final ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache[] blockCache, @@ -832,6 +847,16 @@ public class Explosion { // CraftBukkit start - TNTPrimeEvent BlockState iblockdata = this.level.getBlockState(blockposition); Block block = iblockdata.getBlock(); + // Sakura start - explosion durable blocks + if (this.level.sakuraConfig().cannons.explosion.allowNonTntBreakingDurableBlocks || this.source instanceof net.minecraft.world.entity.item.PrimedTnt) { + me.samsuik.sakura.explosion.durable.DurableMaterial material = this.level.localConfig().config(blockposition).durableMaterials.get(block); + + if (material != null && material.durability() >= 0 && !this.level.durabilityManager.damage(blockposition, material)) { + objectlistiterator.remove(); + continue; + } + } + // Sakura end - explosion durable blocks if (block instanceof net.minecraft.world.level.block.TntBlock) { Entity sourceEntity = this.source == null ? null : this.source; BlockPos sourceBlock = sourceEntity == null ? BlockPos.containing(this.x, this.y, this.z) : null; diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java index 75d11642b7246bae4073feec09c0cf21c24622ca..2cf25b6e51f1c430f80f1defe365b0373227bed2 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -697,6 +697,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl // Paper end - optimise random ticking public final me.samsuik.sakura.entity.merge.EntityMergeHandler mergeHandler = new me.samsuik.sakura.entity.merge.EntityMergeHandler(); // Sakura - merge cannon entities public final me.samsuik.sakura.explosion.density.BlockDensityCache densityCache = new me.samsuik.sakura.explosion.density.BlockDensityCache(); // Sakura - explosion density cache + public final me.samsuik.sakura.explosion.durable.DurableBlockManager durabilityManager = new me.samsuik.sakura.explosion.durable.DurableBlockManager(); // Sakura - explosion durable blocks protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, Supplier sakuraWorldConfigCreator, java.util.concurrent.Executor executor) { // Sakura - sakura configuration files// Paper - create paper world config & Anti-Xray this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot