mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2024-12-23 01:37:37 +00:00
[Forge] Make //regen work better
It now creates a brand-new world, generates the appropriate section there, and copies it over to the original world.
This commit is contained in:
parent
e9419f4280
commit
1752963288
@ -19,16 +19,22 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.forge;
|
package com.sk89q.worldedit.forge;
|
||||||
|
|
||||||
|
import com.google.common.io.Files;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.*;
|
import com.sk89q.worldedit.BlockVector;
|
||||||
|
import com.sk89q.worldedit.EditSession;
|
||||||
|
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.Vector2D;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
import com.sk89q.worldedit.blocks.BaseItem;
|
import com.sk89q.worldedit.blocks.BaseItem;
|
||||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||||
import com.sk89q.worldedit.blocks.LazyBlock;
|
import com.sk89q.worldedit.blocks.LazyBlock;
|
||||||
import com.sk89q.worldedit.entity.BaseEntity;
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
import com.sk89q.worldedit.entity.Entity;
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
import com.sk89q.worldedit.history.change.BlockChange;
|
|
||||||
import com.sk89q.worldedit.internal.Constants;
|
import com.sk89q.worldedit.internal.Constants;
|
||||||
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.util.Direction;
|
import com.sk89q.worldedit.util.Direction;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
@ -36,40 +42,55 @@ import com.sk89q.worldedit.util.TreeGenerator.TreeType;
|
|||||||
import com.sk89q.worldedit.world.AbstractWorld;
|
import com.sk89q.worldedit.world.AbstractWorld;
|
||||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||||
import com.sk89q.worldedit.world.registry.WorldData;
|
import com.sk89q.worldedit.world.registry.WorldData;
|
||||||
import net.minecraft.block.*;
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockLeaves;
|
||||||
|
import net.minecraft.block.BlockOldLeaf;
|
||||||
|
import net.minecraft.block.BlockOldLog;
|
||||||
|
import net.minecraft.block.BlockPlanks;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.EntityList;
|
import net.minecraft.entity.EntityList;
|
||||||
import net.minecraft.entity.item.EntityItem;
|
import net.minecraft.entity.item.EntityItem;
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.inventory.IInventory;
|
import net.minecraft.inventory.IInventory;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.server.management.PlayerChunkMap;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.management.PlayerChunkMapEntry;
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.EnumActionResult;
|
import net.minecraft.util.EnumActionResult;
|
||||||
import net.minecraft.util.EnumHand;
|
import net.minecraft.util.EnumHand;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.ChunkPos;
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.WorldServer;
|
import net.minecraft.world.WorldServer;
|
||||||
import net.minecraft.world.biome.Biome;
|
import net.minecraft.world.biome.Biome;
|
||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
import net.minecraft.world.chunk.IChunkGenerator;
|
|
||||||
import net.minecraft.world.chunk.IChunkProvider;
|
import net.minecraft.world.chunk.IChunkProvider;
|
||||||
|
import net.minecraft.world.chunk.storage.AnvilSaveHandler;
|
||||||
import net.minecraft.world.gen.ChunkProviderServer;
|
import net.minecraft.world.gen.ChunkProviderServer;
|
||||||
import net.minecraft.world.gen.feature.*;
|
import net.minecraft.world.gen.feature.WorldGenBigMushroom;
|
||||||
|
import net.minecraft.world.gen.feature.WorldGenBigTree;
|
||||||
|
import net.minecraft.world.gen.feature.WorldGenBirchTree;
|
||||||
|
import net.minecraft.world.gen.feature.WorldGenCanopyTree;
|
||||||
|
import net.minecraft.world.gen.feature.WorldGenMegaJungle;
|
||||||
|
import net.minecraft.world.gen.feature.WorldGenMegaPineTree;
|
||||||
|
import net.minecraft.world.gen.feature.WorldGenSavannaTree;
|
||||||
|
import net.minecraft.world.gen.feature.WorldGenShrub;
|
||||||
|
import net.minecraft.world.gen.feature.WorldGenSwamp;
|
||||||
|
import net.minecraft.world.gen.feature.WorldGenTaiga1;
|
||||||
|
import net.minecraft.world.gen.feature.WorldGenTaiga2;
|
||||||
|
import net.minecraft.world.gen.feature.WorldGenTrees;
|
||||||
|
import net.minecraft.world.gen.feature.WorldGenerator;
|
||||||
|
import net.minecraftforge.common.DimensionManager;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
@ -80,7 +101,6 @@ public class ForgeWorld extends AbstractWorld {
|
|||||||
|
|
||||||
private static final Random random = new Random();
|
private static final Random random = new Random();
|
||||||
private static final int UPDATE = 1, NOTIFY = 2;
|
private static final int UPDATE = 1, NOTIFY = 2;
|
||||||
private static final Logger logger = Logger.getLogger(ForgeWorld.class.getCanonicalName());
|
|
||||||
|
|
||||||
private static final IBlockState JUNGLE_LOG = Blocks.LOG.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE);
|
private static final IBlockState JUNGLE_LOG = Blocks.LOG.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE);
|
||||||
private static final IBlockState JUNGLE_LEAF = Blocks.LEAVES.getDefaultState().withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.JUNGLE).withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false));
|
private static final IBlockState JUNGLE_LEAF = Blocks.LEAVES.getDefaultState().withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.JUNGLE).withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false));
|
||||||
@ -246,73 +266,41 @@ public class ForgeWorld extends AbstractWorld {
|
|||||||
if (!(provider instanceof ChunkProviderServer)) {
|
if (!(provider instanceof ChunkProviderServer)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
BaseBlock[] history = new BaseBlock[256 * (getMaxY() + 1)];
|
|
||||||
|
|
||||||
for (Vector2D chunk : region.getChunks()) {
|
File saveFolder = Files.createTempDir();
|
||||||
Vector min = new Vector(chunk.getBlockX() * 16, 0, chunk.getBlockZ() * 16);
|
// register this just in case something goes wrong
|
||||||
|
// normally it should be deleted at the end of this method
|
||||||
|
saveFolder.deleteOnExit();
|
||||||
|
|
||||||
for (int x = 0; x < 16; x++) {
|
WorldServer originalWorld = (WorldServer) getWorld();
|
||||||
for (int y = 0; y < getMaxY() + 1; y++) {
|
|
||||||
for (int z = 0; z < 16; z++) {
|
MinecraftServer server = originalWorld.getMinecraftServer();
|
||||||
Vector pt = min.add(x, y, z);
|
AnvilSaveHandler saveHandler = new AnvilSaveHandler(saveFolder,
|
||||||
int index = y * 16 * 16 + z * 16 + x;
|
originalWorld.getSaveHandler().getWorldDirectory().getName(), true, server.getDataFixer());
|
||||||
history[index] = editSession.getBlock(pt);
|
World freshWorld = new WorldServer(server, saveHandler, originalWorld.getWorldInfo(),
|
||||||
|
originalWorld.provider.getDimension(), originalWorld.theProfiler).init();
|
||||||
|
|
||||||
|
// Pre-gen all the chunks
|
||||||
|
// We need to also pull one more chunk in every direction
|
||||||
|
CuboidRegion expandedPreGen = new CuboidRegion(region.getMinimumPoint().subtract(16, 0, 16), region.getMaximumPoint().add(16, 0, 16));
|
||||||
|
for (Vector2D chunk : expandedPreGen.getChunks()) {
|
||||||
|
freshWorld.getChunkFromChunkCoords(chunk.getBlockX(), chunk.getBlockZ());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
ForgeWorld from = new ForgeWorld(freshWorld);
|
||||||
PlayerChunkMap playerManager = ((WorldServer) getWorld()).getPlayerChunkMap();
|
|
||||||
List<EntityPlayerMP> oldWatchers = null;
|
|
||||||
Chunk mcChunk = null;
|
|
||||||
try {
|
try {
|
||||||
ChunkProviderServer chunkServer = (ChunkProviderServer) provider;
|
for (BlockVector vec : region) {
|
||||||
IChunkGenerator gen = chunkServer.chunkGenerator;
|
editSession.setBlock(vec, from.getBlock(vec));
|
||||||
long pos = ChunkPos.asLong(chunk.getBlockX(), chunk.getBlockZ());
|
|
||||||
if (chunkServer.chunkExists(chunk.getBlockX(), chunk.getBlockZ())) {
|
|
||||||
mcChunk = chunkServer.loadChunk(chunk.getBlockX(), chunk.getBlockZ());
|
|
||||||
PlayerChunkMapEntry entry = playerManager.getEntry(chunk.getBlockX(), chunk.getBlockZ());
|
|
||||||
if (entry != null) {
|
|
||||||
oldWatchers = entry.players;
|
|
||||||
playerManager.removeEntry(entry);
|
|
||||||
}
|
}
|
||||||
mcChunk.onChunkUnload();
|
} catch (MaxChangedBlocksException e) {
|
||||||
}
|
throw new RuntimeException(e);
|
||||||
chunkServer.droppedChunksSet.remove(pos);
|
} finally {
|
||||||
chunkServer.id2ChunkMap.remove(pos);
|
saveFolder.delete();
|
||||||
mcChunk = gen.provideChunk(chunk.getBlockX(), chunk.getBlockZ());
|
DimensionManager.setWorld(originalWorld.provider.getDimension(), null, server);
|
||||||
chunkServer.id2ChunkMap.put(pos, mcChunk);
|
DimensionManager.setWorld(originalWorld.provider.getDimension(), originalWorld, server);
|
||||||
if (mcChunk != null) {
|
|
||||||
mcChunk.onChunkLoad();
|
|
||||||
mcChunk.populateChunk(chunkServer, chunkServer.chunkGenerator);
|
|
||||||
}
|
|
||||||
} catch (Throwable t) {
|
|
||||||
logger.log(Level.WARNING, "Failed to generate chunk", t);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int x = 0; x < 16; x++) {
|
return true;
|
||||||
for (int y = 0; y < getMaxY() + 1; y++) {
|
|
||||||
for (int z = 0; z < 16; z++) {
|
|
||||||
Vector pt = min.add(x, y, z);
|
|
||||||
int index = y * 16 * 16 + z * 16 + x;
|
|
||||||
|
|
||||||
if (!region.contains(pt))
|
|
||||||
editSession.smartSetBlock(pt, history[index]);
|
|
||||||
else {
|
|
||||||
editSession.getChangeSet().add(new BlockChange(pt.toBlockVector(), history[index], editSession.getBlock(pt)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// We don't need to recreate the ChunkMapEntry unless there are players
|
|
||||||
// but addPlayer handles that for us
|
|
||||||
if (oldWatchers != null) {
|
|
||||||
for (EntityPlayerMP player : oldWatchers) {
|
|
||||||
playerManager.addPlayer(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
Loading…
Reference in New Issue
Block a user