Working spatial dimensions teleport.

This commit is contained in:
Sebastian Hartte
2020-06-13 01:11:31 +02:00
parent e83429e1bb
commit 94226f3219
22 changed files with 522 additions and 872 deletions
-182
View File
@@ -1,182 +0,0 @@
package appeng;
import appeng.api.util.AEColor;
import appeng.core.AppEng;
import appeng.items.materials.MaterialType;
import appeng.items.parts.PartType;
import com.google.gson.*;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Map;
public class FixupIngredients {
private static Gson gson = new GsonBuilder()
.setPrettyPrinting()
.create();
private static JsonObject visitObjProps(JsonObject obj) {
for (Map.Entry<String, JsonElement> e : obj.entrySet()) {
e.setValue(visitAndReplace(e.getValue()));
}
return obj;
}
private static JsonElement visitAndReplace(JsonElement el) {
if (el.isJsonArray()) {
JsonArray arr = el.getAsJsonArray();
for (int i = 0; i < arr.size(); i++) {
arr.set(i, visitAndReplace(arr.get(i)));
}
return arr;
}
if (!el.isJsonObject()) {
return el;
}
JsonObject obj = el.getAsJsonObject();
if (obj.size() != 2 && (obj.size() != 3 || !obj.has("count"))) {
return visitObjProps(obj);
}
Integer count = null;
if (obj.has("count")) {
count = obj.get("count").getAsInt();
}
JsonPrimitive type = obj.getAsJsonPrimitive("type");
if (type == null) {
return visitObjProps(obj);
}
if ("forge:ore_dict".equals(type.getAsString())) {
String ore = obj.get("ore").getAsString();
JsonObject r = new JsonObject();
r.add("tag", new JsonPrimitive(AppEng.MOD_ID + ':' + "ore_" + ore));
return r;
}
if (!type.getAsString().equals("appliedenergistics2:part")) {
return visitObjProps(obj);
}
String part = obj.getAsJsonPrimitive("part").getAsString();
String itemName = null;
if (part.startsWith("material.")) {
String mtName = part.substring(9).toUpperCase();
if ("WIRELESS".equals(mtName)) {
mtName = "WIRELESS_RECEIVER";
}
itemName = mtName.toLowerCase();
} else if (part.startsWith("part.")) {
part = part.substring(5);
if ("fluid_interface".equals(part)) {
part = "cable_fluid_interface";
} else if ("interface".equals(part)) {
part = "cable_interface";
}
}
if (itemName == null) {
// Handle tags
String tagName = null;
if ( part.equalsIgnoreCase("cable_glass")) {
tagName = "glass_cable";
} else if (part.equalsIgnoreCase("cable_covered")) {
tagName = "covered_cable";
} else if (part.equalsIgnoreCase("cable_smart")) {
tagName = "smart_cable";
} else if (part.equalsIgnoreCase("cable_dense_covered")) {
tagName = "covered_dense_cable";
} else if (part.equalsIgnoreCase("cable_dense_smart")) {
tagName = "smart_dense_cable";
}
if (tagName != null) {
JsonObject r = new JsonObject();
r.add("tag", new JsonPrimitive(AppEng.MOD_ID + ':' + tagName));
return r;
}
itemName = part.toLowerCase();
}
for (AEColor c : AEColor.values()) {
String colorSuffix = '.' + c.registryPrefix;
if (itemName.endsWith(colorSuffix)) {
String p = itemName.substring(0, itemName.length() - colorSuffix.length());
itemName = c.registryPrefix + "_" + p;
break;
}
}
if (itemName.startsWith("p2p_tunnel_")) {
itemName = itemName.substring("p2p_tunnel_".length()) + "_p2p_tunnel";
}
JsonObject r = new JsonObject();
r.add("item", new JsonPrimitive(AppEng.MOD_ID + ':' + itemName));
if (count != null) {
r.add("count", new JsonPrimitive(count));
}
return r;
}
public static void main(String[] args) throws IOException {
Path p= Paths.get("D:\\Applied-Energistics-2\\src\\main\\resources\\data\\appliedenergistics2");
Files.walkFileTree(p, new FileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (!file.getFileName().toString().endsWith(".json")) {
return FileVisitResult.CONTINUE;
}
if (file.getFileName().toString().contains("_constants")) {
return FileVisitResult.CONTINUE;
}
if (file.getFileName().toString().contains("_factories")) {
return FileVisitResult.CONTINUE;
}
JsonElement el;
try (Reader r = Files.newBufferedReader(file, StandardCharsets.UTF_8)) {
el = visitAndReplace(gson.fromJson(r, JsonElement.class));
} catch (Exception e) {
System.err.println("Failed to process file " + file);
e.printStackTrace();
return FileVisitResult.CONTINUE;
}
try (Writer w = Files.newBufferedWriter(file, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
gson.toJson(el, w);
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
});
}
}
@@ -52,7 +52,7 @@ public class BlockMatrixFrame extends AEBaseBlock
public BlockMatrixFrame()
{
super( Properties.create(MATERIAL).hardnessAndResistance(-1.0F, 6000000.0F).noDrops().notSolid() );
super( Properties.create(MATERIAL).hardnessAndResistance(-1.0F, 6000000.0F).noDrops() );
// FIXME this.setLightOpacity( 0 );
// FIXME this.setOpaque( false );
}
@@ -76,7 +76,7 @@ public class BlockMatrixFrame extends AEBaseBlock
@Override
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
return VoxelShapes.empty();
return VoxelShapes.fullCube();
}
@Override
@@ -23,47 +23,49 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import appeng.api.storage.ISpatialDimension;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.server.ServerWorld;
class NullSpatialDimension implements ISpatialDimension
{
@Override
public int createNewCellDimension( BlockPos size, int owner )
{
return -1;
}
@Override
public void deleteCellDimension( int cellStorageId )
{
}
@Override
public int getCellDimensionOwner( int cellStorageId )
{
return -1;
}
@Override
public BlockPos getCellDimensionOrigin( int cellStorageId )
public DimensionType createNewCellDimension(BlockPos size, int owner )
{
return null;
}
@Override
public World getWorld()
public void deleteCellDimension( DimensionType cellStorageId )
{
}
@Override
public int getCellDimensionOwner( DimensionType cellStorageId )
{
return -1;
}
@Override
public BlockPos getCellDimensionOrigin( DimensionType cellStorageId )
{
return null;
}
@Override
public boolean isCellDimension( int cellDimID )
public ServerWorld getWorld(DimensionType cellStorageId )
{
return null;
}
@Override
public boolean isCellDimension( DimensionType cellDimID )
{
return false;
}
@Override
public BlockPos getCellContentSize( int cellDimId )
public BlockPos getCellContentSize( DimensionType cellDimId )
{
return null;
}
@@ -50,15 +50,18 @@ public class SpatialSkyRender implements IRenderHandler
this.dspList = GL11.glGenLists( 1 );
}
//FIXME, Do not use this until the above PR is merged.
// public static IRenderHandler getInstance()
// {
// return INSTANCE;
// }
public static IRenderHandler getInstance()
{
return INSTANCE;
}
@Override
public void render( final int ticks, final float partialTicks, final ClientWorld world, final Minecraft mc )
{
//FIXME, Do not use this until the above PR is merged.
if (true) {
return;
}
final long now = System.currentTimeMillis();
if( now - this.cycle > 2000 )
+8
View File
@@ -54,6 +54,10 @@ import net.minecraft.particles.ParticleType;
import net.minecraft.server.MinecraftServer;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.server.ServerWorld;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.server.ServerWorld;
@@ -62,6 +66,8 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.client.model.geometry.IModelGeometry;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.ModDimension;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.CrashReportExtender;
@@ -132,6 +138,8 @@ public final class AppEng
modEventBus.addGenericListener(ContainerType.class, registration::registerContainerTypes);
modEventBus.addGenericListener(IRecipeSerializer.class, registration::registerRecipeSerializers);
modEventBus.addGenericListener(Feature.class, registration::registerWorldGen);
modEventBus.addGenericListener(Biome.class, registration::registerBiomes);
modEventBus.addGenericListener(ModDimension.class, registration::registerModDimension);
modEventBus.addListener(registration::registerParticleFactories);
modEventBus.addListener(registration::registerTextures);
modEventBus.addListener(registration::registerCommands);
+21 -123
View File
@@ -38,39 +38,7 @@ import appeng.api.networking.storage.IStorageGrid;
import appeng.api.networking.ticking.ITickManager;
import appeng.bootstrap.IModelRegistry;
import appeng.bootstrap.components.*;
import appeng.client.gui.implementations.GuiCellWorkbench;
import appeng.client.gui.implementations.GuiChest;
import appeng.client.gui.implementations.GuiCondenser;
import appeng.client.gui.implementations.GuiCraftAmount;
import appeng.client.gui.implementations.GuiCraftConfirm;
import appeng.client.gui.implementations.GuiCraftingCPU;
import appeng.client.gui.implementations.GuiCraftingStatus;
import appeng.client.gui.implementations.GuiCraftingTerm;
import appeng.client.gui.implementations.GuiDrive;
import appeng.client.gui.implementations.GuiFormationPlane;
import appeng.client.gui.implementations.GuiGrinder;
import appeng.client.gui.implementations.GuiIOPort;
import appeng.client.gui.implementations.GuiInscriber;
import appeng.client.gui.implementations.GuiInterface;
import appeng.client.gui.implementations.GuiInterfaceTerminal;
import appeng.client.gui.implementations.GuiLevelEmitter;
import appeng.client.gui.implementations.GuiMAC;
import appeng.client.gui.implementations.GuiMEMonitorable;
import appeng.client.gui.implementations.GuiMEPortableCell;
import appeng.client.gui.implementations.GuiNetworkStatus;
import appeng.client.gui.implementations.GuiNetworkTool;
import appeng.client.gui.implementations.GuiPatternTerm;
import appeng.client.gui.implementations.GuiPriority;
import appeng.client.gui.implementations.GuiQNB;
import appeng.client.gui.implementations.GuiQuartzKnife;
import appeng.client.gui.implementations.GuiSecurityStation;
import appeng.client.gui.implementations.GuiSkyChest;
import appeng.client.gui.implementations.GuiSpatialIOPort;
import appeng.client.gui.implementations.GuiStorageBus;
import appeng.client.gui.implementations.GuiUpgradeable;
import appeng.client.gui.implementations.GuiVibrationChamber;
import appeng.client.gui.implementations.GuiWireless;
import appeng.client.gui.implementations.GuiWirelessTerm;
import appeng.client.gui.implementations.*;
import appeng.client.render.effects.*;
import appeng.client.render.model.BiometricCardModel;
import appeng.client.render.model.DriveModel;
@@ -99,7 +67,10 @@ import appeng.recipes.handlers.GrinderRecipeSerializer;
import appeng.recipes.handlers.InscriberRecipe;
import appeng.recipes.handlers.InscriberRecipeSerializer;
import appeng.server.AECommand;
import appeng.spatial.StorageCellBiome;
import appeng.spatial.StorageCellModDimension;
import appeng.tile.AEBaseTile;
import appeng.worldgen.MeteoriteWorldGen;
import net.minecraft.advancements.CriteriaTriggers;
import appeng.worldgen.MeteoriteWorldGen;
import net.minecraft.block.Block;
@@ -109,10 +80,16 @@ import net.minecraft.entity.EntityType;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.item.Item;
import net.minecraft.item.crafting.IRecipeSerializer;
import net.minecraft.item.crafting.IRecipeType;
import net.minecraft.particles.ParticleType;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.gen.GenerationStage;
import net.minecraft.world.gen.feature.ConfiguredFeature;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.IFeatureConfig;
import net.minecraft.world.gen.feature.NoFeatureConfig;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.gen.GenerationStage;
import net.minecraft.world.gen.feature.ConfiguredFeature;
@@ -124,8 +101,8 @@ import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.event.*;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.common.ModDimension;
import net.minecraftforge.common.crafting.CraftingHelper;
import net.minecraftforge.common.crafting.conditions.IConditionSerializer;
import net.minecraftforge.common.extensions.IForgeContainerType;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.DistExecutor;
@@ -146,62 +123,8 @@ final class Registration
advancementTriggers = new AdvancementTriggers( CriteriaTriggers::register );
}
// DimensionType storageDimensionType;
// int storageDimensionID;
// Biome storageBiome;
AdvancementTriggers advancementTriggers;
// private void registerSpatialBiome( IForgeRegistry<Biome> registry )
// {
// if( !AEConfig.instance().isFeatureEnabled( AEFeature.SPATIAL_IO ) )
// {
// return;
// }
//
// if( this.storageBiome == null )
// {
// this.storageBiome = new BiomeGenStorage();
// }
// registry.register( this.storageBiome.setRegistryName( "appliedenergistics2:storage_biome" ) );
// }
//
// private void registerSpatialDimension()
// {
// final AEConfig config = AEConfig.instance();
// if( !config.isFeatureEnabled( AEFeature.SPATIAL_IO ) )
// {
// return;
// }
//
// if( config.getStorageProviderID() == -1 )
// {
// final Set<Integer> ids = new HashSet<>();
// for( DimensionType type : DimensionType.values() )
// {
// ids.add( type.getId() );
// }
//
// int newId = -11;
// while( ids.contains( newId ) )
// {
// --newId;
// }
// config.setStorageProviderID( newId );
// config.save();
// }
//
// this.storageDimensionType = DimensionType.register( "Storage Cell", "_cell", config.getStorageProviderID(), StorageWorldProvider.class, true );
//
// if( config.getStorageDimensionID() == -1 )
// {
// config.setStorageDimensionID( DimensionManager.getNextFreeDimId() );
// config.save();
// }
// this.storageDimensionID = config.getStorageDimensionID();
//
// DimensionManager.registerDimension( this.storageDimensionID, this.storageDimensionType );
// }
public static void setupInternalRegistries()
{
// TODO: Do not use the internal API
@@ -233,13 +156,6 @@ final class Registration
PartItemPredicate.register();
}
// @SubscribeEvent
// public void registerBiomes( RegistryEvent.Register<Biome> event )
// {
// final IForgeRegistry<Biome> registry = event.getRegistry();
// this.registerSpatialBiome( registry );
// }
//
@OnlyIn( Dist.CLIENT )
public void modelRegistryEvent( ModelRegistryEvent event )
{
@@ -837,33 +753,14 @@ final class Registration
r.register( MeteoriteWorldGen.INSTANCE );
}
// private static class ModelLoaderWrapper implements IModelRegistry
// {
//
// @Override
// public void registerItemVariants( Item item, ResourceLocation... names )
// {
// ModelLoader.registerItemVariants( item, names );
// }
//
// @Override
// public void setCustomModelResourceLocation( Item item, int metadata, ModelResourceLocation model )
// {
// ModelLoader.setCustomModelResourceLocation( item, metadata, model );
// }
//
// @Override
// public void setCustomMeshDefinition( Item item, ItemMeshDefinition meshDefinition )
// {
// ModelLoader.setCustomMeshDefinition( item, meshDefinition );
// }
//
// @Override
// public void setCustomStateMapper( Block block, IStateMapper mapper )
// {
// ModelLoader.setCustomStateMapper( block, mapper );
// }
// }
public void registerBiomes(RegistryEvent.Register<Biome> evt) {
evt.getRegistry().register(StorageCellBiome.INSTANCE);
}
public void registerModDimension(RegistryEvent.Register<ModDimension> evt)
{
evt.getRegistry().register(StorageCellModDimension.INSTANCE);
}
public void registerTextures(TextureStitchEvent.Pre event) {
SkyChestTESR.registerTextures(event);
@@ -887,4 +784,5 @@ final class Registration
final ApiDefinitions definitions = Api.INSTANCE.definitions();
definitions.getRegistry().getBootstrapComponents( IModelBakeComponent.class ).forEachRemaining(c -> c.onModelBakeEvent(event));
}
}
@@ -248,21 +248,23 @@ public final class ApiItems implements IItems
.features( AEFeature.VIEW_CELL )
.build();
FeatureFactory storageCells = registry.features( AEFeature.STORAGE_CELLS );
this.cell1k = storageCells.item( "1k_storage_cell", props -> new BasicItemStorageCell(props, MaterialType.ITEM_1K_CELL_COMPONENT, 1 ) ).build();
this.cell4k = storageCells.item( "4k_storage_cell", props -> new BasicItemStorageCell(props, MaterialType.ITEM_4K_CELL_COMPONENT, 4 ) ).build();
this.cell16k = storageCells.item( "16k_storage_cell", props -> new BasicItemStorageCell(props, MaterialType.ITEM_16K_CELL_COMPONENT, 16 ) ).build();
this.cell64k = storageCells.item( "64k_storage_cell", props -> new BasicItemStorageCell(props, MaterialType.ITEM_64K_CELL_COMPONENT, 64 ) ).build();
Consumer<Item.Properties> storageCellProps = p -> p.maxStackSize(1);
this.fluidCell1k = storageCells.item( "1k_fluid_storage_cell", props -> new BasicFluidStorageCell(props, MaterialType.FLUID_1K_CELL_COMPONENT, 1 ) ).build();
this.fluidCell4k = storageCells.item( "4k_fluid_storage_cell", props -> new BasicFluidStorageCell(props, MaterialType.FLUID_4K_CELL_COMPONENT, 4 ) ).build();
this.fluidCell16k = storageCells.item( "16k_fluid_storage_cell", props -> new BasicFluidStorageCell(props, MaterialType.FLUID_16K_CELL_COMPONENT, 16 ) ).build();
this.fluidCell64k = storageCells.item( "64k_fluid_storage_cell", props -> new BasicFluidStorageCell(props, MaterialType.FLUID_64K_CELL_COMPONENT, 64 ) ).build();
FeatureFactory storageCells = registry.features( AEFeature.STORAGE_CELLS );
this.cell1k = storageCells.item( "1k_storage_cell", props -> new BasicItemStorageCell(props, MaterialType.ITEM_1K_CELL_COMPONENT, 1 ) ).props(storageCellProps).build();
this.cell4k = storageCells.item( "4k_storage_cell", props -> new BasicItemStorageCell(props, MaterialType.ITEM_4K_CELL_COMPONENT, 4 ) ).props(storageCellProps).build();
this.cell16k = storageCells.item( "16k_storage_cell", props -> new BasicItemStorageCell(props, MaterialType.ITEM_16K_CELL_COMPONENT, 16 ) ).props(storageCellProps).build();
this.cell64k = storageCells.item( "64k_storage_cell", props -> new BasicItemStorageCell(props, MaterialType.ITEM_64K_CELL_COMPONENT, 64 ) ).props(storageCellProps).build();
this.fluidCell1k = storageCells.item( "1k_fluid_storage_cell", props -> new BasicFluidStorageCell(props, MaterialType.FLUID_1K_CELL_COMPONENT, 1 ) ).props(storageCellProps).build();
this.fluidCell4k = storageCells.item( "4k_fluid_storage_cell", props -> new BasicFluidStorageCell(props, MaterialType.FLUID_4K_CELL_COMPONENT, 4 ) ).props(storageCellProps).build();
this.fluidCell16k = storageCells.item( "16k_fluid_storage_cell", props -> new BasicFluidStorageCell(props, MaterialType.FLUID_16K_CELL_COMPONENT, 16 ) ).props(storageCellProps).build();
this.fluidCell64k = storageCells.item( "64k_fluid_storage_cell", props -> new BasicFluidStorageCell(props, MaterialType.FLUID_64K_CELL_COMPONENT, 64 ) ).props(storageCellProps).build();
FeatureFactory spatialCells = registry.features( AEFeature.SPATIAL_IO );
this.spatialCell2 = spatialCells.item( "2_cubed_spatial_storage_cell", props -> new ItemSpatialStorageCell(props, 2 ) ).build();
this.spatialCell16 = spatialCells.item( "16_cubed_spatial_storage_cell", props -> new ItemSpatialStorageCell(props, 16 ) ).build();
this.spatialCell128 = spatialCells.item( "128_cubed_spatial_storage_cell", props -> new ItemSpatialStorageCell(props, 128 ) ).build();
this.spatialCell2 = spatialCells.item( "2_cubed_spatial_storage_cell", props -> new ItemSpatialStorageCell(props, 2 ) ).props(storageCellProps).build();
this.spatialCell16 = spatialCells.item( "16_cubed_spatial_storage_cell", props -> new ItemSpatialStorageCell(props, 16 ) ).props(storageCellProps).build();
this.spatialCell128 = spatialCells.item( "128_cubed_spatial_storage_cell", props -> new ItemSpatialStorageCell(props, 128 ) ).props(storageCellProps).build();
this.facade = registry.item( "facade", ItemFacade::new )
.features( AEFeature.FACADES )
@@ -19,164 +19,126 @@
package appeng.core.worlddata;
import java.util.HashMap;
import java.util.Map;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
import net.minecraftforge.common.util.INBTSerializable;
import appeng.api.storage.ISpatialDimension;
import appeng.capabilities.Capabilities;
import net.minecraftforge.common.util.LazyOptional;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import appeng.core.AELog;
import appeng.core.AppEng;
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;
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, ICapabilitySerializable<CompoundNBT>
public class SpatialDimensionManager implements ISpatialDimension
{
private static final String NBT_SPATIAL_DATA_KEY = "spatial_data";
private static final String NBT_SPATIAL_ID_KEY = "id";
private World world;
private Map<Integer, StorageCellData> spatialData = new HashMap<>();
private static final int MAX_DIM_PER_PLAYER = 999;
private static final int MAX_CELL_DIMENSION = 512;
public SpatialDimensionManager( World world )
{
this.world = world;
@Override
public ServerWorld getWorld(DimensionType cellDim) {
return DimensionManager.getWorld(getServer(), cellDim, true, true);
}
@Override
public World getWorld()
public DimensionType createNewCellDimension( BlockPos contentSize, int owner )
{
return this.world;
}
@Override
public int createNewCellDimension( BlockPos contentSize, int owner )
{
int newId = this.getNextId();
// 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;
this.spatialData.put( newId, data );
PacketBuffer extraData = new PacketBuffer(Unpooled.buffer());
extraData.writeInt(owner);
extraData.writeBlockPos(contentSize);
return newId;
return DimensionManager.registerDimension(dimKey, StorageCellModDimension.INSTANCE, extraData, true);
}
@Override
public void deleteCellDimension( int cellStorageId )
public void deleteCellDimension( DimensionType cellDim )
{
StorageCellData removed = this.spatialData.remove( cellStorageId );
if( removed != null )
{
this.clearCellArea( cellStorageId, removed );
AELog.info("Unregistering storage cell dimension %s", cellDim.getRegistryName());
MinecraftServer server = getServer();
ServerWorld world = DimensionManager.getWorld(server, cellDim, false, false);
if (world != null) {
DimensionManager.unloadWorld(world);
}
DimensionManager.unloadWorlds(server, true);
DimensionManager.unregisterDimension(cellDim.getId());
}
private static MinecraftServer getServer() {
return ServerLifecycleHooks.getCurrentServer();
}
@Override
public boolean isCellDimension( int cellStorageId )
public boolean isCellDimension( DimensionType cellDim )
{
return this.spatialData.containsKey( cellStorageId );
}
@Override
public int getCellDimensionOwner( int cellStorageId )
{
StorageCellData cell = this.spatialData.get( cellStorageId );
if( cell != null )
{
return cell.owner;
// Check if the cell dimension type is even registered
if (cellDim.getRegistryName() == null || !cellDim.getRegistryName().equals(DimensionType.getKey(cellDim))) {
return false;
}
return -1;
return cellDim.getModType() instanceof StorageCellModDimension;
}
@Override
public BlockPos getCellDimensionOrigin( int cellStorageId )
public int getCellDimensionOwner( DimensionType cellDim )
{
if( this.isCellDimension( cellStorageId ) )
{
return this.getBlockPosFromId( cellStorageId );
if (!(cellDim.getModType() instanceof StorageCellModDimension)) {
return -1;
}
return null;
PacketBuffer data = cellDim.getData();
if (data == null) {
return -1;
}
data.readerIndex(0);
return data.readInt();
}
@Override
public BlockPos getCellContentSize( int cellStorageId )
public BlockPos getCellDimensionOrigin( DimensionType cellDim )
{
StorageCellData cell = this.spatialData.get( cellStorageId );
if( cell != null )
{
return cell.contentDimension;
}
return null;
}
@SuppressWarnings("unchecked")
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap) {
if( cap == Capabilities.SPATIAL_DIMENSION )
{
return LazyOptional.of(() -> (T) this);
}
return LazyOptional.empty();
}
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
return getCapability(cap);
// 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);
}
@Override
public CompoundNBT serializeNBT()
public BlockPos getCellContentSize( DimensionType cellDim )
{
final CompoundNBT ret = new CompoundNBT();
final ListNBT list = new ListNBT();
for( Map.Entry<Integer, StorageCellData> entry : this.spatialData.entrySet() )
{
final CompoundNBT nbt = entry.getValue().serializeNBT();
nbt.putInt( NBT_SPATIAL_ID_KEY, entry.getKey() );
list.add( nbt );
if (!(cellDim.getModType() instanceof StorageCellModDimension)) {
return BlockPos.ZERO;
}
ret.put( NBT_SPATIAL_DATA_KEY, list );
return ret;
}
@Override
public void deserializeNBT( CompoundNBT nbt )
{
if( nbt.contains(NBT_SPATIAL_DATA_KEY) )
{
final ListNBT list = (ListNBT) nbt.get( NBT_SPATIAL_DATA_KEY );
this.spatialData.clear();
for( int i = 0; i < list.size(); ++i )
{
final CompoundNBT entry = list.getCompound( i );
final StorageCellData data = new StorageCellData();
final int id = entry.getInt( NBT_SPATIAL_ID_KEY );
data.deserializeNBT( entry );
this.spatialData.put( id, data );
}
PacketBuffer data = cellDim.getData();
if (data == null) {
return BlockPos.ZERO;
}
}
private int getNextId()
{
return this.spatialData.keySet().stream().max( Integer::compare ).orElse( -1 ) + 1;
data.readerIndex(4);
return data.readBlockPos();
}
private BlockPos getBlockPosFromId( int id )
@@ -214,11 +176,6 @@ public class SpatialDimensionManager implements ISpatialDimension, ICapabilitySe
return new BlockPos( posx, 64, posz );
}
private void clearCellArea( int cellId, StorageCellData cell )
{
// TODO reset chunks?
}
private static class StorageCellData implements INBTSerializable<CompoundNBT>
{
private static final String NBT_OWNER_KEY = "owner";
@@ -21,12 +21,18 @@ package appeng.items.storage;
import java.util.List;
import appeng.core.AELog;
import appeng.core.worlddata.SpatialDimensionManager;
import appeng.spatial.StorageHelper;
import javafx.animation.Transition;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.World;
import net.minecraft.world.dimension.DimensionType;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@@ -54,7 +60,6 @@ public class ItemSpatialStorageCell extends AEBaseItem implements ISpatialStorag
public ItemSpatialStorageCell( Properties props, final int spatialScale )
{
super(props);
// FIXME this.setMaxStackSize( 1 );
this.maxRegion = spatialScale;
}
@@ -62,10 +67,10 @@ public class ItemSpatialStorageCell extends AEBaseItem implements ISpatialStorag
@Override
public void addInformation(final ItemStack stack, final World world, final List<ITextComponent> lines, final ITooltipFlag advancedTooltips )
{
final int id = this.getStoredDimensionID( stack );
if( id >= 0 )
final DimensionType dimType = this.getStoredDimension( stack );
if( dimType != null )
{
lines.add( GuiText.CellId.textComponent().appendText( ": " + id ) );
lines.add( GuiText.CellId.textComponent().appendText( ": " + dimType.getRegistryName() ) );
}
final WorldCoord wc = this.getStoredSize( stack );
@@ -87,46 +92,31 @@ public class ItemSpatialStorageCell extends AEBaseItem implements ISpatialStorag
return this.maxRegion;
}
@Override
public ISpatialDimension getSpatialDimension()
{
World w = null;
// FIXME final int id = AppEng.instance().getStorageDimensionID();
// FIXME World w = DimensionManager.getWorld( id );
// FIXME if( w == null )
// FIXME {
// FIXME DimensionManager.initDimension( id );
// FIXME w = DimensionManager.getWorld( id );
// FIXME }
if( w != null )
{
LazyOptional<ISpatialDimension> spatialCap = w.getCapability(Capabilities.SPATIAL_DIMENSION, null);
return spatialCap.orElse(null);
}
return null;
}
@Override
public WorldCoord getStoredSize( final ItemStack is )
{
if( is.hasTag() )
final CompoundNBT c = is.getTag();
if( c != null )
{
final CompoundNBT c = is.getTag();
return new WorldCoord( c.getInt( NBT_SIZE_X_KEY ), c.getInt( NBT_SIZE_Y_KEY ), c.getInt( NBT_SIZE_Z_KEY ) );
}
return new WorldCoord( 0, 0, 0 );
}
@Override
public int getStoredDimensionID( final ItemStack is )
public DimensionType getStoredDimension(final ItemStack is )
{
if( is.hasTag() )
final CompoundNBT c = is.getTag();
if( c != null && c.contains(NBT_CELL_ID_KEY) )
{
final CompoundNBT c = is.getTag();
return c.getInt( NBT_CELL_ID_KEY );
try {
ResourceLocation dimTypeId = new ResourceLocation(c.getString( NBT_CELL_ID_KEY) );
return DimensionType.byName(dimTypeId);
} catch (Exception e) {
AELog.warn("Failed to retrieve storage cell dimension.", e);
}
}
return -1;
return null;
}
@Override
@@ -139,31 +129,38 @@ public class ItemSpatialStorageCell extends AEBaseItem implements ISpatialStorag
final BlockPos targetSize = new BlockPos( targetX, targetY, targetZ );
ISpatialDimension manager = this.getSpatialDimension();
ISpatialDimension manager = new SpatialDimensionManager();
int cellid = this.getStoredDimensionID( is );
if( cellid < 0 )
DimensionType storedDim = this.getStoredDimension( is );
if( storedDim == null )
{
cellid = manager.createNewCellDimension( targetSize, playerId );
storedDim = manager.createNewCellDimension( targetSize, playerId );
}
if (storedDim == null) {
// Failed to create the dimension
return new TransitionResult(false, 0);
}
try
{
if( manager.isCellDimension( cellid ) )
if( manager.isCellDimension( storedDim ) )
{
BlockPos scale = manager.getCellContentSize( cellid );
World cellWorld = manager.getWorld(storedDim);
BlockPos scale = manager.getCellContentSize( storedDim );
if( scale.equals( targetSize ) )
{
if( targetX <= maxSize && targetY <= maxSize && targetZ <= maxSize )
{
BlockPos offset = manager.getCellDimensionOrigin( cellid );
BlockPos offset = manager.getCellDimensionOrigin( storedDim );
this.setStorageCell( is, cellid, targetSize );
// FIXME StorageHelper.getInstance()
// FIXME .swapRegions( w, min.x + 1, min.y + 1, min.z + 1, manager.getWorld(), offset.getX(), offset.getY(),
// FIXME offset.getZ(), targetX - 1, targetY - 1,
// FIXME targetZ - 1 );
this.setStorageCell( is, storedDim, targetSize );
StorageHelper.getInstance()
.swapRegions( w, min.x + 1, min.y + 1, min.z + 1, cellWorld, offset.getX(), offset.getY(),
offset.getZ(), targetX - 1, targetY - 1,
targetZ - 1 );
return new TransitionResult( true, 0 );
}
@@ -174,18 +171,18 @@ public class ItemSpatialStorageCell extends AEBaseItem implements ISpatialStorag
finally
{
// clean up newly created dimensions that failed transfer
if( manager.isCellDimension( cellid ) && this.getStoredDimensionID( is ) < 0 )
if( manager.isCellDimension( storedDim ) && this.getStoredDimension( is ) == null )
{
manager.deleteCellDimension( cellid );
manager.deleteCellDimension( storedDim );
}
}
}
private void setStorageCell( final ItemStack is, int id, BlockPos size )
private void setStorageCell( final ItemStack is, DimensionType dim, BlockPos size )
{
final CompoundNBT c = is.getOrCreateTag();
c.putInt( NBT_CELL_ID_KEY, id );
c.putString( NBT_CELL_ID_KEY, dim.getRegistryName().toString() );
c.putInt( NBT_SIZE_X_KEY, size.getX() );
c.putInt( NBT_SIZE_Y_KEY, size.getY() );
c.putInt( NBT_SIZE_Z_KEY, size.getZ() );
+51 -52
View File
@@ -20,19 +20,19 @@ package appeng.spatial;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.network.play.server.SChunkDataPacket;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.ITickList;
import net.minecraft.world.NextTickListEntry;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import appeng.api.AEApi;
import appeng.api.movable.IMovableHandler;
@@ -42,6 +42,9 @@ import appeng.api.util.WorldCoord;
import appeng.core.AELog;
import appeng.core.worlddata.WorldData;
import appeng.util.Platform;
import net.minecraft.world.chunk.ChunkSection;
import net.minecraft.world.server.ServerChunkProvider;
import net.minecraft.world.server.ServerTickList;
public class CachedPlane
@@ -57,7 +60,7 @@ public class CachedPlane
private final Chunk[][] myChunks;
private final Column[][] myColumns;
private final List<TileEntity> tiles = new ArrayList<>();
private final List<NextTickListEntry> ticks = new ArrayList<>();
private final List<NextTickListEntry<Block>> ticks = new ArrayList<>();
private final World world;
private final IMovableRegistry reg = AEApi.instance().registries().movable();
private final List<WorldCoord> updates = new ArrayList<>();
@@ -121,13 +124,12 @@ public class CachedPlane
{
for( int cz = 0; cz < this.cz_size; cz++ )
{
final List<Entry<BlockPos, TileEntity>> rawTiles = new ArrayList<>();
final List<BlockPos> deadTiles = new ArrayList<>();
final Chunk c = w.getChunk( minCX + cx, minCZ + cz );
this.myChunks[cx][cz] = c;
rawTiles.addAll( ( (HashMap<BlockPos, TileEntity>) c.getTileEntityMap() ).entrySet() );
final List<Entry<BlockPos, TileEntity>> rawTiles = new ArrayList<>(c.getTileEntityMap().entrySet());
for( final Entry<BlockPos, TileEntity> tx : rawTiles )
{
final BlockPos cp = tx.getKey();
@@ -165,19 +167,15 @@ public class CachedPlane
c.getTileEntityMap().remove( cp );
}
final long k = this.getWorld().getGameTime();
final List<NextTickListEntry> list = this.getWorld().getPendingBlockUpdates( c, false );
if( list != null )
{
for( final NextTickListEntry entry : list )
{
final long gameTime = this.getWorld().getGameTime();
final ITickList<Block> pendingBlockTicks = this.getWorld().getPendingBlockTicks();
if (pendingBlockTicks instanceof ServerTickList) {
List<NextTickListEntry<Block>> pending = ((ServerTickList<Block>) pendingBlockTicks).getPending(c.getPos(), false, true);
for (final NextTickListEntry<Block> entry : pending) {
final BlockPos tePOS = entry.position;
if( tePOS.getX() >= minX && tePOS.getX() <= maxX && tePOS.getY() >= minY && tePOS.getY() <= maxY && tePOS.getZ() >= minZ && tePOS
.getZ() <= maxZ )
{
final NextTickListEntry newEntry = new NextTickListEntry( tePOS, entry.getBlock() );
newEntry.scheduledTime = entry.scheduledTime - k;
this.ticks.add( newEntry );
if (tePOS.getX() >= minX && tePOS.getX() <= maxX && tePOS.getY() >= minY && tePOS.getY() <= maxY && tePOS.getZ() >= minZ && tePOS
.getZ() <= maxZ) {
this.ticks.add(new NextTickListEntry<>(tePOS, entry.getTarget(), entry.scheduledTime - gameTime, entry.priority));
}
}
}
@@ -236,8 +234,8 @@ public class CachedPlane
a.fillData( src_y, aD );
b.fillData( dst_y, bD );
a.setBlockIDWithMetadata( src_y, bD );
b.setBlockIDWithMetadata( dst_y, aD );
a.setBlockState( src_y, bD );
b.setBlockState( dst_y, aD );
}
else
{
@@ -264,13 +262,13 @@ public class CachedPlane
this.addTile( tePOS.getX() - dst.x_offset, tePOS.getY() - dst.y_offset, tePOS.getZ() - dst.z_offset, te, dst, mr );
}
for( final NextTickListEntry entry : this.ticks )
for( final NextTickListEntry<Block> entry : this.ticks )
{
final BlockPos tePOS = entry.position;
dst.addTick( tePOS.getX() - this.x_offset, tePOS.getY() - this.y_offset, tePOS.getZ() - this.z_offset, entry );
}
for( final NextTickListEntry entry : dst.ticks )
for( final NextTickListEntry<Block> entry : dst.ticks )
{
final BlockPos tePOS = entry.position;
this.addTick( tePOS.getX() - dst.x_offset, tePOS.getY() - dst.y_offset, tePOS.getZ() - dst.z_offset, entry );
@@ -295,9 +293,10 @@ public class CachedPlane
}
}
private void addTick( final int x, final int y, final int z, final NextTickListEntry entry )
private void addTick( final int x, final int y, final int z, final NextTickListEntry<Block> entry )
{
this.world.scheduleUpdate( new BlockPos( x + this.x_offset, y + this.y_offset, z + this.z_offset ), entry.getBlock(), (int) entry.scheduledTime );
BlockPos where = new BlockPos(x + this.x_offset, y + this.y_offset, z + this.z_offset);
this.world.getPendingBlockTicks().scheduleTick(where, entry.getTarget(), (int) entry.scheduledTime, entry.priority);
}
private void addTile( final int x, final int y, final int z, final TileEntity te, final CachedPlane alternateDestination, final IMovableRegistry mr )
@@ -321,16 +320,9 @@ public class CachedPlane
final BlockPos pos = new BlockPos( x, y, z );
// attempt recovery...
te.setWorld( this.world );
te.setPos( pos );
c.c.addTileEntity( new BlockPos( c.x, y + y, c.z ), te );
// c.c.setChunkTileEntity( c.x, y + y, c.z, te );
c.c.addTileEntity(te);
if( c.c.isLoaded() )
{
this.world.addTileEntity( te );
this.world.notifyBlockUpdate( pos, this.world.getBlockState( pos ), this.world.getBlockState( pos ), z );
}
this.world.notifyBlockUpdate( pos, this.world.getBlockState( pos ), this.world.getBlockState( pos ), z );
}
mr.doneMoving( te );
@@ -355,9 +347,8 @@ public class CachedPlane
for( int z = 0; z < this.cz_size; z++ )
{
final Chunk c = this.myChunks[x][z];
c.resetRelightChecks();
c.generateSkylightMap();
c.setModified( true );
// FIXME: Light shit
c.markDirty();
}
}
@@ -371,12 +362,20 @@ public class CachedPlane
for( int y = 1; y < 255; y += 32 )
{
WorldData.instance().compassData().service().updateArea( this.getWorld(), c.x << 4, y, c.z << 4 );
WorldData.instance().compassData().service().updateArea( this.getWorld(), c.getPos().x << 4, y, c.getPos().z << 4 );
}
Platform.sendChunk( c, this.verticalBits );
// FIXME this was sending chunks to players...
SChunkDataPacket cdp = new SChunkDataPacket(c, verticalBits);
((ServerChunkProvider) world.getChunkProvider()).chunkManager.getTrackingPlayers(c.getPos(), false)
.forEach(spe -> spe.connection.sendPacket(cdp));
}
}
// FIXME check if this makes any sense at all to send changes to players asap
ServerChunkProvider serverChunkProvider = (ServerChunkProvider) world.getChunkProvider();
serverChunkProvider.tick(() -> false);
}
List<WorldCoord> getUpdates()
@@ -408,46 +407,46 @@ public class CachedPlane
this.z = z;
this.c = chunk;
final ExtendedBlockStorage[] storage = this.c.getBlockStorageArray();
final ChunkSection[] storage = this.c.getSections();
// make sure storage exists before hand...
for( int ay = 0; ay < chunkHeight; ay++ )
{
final int by = ( ay + chunkY );
ExtendedBlockStorage extendedblockstorage = storage[by];
ChunkSection extendedblockstorage = storage[by];
if( extendedblockstorage == null )
{
extendedblockstorage = storage[by] = new ExtendedBlockStorage( by << 4, this.c.getWorld().provider.hasSkyLight() );
extendedblockstorage = storage[by] = new ChunkSection( by << 4 );
}
}
}
private void setBlockIDWithMetadata( final int y, BlockStorageData data )
private void setBlockState(final int y, BlockStorageData data )
{
if( data.state == CachedPlane.this.matrixBlockState )
{
data.state = Platform.AIR_BLOCK.getDefaultState();
}
final ExtendedBlockStorage[] storage = this.c.getBlockStorageArray();
final ExtendedBlockStorage extendedBlockStorage = storage[y >> 4];
extendedBlockStorage.set( this.x, y & 15, this.z, data.state );
extendedBlockStorage.setBlockLight( this.x, y & 15, this.z, data.light );
final ChunkSection[] storage = this.c.getSections();
final ChunkSection extendedBlockStorage = storage[y >> 4];
extendedBlockStorage.setBlockState( this.x, y & 15, this.z, data.state );
// FIXME extendedBlockStorage.setBlockLight( this.x, y & 15, this.z, data.light );
}
private void fillData( final int y, BlockStorageData data )
{
final ExtendedBlockStorage[] storage = this.c.getBlockStorageArray();
final ExtendedBlockStorage extendedblockstorage = storage[y >> 4];
final ChunkSection[] storage = this.c.getSections();
final ChunkSection extendedblockstorage = storage[y >> 4];
data.state = extendedblockstorage.get( this.x, y & 15, this.z );
data.light = extendedblockstorage.getBlockLight( this.x, y & 15, this.z );
data.state = extendedblockstorage.getBlockState( this.x, y & 15, this.z );
// FIXME data.light = extendedblockstorage.getBlockLight( this.x, y & 15, this.z );
}
private boolean doNotSkip( final int y )
{
final ExtendedBlockStorage[] storage = this.c.getBlockStorageArray();
final ExtendedBlockStorage extendedblockstorage = storage[y >> 4];
if( CachedPlane.this.reg.isBlacklisted( extendedblockstorage.get( this.x, y & 15, this.z ).getBlock() ) )
final ChunkSection[] storage = this.c.getSections();
final ChunkSection extendedblockstorage = storage[y >> 4];
if( CachedPlane.this.reg.isBlacklisted( extendedblockstorage.getBlockState( this.x, y & 15, this.z ).getBlock() ) )
{
return false;
}
@@ -19,17 +19,37 @@
package appeng.spatial;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorldReader;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class BiomeGenStorage extends Biome
public class StorageCellBiome extends Biome
{
public BiomeGenStorage()
public static final StorageCellBiome INSTANCE = new StorageCellBiome();
static {
INSTANCE.setRegistryName("appliedenergistics2:storage");
}
public StorageCellBiome()
{
super( new Biome.Builder().precipitation(RainType.NONE).temperature(-100).parent(null) );
super( new Biome.Builder()
.surfaceBuilder(SurfaceBuilder.NOPE, SurfaceBuilder.STONE_STONE_GRAVEL_CONFIG)
.precipitation(RainType.NONE)
.category(Category.NONE)
.depth(0)
.scale(1)
// Copied from the vanilla void biome
.temperature(0.5F)
.downfall(0.5F)
.waterColor(4159204)
.waterFogColor(329011)
.parent(null) );
// FIXME this.decorator.treesPerChunk = 0;
// FIXME this.decorator.flowersPerChunk = 0;
// FIXME this.decorator.grassPerChunk = 0;
@@ -42,7 +62,22 @@ public class BiomeGenStorage extends Biome
@OnlyIn(Dist.CLIENT)
public int getSkyColor() {
return 0;
return 0x111111;
}
@Override
public boolean doesWaterFreeze(IWorldReader worldIn, BlockPos pos) {
return false;
}
@Override
public boolean doesWaterFreeze(IWorldReader worldIn, BlockPos water, boolean mustBeAtEdge) {
return false;
}
@Override
public boolean doesSnowGenerate(IWorldReader worldIn, BlockPos pos) {
return false;
}
}
@@ -19,9 +19,10 @@
package appeng.spatial;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.dimension.Dimension;
@@ -34,23 +35,21 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.client.render.SpatialSkyRender;
import appeng.core.AppEng;
import javax.annotation.Nullable;
// FIXME: Rename suffix to Dimension
public class StorageWorldProvider extends Dimension
public class StorageCellDimension extends Dimension
{
private final Biome biome;
public StorageWorldProvider()
{
this.hasSkyLight = true;
this.biome = AppEng.instance().getStorageBiome();
this.biomeProvider = new BiomeProviderSingle( this.biome );
public StorageCellDimension(World world, DimensionType dimensionType) {
// FIXME: check light value
super(world, dimensionType, 1.0f);
}
@Override
public ChunkGenerator createChunkGenerator()
{
return new StorageChunkProvider( this.world, 0 );
return new StorageChunkGenerator( this.world );
}
@Override
@@ -97,12 +96,6 @@ public class StorageWorldProvider extends Dimension
return false;
}
@Override
public DimensionType getDimensionType()
{
return AppEng.instance().getStorageDimensionType();
}
@Override
public IRenderHandler getSkyRenderer()
{
@@ -115,24 +108,6 @@ public class StorageWorldProvider extends Dimension
return false;
}
@Override
public Vec3d getSkyColor( final Entity cameraEntity, final float partialTicks )
{
return new Vec3d( 0.07, 0.07, 0.07 );
}
@Override
public float getStarBrightness( final float par1 )
{
return 0;
}
@Override
public boolean canSnowAt( final BlockPos pos, final boolean checkLight )
{
return false;
}
@Override
public BlockPos getSpawnCoordinate()
{
@@ -140,7 +115,7 @@ public class StorageWorldProvider extends Dimension
}
@Override
public boolean isBlockHighHumidity( final BlockPos pos )
public boolean isHighHumidity( final BlockPos pos )
{
return false;
}
@@ -152,9 +127,20 @@ public class StorageWorldProvider extends Dimension
}
@Override
public Biome getBiomeForCoords( BlockPos pos )
{
return this.biome;
public boolean canDoRainSnowIce(Chunk chunk) {
return false;
}
@Nullable
@Override
public BlockPos findSpawn(ChunkPos chunkPosIn, boolean checkValid) {
return getSpawnCoordinate();
}
@Nullable
@Override
public BlockPos findSpawn(int posX, int posZ, boolean checkValid) {
return getSpawnCoordinate();
}
}
@@ -0,0 +1,65 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.spatial;
import appeng.client.render.SpatialSkyRender;
import appeng.core.AppEng;
import net.minecraft.entity.Entity;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.dimension.Dimension;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.gen.ChunkGenerator;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.IRenderHandler;
import net.minecraftforge.common.ModDimension;
import java.util.function.BiFunction;
public class StorageCellModDimension extends ModDimension
{
public static final StorageCellModDimension INSTANCE = new StorageCellModDimension();
static {
INSTANCE.setRegistryName(AppEng.MOD_ID, "storage_cell");
}
@Override
public BiFunction<World, DimensionType, ? extends Dimension> getFactory() {
return StorageCellDimension::new;
}
@Override
public void write(PacketBuffer buffer, boolean network) {
super.write(buffer, network);
}
@Override
public void read(PacketBuffer buffer, boolean network) {
super.read(buffer, network);
}
}
@@ -0,0 +1,104 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.spatial;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
import net.minecraft.world.biome.provider.BiomeProvider;
import net.minecraft.world.biome.provider.SingleBiomeProvider;
import net.minecraft.world.biome.provider.SingleBiomeProviderSettings;
import net.minecraft.world.chunk.IChunk;
import net.minecraft.world.gen.ChunkGenerator;
import appeng.api.AEApi;
import net.minecraft.world.gen.GenerationSettings;
import net.minecraft.world.gen.Heightmap;
import net.minecraft.world.gen.WorldGenRegion;
public class StorageChunkGenerator extends ChunkGenerator<GenerationSettings>
{
private final BlockState defaultBlockState;
public StorageChunkGenerator(final World world )
{
super( world, createBiomeProvider(), createSettings() );
this.defaultBlockState = AEApi.instance().definitions().blocks().matrixFrame().block().getDefaultState();
}
private static BiomeProvider createBiomeProvider() {
SingleBiomeProviderSettings biomeSettings = new SingleBiomeProviderSettings(null);
biomeSettings.setBiome(StorageCellBiome.INSTANCE);
return new SingleBiomeProvider(biomeSettings);
}
private static GenerationSettings createSettings() {
return new GenerationSettings();
}
@Override
public void generateSurface(WorldGenRegion region, IChunk chunk) {
this.fillChunk( chunk );
chunk.setModified( false );
}
private void fillChunk( IChunk chunk )
{
BlockPos.Mutable mutPos = new BlockPos.Mutable();
for( int cx = 0; cx < 16; cx++ )
{
mutPos.setX(cx);
for( int cz = 0; cz < 16; cz++ )
{
// FIXME: It's likely a bad idea to fill Y in the inner-loop given the storage layout of chunks
mutPos.setZ(cz);
for( int cy = 0; cy < 256; cy++ )
{
mutPos.setY(cy);
chunk.setBlockState(mutPos, defaultBlockState, false);
}
}
}
}
@Override
public int getGroundHeight() {
return 0;
}
@Override
public void makeBase(IWorld worldIn, IChunk chunkIn) {
}
@Override
public int func_222529_a(int p_222529_1_, int p_222529_2_, Heightmap.Type heightmapType) {
return 0;
}
@Override
public void decorate(WorldGenRegion region) {
// Do not decorate chunks at all
}
}
@@ -1,118 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.spatial;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.block.BlockState;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.gen.ChunkGeneratorOverworld;
import appeng.api.AEApi;
import appeng.core.AppEng;
public class StorageChunkProvider extends ChunkGeneratorOverworld
{
private final World world;
public StorageChunkProvider( final World world, final long i )
{
super( world, i, false, null );
this.world = world;
}
@Override
public Chunk generateChunk( final int x, final int z )
{
final Chunk chunk = new Chunk( this.world, x, z );
final byte[] biomes = chunk.getBiomeArray();
Biome biome = AppEng.instance().getStorageBiome();
byte biomeId = (byte) Biome.getIdForBiome( biome );
for( int k = 0; k < biomes.length; ++k )
{
biomes[k] = biomeId;
}
AEApi.instance().definitions().blocks().matrixFrame().maybeBlock().ifPresent( block -> this.fillChunk( chunk, block.getDefaultState() ) );
chunk.setModified( false );
if( !chunk.isTerrainPopulated() )
{
chunk.setTerrainPopulated( true );
chunk.resetRelightChecks();
}
return chunk;
}
private void fillChunk( Chunk chunk, BlockState defaultState )
{
for( int cx = 0; cx < 16; cx++ )
{
for( int cz = 0; cz < 16; cz++ )
{
for( int cy = 0; cy < 256; cy++ )
{
chunk.setBlockState( new BlockPos( cx, cy, cz ), defaultState );
}
}
}
}
@Override
public void populate( final int par2, final int par3 )
{
}
@Override
public List getPossibleCreatures( final EnumCreatureType creatureType, final BlockPos pos )
{
return new ArrayList();
}
@Override
public boolean generateStructures( Chunk chunkIn, int x, int z )
{
return false;
}
@Override
public BlockPos getNearestStructurePos( World worldIn, String structureName, BlockPos position, boolean p_180513_4_ )
{
return null;
}
@Override
public void recreateStructures( Chunk chunkIn, int x, int z )
{
}
}
+21 -29
View File
@@ -21,6 +21,7 @@ package appeng.spatial;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
@@ -30,7 +31,7 @@ import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.ServerWorld;
import net.minecraft.world.chunk.ChunkStatus;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.util.ITeleporter;
@@ -91,37 +92,34 @@ public class StorageHelper
}
// Are we riding something? Teleport it instead.
if( entity.isRiding() )
if( entity.isPassenger() )
{
return this.teleportEntity( entity.getRidingEntity(), link );
}
// Is something riding us? Handle it first.
final List<Entity> passangers = entity.getPassengers();
final List<Entity> passangersOnOtherSide = new ArrayList<>();
if( !passangers.isEmpty() )
final List<Entity> passengers = entity.getPassengers();
final List<Entity> passengersOnOtherSide = new ArrayList<>(passengers.size());
for( Entity passenger : passengers )
{
for( Entity passanger : passangers )
{
passanger.dismountRidingEntity();
passangersOnOtherSide.add( this.teleportEntity( passanger, link ) );
}
// We keep track of all so we can remount them on the other side.
passenger.stopRiding();
passengersOnOtherSide.add( this.teleportEntity( passenger, link ) );
}
// We keep track of all so we can remount them on the other side.
// load the chunk!
newWorld.getChunkProvider().provideChunk( MathHelper.floor( link.x ) >> 4, MathHelper.floor( link.z ) >> 4 );
newWorld.getChunkProvider().getChunk( MathHelper.floor( link.x ) >> 4, MathHelper.floor( link.z ) >> 4, ChunkStatus.FULL, true );
if( entity instanceof ServerPlayerEntity && link.dim.provider instanceof StorageWorldProvider )
if( entity instanceof ServerPlayerEntity && link.dim.getDimension() instanceof StorageCellDimension)
{
AppEng.instance().getAdvancementTriggers().getSpatialExplorer().trigger( (ServerPlayerEntity) entity );
}
entity.changeDimension( link.dim.getDimension().getType(), new METeleporter( link ) );
if( !passangersOnOtherSide.isEmpty() )
if( !passengersOnOtherSide.isEmpty() )
{
for( Entity passanger : passangersOnOtherSide )
for( Entity passanger : passengersOnOtherSide )
{
passanger.startRiding( entity, true );
}
@@ -195,12 +193,12 @@ public class StorageHelper
for( final WorldCoord wc : cDst.getUpdates() )
{
cSrc.getWorld().notifyNeighborsOfStateChange( wc.getPos(), Platform.AIR_BLOCK, true );
cSrc.getWorld().notifyNeighborsOfStateChange( wc.getPos(), Platform.AIR_BLOCK );
}
for( final WorldCoord wc : cSrc.getUpdates() )
{
cSrc.getWorld().notifyNeighborsOfStateChange( wc.getPos(), Platform.AIR_BLOCK, true );
cSrc.getWorld().notifyNeighborsOfStateChange( wc.getPos(), Platform.AIR_BLOCK );
}
this.transverseEdges( srcX - 1, srcY - 1, srcZ - 1, srcX + scaleX + 1, srcY + scaleY + 1, srcZ + scaleZ + 1, new TriggerUpdates( srcWorld ) );
@@ -208,14 +206,6 @@ public class StorageHelper
this.transverseEdges( srcX, srcY, srcZ, srcX + scaleX, srcY + scaleY, srcZ + scaleZ, new TriggerUpdates( srcWorld ) );
this.transverseEdges( dstX, dstY, dstZ, dstX + scaleX, dstY + scaleY, dstZ + scaleZ, new TriggerUpdates( dstWorld ) );
/*
* IChunkProvider cp = destination.getChunkProvider(); if ( cp instanceof ChunkProviderServer ) {
* ChunkProviderServer
* srv = (ChunkProviderServer) cp; srv.unloadAllChunks(); }
* cp.unloadQueuedChunks();
*/
}
private static class TriggerUpdates implements ISpatialVisitor
@@ -283,10 +273,12 @@ public class StorageHelper
}
@Override
public void placeEntity( World world, Entity entity, float yaw )
{
entity.setLocationAndAngles( this.destination.x, this.destination.y, this.destination.z, yaw, entity.rotationPitch );
entity.motionX = entity.motionY = entity.motionZ = 0.0D;
public Entity placeEntity(Entity entity, ServerWorld currentWorld, ServerWorld destWorld, float yaw, Function<Boolean, Entity> repositionEntity) {
Entity newEntity = repositionEntity.apply(false);
newEntity.rotationYaw = yaw;
newEntity.setPositionAndUpdate( this.destination.x, this.destination.y, this.destination.z );
newEntity.setMotion(0, 0, 0);
return newEntity;
}
}
}
+5 -20
View File
@@ -73,6 +73,7 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.network.play.server.SChunkDataPacket;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
@@ -82,6 +83,7 @@ import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@@ -89,6 +91,8 @@ import net.minecraftforge.common.util.FakePlayerFactory;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fml.common.thread.SidedThreadGroups;
import net.minecraftforge.fml.loading.FMLEnvironment;
import net.minecraftforge.fml.network.FMLNetworkConstants;
import net.minecraftforge.fml.network.NetworkDirection;
import net.minecraftforge.fml.network.NetworkHooks;
import net.minecraftforge.registries.ForgeRegistries;
@@ -1528,26 +1532,7 @@ public class Platform
//
// return Lists.newArrayList( is );
// }
//
// public static void sendChunk( final Chunk c, final int verticalBits )
// {
// try
// {
// // FIXME final ServerWorld ws = (ServerWorld) c.getWorld();
// // FIXME final PlayerChunkMap pm = ws.getPlayerChunkMap();
// // FIXME final PlayerChunkMapEntry playerInstance = pm.getEntry( c.x, c.z );
//// FIXME
// // FIXME if( playerInstance != null )
// // FIXME {
// // FIXME playerInstance.sendPacket( new SChunkDataPacket( c, verticalBits ) );
// // FIXME }
// }
// catch( final Throwable t )
// {
// AELog.debug( t );
// }
// }
//
public static float getEyeOffset( final PlayerEntity player )
{
assert player.world.isRemote : "Valid only on client";