Spatial Dimension Changes

This commit is contained in:
Sebastian Hartte
2020-06-13 12:28:56 +02:00
parent 94226f3219
commit 832d517e98
8 changed files with 72 additions and 199 deletions
@@ -22,9 +22,9 @@ package appeng.core.worlddata;
import appeng.api.storage.ISpatialDimension;
import appeng.core.AELog;
import appeng.core.AppEng;
import appeng.spatial.StorageCellDimension;
import appeng.spatial.StorageCellModDimension;
import io.netty.buffer.Unpooled;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.PacketBuffer;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ResourceLocation;
@@ -32,15 +32,13 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.util.INBTSerializable;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
public class SpatialDimensionManager implements ISpatialDimension
{
private static final int MAX_DIM_PER_PLAYER = 999;
private static final int MAX_CELL_DIMENSION = 512;
private static final String DIM_ID_PREFIX = "storage_cell_";
@Override
public ServerWorld getWorld(DimensionType cellDim) {
@@ -48,32 +46,47 @@ public class SpatialDimensionManager implements ISpatialDimension
}
@Override
public DimensionType createNewCellDimension( BlockPos contentSize, int owner )
public DimensionType createNewCellDimension(BlockPos contentSize)
{
// Try to find a free dimension ID for the player
ResourceLocation dimKey = null;
for (int i = 1; i <= MAX_DIM_PER_PLAYER; i++) {
dimKey = new ResourceLocation(AppEng.MOD_ID, "spatial_cell_" + owner + "_" + i);
if (DimensionType.byName(dimKey) == null) {
break;
}
dimKey = null;
}
if (dimKey == null) {
return null;
}
StorageCellData data = new StorageCellData();
data.contentDimension = contentSize;
data.owner = owner;
ResourceLocation dimKey = findFreeDimensionId();
AELog.info("Allocating storage cell dimension '%s' for %d", dimKey);
PacketBuffer extraData = new PacketBuffer(Unpooled.buffer());
extraData.writeInt(owner);
extraData.writeBlockPos(contentSize);
return DimensionManager.registerDimension(dimKey, StorageCellModDimension.INSTANCE, extraData, true);
}
/**
* Tries finding the next free storage cell dimension ID based on the currently registered storage
* cell dimensions.
*/
private ResourceLocation findFreeDimensionId() {
int maxId = 0;
for (DimensionType dimensionType : DimensionType.getAll()) {
ResourceLocation regName = dimensionType.getRegistryName();
if (regName == null || !AppEng.MOD_ID.equals(regName.getNamespace())) {
continue;
}
String path = regName.getPath();
if (!path.startsWith(DIM_ID_PREFIX)) {
continue;
}
try {
String numericIdPart = path.substring(DIM_ID_PREFIX.length());
maxId = Math.max(Integer.parseUnsignedInt(numericIdPart), maxId);
} catch (NumberFormatException e) {
AELog.warn("Unparsable storage cell dimension id '%s'", path, e);
}
}
++maxId;
return new ResourceLocation(AppEng.MOD_ID, DIM_ID_PREFIX + maxId);
}
@Override
public void deleteCellDimension( DimensionType cellDim )
{
@@ -102,28 +115,10 @@ public class SpatialDimensionManager implements ISpatialDimension
return cellDim.getModType() instanceof StorageCellModDimension;
}
@Override
public int getCellDimensionOwner( DimensionType cellDim )
{
if (!(cellDim.getModType() instanceof StorageCellModDimension)) {
return -1;
}
PacketBuffer data = cellDim.getData();
if (data == null) {
return -1;
}
data.readerIndex(0);
return data.readInt();
}
@Override
public BlockPos getCellDimensionOrigin( DimensionType cellDim )
{
// A region file is 512x512 blocks (32x32 chunks),
// to avoid creating the 4 regions around 0,0,0,
// we move the origin to the middle of region 0,0
return new BlockPos(512 / 2, 61, 512 / 2);
return StorageCellDimension.REGION_CENTER;
}
@Override
@@ -141,67 +136,4 @@ public class SpatialDimensionManager implements ISpatialDimension
return data.readBlockPos();
}
private BlockPos getBlockPosFromId( int id )
{
int signBits = id & 0b11;
int offsetBits = id >> 2;
int offsetScale = 1;
int posx = MAX_CELL_DIMENSION / 2;
int posz = MAX_CELL_DIMENSION / 2;
// find quadrant
while( offsetBits != 0 )
{
posx += MAX_CELL_DIMENSION * offsetScale * ( offsetBits & 0b01 );
posz += MAX_CELL_DIMENSION * offsetScale * ( offsetBits >> 1 & 0b01 );
offsetBits >>= 2;
offsetScale <<= 1;
}
// mirror in one of 4 directions
if( ( signBits & 0b01 ) == 0 )
{
posx *= -1;
}
if( ( signBits & 0b10 ) == 0 )
{
posz *= -1;
}
// offset from cell center
posx -= 64;
posz -= 64;
return new BlockPos( posx, 64, posz );
}
private static class StorageCellData implements INBTSerializable<CompoundNBT>
{
private static final String NBT_OWNER_KEY = "owner";
private static final String NBT_DIM_X_KEY = "dim_x";
private static final String NBT_DIM_Y_KEY = "dim_y";
private static final String NBT_DIM_Z_KEY = "dim_z";
public BlockPos contentDimension;
public int owner;
@Override
public CompoundNBT serializeNBT()
{
CompoundNBT nbt = new CompoundNBT();
nbt.putInt( NBT_DIM_X_KEY, this.contentDimension.getX() );
nbt.putInt( NBT_DIM_Y_KEY, this.contentDimension.getY() );
nbt.putInt( NBT_DIM_Z_KEY, this.contentDimension.getZ() );
nbt.putInt( NBT_OWNER_KEY, this.owner );
return nbt;
}
@Override
public void deserializeNBT( CompoundNBT nbt )
{
this.contentDimension = new BlockPos( nbt.getInt( NBT_DIM_X_KEY ), nbt.getInt( NBT_DIM_Y_KEY ), nbt.getInt( NBT_DIM_Z_KEY ) );
this.owner = nbt.getInt( NBT_OWNER_KEY );
}
}
}