Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-09-06 08:02:50 +02:00
Differentiate passthrough / abstract delegate
AbstractDelegateExtent allows overriding just the basic set/get to change behavior - at performance cost Passthrough passes all operation, so each must be individually overrided.
Dieser Commit ist enthalten in:
Ursprung
322a3e66be
Commit
3c626ef25a
@ -9,6 +9,7 @@ import com.boydti.fawe.beta.filters.DistrFilter;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.PassthroughExtent;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
@ -25,7 +26,7 @@ import java.util.Set;
|
||||
import java.util.concurrent.ForkJoinTask;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class MultiThreadedQueue extends AbstractDelegateExtent implements IQueueWrapper {
|
||||
public class MultiThreadedQueue extends PassthroughExtent implements IQueueWrapper {
|
||||
|
||||
private final World world;
|
||||
private final QueueHandler handler;
|
||||
|
@ -142,7 +142,7 @@ public class Settings extends Config {
|
||||
public int MAX_EXPRESSION_MS = 50;
|
||||
@Comment({
|
||||
"Cinematic block placement:",
|
||||
" - Adds a delay to block placement (ms/block)",
|
||||
" - Adds a delay to block placement (nanoseconds/block)",
|
||||
" - Having an artificial delay will use more CPU/Memory",
|
||||
})
|
||||
public int SPEED_REDUCTION = 0;
|
||||
|
@ -7,6 +7,7 @@ import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.PassthroughExtent;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.boydti.fawe.object.extent;
|
||||
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.PassthroughExtent;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
|
@ -2,9 +2,11 @@ package com.boydti.fawe.object.extent;
|
||||
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.PassthroughExtent;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ExtentHeightCacher extends AbstractDelegateExtent {
|
||||
public class ExtentHeightCacher extends PassthroughExtent {
|
||||
|
||||
public ExtentHeightCacher(Extent extent) {
|
||||
super(extent);
|
||||
@ -18,15 +20,10 @@ public class ExtentHeightCacher extends AbstractDelegateExtent {
|
||||
}
|
||||
}
|
||||
|
||||
private transient int cacheCenX;
|
||||
private transient int cacheCenZ;
|
||||
private transient int cacheBotX = Integer.MIN_VALUE;
|
||||
private transient int cacheBotZ = Integer.MIN_VALUE;
|
||||
private transient int cacheCenterZ;
|
||||
private transient byte[] cacheHeights;
|
||||
private transient int lastY;
|
||||
private transient boolean foundY;
|
||||
private transient boolean lastValue;
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY) {
|
||||
|
@ -9,10 +9,11 @@ import com.boydti.fawe.util.WEManager;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.PassthroughExtent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
|
||||
public class MemoryCheckingExtent extends AbstractDelegateExtent {
|
||||
public class MemoryCheckingExtent extends PassthroughExtent {
|
||||
private final FawePlayer<?> player;
|
||||
|
||||
public MemoryCheckingExtent(final FawePlayer<?> player, final Extent extent) {
|
||||
@ -21,20 +22,16 @@ public class MemoryCheckingExtent extends AbstractDelegateExtent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(final BlockVector3 location, final B block) throws WorldEditException {
|
||||
if (super.setBlock(location, block)) {
|
||||
if (MemUtil.isMemoryLimited()) {
|
||||
if (this.player != null) {
|
||||
player.sendMessage(BBC.WORLDEDIT_CANCEL_REASON.format(BBC.WORLDEDIT_CANCEL_REASON_LOW_MEMORY.s()));
|
||||
if (Permission.hasPermission(this.player.toWorldEditPlayer(), "worldedit.fast")) {
|
||||
BBC.WORLDEDIT_OOM_ADMIN.send(this.player);
|
||||
}
|
||||
public Extent getExtent() {
|
||||
if (MemUtil.isMemoryLimited()) {
|
||||
if (this.player != null) {
|
||||
player.sendMessage(BBC.WORLDEDIT_CANCEL_REASON.format(BBC.WORLDEDIT_CANCEL_REASON_LOW_MEMORY.s()));
|
||||
if (Permission.hasPermission(this.player.toWorldEditPlayer(), "worldedit.fast")) {
|
||||
BBC.WORLDEDIT_OOM_ADMIN.send(this.player);
|
||||
}
|
||||
WEManager.IMP.cancelEdit(this, FaweException.LOW_MEMORY);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
WEManager.IMP.cancelEdit(this, FaweException.LOW_MEMORY);
|
||||
}
|
||||
return false;
|
||||
return super.getExtent();
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package com.boydti.fawe.object.extent;
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
|
||||
import com.sk89q.worldedit.extent.PassthroughExtent;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
@ -10,20 +11,33 @@ import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
|
||||
public class SlowExtent extends AbstractDelegateExtent {
|
||||
private final long sleep;
|
||||
private long THRESHOLD = 50 * 1000000; // 1 tick
|
||||
private final long nanos;
|
||||
private long increment;
|
||||
|
||||
public SlowExtent(Extent extent, long sleep) {
|
||||
public SlowExtent(Extent extent, long nanos) {
|
||||
super(extent);
|
||||
this.sleep = sleep;
|
||||
this.nanos = nanos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 location, B block) throws WorldEditException {
|
||||
if (!Fawe.isMainThread()) try {
|
||||
Thread.sleep(sleep);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
public <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block) throws WorldEditException {
|
||||
delay();
|
||||
return super.setBlock(x, y, z, block);
|
||||
}
|
||||
|
||||
public void delay() {
|
||||
increment += nanos;
|
||||
if (increment >= THRESHOLD) {
|
||||
long wait = increment / 1000000;
|
||||
if (!Fawe.isMainThread()) {
|
||||
try {
|
||||
Thread.sleep(wait);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
increment -= wait * 1000000;
|
||||
}
|
||||
return super.setBlock(location, block);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.boydti.fawe.object.extent;
|
||||
|
||||
import com.sk89q.worldedit.extent.PassthroughExtent;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
@ -10,7 +11,7 @@ import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
public class TemporalExtent extends AbstractDelegateExtent {
|
||||
public class TemporalExtent extends PassthroughExtent {
|
||||
private int x, y, z = Integer.MAX_VALUE;
|
||||
private BlockStateHolder<?> block = BlockTypes.AIR.getDefaultState();
|
||||
|
||||
|
@ -12,6 +12,7 @@ import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.PassthroughExtent;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
@ -24,7 +25,7 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class FuzzyRegionSelector extends AbstractDelegateExtent implements RegionSelector {
|
||||
public class FuzzyRegionSelector extends PassthroughExtent implements RegionSelector {
|
||||
|
||||
private final Player player;
|
||||
private FuzzyRegion region;
|
||||
|
@ -59,6 +59,7 @@ import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.ChangeSetExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.MaskingExtent;
|
||||
import com.sk89q.worldedit.extent.PassthroughExtent;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBagExtent;
|
||||
import com.sk89q.worldedit.extent.world.SurvivalModeExtent;
|
||||
@ -163,7 +164,7 @@ import org.slf4j.LoggerFactory;
|
||||
* using the {@link ChangeSetExtent}.</p>
|
||||
*/
|
||||
@SuppressWarnings({"FieldCanBeLocal"})
|
||||
public class EditSession extends AbstractDelegateExtent implements SimpleWorld, AutoCloseable {
|
||||
public class EditSession extends PassthroughExtent implements SimpleWorld, AutoCloseable {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(EditSession.class);
|
||||
|
||||
|
@ -0,0 +1,291 @@
|
||||
package com.sk89q.worldedit.extent;
|
||||
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.function.generator.GenBase;
|
||||
import com.sk89q.worldedit.function.generator.Resource;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.operation.Operation;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.util.Countable;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PassthroughExtent extends AbstractDelegateExtent {
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param extent the extent
|
||||
*/
|
||||
public PassthroughExtent(Extent extent) {
|
||||
super(extent);
|
||||
}
|
||||
|
||||
public BlockVector3 getMinimumPoint() {
|
||||
return getExtent().getMinimumPoint();
|
||||
}
|
||||
|
||||
public BlockVector3 getMaximumPoint() {
|
||||
return getExtent().getMaximumPoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Entity> getEntities(Region region) {
|
||||
return getExtent().getEntities(region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Entity> getEntities() {
|
||||
return getExtent().getEntities();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Entity createEntity(Location location, BaseEntity entity) {
|
||||
return getExtent().createEntity(location, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public void removeEntity(int x, int y, int z, UUID uuid) {
|
||||
getExtent().removeEntity(x, y, z, uuid);
|
||||
}
|
||||
|
||||
public boolean isQueueEnabled() {
|
||||
return getExtent().isQueueEnabled();
|
||||
}
|
||||
|
||||
public void enableQueue() {
|
||||
getExtent().enableQueue();
|
||||
}
|
||||
|
||||
public void disableQueue() {
|
||||
getExtent().disableQueue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWorld() {
|
||||
return getExtent().isWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean regenerateChunk(int x, int z, @Nullable BiomeType type, @Nullable Long seed) {
|
||||
return getExtent().regenerateChunk(x, z, type, seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighestTerrainBlock(int x, int z, int minY, int maxY) {
|
||||
return getExtent().getHighestTerrainBlock(x, z, minY, maxY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighestTerrainBlock(int x, int z, int minY, int maxY, Mask filter) {
|
||||
return getExtent().getHighestTerrainBlock(x, z, minY, maxY, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceLayer(int x, int z, int y, int minY, int maxY) {
|
||||
return getExtent().getNearestSurfaceLayer(x, z, y, minY, maxY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, boolean ignoreAir) {
|
||||
return getExtent().getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, ignoreAir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY) {
|
||||
return getExtent().getNearestSurfaceTerrainBlock(x, z, y, minY, maxY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax) {
|
||||
return getExtent().getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax, Mask mask) {
|
||||
return getExtent().getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, mask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax, boolean ignoreAir) {
|
||||
return getExtent().getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, ignoreAir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCaves(Region region) throws WorldEditException {
|
||||
getExtent().addCaves(region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(Region region, GenBase gen) throws WorldEditException {
|
||||
getExtent().generate(region, gen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSchems(Region region, Mask mask, List<ClipboardHolder> clipboards, int rarity, boolean rotate) throws WorldEditException {
|
||||
getExtent().addSchems(region, mask, clipboards, rarity, rotate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawnResource(Region region, Resource gen, int rarity, int frequency) throws WorldEditException {
|
||||
getExtent().spawnResource(region, gen, rarity, frequency);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(BlockVector3 pt) {
|
||||
return getExtent().contains(pt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOre(Region region, Mask mask, Pattern material, int size, int frequency, int rarity, int minY, int maxY) throws WorldEditException {
|
||||
getExtent().addOre(region, mask, material, size, frequency, rarity, minY, maxY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOres(Region region, Mask mask) throws WorldEditException {
|
||||
getExtent().addOres(region, mask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Countable<BlockType>> getBlockDistribution(Region region) {
|
||||
return getExtent().getBlockDistribution(region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Countable<BlockState>> getBlockDistributionWithData(Region region) {
|
||||
return getExtent().getBlockDistributionWithData(region);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Operation commit() {
|
||||
return getExtent().commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel() {
|
||||
return getExtent().cancel();
|
||||
}
|
||||
|
||||
public int getMaxY() {
|
||||
return getExtent().getMaxY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockArrayClipboard lazyCopy(Region region) {
|
||||
return getExtent().lazyCopy(region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countBlocks(Region region, Set<BaseBlock> searchBlocks) {
|
||||
return getExtent().countBlocks(region, searchBlocks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countBlocks(Region region, Mask searchMask) {
|
||||
return getExtent().countBlocks(region, searchMask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> int setBlocks(Region region, B block) throws MaxChangedBlocksException {
|
||||
return getExtent().setBlocks(region, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
|
||||
return getExtent().setBlocks(region, pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> int replaceBlocks(Region region, Set<BaseBlock> filter, B replacement) throws MaxChangedBlocksException {
|
||||
return getExtent().replaceBlocks(region, filter, replacement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int replaceBlocks(Region region, Set<BaseBlock> filter, Pattern pattern) throws MaxChangedBlocksException {
|
||||
return getExtent().replaceBlocks(region, filter, pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int replaceBlocks(Region region, Mask mask, Pattern pattern) throws MaxChangedBlocksException {
|
||||
return getExtent().replaceBlocks(region, mask, pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int center(Region region, Pattern pattern) throws MaxChangedBlocksException {
|
||||
return getExtent().center(region, pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setBlocks(Set<BlockVector3> vset, Pattern pattern) {
|
||||
return getExtent().setBlocks(vset, pattern);
|
||||
}
|
||||
|
||||
public BlockState getBlock(BlockVector3 position) {
|
||||
return getExtent().getBlock(position);
|
||||
}
|
||||
|
||||
public BlockState getBlock(int x, int y, int z) {
|
||||
return getExtent().getBlock(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
return getExtent().getFullBlock(position);
|
||||
}
|
||||
|
||||
public BaseBlock getFullBlock(int x, int y, int z) {
|
||||
return getExtent().getFullBlock(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeType getBiome(BlockVector2 position) {
|
||||
return getExtent().getBiome(position);
|
||||
}
|
||||
|
||||
public BiomeType getBiomeType(int x, int z) {
|
||||
return getExtent().getBiomeType(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 position, T block) throws WorldEditException {
|
||||
return getExtent().setBlock(position, block);
|
||||
}
|
||||
|
||||
public <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block) throws WorldEditException {
|
||||
return getExtent().setBlock(x, y, z, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException {
|
||||
return getExtent().setTile(x, y, z, tile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(BlockVector2 position, BiomeType biome) {
|
||||
return getExtent().setBiome(position, biome);
|
||||
}
|
||||
|
||||
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||
return getExtent().setBiome(x, y, z, biome);
|
||||
}
|
||||
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren