9
0
mirror of https://github.com/Samsuik/Sakura.git synced 2025-12-19 14:59:30 +00:00

Add customisable explosion durable blocks

This commit is contained in:
Samsuik
2023-11-15 23:56:00 +00:00
parent d5c1f837a6
commit 3594bdeb3c
5 changed files with 245 additions and 30 deletions

View File

@@ -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

View File

@@ -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;
+ }
+
+}

View File

@@ -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 = "<dark_gray>(<light_purple>S</light_purple>) <white>This block has <gray><remaining></gray> of <gray><durability>";
+ }
+
+}
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<EntityType<?>>() {}, 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<ConfiguredFeature<?, ?>>() {}, 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<Block, DurableMaterial> 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

View File

@@ -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 {

View File

@@ -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<DurableBlock> 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<TickTa
worldserver.minimalTNT.clear(); // Sakura - visibility api
worldserver.mergeHistory.expire(currentTickLong); // Sakura - merge cannoning entities
worldserver.densityCache.clear(); // Sakura
+ worldserver.durabilityManager.expire(currentTickLong); // Sakura
}
this.isIteratingOverLevels = false; // Paper
diff --git a/src/main/java/net/minecraft/world/item/ItemNameBlockItem.java b/src/main/java/net/minecraft/world/item/ItemNameBlockItem.java
index a8008c7550488be34b51f4280f5569170b1ebd1d..82a68c0039feea8519477d6542a6e339a7f028f2 100644
--- a/src/main/java/net/minecraft/world/item/ItemNameBlockItem.java
+++ b/src/main/java/net/minecraft/world/item/ItemNameBlockItem.java
@@ -7,6 +7,33 @@ public class ItemNameBlockItem extends BlockItem {
super(block, settings);
}
+ // Sakura start
+ @Override
+ public net.minecraft.world.InteractionResult useOn(net.minecraft.world.item.context.UseOnContext context) {
+ Block itemBlock = this.getBlock();
+ if (context.getPlayer() != null && itemBlock.equals(net.minecraft.world.level.block.Blocks.POTATOES)) {
+ net.minecraft.world.entity.player.Player player = context.getPlayer();
+ net.minecraft.world.level.block.state.BlockState state = player.level().getBlockState(context.getClickedPos());
+ Block block = state.getBlock();
+ me.samsuik.sakura.explosion.durable.DurableMaterial material = player.level().sakuraConfig().cannons.explosion.durableMaterials.get(block);
+
+ if (material != null) {
+ int durability = player.level().durabilityManager.durability(context.getClickedPos(), material);
+ this.sendPotatoMessage(player, durability, material.durability());
+ }
+ }
+ return super.useOn(context);
+ }
+
+ private void sendPotatoMessage(net.minecraft.world.entity.player.Player player, int remaining, int durability) {
+ player.getBukkitEntity().sendRichMessage(
+ me.samsuik.sakura.configuration.GlobalConfiguration.get().players.potatoMessage,
+ net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.unparsed("remaining", String.valueOf(remaining)),
+ net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.unparsed("durability", String.valueOf(durability))
+ );
+ }
+ // Sakura end
+
@Override
public String getDescriptionId() {
return this.getOrCreateDescriptionId();
diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
index e5a0ba896ae2c1e21514e1156f9ce0457ea2abb5..b2f42287db6d107c7e8adabd98f007e6b9c7d42b 100644
--- a/src/main/java/net/minecraft/world/level/Explosion.java
+++ b/src/main/java/net/minecraft/world/level/Explosion.java
@@ -198,6 +198,15 @@ public class Explosion {
Optional<Float> 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<? super Entity> predicate, List<Entity> into, int limit, int search) {
((ServerLevel)this).getEntityLookup().getLimitedEntities(except, box, into, predicate, limit, search);