API Blueprints

- Implement an api for registering schematic requirements for PartialSafeNBT providers for block entities
- Related issue: Creators-of-Create/Create#4702
This commit is contained in:
IThundxr 2024-12-13 10:00:49 -05:00
parent d378f2e529
commit 03b9e6a396
No known key found for this signature in database
34 changed files with 339 additions and 71 deletions

View file

@ -0,0 +1,11 @@
package com.simibubi.create.api.schematic.nbt;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.entity.BlockEntity;
import org.jetbrains.annotations.ApiStatus;
public interface IPartialSafeNBT {
/** This will always be called from the logical server */
void writeSafe(CompoundTag compound);
}

View file

@ -0,0 +1,35 @@
package com.simibubi.create.api.schematic.nbt;
import com.simibubi.create.impl.schematic.nbt.SchematicSafeNBTRegistryImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
/**
* Registry for modifying the data of BlockEntities when being placed with the schematic system.
* </br>
* Mostly used to exclude specific tags that would result in exploits from being written.
*/
public class SchematicSafeNBTRegistry {
/**
* Register a new partial safe nbt provider for a specific blockEntityType
*
* @param blockEntityType The block entity type you would like to register this for
* @param safeNBT The custom PartialSafeNBT provider you would like to register for this blockEntityType,
* your {@link ContextProvidingPartialSafeNBT#writeSafe(BlockEntity, CompoundTag)} method will be
* called on the passed {@link ContextProvidingPartialSafeNBT}
* when the block entities data is being prepared for placement.
*/
public static void register(BlockEntityType<? extends BlockEntity> blockEntityType, ContextProvidingPartialSafeNBT safeNBT) {
SchematicSafeNBTRegistryImpl.register(blockEntityType, safeNBT);
}
// --- Interface that provides the context that would be available if you were to implement IPartialSafeNBT instead ---
@FunctionalInterface
public interface ContextProvidingPartialSafeNBT {
/** This will always be called from the logical server */
void writeSafe(BlockEntity blockEntity, CompoundTag tag);
}
}

View file

@ -0,0 +1,9 @@
package com.simibubi.create.api.schematic.requirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import net.minecraft.world.level.block.state.BlockState;
public interface ISpecialBlockEntityItemRequirement {
ItemRequirement getRequiredItems(BlockState state);
}

View file

@ -0,0 +1,9 @@
package com.simibubi.create.api.schematic.requirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
public interface ISpecialBlockItemRequirement {
ItemRequirement getRequiredItems(BlockState state, BlockEntity blockEntity);
}

View file

@ -0,0 +1,7 @@
package com.simibubi.create.api.schematic.requirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
public interface ISpecialEntityItemRequirement {
ItemRequirement getRequiredItems();
}

View file

@ -0,0 +1,121 @@
package com.simibubi.create.api.schematic.requirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.utility.AttachedRegistry;
import com.simibubi.create.impl.schematic.requirement.SchematicRequirementsRegistryImpl;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.registries.ForgeRegistries;
import org.jetbrains.annotations.ApiStatus;
import java.util.function.BiFunction;
import java.util.function.Function;
/**
* Registry for schematic requirements for blocks, block entities, and entities.
*/
public class SchematicRequirementsRegistry {
/**
* Register a new special requirement for a specified block
*
* @param block The block you want to register a {@link BlockRequirement} for
* @param requirement The requirement you would like to add to this block,
* the {@link BlockRequirement#getRequiredItems(BlockState, BlockEntity)}
* method will be called on the {@link BlockRequirement} you have provided,
* and you will be able to insert requirements based off the context that is given
*/
public static void registerForBlock(Block block, BlockRequirement requirement) {
SchematicRequirementsRegistryImpl.registerForBlock(block, requirement);
}
/**
* Register a new special requirement for a specified block
*
* @param block The id of the block you want to register a {@link BlockRequirement} for
* @param requirement The requirement you would like to add to this block,
* the {@link BlockRequirement#getRequiredItems(BlockState, BlockEntity)}
* method will be called on the {@link BlockRequirement} you have provided,
* and you will be able to insert requirements based off the context that is given
*/
public static void registerForBlock(ResourceLocation block, BlockRequirement requirement) {
SchematicRequirementsRegistryImpl.registerForBlock(block, requirement);
}
/**
* Register a new special requirement for a specified block entity type
*
* @param blockEntityType The blockEntityType you want to register a {@link BlockEntityRequirement} for
* @param requirement The requirement you would like to add to this block entity type,
* the {@link BlockEntityRequirement#getRequiredItems(BlockEntity, BlockState)}
* method will be called on the {@link BlockEntityRequirement} you have provided,
* and you will be able to insert requirements based off the context that is given
*/
public static void registerForBlockEntity(BlockEntityType<BlockEntity> blockEntityType, BlockEntityRequirement requirement) {
SchematicRequirementsRegistryImpl.registerForBlockEntity(blockEntityType, requirement);
}
/**
* Register a new special requirement for a specified block entity type
*
* @param blockEntityType The id of the blockEntityType you want to register a {@link BlockEntityRequirement} for
* @param requirement The requirement you would like to add to this block entity type,
* the {@link BlockEntityRequirement#getRequiredItems(BlockEntity, BlockState)}
* method will be called on the {@link BlockEntityRequirement} you have provided,
* and you will be able to insert requirements based off the context that is given
*/
public static void registerForBlockEntity(ResourceLocation blockEntityType, BlockEntityRequirement requirement) {
SchematicRequirementsRegistryImpl.registerForBlockEntity(blockEntityType, requirement);
}
/**
* Register a new special requirement for a specified entity type
*
* @param entityType The entityType you want to register a {@link EntityRequirement} for
* @param requirement The requirement you would like to add to this entity type,
* the {@link EntityRequirement#getRequiredItems(Entity)}
* method will be called on the {@link EntityRequirement} you have provided,
* and you will be able to insert requirements based off the context that is given
*/
public static void registerForEntity(EntityType<Entity> entityType, EntityRequirement requirement) {
SchematicRequirementsRegistryImpl.registerForEntity(entityType, requirement);
}
/**
* Register a new special requirement for a specified entity type
*
* @param entityType The id of the entityType you want to register a {@link EntityRequirement} for
* @param requirement The requirement you would like to add to this entity type,
* the {@link EntityRequirement#getRequiredItems(Entity)}
* method will be called on the {@link EntityRequirement} you have provided,
* and you will be able to insert requirements based off the context that is given
*/
public static void registerForEntity(ResourceLocation entityType, EntityRequirement requirement) {
SchematicRequirementsRegistryImpl.registerForEntity(entityType, requirement);
}
// --- Interfaces that provide the context that would be accessible if you implemented the ISpecial* interfaces ---
@FunctionalInterface
public interface BlockRequirement {
ItemRequirement getRequiredItems(BlockState state, BlockEntity blockEntity);
}
@FunctionalInterface
public interface BlockEntityRequirement {
ItemRequirement getRequiredItems(BlockEntity blockEntity, BlockState state);
}
@FunctionalInterface
public interface EntityRequirement {
ItemRequirement getRequiredItems(Entity entity);
}
}

View file

@ -6,7 +6,7 @@ import com.simibubi.create.AllItems;
import com.simibubi.create.content.contraptions.elevator.ElevatorColumn.ColumnCoords;
import com.simibubi.create.content.redstone.contact.RedstoneContactBlock;
import com.simibubi.create.content.redstone.diodes.BrassDiodeBlock;
import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.block.IBE;
import com.simibubi.create.foundation.block.WrenchableDirectionalBlock;

View file

@ -12,7 +12,7 @@ import com.simibubi.create.content.contraptions.BlockMovementChecks;
import com.simibubi.create.content.contraptions.bearing.BearingBlock;
import com.simibubi.create.content.contraptions.chassis.AbstractChassisBlock;
import com.simibubi.create.content.kinetics.base.DirectionalKineticBlock;
import com.simibubi.create.content.schematics.requirement.ISpecialEntityItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialEntityItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement.ItemUseType;

View file

@ -5,7 +5,7 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.content.redstone.rail.ControllerRailBlock;
import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement.ItemUseType;
import com.simibubi.create.foundation.block.IBE;

View file

@ -4,12 +4,12 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.ITransformableBlockEntity;
import com.simibubi.create.content.contraptions.StructureTransform;
import com.simibubi.create.content.redstone.RoseQuartzLampBlock;
import com.simibubi.create.content.schematics.requirement.ISpecialBlockEntityItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockEntityItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement.ItemUseType;
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.utility.IPartialSafeNBT;
import com.simibubi.create.api.schematic.nbt.IPartialSafeNBT;
import net.createmod.catnip.utility.Iterate;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;

View file

@ -8,7 +8,7 @@ import com.simibubi.create.AllShapes;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.content.kinetics.base.HorizontalAxisKineticBlock;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.block.IBE;

View file

@ -9,7 +9,7 @@ import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.content.logistics.filter.FilterItem;
import com.simibubi.create.content.logistics.filter.FilterItemStack;
import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement.ItemUseType;
import com.simibubi.create.foundation.block.IBE;

View file

@ -7,7 +7,7 @@ import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllEnchantments;
import com.simibubi.create.AllShapes;
import com.simibubi.create.content.kinetics.base.HorizontalKineticBlock;
import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement.ItemUseType;
import com.simibubi.create.foundation.block.IBE;

View file

@ -13,7 +13,7 @@ import com.simibubi.create.AllEntityTypes;
import com.simibubi.create.AllItems;
import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.filter.FilterItemStack;
import com.simibubi.create.content.schematics.requirement.ISpecialEntityItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialEntityItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement.ItemUseType;
import com.simibubi.create.foundation.networking.ISyncPersistentData;
@ -207,7 +207,7 @@ public class BlueprintEntity extends HangingEntity
d6 = d6 / 32.0D;
this.setBoundingBox(new AABB(d1 - d4, d2 - d5, d3 - d6, d1 + d4, d2 + d5, d3 + d6));
}
@Override
public void setPos(double pX, double pY, double pZ) {
setPosRaw(pX, pY, pZ);

View file

@ -18,7 +18,7 @@ import com.simibubi.create.content.decoration.encasing.EncasedBlock;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.content.fluids.FluidPropagator;
import com.simibubi.create.content.fluids.FluidTransportBehaviour;
import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.advancement.AdvancementBehaviour;
import com.simibubi.create.foundation.block.IBE;

View file

@ -5,7 +5,7 @@ import javax.annotation.ParametersAreNonnullByDefault;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.fluids.FluidTransportBehaviour;
import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.block.IBE;

View file

@ -28,7 +28,7 @@ import com.simibubi.create.content.logistics.box.PackageEntity;
import com.simibubi.create.content.logistics.box.PackageItem;
import com.simibubi.create.content.logistics.funnel.FunnelBlock;
import com.simibubi.create.content.logistics.tunnel.BeltTunnelBlock;
import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement.ItemUseType;
import com.simibubi.create.foundation.block.IBE;
@ -292,7 +292,7 @@ public class BeltBlock extends HorizontalKineticBlock
return InteractionResult.SUCCESS;
}
}
if (isHand) {
BeltBlockEntity controllerBelt = belt.getControllerBE();
if (controllerBelt == null)

View file

@ -14,7 +14,7 @@ import com.simibubi.create.content.kinetics.base.RotatedPillarKineticBlock;
import com.simibubi.create.content.kinetics.simpleRelays.CogWheelBlock;
import com.simibubi.create.content.kinetics.simpleRelays.ICogWheel;
import com.simibubi.create.content.kinetics.simpleRelays.SimpleKineticBlockEntity;
import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.block.IBE;

View file

@ -8,7 +8,7 @@ import com.simibubi.create.content.decoration.encasing.EncasedBlock;
import com.simibubi.create.content.kinetics.base.AbstractEncasedShaftBlock;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.content.kinetics.base.RotatedPillarKineticBlock;
import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.block.IBE;

View file

@ -5,7 +5,7 @@ import com.simibubi.create.AllShapes;
import com.simibubi.create.content.kinetics.belt.BeltBlock;
import com.simibubi.create.content.kinetics.belt.BeltSlope;
import com.simibubi.create.content.kinetics.belt.behaviour.DirectBeltInputBehaviour;
import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.advancement.AllAdvancements;
import com.simibubi.create.foundation.block.ProperWaterloggedBlock;

View file

@ -5,7 +5,7 @@ import java.util.ArrayList;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllItems;
import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.block.IBE;

View file

@ -10,7 +10,7 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes;
import com.simibubi.create.content.equipment.clipboard.ClipboardEntry;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement.ItemUseType;
import com.simibubi.create.foundation.block.IBE;

View file

@ -1,9 +0,0 @@
package com.simibubi.create.content.schematics.requirement;
import net.minecraft.world.level.block.state.BlockState;
public interface ISpecialBlockEntityItemRequirement {
public ItemRequirement getRequiredItems(BlockState state);
}

View file

@ -1,10 +0,0 @@
package com.simibubi.create.content.schematics.requirement;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
public interface ISpecialBlockItemRequirement {
public ItemRequirement getRequiredItems(BlockState state, BlockEntity blockEntity);
}

View file

@ -1,7 +0,0 @@
package com.simibubi.create.content.schematics.requirement;
public interface ISpecialEntityItemRequirement {
public ItemRequirement getRequiredItems();
}

View file

@ -3,12 +3,20 @@ package com.simibubi.create.content.schematics.requirement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockEntityItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialEntityItemRequirement;
import com.simibubi.create.api.schematic.requirement.SchematicRequirementsRegistry;
import com.simibubi.create.compat.framedblocks.FramedBlocksInSchematics;
import com.simibubi.create.foundation.data.recipe.Mods;
import com.simibubi.create.impl.schematic.requirement.SchematicRequirementsRegistryImpl;
import net.createmod.catnip.utility.NBTProcessors;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.decoration.ArmorStand;
@ -63,17 +71,23 @@ public class ItemRequirement {
Block block = state.getBlock();
ItemRequirement requirement;
if (block instanceof ISpecialBlockItemRequirement specialBlock) {
SchematicRequirementsRegistry.BlockRequirement blockItemRequirement = SchematicRequirementsRegistryImpl.getRequirementForBlock(block);
if (blockItemRequirement != null) {
requirement = blockItemRequirement.getRequiredItems(state, be);
} else if (block instanceof ISpecialBlockItemRequirement specialBlock) {
requirement = specialBlock.getRequiredItems(state, be);
} else {
requirement = defaultOf(state, be);
}
if (be instanceof ISpecialBlockEntityItemRequirement specialBE)
SchematicRequirementsRegistry.BlockEntityRequirement blockEntityItemRequirement = SchematicRequirementsRegistryImpl.getRequirementForBlockEntityType(be.getType());
if (blockEntityItemRequirement != null) {
requirement = requirement.union(blockEntityItemRequirement.getRequiredItems(be, state));
} else if (be instanceof ISpecialBlockEntityItemRequirement specialBE) {
requirement = requirement.union(specialBE.getRequiredItems(state));
if (com.simibubi.create.compat.Mods.FRAMEDBLOCKS.contains(block))
} else if (com.simibubi.create.compat.Mods.FRAMEDBLOCKS.contains(block)) {
requirement = requirement.union(FramedBlocksInSchematics.getRequiredItems(state, be));
}
return requirement;
}
@ -118,8 +132,12 @@ public class ItemRequirement {
}
public static ItemRequirement of(Entity entity) {
if (entity instanceof ISpecialEntityItemRequirement specialEntity)
SchematicRequirementsRegistry.EntityRequirement entityItemRequirement = SchematicRequirementsRegistryImpl.getRequirementForEntityType(entity.getType());
if (entityItemRequirement != null) {
return entityItemRequirement.getRequiredItems(entity);
} else if (entity instanceof ISpecialEntityItemRequirement specialEntity) {
return specialEntity.getRequiredItems();
}
if (entity instanceof ItemFrame itemFrame) {
ItemStack frame = new ItemStack(Items.ITEM_FRAME);

View file

@ -17,7 +17,7 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllBogeyStyles;
import com.simibubi.create.AllItems;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.content.trains.entity.Carriage;
import com.simibubi.create.content.trains.entity.CarriageBogey;

View file

@ -3,7 +3,7 @@ package com.simibubi.create.content.trains.bogey;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllBogeyStyles;
import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.trains.track.TrackMaterial;
import com.simibubi.create.foundation.block.IBE;
import com.simibubi.create.foundation.block.ProperWaterloggedBlock;

View file

@ -30,7 +30,7 @@ import com.simibubi.create.AllShapes;
import com.simibubi.create.AllTags;
import com.simibubi.create.content.decoration.girder.GirderBlock;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement.ItemUseType;
import com.simibubi.create.content.trains.CubeParticleData;

View file

@ -8,14 +8,14 @@ import java.util.Map;
import java.util.function.Consumer;
import com.simibubi.create.api.event.BlockEntityBehaviourEvent;
import com.simibubi.create.content.schematics.requirement.ISpecialBlockEntityItemRequirement;
import com.simibubi.create.api.schematic.requirement.ISpecialBlockEntityItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.advancement.AdvancementBehaviour;
import com.simibubi.create.foundation.advancement.CreateAdvancement;
import com.simibubi.create.foundation.blockEntity.behaviour.BehaviourType;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.utility.IInteractionChecker;
import com.simibubi.create.foundation.utility.IPartialSafeNBT;
import com.simibubi.create.api.schematic.nbt.IPartialSafeNBT;
import net.createmod.ponder.api.VirtualBlockEntity;
import net.minecraft.core.BlockPos;

View file

@ -1,11 +1,14 @@
package com.simibubi.create.foundation.utility;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import javax.annotation.Nullable;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllTags.AllBlockTags;
import com.simibubi.create.api.schematic.nbt.IPartialSafeNBT;
import com.simibubi.create.api.schematic.nbt.SchematicSafeNBTRegistry;
import com.simibubi.create.compat.Mods;
import com.simibubi.create.compat.framedblocks.FramedBlocksInSchematics;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
@ -14,6 +17,8 @@ import com.simibubi.create.content.processing.burner.BlazeBurnerBlock.HeatLevel;
import com.simibubi.create.foundation.blockEntity.IMergeableBE;
import com.simibubi.create.foundation.blockEntity.IMultiBlockEntityContainer;
import com.simibubi.create.impl.schematic.nbt.SchematicSafeNBTRegistryImpl;
import net.createmod.catnip.utility.NBTProcessors;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@ -243,18 +248,21 @@ public class BlockHelper {
public static CompoundTag prepareBlockEntityData(BlockState blockState, BlockEntity blockEntity) {
CompoundTag data = null;
if (blockEntity == null)
return data;
return null;
SchematicSafeNBTRegistry.ContextProvidingPartialSafeNBT safeNBT = SchematicSafeNBTRegistryImpl.getPartialSafeNBT(blockEntity.getType());
if (AllBlockTags.SAFE_NBT.matches(blockState)) {
data = blockEntity.saveWithFullMetadata();
} else if (blockEntity instanceof IPartialSafeNBT) {
} else if (safeNBT != null) {
data = new CompoundTag();
((IPartialSafeNBT) blockEntity).writeSafe(data);
} else if (Mods.FRAMEDBLOCKS.contains(blockState.getBlock()))
safeNBT.writeSafe(blockEntity, data);
} else if (blockEntity instanceof IPartialSafeNBT safeNbtBE) {
data = new CompoundTag();
safeNbtBE.writeSafe(data);
} else if (Mods.FRAMEDBLOCKS.contains(blockState.getBlock())) {
data = FramedBlocksInSchematics.prepareBlockEntityData(blockState, blockEntity);
}
return NBTProcessors.process(blockState, blockEntity, data, true);
}

View file

@ -1,8 +0,0 @@
package com.simibubi.create.foundation.utility;
import net.minecraft.nbt.CompoundTag;
public interface IPartialSafeNBT {
/** This method always runs on the logical server. */
public void writeSafe(CompoundTag compound);
}

View file

@ -0,0 +1,23 @@
package com.simibubi.create.impl.schematic.nbt;
import com.simibubi.create.api.schematic.nbt.SchematicSafeNBTRegistry;
import com.simibubi.create.foundation.utility.AttachedRegistry;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraftforge.registries.ForgeRegistries;
import org.jetbrains.annotations.ApiStatus;
@ApiStatus.Internal
public class SchematicSafeNBTRegistryImpl {
private static final AttachedRegistry<BlockEntityType<? extends BlockEntity>, SchematicSafeNBTRegistry.ContextProvidingPartialSafeNBT> BLOCK_ENTITY_PARTIAL_SAFE_NBT = new AttachedRegistry<>(ForgeRegistries.BLOCK_ENTITY_TYPES);
public static void register(BlockEntityType<? extends BlockEntity> blockEntityType, SchematicSafeNBTRegistry.ContextProvidingPartialSafeNBT safeNBT) {
BLOCK_ENTITY_PARTIAL_SAFE_NBT.register(blockEntityType, safeNBT);
}
public static SchematicSafeNBTRegistry.ContextProvidingPartialSafeNBT getPartialSafeNBT(BlockEntityType<? extends BlockEntity> blockEntityType) {
return BLOCK_ENTITY_PARTIAL_SAFE_NBT.get(blockEntityType);
}
}

View file

@ -0,0 +1,61 @@
package com.simibubi.create.impl.schematic.requirement;
import com.simibubi.create.api.schematic.requirement.SchematicRequirementsRegistry;
import com.simibubi.create.foundation.utility.AttachedRegistry;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraftforge.registries.ForgeRegistries;
import org.jetbrains.annotations.ApiStatus;
@ApiStatus.Internal
public class SchematicRequirementsRegistryImpl {
private static final AttachedRegistry<Block, SchematicRequirementsRegistry.BlockRequirement> BLOCK_REQUIREMENTS = new AttachedRegistry<>(ForgeRegistries.BLOCKS);
private static final AttachedRegistry<BlockEntityType<? extends BlockEntity>, SchematicRequirementsRegistry.BlockEntityRequirement> BLOCK_ENTITY_REQUIREMENTS = new AttachedRegistry<>(ForgeRegistries.BLOCK_ENTITY_TYPES);
private static final AttachedRegistry<EntityType<? extends Entity>, SchematicRequirementsRegistry.EntityRequirement> ENTITY_REQUIREMENTS = new AttachedRegistry<>(ForgeRegistries.ENTITY_TYPES);
public static void registerForBlock(Block block, SchematicRequirementsRegistry.BlockRequirement requirement) {
BLOCK_REQUIREMENTS.register(block, requirement);
}
public static void registerForBlock(ResourceLocation block, SchematicRequirementsRegistry.BlockRequirement requirement) {
BLOCK_REQUIREMENTS.register(block, requirement);
}
public static void registerForBlockEntity(BlockEntityType<BlockEntity> blockEntityType, SchematicRequirementsRegistry.BlockEntityRequirement requirement) {
BLOCK_ENTITY_REQUIREMENTS.register(blockEntityType, requirement);
}
public static void registerForBlockEntity(ResourceLocation blockEntityType, SchematicRequirementsRegistry.BlockEntityRequirement requirement) {
BLOCK_ENTITY_REQUIREMENTS.register(blockEntityType, requirement);
}
public static void registerForEntity(EntityType<Entity> entityType, SchematicRequirementsRegistry.EntityRequirement requirement) {
ENTITY_REQUIREMENTS.register(entityType, requirement);
}
// ---
public static void registerForEntity(ResourceLocation entityType, SchematicRequirementsRegistry.EntityRequirement requirement) {
ENTITY_REQUIREMENTS.register(entityType, requirement);
}
public static SchematicRequirementsRegistry.BlockRequirement getRequirementForBlock(Block block) {
return BLOCK_REQUIREMENTS.get(block);
}
public static SchematicRequirementsRegistry.BlockEntityRequirement getRequirementForBlockEntityType(BlockEntityType<? extends BlockEntity> blockEntityType) {
return BLOCK_ENTITY_REQUIREMENTS.get(blockEntityType);
}
public static SchematicRequirementsRegistry.EntityRequirement getRequirementForEntityType(EntityType<? extends Entity> entityType) {
return ENTITY_REQUIREMENTS.get(entityType);
}
}