From 3594bdeb3c995d88f26faf82b048c9ac7ae29d53 Mon Sep 17 00:00:00 2001 From: Samsuik <40902469+Samsuik@users.noreply.github.com> Date: Wed, 15 Nov 2023 23:56:00 +0000 Subject: [PATCH] Add customisable explosion durable blocks --- build-data/dev-imports.txt | 1 + patches/server/0002-Sakura-Utils.patch | 27 +++ .../0004-Sakura-Configuration-Files.patch | 47 ++++- .../server/0018-Merge-Cannon-Entities.patch | 27 +-- .../0029-Explosion-Durable-Blocks.patch | 173 ++++++++++++++++++ 5 files changed, 245 insertions(+), 30 deletions(-) create mode 100644 patches/server/0029-Explosion-Durable-Blocks.patch diff --git a/build-data/dev-imports.txt b/build-data/dev-imports.txt index f8483bf..d40cac0 100644 --- a/build-data/dev-imports.txt +++ b/build-data/dev-imports.txt @@ -10,3 +10,4 @@ # minecraft net/minecraft/world/level/entity/LevelEntityGetter.java minecraft net.minecraft.world.level.block.piston.PistonStructureResolver minecraft net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket +minecraft net.minecraft.world.item.ItemNameBlockItem \ No newline at end of file diff --git a/patches/server/0002-Sakura-Utils.patch b/patches/server/0002-Sakura-Utils.patch index 0f6cb02..dd59c91 100644 --- a/patches/server/0002-Sakura-Utils.patch +++ b/patches/server/0002-Sakura-Utils.patch @@ -172,3 +172,30 @@ index 0000000000000000000000000000000000000000..be4f5b4999c85fc6765e37cc9af0a872 + } + +} +diff --git a/src/main/java/me/samsuik/sakura/utils/objects/Expiry.java b/src/main/java/me/samsuik/sakura/utils/objects/Expiry.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a05e7d03f17f675e190d63a4206129a74f42cadc +--- /dev/null ++++ b/src/main/java/me/samsuik/sakura/utils/objects/Expiry.java +@@ -0,0 +1,21 @@ ++package me.samsuik.sakura.utils.objects; ++ ++public class Expiry { ++ ++ private long expireAt; ++ private final int inc; ++ ++ public Expiry(long tick, int inc) { ++ this.expireAt = tick + inc; ++ this.inc = inc; ++ } ++ ++ public void refresh(long tick) { ++ this.expireAt = tick + this.inc; ++ } ++ ++ public boolean isExpired(long tick) { ++ return tick >= this.expireAt; ++ } ++ ++} diff --git a/patches/server/0004-Sakura-Configuration-Files.patch b/patches/server/0004-Sakura-Configuration-Files.patch index 7af6df7..0a527a5 100644 --- a/patches/server/0004-Sakura-Configuration-Files.patch +++ b/patches/server/0004-Sakura-Configuration-Files.patch @@ -318,10 +318,10 @@ index 0000000000000000000000000000000000000000..0b5f50c7447d1c1732a745bae54c4fcd +} diff --git a/src/main/java/me/samsuik/sakura/configuration/GlobalConfiguration.java b/src/main/java/me/samsuik/sakura/configuration/GlobalConfiguration.java new file mode 100644 -index 0000000000000000000000000000000000000000..bc6db446dca3024b8f6d3f24499242775dd02219 +index 0000000000000000000000000000000000000000..911c81920bda503577ed63c9ea4505ccbf70c783 --- /dev/null +++ b/src/main/java/me/samsuik/sakura/configuration/GlobalConfiguration.java -@@ -0,0 +1,42 @@ +@@ -0,0 +1,47 @@ +package me.samsuik.sakura.configuration; + +import com.mojang.logging.LogUtils; @@ -363,10 +363,15 @@ index 0000000000000000000000000000000000000000..bc6db446dca3024b8f6d3f2449924277 + } + } + ++ public Players players; ++ public class Players extends ConfigurationPart { ++ public String potatoMessage = "(S) This block has of "; ++ } ++ +} diff --git a/src/main/java/me/samsuik/sakura/configuration/SakuraConfigurations.java b/src/main/java/me/samsuik/sakura/configuration/SakuraConfigurations.java new file mode 100644 -index 0000000000000000000000000000000000000000..37f41089a2fb7ad11ceda07cf5de0fc8b34b8db2 +index 0000000000000000000000000000000000000000..ebaa184d795dd57e97c4663f731e1284de106833 --- /dev/null +++ b/src/main/java/me/samsuik/sakura/configuration/SakuraConfigurations.java @@ -0,0 +1,220 @@ @@ -388,7 +393,6 @@ index 0000000000000000000000000000000000000000..37f41089a2fb7ad11ceda07cf5de0fc8 +import io.papermc.paper.configuration.type.BooleanOrDefault; +import io.papermc.paper.configuration.type.Duration; +import io.papermc.paper.configuration.type.DurationOrDisabled; -+import io.papermc.paper.configuration.type.EngineMode; +import io.papermc.paper.configuration.type.number.DoubleOr; +import io.papermc.paper.configuration.type.number.IntOr; +import it.unimi.dsi.fastutil.objects.Reference2IntMap; @@ -402,10 +406,10 @@ index 0000000000000000000000000000000000000000..37f41089a2fb7ad11ceda07cf5de0fc8 +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.item.Item; ++import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import org.slf4j.Logger; +import org.spongepowered.configurate.ConfigurateException; -+import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.ConfigurationOptions; +import org.spongepowered.configurate.objectmapping.ObjectMapper; +import org.spongepowered.configurate.yaml.YamlConfigurationLoader; @@ -531,12 +535,13 @@ index 0000000000000000000000000000000000000000..37f41089a2fb7ad11ceda07cf5de0fc8 + .register(BooleanOrDefault.SERIALIZER) + .register(Duration.SERIALIZER) + .register(DurationOrDisabled.SERIALIZER) -+ .register(EngineMode.SERIALIZER) + .register(NbtPathSerializer.SERIALIZER) + .register(new RegistryValueSerializer<>(new TypeToken>() {}, Registries.ENTITY_TYPE, true)) + .register(new RegistryValueSerializer<>(Item.class, Registries.ITEM, true)) ++ .register(new RegistryValueSerializer<>(Block.class, Registries.BLOCK, true)) + .register(new RegistryHolderSerializer<>(new TypeToken>() {}, Registries.CONFIGURED_FEATURE, false)) + .register(new RegistryHolderSerializer<>(Item.class, Registries.ITEM, true)) ++ .register(new RegistryHolderSerializer<>(Block.class, Registries.BLOCK, true)) + ) + ); + } @@ -592,10 +597,10 @@ index 0000000000000000000000000000000000000000..37f41089a2fb7ad11ceda07cf5de0fc8 +} diff --git a/src/main/java/me/samsuik/sakura/configuration/WorldConfiguration.java b/src/main/java/me/samsuik/sakura/configuration/WorldConfiguration.java new file mode 100644 -index 0000000000000000000000000000000000000000..8672703c0719b531bc1798c3754c27591e9ed7aa +index 0000000000000000000000000000000000000000..ac508289b63568359e86b507a3c263cd66dd3774 --- /dev/null +++ b/src/main/java/me/samsuik/sakura/configuration/WorldConfiguration.java -@@ -0,0 +1,93 @@ +@@ -0,0 +1,106 @@ +package me.samsuik.sakura.configuration; + +import com.mojang.logging.LogUtils; @@ -603,12 +608,19 @@ index 0000000000000000000000000000000000000000..8672703c0719b531bc1798c3754c2759 +import io.papermc.paper.configuration.ConfigurationPart; +import io.papermc.paper.configuration.PaperConfigurations; +import io.papermc.paper.configuration.type.number.IntOr; ++import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; +import me.samsuik.sakura.entity.merge.MergeLevel; ++import me.samsuik.sakura.explosion.durable.DurableMaterial; ++import net.minecraft.Util; +import net.minecraft.resources.ResourceLocation; ++import net.minecraft.world.level.block.Block; ++import net.minecraft.world.level.block.Blocks; +import org.slf4j.Logger; +import org.spongepowered.configurate.objectmapping.meta.Comment; +import org.spongepowered.configurate.objectmapping.meta.Setting; + ++import java.util.Map; ++ +@SuppressWarnings({"FieldCanBeLocal", "FieldMayBeFinal", "NotNullFieldNotInitialized", "InnerClassMayBeStatic", "RedundantSuppression"}) +public class WorldConfiguration extends ConfigurationPart { + @@ -647,6 +659,12 @@ index 0000000000000000000000000000000000000000..8672703c0719b531bc1798c3754c2759 + public class Explosion extends ConfigurationPart { + public boolean optimiseProtectedRegions = true; + public boolean avoidRedundantBlockSearches = true; ++ public Map durableMaterials = Util.make(new Reference2ObjectOpenHashMap<>(), map -> { ++ map.put(Blocks.OBSIDIAN, new DurableMaterial(4, Blocks.COBBLESTONE.getExplosionResistance())); ++ map.put(Blocks.ANVIL, new DurableMaterial(3, Blocks.END_STONE.getExplosionResistance())); ++ map.put(Blocks.CHIPPED_ANVIL, new DurableMaterial(3, Blocks.END_STONE.getExplosionResistance())); ++ map.put(Blocks.DAMAGED_ANVIL, new DurableMaterial(3, Blocks.END_STONE.getExplosionResistance())); ++ }); + } + + public Mechanics mechanics = new Mechanics(); @@ -750,6 +768,19 @@ index 0000000000000000000000000000000000000000..96080117b5ac9dea6b9eeb7489dc0c87 + return new InnerClassFieldDiscoverer(Collections.emptyMap()); + } +} +diff --git a/src/main/java/me/samsuik/sakura/explosion/durable/DurableMaterial.java b/src/main/java/me/samsuik/sakura/explosion/durable/DurableMaterial.java +new file mode 100644 +index 0000000000000000000000000000000000000000..4024f9738e039ffffd560a07a2210f758879d3c0 +--- /dev/null ++++ b/src/main/java/me/samsuik/sakura/explosion/durable/DurableMaterial.java +@@ -0,0 +1,7 @@ ++package me.samsuik.sakura.explosion.durable; ++ ++import org.spongepowered.configurate.objectmapping.ConfigSerializable; ++ ++@ConfigSerializable ++public record DurableMaterial(int durability, float resistance) { ++} diff --git a/src/main/java/me/samsuik/sakura/utils/VariousHelpers.java b/src/main/java/me/samsuik/sakura/utils/VariousHelpers.java new file mode 100644 index 0000000000000000000000000000000000000000..141b15887ca075fef5d36ff15125b3e071049917 diff --git a/patches/server/0018-Merge-Cannon-Entities.patch b/patches/server/0018-Merge-Cannon-Entities.patch index 770779a..0347a08 100644 --- a/patches/server/0018-Merge-Cannon-Entities.patch +++ b/patches/server/0018-Merge-Cannon-Entities.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Merge Cannon Entities diff --git a/src/main/java/me/samsuik/sakura/entity/merge/MergeHistory.java b/src/main/java/me/samsuik/sakura/entity/merge/MergeHistory.java new file mode 100644 -index 0000000000000000000000000000000000000000..794547b36f0780b4dd300fc162cd9b7018c38edb +index 0000000000000000000000000000000000000000..7cb3b0d5a284199cdc117038227d33681b356aa3 --- /dev/null +++ b/src/main/java/me/samsuik/sakura/entity/merge/MergeHistory.java -@@ -0,0 +1,155 @@ +@@ -0,0 +1,138 @@ +package me.samsuik.sakura.entity.merge; + +import it.unimi.dsi.fastutil.HashCommon; @@ -17,6 +17,7 @@ index 0000000000000000000000000000000000000000..794547b36f0780b4dd300fc162cd9b70 +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.longs.LongOpenHashSet; +import it.unimi.dsi.fastutil.longs.LongSet; ++import me.samsuik.sakura.utils.objects.Expiry; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.entity.Entity; + @@ -146,24 +147,6 @@ index 0000000000000000000000000000000000000000..794547b36f0780b4dd300fc162cd9b70 + } + } + -+ private static class Expiry { -+ private long expireAt; -+ private final int inc; -+ -+ Expiry(long tick, int inc) { -+ expireAt = tick + inc; -+ this.inc = inc; -+ } -+ -+ void refresh(long tick) { -+ expireAt = tick + inc; -+ } -+ -+ boolean isExpired(long tick) { -+ return tick >= expireAt; -+ } -+ } -+ +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index d559fb2adbebd47d8be75c9dd3477edfca142790..a520e0dbbe2b5baaeba32020d217b5f08870044b 100644 @@ -206,7 +189,7 @@ index f3da674ae3a38a6c7af488580a685eb4c1523e0c..6beee8db675d737dc492065f0f12b617 this.guardEntityTick(this::tickNonPassenger, entity); gameprofilerfiller.pop(); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index b1e8cc0da8d6754946ca05745256ea0b144757cb..22c43e5a12c254da2d427af28012adfb39f0ce7f 100644 +index 9118ebf8c0f2fc4cb8fb438426ef49cbdf9acc52..639712fe3e81703791b87622ae598c11b274802f 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -562,6 +562,105 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { @@ -360,7 +343,7 @@ index b1e8cc0da8d6754946ca05745256ea0b144757cb..22c43e5a12c254da2d427af28012adfb if (this.removalReason == null) { this.removalReason = reason; diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java -index 354e210a52e5ce7b1b8cf75ce132e59c02f664ab..f9d2ec92e46f7f0ca2a6c93b90d9a5afa2047658 100644 +index 24586ae4833b5bf3596b0921273f712c14f1be9c..45e042dc8b875b08f5f09955258913a256371b54 100644 --- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java @@ -132,6 +132,58 @@ public class FallingBlockEntity extends Entity { diff --git a/patches/server/0029-Explosion-Durable-Blocks.patch b/patches/server/0029-Explosion-Durable-Blocks.patch new file mode 100644 index 0000000..4b450d2 --- /dev/null +++ b/patches/server/0029-Explosion-Durable-Blocks.patch @@ -0,0 +1,173 @@ +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..2e11ba36e9e820f17839d696e5d7d876e7437fbf +--- /dev/null ++++ b/src/main/java/me/samsuik/sakura/explosion/durable/DurableBlockManager.java +@@ -0,0 +1,63 @@ ++package me.samsuik.sakura.explosion.durable; ++ ++import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; ++import me.samsuik.sakura.utils.objects.Expiry; ++import net.minecraft.core.BlockPos; ++import net.minecraft.server.MinecraftServer; ++ ++public class DurableBlockManager { ++ ++ private final Long2ObjectOpenHashMap blocks = new Long2ObjectOpenHashMap<>(); ++ ++ public boolean damage(BlockPos pos, DurableMaterial material) { ++ long packed = pos.asLong(); ++ ++ DurableBlock block = this.blocks.computeIfAbsent(packed, k -> new DurableBlock( ++ material.durability(), ++ // expire after 1 minute ++ new Expiry(MinecraftServer.currentTickLong, 1200) ++ )); ++ ++ if (block.damage()) { ++ this.blocks.remove(packed); ++ return true; ++ } else { ++ block.getExpiry().refresh(MinecraftServer.currentTickLong); ++ return false; ++ } ++ } ++ ++ public int durability(BlockPos pos, DurableMaterial material) { ++ DurableBlock block = this.blocks.get(pos.asLong()); ++ return block != null ? block.getDurability() : material.durability(); ++ } ++ ++ public void expire(long tick) { ++ if (tick % 200 == 0) { ++ this.blocks.values().removeIf(block -> block.getExpiry().isExpired(tick)); ++ } ++ } ++ ++ private static class DurableBlock { ++ private int durability; ++ private final Expiry expiry; ++ ++ public DurableBlock(int durability, Expiry expiry) { ++ this.durability = durability; ++ this.expiry = expiry; ++ } ++ ++ public Expiry getExpiry() { ++ return expiry; ++ } ++ ++ public int getDurability() { ++ return 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 805396ad55b551080e5796cbbc493fe10d2997b6..c061991f23748395fe07205e80b288b166c07c49 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -1581,6 +1581,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop resistance = !calculateResistance ? Optional.empty() : this.damageCalculator.getBlockExplosionResistance((Explosion)(Object)this, this.level, pos, blockState, fluidState); + ++ // Sakura start - durable materials ++ Block block = blockState.getBlock(); ++ me.samsuik.sakura.explosion.durable.DurableMaterial material = level.sakuraConfig().cannons.explosion.durableMaterials.get(block); ++ ++ if (material != null && material.resistance() >= 0.0f) { ++ resistance = Optional.of(material.resistance()); ++ } ++ // Sakura end ++ + ret = new ExplosionBlockCache( + key, pos, blockState, fluidState, + (resistance.orElse(ZERO_RESISTANCE).floatValue() + 0.3f) * 0.3f, +@@ -791,6 +800,14 @@ public class Explosion { + BlockPos blockposition = (BlockPos) objectlistiterator.next(); + BlockState iblockdata = this.level.getBlockState(blockposition); + Block block = iblockdata.getBlock(); ++ // Sakura start - durable materials ++ me.samsuik.sakura.explosion.durable.DurableMaterial material = level.sakuraConfig().cannons.explosion.durableMaterials.get(block); ++ ++ if (material != null && material.durability() >= 0 && !level.durabilityManager.damage(blockposition, material)) { ++ objectlistiterator.remove(); ++ continue; ++ } ++ // Sakura end + // CraftBukkit start - TNTPrimeEvent + if (block instanceof net.minecraft.world.level.block.TntBlock) { + Entity sourceEntity = this.source == null ? null : this.source; +diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java +index a17ea99a4de4f69ca95a67f9a9b977b49148a261..0c61c0565dac31835be9054a21b1dae6fdf77466 100644 +--- a/src/main/java/net/minecraft/world/level/Level.java ++++ b/src/main/java/net/minecraft/world/level/Level.java +@@ -229,7 +229,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + // Sakura end + public final me.samsuik.sakura.entity.merge.MergeHistory mergeHistory = new me.samsuik.sakura.entity.merge.MergeHistory(); // Sakura + public final me.samsuik.sakura.explosion.DensityCache densityCache = new me.samsuik.sakura.explosion.DensityCache(); +- ++ public final me.samsuik.sakura.explosion.durable.DurableBlockManager durabilityManager = new me.samsuik.sakura.explosion.durable.DurableBlockManager(); + // Sakura start - limited get entities + public void getLimitedEntities(Entity except, AABB box, Predicate predicate, List into, int limit, int search) { + ((ServerLevel)this).getEntityLookup().getLimitedEntities(except, box, into, predicate, limit, search);