11package com .fastasyncworldedit .bukkit .adapter ;
22
3+ import com .fastasyncworldedit .core .queue .IChunk ;
34import com .fastasyncworldedit .core .queue .IChunkCache ;
45import com .fastasyncworldedit .core .queue .IChunkGet ;
56import com .fastasyncworldedit .core .queue .implementation .SingleThreadQueueExtent ;
1617import com .sk89q .worldedit .world .block .BaseBlock ;
1718import org .bukkit .generator .BiomeProvider ;
1819import org .bukkit .generator .WorldInfo ;
20+ import org .jetbrains .annotations .NotNull ;
21+ import org .jetbrains .annotations .Nullable ;
1922
2023import java .util .Collections ;
2124import java .util .List ;
2225import java .util .concurrent .TimeUnit ;
26+ import java .util .function .BiFunction ;
2327import java .util .function .BooleanSupplier ;
24- import java .util .function .Function ;
2528
2629/**
2730 * Represents an abstract regeneration handler.
@@ -109,18 +112,45 @@ private void copyToWorld() {
109112 boolean genbiomes = options .shouldRegenBiomes ();
110113 boolean hasBiome = options .hasBiomeType ();
111114 BiomeType biome = options .getBiomeType ();
115+ Pattern pattern ;
112116 if (!genbiomes && !hasBiome ) {
113- target .setBlocks (region , new PlacementPattern ());
114- }
115- if (hasBiome ) {
116- target .setBlocks (region , new WithBiomePlacementPattern (ignored -> biome ));
117- } else if (genbiomes ) {
118- target .setBlocks (region , new WithBiomePlacementPattern (vec -> source .getBiome (vec )));
117+ pattern = new PlacementPattern ();
118+ } else if (hasBiome ) {
119+ pattern = new WithBiomePlacementPattern ((ignored1 , ignored2 ) -> biome );
120+ } else {
121+ pattern = new WithBiomePlacementPattern ((vec , chunk ) -> {
122+ if (chunk != null ) {
123+ return chunk .getBiomeType (vec .x () & 15 , vec .y (), vec .z () & 15 );
124+ }
125+ return source .getBiome (vec );
126+ });
119127 }
128+ target .setBlocks (region , pattern );
120129 TaskManager .taskManager ().cancel (taskId );
121130 }
122131
123- private class PlacementPattern implements Pattern {
132+ private abstract class ChunkwisePattern implements Pattern {
133+ // the chunk we're currently operating on, if any.
134+ // allows faster access to chunk data than source.getFullBlock(...)
135+ protected @ Nullable IChunk chunk ;
136+
137+ @ Override
138+ public @ NotNull <T extends IChunk > T applyChunk (final T chunk , @ Nullable final Region region ) {
139+ this .chunk = source .getOrCreateChunk (chunk .getX (), chunk .getZ ());
140+ return chunk ;
141+ }
142+
143+ @ Override
144+ public void finishChunk (final IChunk chunk ) {
145+ this .chunk = null ;
146+ }
147+
148+ @ Override
149+ public abstract Pattern fork ();
150+
151+ }
152+
153+ private class PlacementPattern extends ChunkwisePattern {
124154
125155 @ Override
126156 public BaseBlock applyBlock (final BlockVector3 position ) {
@@ -129,16 +159,26 @@ public BaseBlock applyBlock(final BlockVector3 position) {
129159
130160 @ Override
131161 public boolean apply (final Extent extent , final BlockVector3 get , final BlockVector3 set ) throws WorldEditException {
132- return extent .setBlock (set .x (), set .y (), set .z (), source .getFullBlock (get .x (), get .y (), get .z ()));
162+ BaseBlock fullBlock ;
163+ if (chunk != null ) {
164+ fullBlock = chunk .getFullBlock (get .x () & 15 , get .y (), get .z () & 15 );
165+ } else {
166+ fullBlock = source .getFullBlock (get .x (), get .y (), get .z ());
167+ }
168+ return set .setFullBlock (extent , fullBlock );
133169 }
134170
171+ @ Override
172+ public Pattern fork () {
173+ return new PlacementPattern ();
174+ }
135175 }
136176
137- private class WithBiomePlacementPattern implements Pattern {
177+ private class WithBiomePlacementPattern extends ChunkwisePattern {
138178
139- private final Function <BlockVector3 , BiomeType > biomeGetter ;
179+ private final BiFunction <BlockVector3 , @ Nullable IChunk , BiomeType > biomeGetter ;
140180
141- private WithBiomePlacementPattern (final Function <BlockVector3 , BiomeType > biomeGetter ) {
181+ private WithBiomePlacementPattern (final BiFunction <BlockVector3 , @ Nullable IChunk , BiomeType > biomeGetter ) {
142182 this .biomeGetter = biomeGetter ;
143183 }
144184
@@ -149,10 +189,20 @@ public BaseBlock applyBlock(final BlockVector3 position) {
149189
150190 @ Override
151191 public boolean apply (final Extent extent , final BlockVector3 get , final BlockVector3 set ) throws WorldEditException {
152- return extent .setBlock (set .x (), set .y (), set .z (), source .getFullBlock (get .x (), get .y (), get .z ()))
153- && extent .setBiome (set .x (), set .y (), set .z (), biomeGetter .apply (get ));
192+ final BaseBlock fullBlock ;
193+ if (chunk != null ) {
194+ fullBlock = chunk .getFullBlock (get .x () & 15 , get .y (), get .z () & 15 );
195+ } else {
196+ fullBlock = source .getFullBlock (get .x (), get .y (), get .z ());
197+ }
198+ return extent .setBlock (set .x (), set .y (), set .z (), fullBlock )
199+ && extent .setBiome (set .x (), set .y (), set .z (), biomeGetter .apply (get , chunk ));
154200 }
155201
202+ @ Override
203+ public Pattern fork () {
204+ return new WithBiomePlacementPattern (this .biomeGetter );
205+ }
156206 }
157207
158208 //functions to be implemented by sub class
0 commit comments