diff --git a/patches/api/0054-lightning-transforms-blocks.patch b/patches/api/0054-lightning-transforms-blocks.patch new file mode 100644 index 000000000..bbf0f55f6 --- /dev/null +++ b/patches/api/0054-lightning-transforms-blocks.patch @@ -0,0 +1,56 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: granny +Date: Sun, 27 Aug 2023 02:09:51 -0700 +Subject: [PATCH] lightning transforms blocks + + +diff --git a/src/main/java/org/bukkit/event/weather/LightningStrikeEvent.java b/src/main/java/org/bukkit/event/weather/LightningStrikeEvent.java +index c98f07f82d179dffe162bb5cd85efe97de1b6175..4f980ab45073b293d03a00857e896375758f7249 100644 +--- a/src/main/java/org/bukkit/event/weather/LightningStrikeEvent.java ++++ b/src/main/java/org/bukkit/event/weather/LightningStrikeEvent.java +@@ -14,6 +14,7 @@ public class LightningStrikeEvent extends WeatherEvent implements Cancellable { + private boolean canceled; + private final LightningStrike bolt; + private final Cause cause; ++ private final java.util.List blocks; // Purpur + + @Deprecated + public LightningStrikeEvent(@NotNull final World world, @NotNull final LightningStrike bolt) { +@@ -21,9 +22,15 @@ public class LightningStrikeEvent extends WeatherEvent implements Cancellable { + } + + public LightningStrikeEvent(@NotNull final World world, @NotNull final LightningStrike bolt, @NotNull final Cause cause) { ++ // Purpur start ++ this(world, bolt, cause, new java.util.ArrayList<>()); ++ } ++ public LightningStrikeEvent(@NotNull final World world, @NotNull final LightningStrike bolt, @NotNull final Cause cause, java.util.List blocks) { ++ // Purpur end + super(world); + this.bolt = bolt; + this.cause = cause; ++ this.blocks = blocks; // Purpur + } + + @Override +@@ -56,6 +63,21 @@ public class LightningStrikeEvent extends WeatherEvent implements Cancellable { + return cause; + } + ++ // Purpur start ++ /** ++ * Get a list of all blocks that will be modified by the lightning strike. ++ *
++ * This list is mutable and contains the blocks in their changed state, i.e. ++ * having a type of {@link org.bukkit.Material#GLASS}. ++ * ++ * @return list of the modified blocks. ++ */ ++ @NotNull ++ public java.util.List getBlocks() { ++ return blocks; ++ } ++ // Purpur end ++ + @NotNull + @Override + public HandlerList getHandlers() { diff --git a/patches/server/0309-lightning-transforms-blocks.patch b/patches/server/0309-lightning-transforms-blocks.patch index 322312975..8ce2c8a03 100644 --- a/patches/server/0309-lightning-transforms-blocks.patch +++ b/patches/server/0309-lightning-transforms-blocks.patch @@ -5,16 +5,36 @@ Subject: [PATCH] lightning transforms blocks diff --git a/src/main/java/net/minecraft/world/entity/LightningBolt.java b/src/main/java/net/minecraft/world/entity/LightningBolt.java -index a01a8ba27534d2b0d544423bc2c48fd29d0a6d64..6036a6fba66bec97ac46f2984356e2d1d6d94994 100644 +index a01a8ba27534d2b0d544423bc2c48fd29d0a6d64..ec347f8e35bfe4280a9fba3ccb1bc99fd91f7180 100644 --- a/src/main/java/net/minecraft/world/entity/LightningBolt.java +++ b/src/main/java/net/minecraft/world/entity/LightningBolt.java -@@ -83,6 +83,51 @@ public class LightningBolt extends Entity { +@@ -44,6 +44,8 @@ public class LightningBolt extends Entity { + @Nullable + private ServerPlayer cause; + private final Set hitEntities = Sets.newHashSet(); ++ public List blocks; // Purpur ++ private BlockPos blockPos; // Purpur - TODO find a way to not need this variable + private int blocksSetOnFire; + public boolean isSilent = false; // Spigot + +@@ -53,6 +55,10 @@ public class LightningBolt extends Entity { + this.life = 2; + this.seed = this.random.nextLong(); + this.flashes = this.random.nextInt(3) + 1; ++ // Purpur start ++ this.blocks = this.getTransformedBlocks(); ++ this.blockPos = this.getStrikePosition(); // TODO find a way to not need this variable ++ // Purpur end + } + + public void setVisualOnly(boolean cosmetic) { +@@ -83,6 +89,55 @@ public class LightningBolt extends Entity { } + // Purpur start -+ private void transformBlocks() { -+ if (!level().purpurConfig.lightningTransformsBlocks) return; ++ private List getTransformedBlocks() { ++ if (!level().purpurConfig.lightningTransformsBlocks) return new java.util.ArrayList<>(); + + BlockPos blockposition = this.getStrikePosition(); + BlockState iblockdata = this.level().getBlockState(blockposition); @@ -36,7 +56,7 @@ index a01a8ba27534d2b0d544423bc2c48fd29d0a6d64..6036a6fba66bec97ac46f2984356e2d1 + } else if (level().purpurConfig.lightningTurnsWaterIntoStone && iblockdata2.is(Blocks.WATER)) { + level().setBlock(blockposition2, Blocks.STONE.defaultBlockState(), 2); + } else if (!level().purpurConfig.lightningTurnsNearbySandIntoGlass) { -+ return; ++ return new java.util.ArrayList<>(); + } + + org.bukkit.craftbukkit.util.BlockStateListPopulator blockList = new org.bukkit.craftbukkit.util.BlockStateListPopulator(level()); @@ -54,22 +74,26 @@ index a01a8ba27534d2b0d544423bc2c48fd29d0a6d64..6036a6fba66bec97ac46f2984356e2d1 + } + } + }); ++ ++ this.blockPos = blockposition2; // TODO find a way to not need this variable ++ ++ return blockList.getList(); + } + // Purpur end + @Override public void tick() { super.tick(); -@@ -98,6 +143,7 @@ public class LightningBolt extends Entity { +@@ -98,6 +153,7 @@ public class LightningBolt extends Entity { } this.powerLightningRod(); -+ if (level().purpurConfig.lightningTransformsBlocks) this.transformBlocks(); // Purpur ++ if (level().purpurConfig.lightningTransformsBlocks) net.minecraft.world.level.block.SpongeBlock.processBlocksBreadthFirstSearch(level(), this.blockPos, this.blocks, false); // Purpur LightningBolt.clearCopperOnLightningStrike(this.level(), this.getStrikePosition(), this); // Paper - transmit LightningBolt instance to call EntityChangeBlockEvent this.gameEvent(GameEvent.LIGHTNING_STRIKE); } diff --git a/src/main/java/net/minecraft/world/level/block/SpongeBlock.java b/src/main/java/net/minecraft/world/level/block/SpongeBlock.java -index 2276fed1feb4fea59b5bd49b5e4586d49478b3cc..bd1edc58a863673491a2935af4dc92996d1edb4c 100644 +index 2276fed1feb4fea59b5bd49b5e4586d49478b3cc..13d5b1591e367a9e01a3f33becaa779bc8a53072 100644 --- a/src/main/java/net/minecraft/world/level/block/SpongeBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SpongeBlock.java @@ -47,8 +47,12 @@ public class SpongeBlock extends Block { @@ -96,7 +120,7 @@ index 2276fed1feb4fea59b5bd49b5e4586d49478b3cc..bd1edc58a863673491a2935af4dc9299 if (blockposition1.equals(pos)) { return true; } else { -@@ -102,17 +106,19 @@ public class SpongeBlock extends Block { +@@ -102,17 +106,24 @@ public class SpongeBlock extends Block { return true; } } @@ -104,10 +128,15 @@ index 2276fed1feb4fea59b5bd49b5e4586d49478b3cc..bd1edc58a863673491a2935af4dc9299 + } : customCallback); // Purpur // CraftBukkit start List blocks = blockList.getList(); // Is a clone ++ // Purpur start ++ return customCallback != null || processBlocksBreadthFirstSearch(world, pos, blocks, true); ++ } ++ public static boolean processBlocksBreadthFirstSearch(Level world, BlockPos pos, List blocks, boolean emitEvent) { ++ // Purpur end if (!blocks.isEmpty()) { final org.bukkit.block.Block bblock = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); -+ if (customCallback != null) { // Purpur - TODO: custom event that extends spongeabsorbevent?? or use a pre-existing block event? or leave it as is.. ++ if (emitEvent) { // Purpur SpongeAbsorbEvent event = new SpongeAbsorbEvent(bblock, (List) (List) blocks); world.getCraftServer().getPluginManager().callEvent(event); @@ -117,6 +146,34 @@ index 2276fed1feb4fea59b5bd49b5e4586d49478b3cc..bd1edc58a863673491a2935af4dc9299 } for (CraftBlockState block : blocks) { +@@ -121,7 +132,7 @@ public class SpongeBlock extends Block { + FluidState fluid = world.getFluidState(blockposition1); + + if (fluid.is(FluidTags.WATER)) { +- if (iblockdata.getBlock() instanceof BucketPickup && !((BucketPickup) iblockdata.getBlock()).pickupBlock(blockList, blockposition1, iblockdata).isEmpty()) { ++ if (iblockdata.getBlock() instanceof BucketPickup && !((BucketPickup) iblockdata.getBlock()).pickupBlock(world, blockposition1, iblockdata).isEmpty()) { // Purpur - TODO make sure this doesn't fuck with shit + // NOP + } else if (iblockdata.getBlock() instanceof LiquidBlock) { + // NOP +diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +index 5641df31686d6203a523b04406c2c85eab2240d2..5ceb5d92c79e2427123062ca988d36aa0c3ebffc 100644 +--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java ++++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +@@ -1925,7 +1925,13 @@ public class CraftEventFactory { + } + + public static LightningStrikeEvent callLightningStrikeEvent(LightningStrike entity, LightningStrikeEvent.Cause cause) { +- LightningStrikeEvent event = new LightningStrikeEvent(entity.getWorld(), entity, cause); ++ // Purpur start ++ List blocks = ((org.bukkit.craftbukkit.entity.CraftLightningStrike) entity).getHandle().blocks; ++ LightningStrikeEvent event = new LightningStrikeEvent(entity.getWorld(), entity, cause, (List) (List) blocks); ++ if (!event.getBlocks().equals(blocks)) { ++ ((org.bukkit.craftbukkit.entity.CraftLightningStrike) entity).getHandle().blocks = (List) (List) event.getBlocks(); ++ } ++ // Purpur end + Bukkit.getPluginManager().callEvent(event); + return event; + } diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java index 078102e636803f38facc049952813ff2f8b63594..36ec3a3d830aab562bfe9e8d657fa3232360f0cb 100644 --- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java