Working on Spatial Stuff.
This commit is contained in:
@@ -26,6 +26,7 @@ package appeng.api.implementations.items;
|
|||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.util.registry.RegistryKey;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.dimension.DimensionType;
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
|
|
||||||
@@ -58,7 +59,7 @@ public interface ISpatialStorageCell {
|
|||||||
*
|
*
|
||||||
* @return dimension id or -1
|
* @return dimension id or -1
|
||||||
*/
|
*/
|
||||||
DimensionType getStoredDimension(ItemStack is);
|
RegistryKey<World> getStoredDimension(ItemStack is);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform a spatial swap with the contents of the cell, and the world.
|
* Perform a spatial swap with the contents of the cell, and the world.
|
||||||
|
|||||||
@@ -24,27 +24,29 @@ import javax.annotation.Nullable;
|
|||||||
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.registry.RegistryKey;
|
||||||
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.dimension.DimensionType;
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
|
||||||
public interface ISpatialDimension {
|
public interface ISpatialDimension {
|
||||||
ServerWorld getWorld(DimensionType cellDim);
|
ServerWorld getWorld(RegistryKey<World> cellDim);
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
DimensionType createNewCellDimension(BlockPos capacity);
|
RegistryKey<World> createNewCellDimension(BlockPos capacity);
|
||||||
|
|
||||||
void deleteCellDimension(DimensionType cellDim);
|
void deleteCellDimension(RegistryKey<World> cellDim);
|
||||||
|
|
||||||
boolean isCellDimension(DimensionType cellDim);
|
boolean isCellDimension(RegistryKey<World> cellDim);
|
||||||
|
|
||||||
BlockPos getCellDimensionOrigin(DimensionType cellDim);
|
BlockPos getCellDimensionOrigin(RegistryKey<World> cellDim);
|
||||||
|
|
||||||
BlockPos getCellDimensionSize(DimensionType cellDim);
|
BlockPos getCellDimensionSize(RegistryKey<World> cellDim);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a user-facing tooltip that describes this dimension so that a player can
|
* Adds a user-facing tooltip that describes this dimension so that a player can
|
||||||
* keep storage cells apart.
|
* keep storage cells apart.
|
||||||
*/
|
*/
|
||||||
void addCellDimensionTooltip(DimensionType cellDim, List<Text> lines);
|
void addCellDimensionTooltip(RegistryKey<World> cellDim, List<Text> lines);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import appeng.client.render.SimpleModelLoader;
|
|||||||
import appeng.client.render.cablebus.CableBusModelLoader;
|
import appeng.client.render.cablebus.CableBusModelLoader;
|
||||||
import appeng.client.render.effects.*;
|
import appeng.client.render.effects.*;
|
||||||
import appeng.client.render.model.SkyCompassModel;
|
import appeng.client.render.model.SkyCompassModel;
|
||||||
|
import appeng.client.render.spatial.SpatialPylonModel;
|
||||||
import appeng.client.render.tesr.InscriberTESR;
|
import appeng.client.render.tesr.InscriberTESR;
|
||||||
import appeng.client.render.tesr.SkyChestTESR;
|
import appeng.client.render.tesr.SkyChestTESR;
|
||||||
import appeng.container.implementations.*;
|
import appeng.container.implementations.*;
|
||||||
@@ -245,7 +246,7 @@ public final class AppEngClient extends AppEngBase {
|
|||||||
// FIXME FABRIC addBuiltInModel("biometric_card", BiometricCardModel::new);
|
// FIXME FABRIC addBuiltInModel("biometric_card", BiometricCardModel::new);
|
||||||
// FIXME FABRIC addBuiltInModel("drive", DriveModel::new);
|
// FIXME FABRIC addBuiltInModel("drive", DriveModel::new);
|
||||||
// FIXME FABRIC addBuiltInModel("color_applicator", ColorApplicatorModel::new);
|
// FIXME FABRIC addBuiltInModel("color_applicator", ColorApplicatorModel::new);
|
||||||
// FIXME FABRIC addBuiltInModel("spatial_pylon", SpatialPylonModel::new);
|
addBuiltInModel("block/spatial_pylon", SpatialPylonModel::new);
|
||||||
// FIXME FABRIC addBuiltInModel("paint_splotches", PaintSplotchesModel::new);
|
// FIXME FABRIC addBuiltInModel("paint_splotches", PaintSplotchesModel::new);
|
||||||
// FIXME FABRIC addBuiltInModel("quantum_bridge_formed", QnbFormedModel::new);
|
// FIXME FABRIC addBuiltInModel("quantum_bridge_formed", QnbFormedModel::new);
|
||||||
// FIXME FABRIC addBuiltInModel("p2p_tunnel_frequency", P2PTunnelFrequencyModel::new);
|
// FIXME FABRIC addBuiltInModel("p2p_tunnel_frequency", P2PTunnelFrequencyModel::new);
|
||||||
|
|||||||
@@ -45,26 +45,26 @@ public class SpatialIOPortScreen extends AEBaseScreen<SpatialIOPortContainer> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawFG(MatrixStack matrices, final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
|
public void drawFG(MatrixStack matrices, final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
|
||||||
this.textRenderer.draw(matrices, GuiText.StoredPower.text() + ": "
|
this.textRenderer.draw(matrices, GuiText.StoredPower.withSuffix(": "
|
||||||
+ Platform.formatPowerLong(this.handler.getCurrentPower(), false), 13, 21, 4210752);
|
+ Platform.formatPowerLong(this.handler.getCurrentPower(), false)), 13, 21, 4210752);
|
||||||
this.textRenderer.draw(matrices,
|
this.textRenderer.draw(matrices,
|
||||||
GuiText.MaxPower.text() + ": " + Platform.formatPowerLong(this.handler.getMaxPower(), false), 13,
|
GuiText.MaxPower.withSuffix(": " + Platform.formatPowerLong(this.handler.getMaxPower(), false)), 13,
|
||||||
31, 4210752);
|
31, 4210752);
|
||||||
this.textRenderer.draw(matrices, GuiText.RequiredPower.text() + ": "
|
this.textRenderer.draw(matrices, GuiText.RequiredPower.withSuffix(": "
|
||||||
+ Platform.formatPowerLong(this.handler.getRequiredPower(), false), 13, 73, 4210752);
|
+ Platform.formatPowerLong(this.handler.getRequiredPower(), false)), 13, 73, 4210752);
|
||||||
this.textRenderer.draw(matrices,
|
this.textRenderer.draw(matrices,
|
||||||
GuiText.Efficiency.text() + ": " + (((float) this.handler.getEfficency()) / 100) + '%', 13, 83,
|
GuiText.Efficiency.withSuffix(": " + (((float) this.handler.getEfficency()) / 100) + '%'), 13, 83,
|
||||||
4210752);
|
4210752);
|
||||||
|
|
||||||
this.textRenderer.draw(matrices, this.getGuiDisplayName(GuiText.SpatialIOPort.text()), 8, 6, 4210752);
|
this.textRenderer.draw(matrices, this.getGuiDisplayName(GuiText.SpatialIOPort.text()), 8, 6, 4210752);
|
||||||
this.textRenderer.draw(matrices, GuiText.inventory.text(), 8, this.backgroundHeight - 96, 4210752);
|
this.textRenderer.draw(matrices, GuiText.inventory.text(), 8, this.backgroundHeight - 96, 4210752);
|
||||||
|
|
||||||
if (this.handler.xSize != 0 && this.handler.ySize != 0 && this.handler.zSize != 0) {
|
if (this.handler.xSize != 0 && this.handler.ySize != 0 && this.handler.zSize != 0) {
|
||||||
final String text = GuiText.SCSSize.text() + ": " + this.handler.xSize + "x" + this.handler.ySize
|
final Text text = GuiText.SCSSize.withSuffix(": " + this.handler.xSize + "x" + this.handler.ySize
|
||||||
+ "x" + this.handler.zSize;
|
+ "x" + this.handler.zSize);
|
||||||
this.textRenderer.draw(matrices, text, 13, 93, 4210752);
|
this.textRenderer.draw(matrices, text, 13, 93, 4210752);
|
||||||
} else {
|
} else {
|
||||||
this.textRenderer.draw(matrices, GuiText.SCSSize.text() + ": " + GuiText.SCSInvalid.text(), 13, 93, 4210752);
|
this.textRenderer.draw(matrices, GuiText.SCSSize.withSuffix(": ").append(GuiText.SCSInvalid.text()), 13, 93, 4210752);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import net.minecraft.client.util.SpriteIdentifier;
|
|||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -17,6 +18,11 @@ import java.util.stream.Stream;
|
|||||||
*/
|
*/
|
||||||
public interface BasicUnbakedModel extends UnbakedModel {
|
public interface BasicUnbakedModel extends UnbakedModel {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default Collection<Identifier> getModelDependencies() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
default Stream<SpriteIdentifier> getAdditionalTextures() {
|
default Stream<SpriteIdentifier> getAdditionalTextures() {
|
||||||
return Stream.empty();
|
return Stream.empty();
|
||||||
}
|
}
|
||||||
|
|||||||
+47
-12
@@ -18,21 +18,30 @@
|
|||||||
|
|
||||||
package appeng.client.render.spatial;
|
package appeng.client.render.spatial;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
|
||||||
|
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||||
|
import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachedBlockView;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.client.render.model.BakedModel;
|
||||||
import net.minecraft.client.render.model.BakedQuad;
|
import net.minecraft.client.render.model.BakedQuad;
|
||||||
import net.minecraft.client.render.model.json.ModelOverrideList;
|
import net.minecraft.client.render.model.json.ModelOverrideList;
|
||||||
|
import net.minecraft.client.render.model.json.ModelTransformation;
|
||||||
import net.minecraft.client.texture.Sprite;
|
import net.minecraft.client.texture.Sprite;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraftforge.client.model.data.IDynamicBakedModel;
|
import net.minecraft.world.BlockRenderView;
|
||||||
|
|
||||||
|
|
||||||
import appeng.client.render.cablebus.CubeBuilder;
|
import appeng.client.render.cablebus.CubeBuilder;
|
||||||
@@ -41,7 +50,7 @@ import appeng.tile.spatial.SpatialPylonBlockEntity;
|
|||||||
/**
|
/**
|
||||||
* The baked model that will be used for rendering the spatial pylon.
|
* The baked model that will be used for rendering the spatial pylon.
|
||||||
*/
|
*/
|
||||||
class SpatialPylonBakedModel implements IDynamicBakedModel {
|
class SpatialPylonBakedModel implements BakedModel, FabricBakedModel {
|
||||||
|
|
||||||
private final Map<SpatialPylonTextureType, Sprite> textures;
|
private final Map<SpatialPylonTextureType, Sprite> textures;
|
||||||
|
|
||||||
@@ -49,13 +58,16 @@ class SpatialPylonBakedModel implements IDynamicBakedModel {
|
|||||||
this.textures = ImmutableMap.copyOf(textures);
|
this.textures = ImmutableMap.copyOf(textures);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
@Override
|
||||||
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand,
|
public boolean isVanillaAdapter() {
|
||||||
@Nonnull IModelData extraData) {
|
return false;
|
||||||
int flags = this.getFlags(extraData);
|
}
|
||||||
|
|
||||||
CubeBuilder builder = new CubeBuilder();
|
@Override
|
||||||
|
public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
|
||||||
|
int flags = getFlags(blockView, pos);
|
||||||
|
|
||||||
|
CubeBuilder builder = new CubeBuilder(context.getEmitter());
|
||||||
|
|
||||||
if (flags != 0) {
|
if (flags != 0) {
|
||||||
Direction ori = null;
|
Direction ori = null;
|
||||||
@@ -134,13 +146,31 @@ class SpatialPylonBakedModel implements IDynamicBakedModel {
|
|||||||
builder.setTexture(this.textures.get(SpatialPylonTextureType.DIM));
|
builder.setTexture(this.textures.get(SpatialPylonTextureType.DIM));
|
||||||
builder.addCube(0, 0, 0, 16, 16, 16);
|
builder.addCube(0, 0, 0, 16, 16, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.getOutput();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getFlags(IModelData modelData) {
|
@Override
|
||||||
Integer flags = modelData.getData(SpatialPylonBlockEntity.STATE);
|
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) {
|
||||||
return flags != null ? flags : 0;
|
// Not intended to be used as an item model.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand) {
|
||||||
|
// Can only sensibly render using the new API
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getFlags(BlockRenderView blockRenderView, BlockPos pos) {
|
||||||
|
if (!(blockRenderView instanceof RenderAttachedBlockView)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object attachment = ((RenderAttachedBlockView) blockRenderView).getBlockEntityRenderAttachment(pos);
|
||||||
|
if (!(attachment instanceof Integer)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (Integer) attachment;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SpatialPylonTextureType getTextureTypeFromSideOutside(int flags, Direction ori, Direction dir) {
|
private static SpatialPylonTextureType getTextureTypeFromSideOutside(int flags, Direction ori, Direction dir) {
|
||||||
@@ -202,6 +232,11 @@ class SpatialPylonBakedModel implements IDynamicBakedModel {
|
|||||||
return this.textures.get(SpatialPylonTextureType.DIM);
|
return this.textures.get(SpatialPylonTextureType.DIM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModelTransformation getTransformation() {
|
||||||
|
return ModelTransformation.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ModelOverrideList getOverrides() {
|
public ModelOverrideList getOverrides() {
|
||||||
return ModelOverrideList.EMPTY;
|
return ModelOverrideList.EMPTY;
|
||||||
+18
-28
@@ -18,50 +18,40 @@
|
|||||||
|
|
||||||
package appeng.client.render.spatial;
|
package appeng.client.render.spatial;
|
||||||
|
|
||||||
|
import appeng.client.render.BasicUnbakedModel;
|
||||||
|
import appeng.core.AppEng;
|
||||||
|
import net.minecraft.client.render.model.BakedModel;
|
||||||
|
import net.minecraft.client.render.model.ModelBakeSettings;
|
||||||
|
import net.minecraft.client.render.model.ModelLoader;
|
||||||
|
import net.minecraft.client.texture.Sprite;
|
||||||
|
import net.minecraft.client.texture.SpriteAtlasTexture;
|
||||||
|
import net.minecraft.client.util.SpriteIdentifier;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import com.mojang.datafixers.util.Pair;
|
public class SpatialPylonModel implements BasicUnbakedModel {
|
||||||
|
|
||||||
import net.minecraft.client.render.model.BakedModel;
|
|
||||||
import net.minecraft.client.render.model.IModelTransform;
|
|
||||||
import net.minecraft.client.render.model.IUnbakedModel;
|
|
||||||
import net.minecraft.client.render.model.json.ModelOverrideList;
|
|
||||||
import net.minecraft.client.util.SpriteIdentifier;
|
|
||||||
import net.minecraft.client.render.model.ModelLoader;
|
|
||||||
import net.minecraft.client.texture.SpriteAtlasTexture;
|
|
||||||
import net.minecraft.client.texture.Sprite;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import net.minecraftforge.client.model.IModelConfiguration;
|
|
||||||
import net.minecraftforge.client.model.geometry.IModelGeometry;
|
|
||||||
|
|
||||||
import appeng.core.AppEng;
|
|
||||||
|
|
||||||
public class SpatialPylonModel implements IModelGeometry<SpatialPylonModel> {
|
|
||||||
|
|
||||||
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
|
public BakedModel bake(ModelLoader loader, Function<SpriteIdentifier, Sprite> textureGetter, ModelBakeSettings rotationContainer, Identifier modelId) {
|
||||||
Function<SpriteIdentifier, Sprite> spriteGetter, IModelTransform modelTransform,
|
|
||||||
ModelOverrideList overrides, Identifier modelLocation) {
|
|
||||||
Map<SpatialPylonTextureType, Sprite> textures = new EnumMap<>(SpatialPylonTextureType.class);
|
Map<SpatialPylonTextureType, Sprite> textures = new EnumMap<>(SpatialPylonTextureType.class);
|
||||||
|
|
||||||
for (SpatialPylonTextureType type : SpatialPylonTextureType.values()) {
|
for (SpatialPylonTextureType type : SpatialPylonTextureType.values()) {
|
||||||
textures.put(type, spriteGetter.apply(getTexturePath(type)));
|
textures.put(type, textureGetter.apply(getTexturePath(type)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SpatialPylonBakedModel(textures);
|
return new SpatialPylonBakedModel(textures);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<SpriteIdentifier> getTextures(IModelConfiguration owner,
|
public Stream<SpriteIdentifier> getAdditionalTextures() {
|
||||||
Function<Identifier, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors) {
|
return Arrays.stream(SpatialPylonTextureType.values()).map(SpatialPylonModel::getTexturePath);
|
||||||
return Arrays.stream(SpatialPylonTextureType.values()).map(SpatialPylonModel::getTexturePath)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SpriteIdentifier getTexturePath(SpatialPylonTextureType type) {
|
private static SpriteIdentifier getTexturePath(SpatialPylonTextureType type) {
|
||||||
@@ -33,8 +33,12 @@ import appeng.hooks.ToolItemHook;
|
|||||||
import appeng.items.tools.NetworkToolItem;
|
import appeng.items.tools.NetworkToolItem;
|
||||||
import appeng.me.cache.*;
|
import appeng.me.cache.*;
|
||||||
import appeng.mixins.CriteriaRegisterMixin;
|
import appeng.mixins.CriteriaRegisterMixin;
|
||||||
|
import appeng.hooks.RegisterDimensionTypeCallback;
|
||||||
import appeng.recipes.handlers.*;
|
import appeng.recipes.handlers.*;
|
||||||
import appeng.server.AECommand;
|
import appeng.server.AECommand;
|
||||||
|
import appeng.spatial.SpatialDimensionManager;
|
||||||
|
import appeng.spatial.StorageCellBiome;
|
||||||
|
import appeng.spatial.StorageChunkGenerator;
|
||||||
import appeng.worldgen.ChargedQuartzOreConfig;
|
import appeng.worldgen.ChargedQuartzOreConfig;
|
||||||
import appeng.worldgen.ChargedQuartzOreFeature;
|
import appeng.worldgen.ChargedQuartzOreFeature;
|
||||||
import appeng.worldgen.meteorite.MeteoriteStructure;
|
import appeng.worldgen.meteorite.MeteoriteStructure;
|
||||||
@@ -50,10 +54,12 @@ import net.minecraft.nbt.CompoundTag;
|
|||||||
import net.minecraft.recipe.Recipe;
|
import net.minecraft.recipe.Recipe;
|
||||||
import net.minecraft.recipe.RecipeType;
|
import net.minecraft.recipe.RecipeType;
|
||||||
import net.minecraft.screen.ScreenHandlerType;
|
import net.minecraft.screen.ScreenHandlerType;
|
||||||
|
import net.minecraft.tag.BlockTags;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.util.registry.Registry;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.biome.Biome;
|
import net.minecraft.world.biome.Biome;
|
||||||
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
import net.minecraft.world.gen.GenerationStep;
|
import net.minecraft.world.gen.GenerationStep;
|
||||||
import net.minecraft.world.gen.chunk.StructureConfig;
|
import net.minecraft.world.gen.chunk.StructureConfig;
|
||||||
import net.minecraft.world.gen.decorator.Decorator;
|
import net.minecraft.world.gen.decorator.Decorator;
|
||||||
@@ -64,6 +70,7 @@ import net.minecraft.world.gen.feature.Feature;
|
|||||||
import net.minecraft.world.gen.feature.FeatureConfig;
|
import net.minecraft.world.gen.feature.FeatureConfig;
|
||||||
import net.minecraft.world.gen.feature.OreFeatureConfig;
|
import net.minecraft.world.gen.feature.OreFeatureConfig;
|
||||||
|
|
||||||
|
import java.util.OptionalLong;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public abstract class AppEngBase implements AppEng {
|
public abstract class AppEngBase implements AppEng {
|
||||||
@@ -97,6 +104,7 @@ public abstract class AppEngBase implements AppEng {
|
|||||||
registerRecipeSerializers();
|
registerRecipeSerializers();
|
||||||
registerWorldGen();
|
registerWorldGen();
|
||||||
registerServerCommands();
|
registerServerCommands();
|
||||||
|
registerDimension();
|
||||||
|
|
||||||
setupInternalRegistries();
|
setupInternalRegistries();
|
||||||
|
|
||||||
@@ -368,4 +376,31 @@ public abstract class AppEngBase implements AppEng {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void registerDimension() {
|
||||||
|
Registry.register(Registry.BIOME, AppEng.makeId("storage"), StorageCellBiome.INSTANCE);
|
||||||
|
Registry.register(Registry.CHUNK_GENERATOR, AppEng.makeId("storage"), StorageChunkGenerator.CODEC);
|
||||||
|
|
||||||
|
RegisterDimensionTypeCallback.EVENT.register(registryTracker -> {
|
||||||
|
|
||||||
|
registryTracker.addDimensionType(
|
||||||
|
SpatialDimensionManager.STORAGE_DIMENSION_TYPE,
|
||||||
|
new DimensionType(
|
||||||
|
OptionalLong.of(12000),
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
256,
|
||||||
|
BlockTags.INFINIBURN_OVERWORLD.getId(),
|
||||||
|
0.5f
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,76 +83,76 @@ import static appeng.block.AEBaseBlock.defaultProps;
|
|||||||
* Internal implementation for the API blocks
|
* Internal implementation for the API blocks
|
||||||
*/
|
*/
|
||||||
public final class ApiBlocks implements IBlocks {
|
public final class ApiBlocks implements IBlocks {
|
||||||
private IBlockDefinition quartzOre;
|
private final IBlockDefinition quartzOre;
|
||||||
private IBlockDefinition quartzOreCharged;
|
private final IBlockDefinition quartzOreCharged;
|
||||||
private IBlockDefinition matrixFrame;
|
private final IBlockDefinition matrixFrame;
|
||||||
private IBlockDefinition quartzBlock;
|
private final IBlockDefinition quartzBlock;
|
||||||
private IBlockDefinition quartzPillar;
|
private final IBlockDefinition quartzPillar;
|
||||||
private IBlockDefinition chiseledQuartzBlock;
|
private final IBlockDefinition chiseledQuartzBlock;
|
||||||
private IBlockDefinition quartzGlass;
|
private final IBlockDefinition quartzGlass;
|
||||||
private IBlockDefinition quartzVibrantGlass;
|
private final IBlockDefinition quartzVibrantGlass;
|
||||||
private IBlockDefinition quartzFixture;
|
private final IBlockDefinition quartzFixture;
|
||||||
private IBlockDefinition fluixBlock;
|
private final IBlockDefinition fluixBlock;
|
||||||
private IBlockDefinition skyStoneBlock;
|
private final IBlockDefinition skyStoneBlock;
|
||||||
private IBlockDefinition smoothSkyStoneBlock;
|
private final IBlockDefinition smoothSkyStoneBlock;
|
||||||
private IBlockDefinition skyStoneBrick;
|
private final IBlockDefinition skyStoneBrick;
|
||||||
private IBlockDefinition skyStoneSmallBrick;
|
private final IBlockDefinition skyStoneSmallBrick;
|
||||||
private IBlockDefinition skyStoneChest;
|
private final IBlockDefinition skyStoneChest;
|
||||||
private IBlockDefinition smoothSkyStoneChest;
|
private final IBlockDefinition smoothSkyStoneChest;
|
||||||
private IBlockDefinition skyCompass;
|
private final IBlockDefinition skyCompass;
|
||||||
private ITileDefinition grindstone;
|
private final ITileDefinition grindstone;
|
||||||
private ITileDefinition crank;
|
private final ITileDefinition crank;
|
||||||
private ITileDefinition inscriber;
|
private final ITileDefinition inscriber;
|
||||||
private ITileDefinition wirelessAccessPoint;
|
private final ITileDefinition wirelessAccessPoint;
|
||||||
private ITileDefinition charger;
|
private final ITileDefinition charger;
|
||||||
private IBlockDefinition tinyTNT;
|
private final IBlockDefinition tinyTNT;
|
||||||
private ITileDefinition securityStation;
|
private final ITileDefinition securityStation;
|
||||||
private ITileDefinition quantumRing;
|
private final ITileDefinition quantumRing;
|
||||||
private ITileDefinition quantumLink;
|
private final ITileDefinition quantumLink;
|
||||||
private ITileDefinition spatialPylon;
|
private final ITileDefinition spatialPylon;
|
||||||
private ITileDefinition spatialIOPort;
|
private final ITileDefinition spatialIOPort;
|
||||||
private ITileDefinition multiPart;
|
private final ITileDefinition multiPart;
|
||||||
private ITileDefinition controller;
|
private final ITileDefinition controller;
|
||||||
private ITileDefinition drive;
|
private final ITileDefinition drive;
|
||||||
private ITileDefinition chest;
|
private final ITileDefinition chest;
|
||||||
private ITileDefinition iface;
|
private final ITileDefinition iface;
|
||||||
private ITileDefinition fluidIface;
|
private final ITileDefinition fluidIface;
|
||||||
private ITileDefinition cellWorkbench;
|
private final ITileDefinition cellWorkbench;
|
||||||
private ITileDefinition iOPort;
|
private final ITileDefinition iOPort;
|
||||||
private ITileDefinition condenser;
|
private final ITileDefinition condenser;
|
||||||
private ITileDefinition energyAcceptor;
|
private final ITileDefinition energyAcceptor;
|
||||||
private ITileDefinition vibrationChamber;
|
private final ITileDefinition vibrationChamber;
|
||||||
private ITileDefinition quartzGrowthAccelerator;
|
private final ITileDefinition quartzGrowthAccelerator;
|
||||||
private ITileDefinition energyCell;
|
private final ITileDefinition energyCell;
|
||||||
private ITileDefinition energyCellDense;
|
private final ITileDefinition energyCellDense;
|
||||||
private ITileDefinition energyCellCreative;
|
private final ITileDefinition energyCellCreative;
|
||||||
private ITileDefinition craftingUnit;
|
private final ITileDefinition craftingUnit;
|
||||||
private ITileDefinition craftingAccelerator;
|
private final ITileDefinition craftingAccelerator;
|
||||||
private ITileDefinition craftingStorage1k;
|
private final ITileDefinition craftingStorage1k;
|
||||||
private ITileDefinition craftingStorage4k;
|
private final ITileDefinition craftingStorage4k;
|
||||||
private ITileDefinition craftingStorage16k;
|
private final ITileDefinition craftingStorage16k;
|
||||||
private ITileDefinition craftingStorage64k;
|
private final ITileDefinition craftingStorage64k;
|
||||||
private ITileDefinition craftingMonitor;
|
private final ITileDefinition craftingMonitor;
|
||||||
private ITileDefinition molecularAssembler;
|
private final ITileDefinition molecularAssembler;
|
||||||
private ITileDefinition lightDetector;
|
private final ITileDefinition lightDetector;
|
||||||
private ITileDefinition paint;
|
private final ITileDefinition paint;
|
||||||
private IBlockDefinition skyStoneStairs;
|
private final IBlockDefinition skyStoneStairs;
|
||||||
private IBlockDefinition smoothSkyStoneStairs;
|
private final IBlockDefinition smoothSkyStoneStairs;
|
||||||
private IBlockDefinition skyStoneBrickStairs;
|
private final IBlockDefinition skyStoneBrickStairs;
|
||||||
private IBlockDefinition skyStoneSmallBrickStairs;
|
private final IBlockDefinition skyStoneSmallBrickStairs;
|
||||||
private IBlockDefinition fluixStairs;
|
private final IBlockDefinition fluixStairs;
|
||||||
private IBlockDefinition quartzStairs;
|
private final IBlockDefinition quartzStairs;
|
||||||
private IBlockDefinition chiseledQuartzStairs;
|
private final IBlockDefinition chiseledQuartzStairs;
|
||||||
private IBlockDefinition quartzPillarStairs;
|
private final IBlockDefinition quartzPillarStairs;
|
||||||
|
|
||||||
private IBlockDefinition skyStoneSlab;
|
private final IBlockDefinition skyStoneSlab;
|
||||||
private IBlockDefinition smoothSkyStoneSlab;
|
private final IBlockDefinition smoothSkyStoneSlab;
|
||||||
private IBlockDefinition skyStoneBrickSlab;
|
private final IBlockDefinition skyStoneBrickSlab;
|
||||||
private IBlockDefinition skyStoneSmallBrickSlab;
|
private final IBlockDefinition skyStoneSmallBrickSlab;
|
||||||
private IBlockDefinition fluixSlab;
|
private final IBlockDefinition fluixSlab;
|
||||||
private IBlockDefinition quartzSlab;
|
private final IBlockDefinition quartzSlab;
|
||||||
private IBlockDefinition chiseledQuartzSlab;
|
private final IBlockDefinition chiseledQuartzSlab;
|
||||||
private IBlockDefinition quartzPillarSlab;
|
private final IBlockDefinition quartzPillarSlab;
|
||||||
|
|
||||||
private IBlockDefinition itemGen;
|
private IBlockDefinition itemGen;
|
||||||
private IBlockDefinition chunkLoader;
|
private IBlockDefinition chunkLoader;
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import appeng.items.misc.PaintBallItemRendering;
|
|||||||
import appeng.items.parts.FacadeItem;
|
import appeng.items.parts.FacadeItem;
|
||||||
import appeng.items.storage.BasicStorageCellItem;
|
import appeng.items.storage.BasicStorageCellItem;
|
||||||
import appeng.items.storage.CreativeStorageCellItem;
|
import appeng.items.storage.CreativeStorageCellItem;
|
||||||
|
import appeng.items.storage.SpatialStorageCellItem;
|
||||||
import appeng.items.storage.ViewCellItem;
|
import appeng.items.storage.ViewCellItem;
|
||||||
import appeng.items.tools.BiometricCardItem;
|
import appeng.items.tools.BiometricCardItem;
|
||||||
import appeng.items.tools.MemoryCardItem;
|
import appeng.items.tools.MemoryCardItem;
|
||||||
@@ -55,7 +56,6 @@ import appeng.items.tools.powered.*;
|
|||||||
import appeng.items.tools.quartz.*;
|
import appeng.items.tools.quartz.*;
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
|
||||||
import net.minecraft.entity.EntityDimensions;
|
import net.minecraft.entity.EntityDimensions;
|
||||||
import net.minecraft.entity.SpawnGroup;
|
import net.minecraft.entity.SpawnGroup;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
@@ -67,59 +67,59 @@ import java.util.function.Consumer;
|
|||||||
* Internal implementation for the API items
|
* Internal implementation for the API items
|
||||||
*/
|
*/
|
||||||
public final class ApiItems implements IItems {
|
public final class ApiItems implements IItems {
|
||||||
private IItemDefinition certusQuartzAxe;
|
private final IItemDefinition certusQuartzAxe;
|
||||||
private IItemDefinition certusQuartzHoe;
|
private final IItemDefinition certusQuartzHoe;
|
||||||
private IItemDefinition certusQuartzShovel;
|
private final IItemDefinition certusQuartzShovel;
|
||||||
private IItemDefinition certusQuartzPick;
|
private final IItemDefinition certusQuartzPick;
|
||||||
private IItemDefinition certusQuartzSword;
|
private final IItemDefinition certusQuartzSword;
|
||||||
private IItemDefinition certusQuartzWrench;
|
private final IItemDefinition certusQuartzWrench;
|
||||||
private IItemDefinition certusQuartzKnife;
|
private final IItemDefinition certusQuartzKnife;
|
||||||
|
|
||||||
private IItemDefinition netherQuartzAxe;
|
private final IItemDefinition netherQuartzAxe;
|
||||||
private IItemDefinition netherQuartzHoe;
|
private final IItemDefinition netherQuartzHoe;
|
||||||
private IItemDefinition netherQuartzShovel;
|
private final IItemDefinition netherQuartzShovel;
|
||||||
private IItemDefinition netherQuartzPick;
|
private final IItemDefinition netherQuartzPick;
|
||||||
private IItemDefinition netherQuartzSword;
|
private final IItemDefinition netherQuartzSword;
|
||||||
private IItemDefinition netherQuartzWrench;
|
private final IItemDefinition netherQuartzWrench;
|
||||||
private IItemDefinition netherQuartzKnife;
|
private final IItemDefinition netherQuartzKnife;
|
||||||
|
|
||||||
private IItemDefinition entropyManipulator;
|
private final IItemDefinition entropyManipulator;
|
||||||
private IItemDefinition wirelessTerminal;
|
private final IItemDefinition wirelessTerminal;
|
||||||
private IItemDefinition biometricCard;
|
private final IItemDefinition biometricCard;
|
||||||
private IItemDefinition chargedStaff;
|
private final IItemDefinition chargedStaff;
|
||||||
private IItemDefinition massCannon;
|
private final IItemDefinition massCannon;
|
||||||
private IItemDefinition memoryCard;
|
private final IItemDefinition memoryCard;
|
||||||
private IItemDefinition networkTool;
|
private final IItemDefinition networkTool;
|
||||||
private IItemDefinition portableCell;
|
private final IItemDefinition portableCell;
|
||||||
|
|
||||||
private IItemDefinition cellCreative;
|
private final IItemDefinition cellCreative;
|
||||||
private IItemDefinition viewCell;
|
private final IItemDefinition viewCell;
|
||||||
|
|
||||||
private IItemDefinition cell1k;
|
private final IItemDefinition cell1k;
|
||||||
private IItemDefinition cell4k;
|
private final IItemDefinition cell4k;
|
||||||
private IItemDefinition cell16k;
|
private final IItemDefinition cell16k;
|
||||||
private IItemDefinition cell64k;
|
private final IItemDefinition cell64k;
|
||||||
|
|
||||||
private IItemDefinition fluidCell1k;
|
private final IItemDefinition fluidCell1k;
|
||||||
private IItemDefinition fluidCell4k;
|
private final IItemDefinition fluidCell4k;
|
||||||
private IItemDefinition fluidCell16k;
|
private final IItemDefinition fluidCell16k;
|
||||||
private IItemDefinition fluidCell64k;
|
private final IItemDefinition fluidCell64k;
|
||||||
|
|
||||||
private IItemDefinition spatialCell2;
|
private final IItemDefinition spatialCell2;
|
||||||
private IItemDefinition spatialCell16;
|
private final IItemDefinition spatialCell16;
|
||||||
private IItemDefinition spatialCell128;
|
private final IItemDefinition spatialCell128;
|
||||||
|
|
||||||
private IItemDefinition facade;
|
private final IItemDefinition facade;
|
||||||
private IItemDefinition certusCrystalSeed;
|
private final IItemDefinition certusCrystalSeed;
|
||||||
private IItemDefinition fluixCrystalSeed;
|
private final IItemDefinition fluixCrystalSeed;
|
||||||
private IItemDefinition netherQuartzSeed;
|
private final IItemDefinition netherQuartzSeed;
|
||||||
|
|
||||||
// rv1
|
// rv1
|
||||||
private IItemDefinition encodedPattern;
|
private final IItemDefinition encodedPattern;
|
||||||
private IItemDefinition colorApplicator;
|
private final IItemDefinition colorApplicator;
|
||||||
|
|
||||||
private AEColoredItemDefinition coloredPaintBall;
|
private final AEColoredItemDefinition coloredPaintBall;
|
||||||
private AEColoredItemDefinition coloredLumenPaintBall;
|
private final AEColoredItemDefinition coloredLumenPaintBall;
|
||||||
|
|
||||||
// unsupported dev tools
|
// unsupported dev tools
|
||||||
private IItemDefinition toolEraser;
|
private IItemDefinition toolEraser;
|
||||||
@@ -249,15 +249,15 @@ public final class ApiItems implements IItems {
|
|||||||
.props(storageCellProps).build();
|
.props(storageCellProps).build();
|
||||||
|
|
||||||
FeatureFactory spatialCells = registry.features(AEFeature.SPATIAL_IO);
|
FeatureFactory spatialCells = registry.features(AEFeature.SPATIAL_IO);
|
||||||
// FIXME FABRIC this.spatialCell2 = spatialCells
|
this.spatialCell2 = spatialCells
|
||||||
// FIXME FABRIC .item("2_cubed_spatial_storage_cell", props -> new SpatialStorageCellItem(props, 2))
|
.item("2_cubed_spatial_storage_cell", props -> new SpatialStorageCellItem(props, 2))
|
||||||
// FIXME FABRIC .props(storageCellProps).build();
|
.props(storageCellProps).build();
|
||||||
// FIXME FABRIC this.spatialCell16 = spatialCells
|
this.spatialCell16 = spatialCells
|
||||||
// FIXME FABRIC .item("16_cubed_spatial_storage_cell", props -> new SpatialStorageCellItem(props, 16))
|
.item("16_cubed_spatial_storage_cell", props -> new SpatialStorageCellItem(props, 16))
|
||||||
// FIXME FABRIC .props(storageCellProps).build();
|
.props(storageCellProps).build();
|
||||||
// FIXME FABRIC this.spatialCell128 = spatialCells
|
this.spatialCell128 = spatialCells
|
||||||
// FIXME FABRIC .item("128_cubed_spatial_storage_cell", props -> new SpatialStorageCellItem(props, 128))
|
.item("128_cubed_spatial_storage_cell", props -> new SpatialStorageCellItem(props, 128))
|
||||||
// FIXME FABRIC .props(storageCellProps).build();
|
.props(storageCellProps).build();
|
||||||
|
|
||||||
this.facade = registry.item("facade", FacadeItem::new).features(AEFeature.FACADES).build();
|
this.facade = registry.item("facade", FacadeItem::new).features(AEFeature.FACADES).build();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package appeng.hooks;
|
||||||
|
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.util.registry.RegistryKey;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
|
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
||||||
|
|
||||||
|
public interface DynamicDimensions {
|
||||||
|
|
||||||
|
ServerWorld addWorld(RegistryKey<World> worldId, RegistryKey<DimensionType> dimensionTypeId, ChunkGenerator chunkGenerator);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package appeng.hooks;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.event.Event;
|
||||||
|
import net.fabricmc.fabric.api.event.EventFactory;
|
||||||
|
import net.minecraft.util.registry.RegistryTracker;
|
||||||
|
|
||||||
|
public interface RegisterDimensionTypeCallback {
|
||||||
|
|
||||||
|
Event<RegisterDimensionTypeCallback> EVENT = EventFactory.createArrayBacked(RegisterDimensionTypeCallback.class, (listeners) -> (registryTracker) -> {
|
||||||
|
for (RegisterDimensionTypeCallback listener : listeners) {
|
||||||
|
listener.addDimensionTypes(registryTracker);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
void addDimensionTypes(RegistryTracker.Modifiable registryTracker);
|
||||||
|
|
||||||
|
}
|
||||||
+24
-23
@@ -30,8 +30,9 @@ import net.minecraft.util.Formatting;
|
|||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
import net.minecraft.util.registry.RegistryKey;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.dimension.DimensionType;
|
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
|
|
||||||
import appeng.api.implementations.TransitionResult;
|
import appeng.api.implementations.TransitionResult;
|
||||||
@@ -58,17 +59,17 @@ public class SpatialStorageCellItem extends AEBaseItem implements ISpatialStorag
|
|||||||
@Override
|
@Override
|
||||||
public void appendTooltip(final ItemStack stack, final World world, final List<Text> lines,
|
public void appendTooltip(final ItemStack stack, final World world, final List<Text> lines,
|
||||||
final TooltipContext advancedTooltips) {
|
final TooltipContext advancedTooltips) {
|
||||||
final DimensionType dimType = this.getStoredDimension(stack);
|
final RegistryKey<World> worldId = this.getStoredDimension(stack);
|
||||||
if (dimType == null) {
|
if (worldId == null) {
|
||||||
lines.add(GuiText.Unformatted.text().formatted(Formatting.ITALIC));
|
lines.add(GuiText.Unformatted.text().copy().formatted(Formatting.ITALIC));
|
||||||
lines.add(GuiText.SpatialCapacity.text(maxRegion, maxRegion, maxRegion));
|
lines.add(GuiText.SpatialCapacity.text(maxRegion, maxRegion, maxRegion));
|
||||||
} else {
|
} else {
|
||||||
SpatialDimensionManager.INSTANCE.addCellDimensionTooltip(dimType, lines);
|
SpatialDimensionManager.INSTANCE.addCellDimensionTooltip(worldId, lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (advancedTooltips.isAdvanced()) {
|
if (advancedTooltips.isAdvanced()) {
|
||||||
if (dimType != null && dimType.getRegistryName() != null) {
|
if (worldId != null && worldId.getValue() != null) {
|
||||||
lines.add(new LiteralText("Dimension: " + dimType.getRegistryName()));
|
lines.add(new LiteralText("Dimension: " + worldId.getValue()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,12 +85,12 @@ public class SpatialStorageCellItem extends AEBaseItem implements ISpatialStorag
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DimensionType getStoredDimension(final ItemStack is) {
|
public RegistryKey<World> getStoredDimension(final ItemStack is) {
|
||||||
final CompoundTag c = is.getTag();
|
final CompoundTag c = is.getTag();
|
||||||
if (c != null && c.contains(TAG_DIMENSION_ID)) {
|
if (c != null && c.contains(TAG_DIMENSION_ID)) {
|
||||||
try {
|
try {
|
||||||
Identifier dimTypeId = new Identifier(c.getString(TAG_DIMENSION_ID));
|
Identifier worldId = new Identifier(c.getString(TAG_DIMENSION_ID));
|
||||||
return DimensionType.byName(dimTypeId);
|
return RegistryKey.of(Registry.DIMENSION, worldId);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
AELog.warn("Failed to retrieve storage cell dimension.", e);
|
AELog.warn("Failed to retrieve storage cell dimension.", e);
|
||||||
}
|
}
|
||||||
@@ -109,27 +110,27 @@ public class SpatialStorageCellItem extends AEBaseItem implements ISpatialStorag
|
|||||||
|
|
||||||
ISpatialDimension manager = SpatialDimensionManager.INSTANCE;
|
ISpatialDimension manager = SpatialDimensionManager.INSTANCE;
|
||||||
|
|
||||||
DimensionType storedDim = this.getStoredDimension(is);
|
RegistryKey<World> worldId = this.getStoredDimension(is);
|
||||||
if (storedDim == null) {
|
if (worldId == null || manager.getWorld(worldId) == null) {
|
||||||
storedDim = manager.createNewCellDimension(targetSize);
|
worldId = manager.createNewCellDimension(targetSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (storedDim == null) {
|
if (worldId == null) {
|
||||||
// Failed to create the dimension
|
// Failed to create the dimension
|
||||||
return new TransitionResult(false, 0);
|
return new TransitionResult(false, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (manager.isCellDimension(storedDim)) {
|
if (manager.isCellDimension(worldId)) {
|
||||||
ServerWorld cellWorld = manager.getWorld(storedDim);
|
ServerWorld cellWorld = manager.getWorld(worldId);
|
||||||
|
|
||||||
BlockPos scale = manager.getCellDimensionSize(storedDim);
|
BlockPos scale = manager.getCellDimensionSize(worldId);
|
||||||
|
|
||||||
if (scale.equals(targetSize)) {
|
if (scale.equals(targetSize)) {
|
||||||
if (targetX <= maxSize && targetY <= maxSize && targetZ <= maxSize) {
|
if (targetX <= maxSize && targetY <= maxSize && targetZ <= maxSize) {
|
||||||
BlockPos offset = manager.getCellDimensionOrigin(storedDim);
|
BlockPos offset = manager.getCellDimensionOrigin(worldId);
|
||||||
|
|
||||||
this.setStoredDimension(is, storedDim);
|
this.setStoredDimension(is, worldId);
|
||||||
StorageHelper.getInstance().swapRegions(w, min.x + 1, min.y + 1, min.z + 1, cellWorld,
|
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);
|
offset.getX(), offset.getY(), offset.getZ(), targetX - 1, targetY - 1, targetZ - 1);
|
||||||
|
|
||||||
@@ -140,14 +141,14 @@ public class SpatialStorageCellItem extends AEBaseItem implements ISpatialStorag
|
|||||||
return new TransitionResult(false, 0);
|
return new TransitionResult(false, 0);
|
||||||
} finally {
|
} finally {
|
||||||
// clean up newly created dimensions that failed transfer
|
// clean up newly created dimensions that failed transfer
|
||||||
if (manager.isCellDimension(storedDim) && this.getStoredDimension(is) == null) {
|
if (manager.isCellDimension(worldId) && this.getStoredDimension(is) == null) {
|
||||||
manager.deleteCellDimension(storedDim);
|
manager.deleteCellDimension(worldId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setStoredDimension(final ItemStack is, DimensionType dim) {
|
private void setStoredDimension(final ItemStack is, RegistryKey<World> worldId) {
|
||||||
final CompoundTag c = is.getOrCreateTag();
|
final CompoundTag c = is.getOrCreateTag();
|
||||||
c.putString(TAG_DIMENSION_ID, dim.getRegistryName().toString());
|
c.putString(TAG_DIMENSION_ID, worldId.getValue().toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package appeng.mixins;
|
||||||
|
|
||||||
|
import appeng.hooks.RegisterDimensionTypeCallback;
|
||||||
|
import net.minecraft.util.registry.RegistryTracker;
|
||||||
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
@Mixin(DimensionType.class)
|
||||||
|
public class DimensionTypeMixin {
|
||||||
|
|
||||||
|
@Inject(method="addRegistryDefaults", at=@At("TAIL"))
|
||||||
|
private static void addRegistryDefaults(RegistryTracker.Modifiable registryTracker, CallbackInfoReturnable<?> cir) {
|
||||||
|
RegisterDimensionTypeCallback.EVENT.invoker().addDimensionTypes(registryTracker);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
package appeng.mixins;
|
||||||
|
|
||||||
|
import appeng.hooks.DynamicDimensions;
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.WorldGenerationProgressListener;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
import net.minecraft.util.registry.RegistryKey;
|
||||||
|
import net.minecraft.util.registry.RegistryTracker;
|
||||||
|
import net.minecraft.world.SaveProperties;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.border.WorldBorder;
|
||||||
|
import net.minecraft.world.border.WorldBorderListener;
|
||||||
|
import net.minecraft.world.dimension.DimensionOptions;
|
||||||
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
|
import net.minecraft.world.gen.GeneratorOptions;
|
||||||
|
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
||||||
|
import net.minecraft.world.level.ServerWorldProperties;
|
||||||
|
import net.minecraft.world.level.UnmodifiableLevelProperties;
|
||||||
|
import net.minecraft.world.level.storage.LevelStorage;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
@Mixin(MinecraftServer.class)
|
||||||
|
public class MinecraftServerMixin implements DynamicDimensions {
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private RegistryTracker.Modifiable dimensionTracker;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private Map<RegistryKey<World>, ServerWorld> worlds;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private SaveProperties saveProperties;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private Executor workerExecutor;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private LevelStorage.Session session;
|
||||||
|
|
||||||
|
public ServerWorld addWorld(RegistryKey<World> worldId, RegistryKey<DimensionType> dimensionTypeId, ChunkGenerator chunkGenerator) {
|
||||||
|
Preconditions.checkArgument(!worlds.containsKey(worldId), "World with id %s already exists.", worldId.getValue());
|
||||||
|
|
||||||
|
// Each worlds must have a corresponding dimension options, otherwise they will not be re-created on load
|
||||||
|
GeneratorOptions generatorOptions = this.saveProperties.getGeneratorOptions();
|
||||||
|
Preconditions.checkArgument(!generatorOptions.getDimensionMap().containsId(worldId.getValue()),
|
||||||
|
"Dimension config with id %s already exists.", worldId.getValue());
|
||||||
|
|
||||||
|
DimensionType dimensionType = dimensionTracker.getDimensionTypeRegistry().get(dimensionTypeId);
|
||||||
|
Preconditions.checkArgument(dimensionType != null, "dimensionTypeId %s is not registered", dimensionTypeId);
|
||||||
|
|
||||||
|
// Create dimension options with the given world-id and chunk generator
|
||||||
|
DimensionOptions dimensionOptions = new DimensionOptions(
|
||||||
|
() -> dimensionTracker.getDimensionTypeRegistry().get(dimensionTypeId),
|
||||||
|
chunkGenerator
|
||||||
|
);
|
||||||
|
|
||||||
|
ServerWorldProperties serverWorldProperties = this.saveProperties.getMainWorldProperties();
|
||||||
|
|
||||||
|
// This sucks a little, but during startup, the server will use the same listener for every world,
|
||||||
|
// but it is ultimately only stored in the chunk storage. So we retrieve it from the overworld to
|
||||||
|
// mirror the original code as much as possible
|
||||||
|
ServerWorld overworld = worlds.get(ServerWorld.OVERWORLD);
|
||||||
|
Preconditions.checkState(overworld != null, "Overworld does not exist!");
|
||||||
|
WorldGenerationProgressListener worldGenerationProgressListener = ((ThreadedAnvilChunkStorageAccessor) overworld.getChunkManager().threadedAnvilChunkStorage).getWorldGenerationProgressListener();
|
||||||
|
|
||||||
|
// Inherit seed + WorldBorder from overworld
|
||||||
|
long seed = overworld.getSeed();
|
||||||
|
WorldBorder worldBorder = overworld.getWorldBorder();
|
||||||
|
|
||||||
|
MinecraftServer self = (MinecraftServer) (Object) this;
|
||||||
|
UnmodifiableLevelProperties unmodifiableLevelProperties = new UnmodifiableLevelProperties(this.saveProperties, serverWorldProperties);
|
||||||
|
ServerWorld world = new ServerWorld(
|
||||||
|
self, this.workerExecutor, this.session, unmodifiableLevelProperties, worldId, dimensionTypeId, dimensionType, worldGenerationProgressListener, chunkGenerator, false, seed, ImmutableList.of(), false
|
||||||
|
);
|
||||||
|
worldBorder.addListener(new WorldBorderListener.WorldBorderSyncer(world.getWorldBorder()));
|
||||||
|
this.worlds.put(worldId, world);
|
||||||
|
|
||||||
|
// Adding it here will cause the world to be re-created on server restart
|
||||||
|
RegistryKey<DimensionOptions> dimOptKey = RegistryKey.of(Registry.DIMENSION_OPTIONS, worldId.getValue());
|
||||||
|
generatorOptions.getDimensionMap().add(dimOptKey, dimensionOptions);
|
||||||
|
generatorOptions.getDimensionMap().markLoaded(dimOptKey); // Otherwise it wont be saved
|
||||||
|
// Ensure the save properties are saved, or the world will potentially be lost on restart
|
||||||
|
this.session.method_27426(this.dimensionTracker, this.saveProperties, self.getPlayerManager().getUserData());
|
||||||
|
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package appeng.mixins;
|
||||||
|
|
||||||
|
import net.minecraft.server.WorldGenerationProgressListener;
|
||||||
|
import net.minecraft.server.world.ThreadedAnvilChunkStorage;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
|
@Mixin(ThreadedAnvilChunkStorage.class)
|
||||||
|
public interface ThreadedAnvilChunkStorageAccessor {
|
||||||
|
|
||||||
|
@Accessor
|
||||||
|
WorldGenerationProgressListener getWorldGenerationProgressListener();
|
||||||
|
|
||||||
|
}
|
||||||
+61
-62
@@ -18,26 +18,6 @@
|
|||||||
|
|
||||||
package appeng.spatial;
|
package appeng.spatial;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
|
||||||
import net.minecraft.network.play.server.SChunkDataPacket;
|
|
||||||
import net.minecraft.util.Tickable;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.EmptyBlockView;
|
|
||||||
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.ChunkSection;
|
|
||||||
import net.minecraft.world.server.ServerChunkProvider;
|
|
||||||
import net.minecraft.world.server.ServerTickList;
|
|
||||||
|
|
||||||
import appeng.api.AEApi;
|
import appeng.api.AEApi;
|
||||||
import appeng.api.movable.IMovableHandler;
|
import appeng.api.movable.IMovableHandler;
|
||||||
import appeng.api.movable.IMovableRegistry;
|
import appeng.api.movable.IMovableRegistry;
|
||||||
@@ -45,6 +25,26 @@ import appeng.api.util.AEPartLocation;
|
|||||||
import appeng.api.util.WorldCoord;
|
import appeng.api.util.WorldCoord;
|
||||||
import appeng.core.AELog;
|
import appeng.core.AELog;
|
||||||
import appeng.core.worlddata.WorldData;
|
import appeng.core.worlddata.WorldData;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.network.packet.s2c.play.ChunkDataS2CPacket;
|
||||||
|
import net.minecraft.server.world.ServerChunkManager;
|
||||||
|
import net.minecraft.server.world.ServerTickScheduler;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.util.Tickable;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.ScheduledTick;
|
||||||
|
import net.minecraft.world.TickScheduler;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.chunk.Chunk;
|
||||||
|
import net.minecraft.world.chunk.ChunkSection;
|
||||||
|
import net.minecraft.world.chunk.WorldChunk;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class CachedPlane {
|
public class CachedPlane {
|
||||||
private final int x_size;
|
private final int x_size;
|
||||||
@@ -55,10 +55,10 @@ public class CachedPlane {
|
|||||||
private final int y_offset;
|
private final int y_offset;
|
||||||
private final int z_offset;
|
private final int z_offset;
|
||||||
private final int y_size;
|
private final int y_size;
|
||||||
private final Chunk[][] myChunks;
|
private final WorldChunk[][] myChunks;
|
||||||
private final Column[][] myColumns;
|
private final Column[][] myColumns;
|
||||||
private final List<BlockEntity> tiles = new ArrayList<>();
|
private final List<BlockEntity> tiles = new ArrayList<>();
|
||||||
private final List<NextTickListEntry<Block>> ticks = new ArrayList<>();
|
private final List<ScheduledTick<Block>> ticks = new ArrayList<>();
|
||||||
private final World world;
|
private final World world;
|
||||||
private final IMovableRegistry reg = AEApi.instance().registries().movable();
|
private final IMovableRegistry reg = AEApi.instance().registries().movable();
|
||||||
private final List<WorldCoord> updates = new ArrayList<>();
|
private final List<WorldCoord> updates = new ArrayList<>();
|
||||||
@@ -96,7 +96,7 @@ public class CachedPlane {
|
|||||||
final int cy_size = maxCY - minCY + 1;
|
final int cy_size = maxCY - minCY + 1;
|
||||||
this.cz_size = maxCZ - minCZ + 1;
|
this.cz_size = maxCZ - minCZ + 1;
|
||||||
|
|
||||||
this.myChunks = new Chunk[this.cx_size][this.cz_size];
|
this.myChunks = new WorldChunk[this.cx_size][this.cz_size];
|
||||||
this.myColumns = new Column[this.x_size][this.z_size];
|
this.myColumns = new Column[this.x_size][this.z_size];
|
||||||
|
|
||||||
this.verticalBits = 0;
|
this.verticalBits = 0;
|
||||||
@@ -117,26 +117,27 @@ public class CachedPlane {
|
|||||||
for (int cz = 0; cz < this.cz_size; cz++) {
|
for (int cz = 0; cz < this.cz_size; cz++) {
|
||||||
final List<BlockPos> deadTiles = new ArrayList<>();
|
final List<BlockPos> deadTiles = new ArrayList<>();
|
||||||
|
|
||||||
final Chunk c = w.getChunk(minCX + cx, minCZ + cz);
|
final WorldChunk c = w.getChunk(minCX + cx, minCZ + cz);
|
||||||
this.myChunks[cx][cz] = c;
|
this.myChunks[cx][cz] = c;
|
||||||
|
|
||||||
final List<Entry<BlockPos, BlockEntity>> rawTiles = new ArrayList<>(c.getBlockEntityMap().entrySet());
|
Set<BlockPos> blockEntityPositions = c.getBlockEntityPositions();
|
||||||
for (final Entry<BlockPos, BlockEntity> tx : rawTiles) {
|
for (BlockPos tePOS : blockEntityPositions) {
|
||||||
final BlockPos cp = tx.getKey();
|
final BlockEntity te = c.getBlockEntity(tePOS);
|
||||||
final BlockEntity te = tx.getValue();
|
if (te == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
final BlockPos tePOS = te.getPos();
|
|
||||||
if (tePOS.getX() >= minX && tePOS.getX() <= maxX && tePOS.getY() >= minY && tePOS.getY() <= maxY
|
if (tePOS.getX() >= minX && tePOS.getX() <= maxX && tePOS.getY() >= minY && tePOS.getY() <= maxY
|
||||||
&& tePOS.getZ() >= minZ && tePOS.getZ() <= maxZ) {
|
&& tePOS.getZ() >= minZ && tePOS.getZ() <= maxZ) {
|
||||||
if (mr.askToMove(te)) {
|
if (mr.askToMove(te)) {
|
||||||
this.tiles.add(te);
|
this.tiles.add(te);
|
||||||
deadTiles.add(cp);
|
deadTiles.add(tePOS);
|
||||||
} else {
|
} else {
|
||||||
final BlockStorageData details = new BlockStorageData();
|
final BlockStorageData details = new BlockStorageData();
|
||||||
this.myColumns[tePOS.getX() - minX][tePOS.getZ() - minZ].fillData(tePOS.getY(), details);
|
this.myColumns[tePOS.getX() - minX][tePOS.getZ() - minZ].fillData(tePOS.getY(), details);
|
||||||
|
|
||||||
// don't skip air, just let the code replace it...
|
// don't skip air, just let the code replace it...
|
||||||
if (details.state.isAir(EmptyBlockView.INSTANCE, tePOS)) {
|
if (details.state.isAir()) {
|
||||||
w.removeBlock(tePOS, false);
|
w.removeBlock(tePOS, false);
|
||||||
} else {
|
} else {
|
||||||
this.myColumns[tePOS.getX() - minX][tePOS.getZ() - minZ].setSkip(tePOS.getY());
|
this.myColumns[tePOS.getX() - minX][tePOS.getZ() - minZ].setSkip(tePOS.getY());
|
||||||
@@ -146,20 +147,20 @@ public class CachedPlane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (final BlockPos cp : deadTiles) {
|
for (final BlockPos cp : deadTiles) {
|
||||||
c.getBlockEntityMap().remove(cp);
|
c.removeBlockEntity(cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
final long gameTime = this.getWorld().getTime();
|
final long gameTime = this.getWorld().getTime();
|
||||||
final ITickList<Block> pendingBlockTicks = this.getWorld().getPendingBlockTicks();
|
final TickScheduler<Block> pendingBlockTicks = this.getWorld().getBlockTickScheduler();
|
||||||
if (pendingBlockTicks instanceof ServerTickList) {
|
if (pendingBlockTicks instanceof ServerTickScheduler) {
|
||||||
List<NextTickListEntry<Block>> pending = ((ServerTickList<Block>) pendingBlockTicks)
|
List<ScheduledTick<Block>> pending = ((ServerTickScheduler<Block>) pendingBlockTicks)
|
||||||
.getPending(c.getPos(), false, true);
|
.getScheduledTicksInChunk(c.getPos(), false, true);
|
||||||
for (final NextTickListEntry<Block> entry : pending) {
|
for (final ScheduledTick<Block> entry : pending) {
|
||||||
final BlockPos tePOS = entry.position;
|
final BlockPos tePOS = entry.pos;
|
||||||
if (tePOS.getX() >= minX && tePOS.getX() <= maxX && tePOS.getY() >= minY && tePOS.getY() <= maxY
|
if (tePOS.getX() >= minX && tePOS.getX() <= maxX && tePOS.getY() >= minY && tePOS.getY() <= maxY
|
||||||
&& tePOS.getZ() >= minZ && tePOS.getZ() <= maxZ) {
|
&& tePOS.getZ() >= minZ && tePOS.getZ() <= maxZ) {
|
||||||
this.ticks.add(new NextTickListEntry<>(tePOS, entry.getTarget(),
|
this.ticks.add(new ScheduledTick<>(tePOS, entry.getObject(),
|
||||||
entry.scheduledTime - gameTime, entry.priority));
|
entry.time - gameTime, entry.priority));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,9 +169,9 @@ public class CachedPlane {
|
|||||||
|
|
||||||
for (final BlockEntity te : this.tiles) {
|
for (final BlockEntity te : this.tiles) {
|
||||||
try {
|
try {
|
||||||
this.getWorld().loadedTileEntityList.remove(te);
|
this.getWorld().blockEntities.remove(te);
|
||||||
if (te instanceof Tickable) {
|
if (te instanceof Tickable) {
|
||||||
this.getWorld().tickableTileEntities.remove(te);
|
this.getWorld().tickingBlockEntities.remove(te);
|
||||||
}
|
}
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
AELog.debug(e);
|
AELog.debug(e);
|
||||||
@@ -232,14 +233,14 @@ public class CachedPlane {
|
|||||||
dst, mr);
|
dst, mr);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final NextTickListEntry<Block> entry : this.ticks) {
|
for (final ScheduledTick<Block> entry : this.ticks) {
|
||||||
final BlockPos tePOS = entry.position;
|
final BlockPos tePOS = entry.pos;
|
||||||
dst.addTick(tePOS.getX() - this.x_offset, tePOS.getY() - this.y_offset, tePOS.getZ() - this.z_offset,
|
dst.addTick(tePOS.getX() - this.x_offset, tePOS.getY() - this.y_offset, tePOS.getZ() - this.z_offset,
|
||||||
entry);
|
entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final NextTickListEntry<Block> entry : dst.ticks) {
|
for (final ScheduledTick<Block> entry : dst.ticks) {
|
||||||
final BlockPos tePOS = entry.position;
|
final BlockPos tePOS = entry.pos;
|
||||||
this.addTick(tePOS.getX() - dst.x_offset, tePOS.getY() - dst.y_offset, tePOS.getZ() - dst.z_offset,
|
this.addTick(tePOS.getX() - dst.x_offset, tePOS.getY() - dst.y_offset, tePOS.getZ() - dst.z_offset,
|
||||||
entry);
|
entry);
|
||||||
}
|
}
|
||||||
@@ -261,9 +262,9 @@ public class CachedPlane {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addTick(final int x, final int y, final int z, final NextTickListEntry<Block> entry) {
|
private void addTick(final int x, final int y, final int z, final ScheduledTick<Block> entry) {
|
||||||
BlockPos where = new BlockPos(x + this.x_offset, y + this.y_offset, z + this.z_offset);
|
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,
|
this.world.getBlockTickScheduler().schedule(where, entry.getObject(), (int) entry.time,
|
||||||
entry.priority);
|
entry.priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,7 +285,7 @@ public class CachedPlane {
|
|||||||
final BlockPos pos = new BlockPos(x, y, z);
|
final BlockPos pos = new BlockPos(x, y, z);
|
||||||
|
|
||||||
// attempt recovery...
|
// attempt recovery...
|
||||||
c.c.addBlockEntity(te);
|
c.c.setBlockEntity(pos, te);
|
||||||
|
|
||||||
this.world.updateListeners(pos, this.world.getBlockState(pos), this.world.getBlockState(pos), z);
|
this.world.updateListeners(pos, this.world.getBlockState(pos), this.world.getBlockState(pos), z);
|
||||||
}
|
}
|
||||||
@@ -303,7 +304,7 @@ public class CachedPlane {
|
|||||||
// update shit..
|
// update shit..
|
||||||
for (int x = 0; x < this.cx_size; x++) {
|
for (int x = 0; x < this.cx_size; x++) {
|
||||||
for (int z = 0; z < this.cz_size; z++) {
|
for (int z = 0; z < this.cz_size; z++) {
|
||||||
final Chunk c = this.myChunks[x][z];
|
final WorldChunk c = this.myChunks[x][z];
|
||||||
// FIXME: Light shit
|
// FIXME: Light shit
|
||||||
c.markDirty();
|
c.markDirty();
|
||||||
}
|
}
|
||||||
@@ -313,22 +314,20 @@ public class CachedPlane {
|
|||||||
for (int x = 0; x < this.cx_size; x++) {
|
for (int x = 0; x < this.cx_size; x++) {
|
||||||
for (int z = 0; z < this.cz_size; z++) {
|
for (int z = 0; z < this.cz_size; z++) {
|
||||||
|
|
||||||
final Chunk c = this.myChunks[x][z];
|
final WorldChunk c = this.myChunks[x][z];
|
||||||
|
|
||||||
for (int y = 1; y < 255; y += 32) {
|
WorldData.instance().compassData().service().updateArea((ServerWorld) this.getWorld(), c);
|
||||||
WorldData.instance().compassData().service().updateArea(this.getWorld(), c.getPos(), y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME this was sending chunks to players...
|
// FIXME this was sending chunks to players...
|
||||||
SChunkDataPacket cdp = new SChunkDataPacket(c, verticalBits);
|
ChunkDataS2CPacket cdp = new ChunkDataS2CPacket(c, verticalBits, false);
|
||||||
((ServerChunkProvider) world.getChunkManager()).chunkManager.getTrackingPlayers(c.getPos(), false)
|
((ServerChunkManager) world.getChunkManager()).threadedAnvilChunkStorage.getPlayersWatchingChunk(c.getPos(), false)
|
||||||
.forEach(spe -> spe.connection.sendPacket(cdp));
|
.forEach(spe -> spe.networkHandler.sendPacket(cdp));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME check if this makes any sense at all to send changes to players asap
|
// FIXME check if this makes any sense at all to send changes to players asap
|
||||||
ServerChunkProvider serverChunkProvider = (ServerChunkProvider) world.getChunkManager();
|
ServerChunkManager serverChunkProvider = (ServerChunkManager) world.getChunkManager();
|
||||||
serverChunkProvider.tick(() -> false);
|
serverChunkProvider.tick(() -> false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,7 +355,7 @@ public class CachedPlane {
|
|||||||
this.z = z;
|
this.z = z;
|
||||||
this.c = chunk;
|
this.c = chunk;
|
||||||
|
|
||||||
final ChunkSection[] storage = this.c.getSections();
|
final ChunkSection[] storage = this.c.getSectionArray();
|
||||||
|
|
||||||
// make sure storage exists before hand...
|
// make sure storage exists before hand...
|
||||||
for (int ay = 0; ay < chunkHeight; ay++) {
|
for (int ay = 0; ay < chunkHeight; ay++) {
|
||||||
@@ -372,7 +371,7 @@ public class CachedPlane {
|
|||||||
if (data.state == CachedPlane.this.matrixBlockState) {
|
if (data.state == CachedPlane.this.matrixBlockState) {
|
||||||
data.state = Blocks.AIR.getDefaultState();
|
data.state = Blocks.AIR.getDefaultState();
|
||||||
}
|
}
|
||||||
final ChunkSection[] storage = this.c.getSections();
|
final ChunkSection[] storage = this.c.getSectionArray();
|
||||||
final ChunkSection extendedBlockStorage = storage[y >> 4];
|
final ChunkSection extendedBlockStorage = storage[y >> 4];
|
||||||
extendedBlockStorage.setBlockState(this.x, y & 15, this.z, data.state);
|
extendedBlockStorage.setBlockState(this.x, y & 15, this.z, data.state);
|
||||||
// FIXME extendedBlockStorage.setBlockLight( this.x, y & 15, this.z, data.light
|
// FIXME extendedBlockStorage.setBlockLight( this.x, y & 15, this.z, data.light
|
||||||
@@ -380,7 +379,7 @@ public class CachedPlane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void fillData(final int y, BlockStorageData data) {
|
private void fillData(final int y, BlockStorageData data) {
|
||||||
final ChunkSection[] storage = this.c.getSections();
|
final ChunkSection[] storage = this.c.getSectionArray();
|
||||||
final ChunkSection extendedblockstorage = storage[y >> 4];
|
final ChunkSection extendedblockstorage = storage[y >> 4];
|
||||||
|
|
||||||
data.state = extendedblockstorage.getBlockState(this.x, y & 15, this.z);
|
data.state = extendedblockstorage.getBlockState(this.x, y & 15, this.z);
|
||||||
@@ -389,7 +388,7 @@ public class CachedPlane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean doNotSkip(final int y) {
|
private boolean doNotSkip(final int y) {
|
||||||
final ChunkSection[] storage = this.c.getSections();
|
final ChunkSection[] storage = this.c.getSectionArray();
|
||||||
final ChunkSection extendedblockstorage = storage[y >> 4];
|
final ChunkSection extendedblockstorage = storage[y >> 4];
|
||||||
if (CachedPlane.this.reg
|
if (CachedPlane.this.reg
|
||||||
.isBlacklisted(extendedblockstorage.getBlockState(this.x, y & 15, this.z).getBlock())) {
|
.isBlacklisted(extendedblockstorage.getBlockState(this.x, y & 15, this.z).getBlock())) {
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package appeng.spatial;
|
||||||
|
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.nbt.NbtHelper;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.PersistentState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helps with encoding and decoding the extra data we attach to each created
|
||||||
|
* storage dimension world as persistent state.
|
||||||
|
*/
|
||||||
|
public final class SpatialDimensionExtraData extends PersistentState {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ID of this data when it is attached to a world.
|
||||||
|
*/
|
||||||
|
public static final String ID = "ae2_spatial_info";
|
||||||
|
|
||||||
|
// Used to allow forward compatibility
|
||||||
|
private static final int CURRENT_FORMAT = 1;
|
||||||
|
|
||||||
|
private static final String TAG_FORMAT = "format";
|
||||||
|
|
||||||
|
private static final String TAG_SIZE = "size";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The storage size of this dimension. This is dicateted by the pylon structure
|
||||||
|
* size used to perform the first transfer into this dimension. Once it's set,
|
||||||
|
* it cannot be changed anymore.
|
||||||
|
*/
|
||||||
|
private BlockPos size = BlockPos.ORIGIN;
|
||||||
|
|
||||||
|
public SpatialDimensionExtraData() {
|
||||||
|
super(ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpatialDimensionExtraData(BlockPos size) {
|
||||||
|
super(ID);
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockPos getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSize(BlockPos size) {
|
||||||
|
this.size = size;
|
||||||
|
setDirty(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fromTag(CompoundTag tag) {
|
||||||
|
int version = tag.getInt(TAG_FORMAT);
|
||||||
|
if (version != CURRENT_FORMAT) {
|
||||||
|
// Currently no new format has been defined, as such anything but the current
|
||||||
|
// version is invalid
|
||||||
|
throw new IllegalStateException("Invalid AE2 spatial info version: " + version);
|
||||||
|
}
|
||||||
|
|
||||||
|
size = NbtHelper.toBlockPos(tag.getCompound(TAG_SIZE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundTag toTag(CompoundTag tag) {
|
||||||
|
tag.putInt(TAG_FORMAT, CURRENT_FORMAT);
|
||||||
|
tag.put(TAG_SIZE, NbtHelper.fromBlockPos(size));
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+71
-45
@@ -18,28 +18,34 @@
|
|||||||
|
|
||||||
package appeng.spatial;
|
package appeng.spatial;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import net.minecraft.network.PacketByteBuf;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.text.Text;
|
|
||||||
import net.minecraft.world.dimension.DimensionType;
|
|
||||||
import net.minecraft.server.world.ServerWorld;
|
|
||||||
import net.minecraftforge.common.DimensionManager;
|
|
||||||
import net.minecraftforge.fml.server.ServerLifecycleHooks;
|
|
||||||
|
|
||||||
import appeng.api.storage.ISpatialDimension;
|
import appeng.api.storage.ISpatialDimension;
|
||||||
import appeng.core.AELog;
|
import appeng.core.AELog;
|
||||||
import appeng.core.AppEng;
|
import appeng.core.AppEng;
|
||||||
import appeng.core.localization.GuiText;
|
import appeng.core.localization.GuiText;
|
||||||
|
import appeng.hooks.DynamicDimensions;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
import net.minecraft.util.registry.RegistryKey;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
public final class SpatialDimensionManager implements ISpatialDimension {
|
public final class SpatialDimensionManager implements ISpatialDimension {
|
||||||
|
|
||||||
|
// 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
|
||||||
|
public static final BlockPos REGION_CENTER = new BlockPos(512 / 2, 64, 512 / 2);
|
||||||
|
|
||||||
|
public static final RegistryKey<DimensionType> STORAGE_DIMENSION_TYPE = RegistryKey.of(Registry.DIMENSION_TYPE_KEY, AppEng.makeId("storage_cell"));
|
||||||
|
|
||||||
public static final ISpatialDimension INSTANCE = new SpatialDimensionManager();
|
public static final ISpatialDimension INSTANCE = new SpatialDimensionManager();
|
||||||
|
|
||||||
private static final String DIM_ID_PREFIX = "spatial_";
|
private static final String DIM_ID_PREFIX = "spatial_";
|
||||||
@@ -48,18 +54,26 @@ public final class SpatialDimensionManager implements ISpatialDimension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServerWorld getWorld(DimensionType cellDim) {
|
public ServerWorld getWorld(RegistryKey<World> cellDim) {
|
||||||
return DimensionManager.getWorld(getServer(), cellDim, true, true);
|
MinecraftServer server = getServer();
|
||||||
|
return server.getWorld(cellDim);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DimensionType createNewCellDimension(BlockPos size) {
|
public RegistryKey<World> createNewCellDimension(BlockPos size) {
|
||||||
Identifier dimKey = findFreeDimensionId();
|
Identifier dimKey = findFreeDimensionId();
|
||||||
AELog.info("Allocating storage cell dimension '%s'", dimKey);
|
AELog.info("Allocating storage cell dimension '%s'", dimKey);
|
||||||
|
|
||||||
PacketByteBuf extraData = new SpatialDimensionExtraData(size).write();
|
DynamicDimensions dynamicDimensions = (DynamicDimensions) getServer();
|
||||||
|
|
||||||
return DimensionManager.registerDimension(dimKey, StorageCellModDimension.INSTANCE, extraData, true);
|
RegistryKey<World> worldId = RegistryKey.of(Registry.DIMENSION, dimKey);
|
||||||
|
|
||||||
|
ServerWorld world = dynamicDimensions.addWorld(worldId, STORAGE_DIMENSION_TYPE, StorageChunkGenerator.INSTANCE);
|
||||||
|
|
||||||
|
SpatialDimensionExtraData spatialExtraData = world.getPersistentStateManager().getOrCreate(SpatialDimensionExtraData::new, SpatialDimensionExtraData.ID);
|
||||||
|
spatialExtraData.setSize(size);
|
||||||
|
|
||||||
|
return worldId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -68,8 +82,8 @@ public final class SpatialDimensionManager implements ISpatialDimension {
|
|||||||
*/
|
*/
|
||||||
private Identifier findFreeDimensionId() {
|
private Identifier findFreeDimensionId() {
|
||||||
int maxId = 0;
|
int maxId = 0;
|
||||||
for (DimensionType dimensionType : DimensionType.getAll()) {
|
for (RegistryKey<World> worldId : getServer().getWorldRegistryKeys()) {
|
||||||
Identifier regName = dimensionType.getRegistryName();
|
Identifier regName = worldId.getValue();
|
||||||
if (regName == null || !AppEng.MOD_ID.equals(regName.getNamespace())) {
|
if (regName == null || !AppEng.MOD_ID.equals(regName.getNamespace())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -93,42 +107,52 @@ public final class SpatialDimensionManager implements ISpatialDimension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteCellDimension(DimensionType cellDim) {
|
public void deleteCellDimension(RegistryKey<World> worldId) {
|
||||||
AELog.info("Unregistering storage cell dimension %s", cellDim.getRegistryName());
|
AELog.info("Unregistering storage cell dimension %s", worldId.getValue());
|
||||||
MinecraftServer server = getServer();
|
MinecraftServer server = getServer();
|
||||||
ServerWorld world = DimensionManager.getWorld(server, cellDim, false, false);
|
// FIXME FABRIC ServerWorld world = DimensionManager.getWorld(server, worldId, false, false);
|
||||||
if (world != null) {
|
// FIXME FABRIC if (world != null) {
|
||||||
DimensionManager.unloadWorld(world);
|
// FIXME FABRIC DimensionManager.unloadWorld(world);
|
||||||
}
|
// FIXME FABRIC }
|
||||||
DimensionManager.unloadWorlds(server, true);
|
// FIXME FABRIC DimensionManager.unloadWorlds(server, true);
|
||||||
DimensionManager.unregisterDimension(cellDim.getId());
|
// FIXME FABRIC DimensionManager.unregisterDimension(worldId.getId());
|
||||||
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCellDimension(DimensionType cellDim) {
|
public boolean isCellDimension(RegistryKey<World> worldId) {
|
||||||
// Check if the cell dimension type is even registered
|
Identifier id = worldId.getValue();
|
||||||
if (cellDim.getRegistryName() == null || !cellDim.getRegistryName().equals(DimensionType.getKey(cellDim))) {
|
if (!id.getNamespace().equals(AppEng.MOD_ID)) {
|
||||||
|
return false; // World belongs to a different mod
|
||||||
|
}
|
||||||
|
if (!id.getPath().startsWith(DIM_ID_PREFIX)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cellDim.getModType() instanceof StorageCellModDimension;
|
// Check that the world has the right dimension type
|
||||||
|
ServerWorld world = getServer().getWorld(worldId);
|
||||||
|
if (world == null) {
|
||||||
|
return false; // Non-existent world
|
||||||
|
}
|
||||||
|
|
||||||
|
return world.getDimensionRegistryKey().equals(STORAGE_DIMENSION_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockPos getCellDimensionOrigin(DimensionType cellDim) {
|
public BlockPos getCellDimensionOrigin(RegistryKey<World> worldId) {
|
||||||
return StorageCellDimension.REGION_CENTER;
|
return REGION_CENTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockPos getCellDimensionSize(DimensionType cellDim) {
|
public BlockPos getCellDimensionSize(RegistryKey<World> worldId) {
|
||||||
SpatialDimensionExtraData extraData = getExtraData(cellDim);
|
SpatialDimensionExtraData extraData = getExtraData(worldId);
|
||||||
return extraData != null ? extraData.getSize() : BlockPos.ORIGIN;
|
return extraData != null ? extraData.getSize() : BlockPos.ORIGIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addCellDimensionTooltip(DimensionType cellDim, List<Text> lines) {
|
public void addCellDimensionTooltip(RegistryKey<World> worldId, List<Text> lines) {
|
||||||
// Check if the cell dimension type is even registered
|
// Check if the cell dimension type is even registered
|
||||||
Identifier registryName = cellDim.getRegistryName();
|
Identifier registryName = worldId.getValue();
|
||||||
if (registryName == null || !AppEng.MOD_ID.equals(registryName.getNamespace())) {
|
if (registryName == null || !AppEng.MOD_ID.equals(registryName.getNamespace())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -138,7 +162,7 @@ public final class SpatialDimensionManager implements ISpatialDimension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add the actual stored size
|
// Add the actual stored size
|
||||||
BlockPos size = SpatialDimensionManager.INSTANCE.getCellDimensionSize(cellDim);
|
BlockPos size = SpatialDimensionManager.INSTANCE.getCellDimensionSize(worldId);
|
||||||
lines.add(GuiText.StoredSize.text(size.getX(), size.getY(), size.getZ()));
|
lines.add(GuiText.StoredSize.text(size.getX(), size.getY(), size.getZ()));
|
||||||
|
|
||||||
// Add a serial number to allows players to keep different cells apart
|
// Add a serial number to allows players to keep different cells apart
|
||||||
@@ -156,15 +180,17 @@ public final class SpatialDimensionManager implements ISpatialDimension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private SpatialDimensionExtraData getExtraData(DimensionType cellDim) {
|
private SpatialDimensionExtraData getExtraData(RegistryKey<World> worldId) {
|
||||||
if (!(cellDim.getModType() instanceof StorageCellModDimension)) {
|
ServerWorld world = getWorld(worldId);
|
||||||
|
if (world == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return SpatialDimensionExtraData.read(cellDim.getData());
|
|
||||||
|
return world.getPersistentStateManager().get(SpatialDimensionExtraData::new, SpatialDimensionExtraData.ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MinecraftServer getServer() {
|
private static MinecraftServer getServer() {
|
||||||
return ServerLifecycleHooks.getCurrentServer();
|
return AppEng.instance().getServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* 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.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.world.biome.Biome;
|
||||||
|
import net.minecraft.world.biome.BiomeEffects;
|
||||||
|
import net.minecraft.world.gen.surfacebuilder.ConfiguredSurfaceBuilder;
|
||||||
|
import net.minecraft.world.gen.surfacebuilder.SurfaceBuilder;
|
||||||
|
|
||||||
|
public class StorageCellBiome extends Biome {
|
||||||
|
|
||||||
|
public static final StorageCellBiome INSTANCE = new StorageCellBiome();
|
||||||
|
|
||||||
|
public StorageCellBiome() {
|
||||||
|
super(new Biome.Settings().surfaceBuilder(new ConfiguredSurfaceBuilder<>(SurfaceBuilder.NOPE, SurfaceBuilder.STONE_CONFIG))
|
||||||
|
.precipitation(Precipitation.NONE).category(Category.NONE).depth(0).scale(1)
|
||||||
|
// Copied from the vanilla void biome
|
||||||
|
.temperature(0.5F).downfall(0.5F)
|
||||||
|
.effects(new BiomeEffects.Builder()
|
||||||
|
.waterColor(4159204)
|
||||||
|
.waterFogColor(329011)
|
||||||
|
.fogColor(0)
|
||||||
|
.build())
|
||||||
|
.parent(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public int getSkyColor() {
|
||||||
|
return 0x111111;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* 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 appeng.api.AEApi;
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.BlockView;
|
||||||
|
import net.minecraft.world.ChunkRegion;
|
||||||
|
import net.minecraft.world.Heightmap;
|
||||||
|
import net.minecraft.world.WorldAccess;
|
||||||
|
import net.minecraft.world.biome.source.BiomeAccess;
|
||||||
|
import net.minecraft.world.biome.source.BiomeSource;
|
||||||
|
import net.minecraft.world.biome.source.FixedBiomeSource;
|
||||||
|
import net.minecraft.world.chunk.Chunk;
|
||||||
|
import net.minecraft.world.gen.GenerationStep;
|
||||||
|
import net.minecraft.world.gen.StructureAccessor;
|
||||||
|
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
||||||
|
import net.minecraft.world.gen.chunk.StructuresConfig;
|
||||||
|
import net.minecraft.world.gen.chunk.VerticalBlockSample;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class StorageChunkGenerator extends ChunkGenerator {
|
||||||
|
|
||||||
|
private final VerticalBlockSample columnSample;
|
||||||
|
|
||||||
|
public static final StorageChunkGenerator INSTANCE = new StorageChunkGenerator();
|
||||||
|
|
||||||
|
public static final Codec<StorageChunkGenerator> CODEC = RecordCodecBuilder.create((instance) ->
|
||||||
|
instance.stable(INSTANCE));
|
||||||
|
|
||||||
|
private final BlockState defaultBlockState;
|
||||||
|
|
||||||
|
private StorageChunkGenerator() {
|
||||||
|
super(createBiomeProvider(), createSettings());
|
||||||
|
this.defaultBlockState = AEApi.instance().definitions().blocks().matrixFrame().block().getDefaultState();
|
||||||
|
|
||||||
|
// Vertical sample is mostly used for Feature generation, for those purposes we're all filled with matrix blocks
|
||||||
|
BlockState[] columnSample = new BlockState[256];
|
||||||
|
Arrays.fill(columnSample, this.defaultBlockState);
|
||||||
|
this.columnSample = new VerticalBlockSample(columnSample);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Codec<? extends ChunkGenerator> method_28506() {
|
||||||
|
return CODEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static BiomeSource createBiomeProvider() {
|
||||||
|
return new FixedBiomeSource(StorageCellBiome.INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static StructuresConfig createSettings() {
|
||||||
|
return new StructuresConfig(Optional.empty(), Collections.emptyMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void buildSurface(ChunkRegion region, Chunk chunk) {
|
||||||
|
this.fillChunk(chunk);
|
||||||
|
chunk.setShouldSave(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fillChunk(Chunk 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 getSeaLevel() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChunkGenerator withSeed(long seed) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void populateNoise(WorldAccess world, StructureAccessor accessor, Chunk chunk) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockView getColumnSample(int x, int z) {
|
||||||
|
return columnSample;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getHeight(int p_222529_1_, int p_222529_2_, Heightmap.Type heightmapType) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateFeatures(ChunkRegion region, StructureAccessor accessor) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void carve(long seed, BiomeAccess access, Chunk chunk, GenerationStep.Carver carver) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+11
-9
@@ -18,24 +18,26 @@
|
|||||||
|
|
||||||
package appeng.spatial;
|
package appeng.spatial;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import appeng.api.AEApi;
|
||||||
import java.util.List;
|
import appeng.api.util.WorldCoord;
|
||||||
|
import appeng.core.AppEng;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import net.minecraft.util.math.Box;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Box;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
import net.minecraft.util.registry.RegistryKey;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.chunk.ChunkStatus;
|
import net.minecraft.world.chunk.ChunkStatus;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
|
|
||||||
import appeng.api.AEApi;
|
import java.util.ArrayList;
|
||||||
import appeng.api.util.WorldCoord;
|
import java.util.List;
|
||||||
import appeng.core.AppEng;
|
|
||||||
|
|
||||||
public class StorageHelper {
|
public class StorageHelper {
|
||||||
|
|
||||||
@@ -95,7 +97,7 @@ public class StorageHelper {
|
|||||||
newWorld.getChunkManager().getChunk(MathHelper.floor(link.x) >> 4, MathHelper.floor(link.z) >> 4,
|
newWorld.getChunkManager().getChunk(MathHelper.floor(link.x) >> 4, MathHelper.floor(link.z) >> 4,
|
||||||
ChunkStatus.FULL, true);
|
ChunkStatus.FULL, true);
|
||||||
|
|
||||||
if (entity instanceof ServerPlayerEntity && link.dim.getDimension() instanceof StorageCellDimension) {
|
if (entity instanceof ServerPlayerEntity && link.dim.getDimensionRegistryKey().equals(SpatialDimensionManager.STORAGE_DIMENSION_TYPE)) {
|
||||||
AppEng.instance().getAdvancementTriggers().getSpatialExplorer().trigger((ServerPlayerEntity) entity);
|
AppEng.instance().getAdvancementTriggers().getSpatialExplorer().trigger((ServerPlayerEntity) entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,10 +117,10 @@ public class SpatialIOPortBlockEntity extends AENetworkInvBlockEntity implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void call(final World world) throws Exception {
|
public Void call(final World world) throws Exception {
|
||||||
if (!(world instanceof ServerWorld)) {
|
if (!(this.world instanceof ServerWorld)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
ServerWorld serverWorld = (ServerWorld) world;
|
ServerWorld serverWorld = (ServerWorld) this.world;
|
||||||
|
|
||||||
final ItemStack cell = this.inv.getInvStack(0);
|
final ItemStack cell = this.inv.getInvStack(0);
|
||||||
if (this.isSpatialCell(cell) && this.inv.getInvStack(1).isEmpty()) {
|
if (this.isSpatialCell(cell) && this.inv.getInvStack(1).isEmpty()) {
|
||||||
|
|||||||
@@ -16,3 +16,5 @@ accessible method net/minecraft/data/server/RecipesProvider saveRecipeAdvancemen
|
|||||||
|
|
||||||
accessible method net/minecraft/data/server/BlockLootTableGenerator dropsWithSilkTouch (Lnet/minecraft/block/Block;Lnet/minecraft/loot/entry/LootPoolEntry$Builder;)Lnet/minecraft/loot/LootTable$Builder;
|
accessible method net/minecraft/data/server/BlockLootTableGenerator dropsWithSilkTouch (Lnet/minecraft/block/Block;Lnet/minecraft/loot/entry/LootPoolEntry$Builder;)Lnet/minecraft/loot/LootTable$Builder;
|
||||||
accessible method net/minecraft/data/server/BlockLootTableGenerator applyExplosionDecay (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/loot/function/LootFunctionConsumingBuilder;)Ljava/lang/Object;
|
accessible method net/minecraft/data/server/BlockLootTableGenerator applyExplosionDecay (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/loot/function/LootFunctionConsumingBuilder;)Ljava/lang/Object;
|
||||||
|
|
||||||
|
accessible method net/minecraft/world/dimension/DimensionType <init> (Ljava/util/OptionalLong;ZZZZZZZZZILnet/minecraft/util/Identifier;F)V
|
||||||
|
|||||||
@@ -9,7 +9,10 @@
|
|||||||
"ScreenHandlerListeners",
|
"ScreenHandlerListeners",
|
||||||
"ShapelessRecipeMixin",
|
"ShapelessRecipeMixin",
|
||||||
"SlotMixin",
|
"SlotMixin",
|
||||||
"TntAccessor"
|
"TntAccessor",
|
||||||
|
"DimensionTypeMixin",
|
||||||
|
"MinecraftServerMixin",
|
||||||
|
"ThreadedAnvilChunkStorageAccessor"
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"ModelsReloadMixin",
|
"ModelsReloadMixin",
|
||||||
|
|||||||
@@ -1,12 +1,25 @@
|
|||||||
{
|
{
|
||||||
"parent": "block/cube",
|
"credit": "Made with Blockbench",
|
||||||
"textures": {
|
"parent": "block/cube",
|
||||||
"particle": "appliedenergistics2:block/chest/side",
|
"textures": {
|
||||||
"up": "appliedenergistics2:block/chest/top",
|
"up": "appliedenergistics2:block/chest/top",
|
||||||
"down": "appliedenergistics2:block/chest/bottom",
|
"down": "appliedenergistics2:block/chest/bottom",
|
||||||
"north": "appliedenergistics2:block/chest/front",
|
"north": "appliedenergistics2:block/chest/front",
|
||||||
"east": "appliedenergistics2:block/chest/side",
|
"particle": "appliedenergistics2:block/chest/side",
|
||||||
"south": "appliedenergistics2:block/chest/side",
|
"east": "appliedenergistics2:block/chest/side"
|
||||||
"west": "appliedenergistics2:block/chest/side"
|
},
|
||||||
}
|
"elements": [
|
||||||
}
|
{
|
||||||
|
"from": [0, 0, 0],
|
||||||
|
"to": [16, 16, 16],
|
||||||
|
"faces": {
|
||||||
|
"north": {"uv": [0, 0, 16, 16], "texture": "#north"},
|
||||||
|
"east": {"uv": [0, 0, 16, 16], "texture": "#east"},
|
||||||
|
"south": {"uv": [0, 0, 16, 16], "texture": "#east"},
|
||||||
|
"west": {"uv": [0, 0, 16, 16], "texture": "#east"},
|
||||||
|
"up": {"uv": [0, 0, 16, 16], "texture": "#up"},
|
||||||
|
"down": {"uv": [0, 0, 16, 16], "texture": "#down"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"loader": "appliedenergistics2:spatial_pylon"
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
package appeng.core.worlddata;
|
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
import net.minecraft.network.PacketByteBuf;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import io.netty.buffer.Unpooled;
|
|
||||||
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
|
|
||||||
import appeng.spatial.SpatialDimensionExtraData;
|
|
||||||
|
|
||||||
public class SpatialDimensionExtraDataTest {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The returned buffer should have just the right capacity.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testCreatedBufferSize() {
|
|
||||||
PacketByteBuf buffer = new SpatialDimensionExtraData(BlockPos.ORIGIN).write();
|
|
||||||
assertEquals(1 + 8 + 8, buffer.array().length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testReadWriteSize() {
|
|
||||||
BlockPos capacity = new BlockPos(1, 2, 3);
|
|
||||||
PacketByteBuf buffer = new SpatialDimensionExtraData(capacity).write();
|
|
||||||
|
|
||||||
PacketByteBuf readBackBuf = new PacketByteBuf(Unpooled.wrappedBuffer(buffer.array()));
|
|
||||||
SpatialDimensionExtraData extraData = SpatialDimensionExtraData.read(readBackBuf);
|
|
||||||
assertNotNull(extraData);
|
|
||||||
assertEquals(capacity, extraData.getSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gracefully handle format version errors.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testHandleInvalidFormatVersion() {
|
|
||||||
PacketByteBuf buffer = new SpatialDimensionExtraData(BlockPos.ORIGIN).write();
|
|
||||||
buffer.writerIndex(0);
|
|
||||||
buffer.writeByte(5);
|
|
||||||
|
|
||||||
PacketByteBuf readBackBuf = new PacketByteBuf(Unpooled.wrappedBuffer(buffer.array()));
|
|
||||||
assertNull(SpatialDimensionExtraData.read(readBackBuf));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Applied Energistics 2.
|
|
||||||
* Copyright (c) 2013 - 2017, 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.attributes;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.text.Text;
|
|
||||||
import net.minecraft.world.dimension.DimensionType;
|
|
||||||
import net.minecraft.server.world.ServerWorld;
|
|
||||||
|
|
||||||
import appeng.api.storage.ISpatialDimension;
|
|
||||||
|
|
||||||
class NullSpatialDimension implements ISpatialDimension {
|
|
||||||
@Override
|
|
||||||
public DimensionType createNewCellDimension(BlockPos size) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteCellDimension(DimensionType cellStorageId) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockPos getCellDimensionOrigin(DimensionType cellStorageId) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockPos getCellDimensionSize(DimensionType cellDim) {
|
|
||||||
return BlockPos.ORIGIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addCellDimensionTooltip(DimensionType cellDim, List<Text> tooltip) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ServerWorld getWorld(DimensionType cellStorageId) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCellDimension(DimensionType cellDimID) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
package appeng.spatial;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import io.netty.buffer.Unpooled;
|
|
||||||
|
|
||||||
import net.minecraft.network.PacketByteBuf;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
|
|
||||||
import appeng.core.AELog;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helps with encoding and decoding the extra data we attach to the spatial
|
|
||||||
* {@link net.minecraft.world.dimension.DimensionType} as "extra data". Keep in
|
|
||||||
* mind this data will also be sent to the client unless
|
|
||||||
* {@link net.minecraftforge.common.ModDimension#write(PacketByteBuf, boolean)}
|
|
||||||
* is overridden.
|
|
||||||
*/
|
|
||||||
public final class SpatialDimensionExtraData {
|
|
||||||
|
|
||||||
// Used to allow forward compatibility
|
|
||||||
private static final int CURRENT_FORMAT = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The storage size of this dimension. This is dicateted by the pylon structure
|
|
||||||
* size used to perform the first transfer into this dimension. Once it's set,
|
|
||||||
* it cannot be changed anymore.
|
|
||||||
*/
|
|
||||||
private final BlockPos size;
|
|
||||||
|
|
||||||
public SpatialDimensionExtraData(BlockPos size) {
|
|
||||||
this.size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PacketByteBuf write() {
|
|
||||||
PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer());
|
|
||||||
buf.writeByte(CURRENT_FORMAT);
|
|
||||||
buf.writeBlockPos(size);
|
|
||||||
buf.capacity(buf.writerIndex()); // This cuts the backing buffer to the required size
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockPos getSize() {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static SpatialDimensionExtraData read(@Nullable PacketByteBuf buf) {
|
|
||||||
if (buf == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
buf.readerIndex(0);
|
|
||||||
byte version = buf.readByte();
|
|
||||||
if (version != CURRENT_FORMAT) {
|
|
||||||
// Currently no new format has been defined, as such anything but the current
|
|
||||||
// version is invalid
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockPos size = buf.readBlockPos();
|
|
||||||
return new SpatialDimensionExtraData(size);
|
|
||||||
} catch (IndexOutOfBoundsException e) {
|
|
||||||
AELog.warn(e, "Failed to read spatial storage dimension data.");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,74 +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 net.minecraft.util.SharedSeedRandom;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.WorldAccess;
|
|
||||||
import net.minecraft.world.WorldView;
|
|
||||||
import net.minecraft.world.biome.Biome;
|
|
||||||
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
|
||||||
import net.minecraft.world.gen.GenerationSettings;
|
|
||||||
import net.minecraft.world.gen.GenerationStep;
|
|
||||||
import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder;
|
|
||||||
import net.fabricmc.api.EnvType;
|
|
||||||
import net.fabricmc.api.Environment;
|
|
||||||
|
|
||||||
public class StorageCellBiome extends Biome {
|
|
||||||
|
|
||||||
public static final StorageCellBiome INSTANCE = new StorageCellBiome();
|
|
||||||
|
|
||||||
static {
|
|
||||||
INSTANCE.setRegistryName("appliedenergistics2:storage");
|
|
||||||
}
|
|
||||||
|
|
||||||
public StorageCellBiome() {
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Environment(EnvType.CLIENT)
|
|
||||||
public int getSkyColor() {
|
|
||||||
return 0x111111;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean doesWaterFreeze(WorldView worldIn, BlockPos pos) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean doesWaterFreeze(WorldView worldIn, BlockPos water, boolean mustBeAtEdge) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean doesSnowGenerate(WorldView worldIn, BlockPos pos) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void decorate(GenerationStep.Decoration stage, ChunkGenerator<? extends GenerationSettings> chunkGenerator,
|
|
||||||
WorldAccess worldIn, long seed, SharedSeedRandom random, BlockPos pos) {
|
|
||||||
// Nothing should ever generate here...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -35,11 +35,6 @@ import appeng.client.render.SpatialSkyRender;
|
|||||||
|
|
||||||
public class StorageCellDimension extends Dimension {
|
public class StorageCellDimension extends Dimension {
|
||||||
|
|
||||||
// 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
|
|
||||||
public static final BlockPos REGION_CENTER = new BlockPos(512 / 2, 64, 512 / 2);
|
|
||||||
|
|
||||||
public StorageCellDimension(World world, DimensionType dimensionType) {
|
public StorageCellDimension(World world, DimensionType dimensionType) {
|
||||||
// FIXME: check light value
|
// FIXME: check light value
|
||||||
super(world, dimensionType, 1.0f);
|
super(world, dimensionType, 1.0f);
|
||||||
|
|||||||
@@ -1,96 +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 net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.WorldAccess;
|
|
||||||
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.Chunk;
|
|
||||||
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
|
||||||
import net.minecraft.world.gen.GenerationSettings;
|
|
||||||
import net.minecraft.world.Heightmap;
|
|
||||||
import net.minecraft.world.gen.WorldGenRegion;
|
|
||||||
|
|
||||||
import appeng.api.AEApi;
|
|
||||||
|
|
||||||
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, Chunk chunk) {
|
|
||||||
this.fillChunk(chunk);
|
|
||||||
chunk.setModified(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fillChunk(Chunk 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(WorldAccess worldIn, Chunk chunkIn) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getHeight(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
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user