From 0b07d29f5106e7eedf249ef75b1fd34e1b303b0e Mon Sep 17 00:00:00 2001 From: Madeline Miller Date: Wed, 29 Nov 2023 22:23:38 +1000 Subject: [PATCH] Send biome updates [WIP] --- .../worldedit/extent/world/SideEffectExtent.java | 14 +++++++++++++- .../com/sk89q/worldedit/world/AbstractWorld.java | 4 ++++ .../main/java/com/sk89q/worldedit/world/World.java | 11 +++++++++++ .../com/sk89q/worldedit/fabric/FabricWorld.java | 11 +++++++++++ 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/SideEffectExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/SideEffectExtent.java index cf07691229..1ce6aee0b6 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/SideEffectExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/SideEffectExtent.java @@ -29,6 +29,7 @@ import com.sk89q.worldedit.util.SideEffectSet; import com.sk89q.worldedit.util.collection.BlockMap; import com.sk89q.worldedit.world.World; +import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; @@ -50,6 +51,7 @@ public class SideEffectExtent extends AbstractDelegateExtent { private final World world; private final Map positions = BlockMap.create(); private final Set dirtyChunks = new HashSet<>(); + private final Set dirtyBiomes = new HashSet<>(); private SideEffectSet sideEffectSet = SideEffectSet.defaults(); private boolean postEditSimulation; @@ -97,8 +99,14 @@ public > boolean setBlock(BlockVector3 location, B return world.setBlock(location, block, postEditSimulation ? INTERNAL_NONE : sideEffectSet); } + @Override + public boolean setBiome(BlockVector3 position, BiomeType biome) { + dirtyBiomes.add(BlockVector2.at(position.getBlockX() >> 4, position.getBlockZ() >> 4)); + return world.setBiome(position, biome); + } + public boolean commitRequired() { - return postEditSimulation || !dirtyChunks.isEmpty(); + return postEditSimulation || !dirtyChunks.isEmpty() || !dirtyBiomes.isEmpty(); } @Override @@ -113,6 +121,10 @@ public Operation resume(RunContext run) throws WorldEditException { world.fixAfterFastMode(dirtyChunks); } + if (!dirtyBiomes.isEmpty()) { + world.sendBiomeUpdates(dirtyBiomes); + } + if (postEditSimulation) { Iterator> positionIterator = positions.entrySet().iterator(); while (run.shouldContinue() && positionIterator.hasNext()) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java index 01a0cc9f13..14c607fa4b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java @@ -94,6 +94,10 @@ public void checkLoadedChunk(BlockVector3 pt) { public void fixAfterFastMode(Iterable chunks) { } + @Override + public void sendBiomeUpdates(Iterable chunks) { + } + @Override public void fixLighting(Iterable chunks) { } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java index a537e5bbeb..2019d49641 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java @@ -311,6 +311,17 @@ default boolean generateFeature(ConfiguredFeatureType type, EditSession editSess */ void fixAfterFastMode(Iterable chunks); + /** + * Sends biome updates for the given chunks. + * + *

This doesn't modify biomes at all, it just sends the current state of the biomes + * in the world to all of the nearby players, updating the visual representation of the + * biomes on their clients.

+ * + * @param chunks a list of chunk coordinates to send biome updates for + */ + void sendBiomeUpdates(Iterable chunks); + /** * Relight the given chunks if possible. * diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java index a1e6b69e6c..71af2dda85 100644 --- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java @@ -23,6 +23,8 @@ import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.common.collect.Streams; import com.google.common.util.concurrent.Futures; @@ -526,6 +528,15 @@ public void fixAfterFastMode(Iterable chunks) { fixLighting(chunks); } + @Override + public void sendBiomeUpdates(Iterable chunks) { + List nativeChunks = Lists.newArrayListWithCapacity(Iterables.size(chunks)); + for (BlockVector2 chunk : chunks) { + nativeChunks.add(getWorld().getChunk(chunk.getBlockX(), chunk.getBlockZ(), ChunkStatus.BIOMES, false)); + } + ((ServerLevel) getWorld()).getChunkSource().chunkMap.resendBiomesForChunks(nativeChunks); + } + @Override public void fixLighting(Iterable chunks) { Level world = getWorld();