mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-03-04 06:44:40 +01:00
AttachedRegistry refactors, and several adjacent ones
This commit is contained in:
parent
888d175695
commit
41d725878e
36 changed files with 568 additions and 992 deletions
|
@ -3,8 +3,8 @@ package com.simibubi.create;
|
|||
import static com.simibubi.create.AllInteractionBehaviours.interactionBehaviour;
|
||||
import static com.simibubi.create.AllMovementBehaviours.movementBehaviour;
|
||||
import static com.simibubi.create.Create.REGISTRATE;
|
||||
import static com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistry.mountedFluidStorage;
|
||||
import static com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistry.mountedItemStorage;
|
||||
import static com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistries.mountedFluidStorage;
|
||||
import static com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistries.mountedItemStorage;
|
||||
import static com.simibubi.create.content.redstone.displayLink.AllDisplayBehaviours.assignDataBehaviour;
|
||||
import static com.simibubi.create.foundation.data.BlockStateGen.axisBlock;
|
||||
import static com.simibubi.create.foundation.data.BlockStateGen.simpleCubeAll;
|
||||
|
@ -768,7 +768,7 @@ public class AllBlocks {
|
|||
.loot((lt, block) -> lt.add(block, BlazeBurnerBlock.buildLootTable()))
|
||||
.blockstate((c, p) -> p.simpleBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p)))
|
||||
.onRegister(movementBehaviour(new BlazeBurnerMovementBehaviour()))
|
||||
.onRegister(block -> TrainConductorHandler.registerBlazeBurner())
|
||||
.onRegister(TrainConductorHandler::registerBlazeBurner)
|
||||
.item(BlazeBurnerBlockItem::withBlaze)
|
||||
.model(AssetLookup.customBlockItemModel("blaze_burner", "block_with_blaze"))
|
||||
.build()
|
||||
|
|
|
@ -1,94 +1,39 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.api.registry.AttachedRegistry;
|
||||
import com.simibubi.create.content.contraptions.behaviour.DoorMovingInteraction;
|
||||
import com.simibubi.create.content.contraptions.behaviour.FenceGateMovingInteraction;
|
||||
import com.simibubi.create.content.contraptions.behaviour.LeverMovingInteraction;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovingInteractionBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.TrapdoorMovingInteraction;
|
||||
import com.simibubi.create.foundation.utility.AttachedRegistry;
|
||||
import com.tterrag.registrate.util.nullness.NonNullConsumer;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
public class AllInteractionBehaviours {
|
||||
private static final AttachedRegistry<Block, MovingInteractionBehaviour> BLOCK_BEHAVIOURS = new AttachedRegistry<>(ForgeRegistries.BLOCKS);
|
||||
private static final List<BehaviourProvider> GLOBAL_BEHAVIOURS = new ArrayList<>();
|
||||
|
||||
public static void registerBehaviour(ResourceLocation block, MovingInteractionBehaviour provider) {
|
||||
BLOCK_BEHAVIOURS.register(block, provider);
|
||||
}
|
||||
|
||||
public static void registerBehaviour(Block block, MovingInteractionBehaviour provider) {
|
||||
BLOCK_BEHAVIOURS.register(block, provider);
|
||||
}
|
||||
|
||||
public static void registerBehaviourProvider(BehaviourProvider provider) {
|
||||
GLOBAL_BEHAVIOURS.add(provider);
|
||||
}
|
||||
public static final AttachedRegistry<Block, MovingInteractionBehaviour> REGISTRY = AttachedRegistry.create();
|
||||
|
||||
@Nullable
|
||||
public static MovingInteractionBehaviour getBehaviour(BlockState state) {
|
||||
MovingInteractionBehaviour behaviour = BLOCK_BEHAVIOURS.get(state.getBlock());
|
||||
if (behaviour != null) {
|
||||
return behaviour;
|
||||
return REGISTRY.get(state.getBlock());
|
||||
}
|
||||
|
||||
for (BehaviourProvider provider : GLOBAL_BEHAVIOURS) {
|
||||
behaviour = provider.getBehaviour(state);
|
||||
if (behaviour != null) {
|
||||
return behaviour;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <B extends Block> NonNullConsumer<? super B> interactionBehaviour(
|
||||
MovingInteractionBehaviour behaviour) {
|
||||
return b -> registerBehaviour(b, behaviour);
|
||||
/**
|
||||
* Creates a consumer that will register a behavior to a block. Useful for Registrate.
|
||||
*/
|
||||
public static <B extends Block> NonNullConsumer<? super B> interactionBehaviour(MovingInteractionBehaviour behaviour) {
|
||||
return b -> REGISTRY.register(b, behaviour);
|
||||
}
|
||||
|
||||
static void registerDefaults() {
|
||||
registerBehaviour(Blocks.LEVER, new LeverMovingInteraction());
|
||||
REGISTRY.register(Blocks.LEVER, new LeverMovingInteraction());
|
||||
|
||||
DoorMovingInteraction doorBehaviour = new DoorMovingInteraction();
|
||||
registerBehaviourProvider(state -> {
|
||||
if (state.is(BlockTags.WOODEN_DOORS)) {
|
||||
return doorBehaviour;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
TrapdoorMovingInteraction trapdoorBehaviour = new TrapdoorMovingInteraction();
|
||||
registerBehaviourProvider(state -> {
|
||||
if (state.is(BlockTags.WOODEN_TRAPDOORS)) {
|
||||
return trapdoorBehaviour;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
FenceGateMovingInteraction fenceGateBehavior = new FenceGateMovingInteraction();
|
||||
registerBehaviourProvider(state -> {
|
||||
if (state.is(BlockTags.FENCE_GATES)) {
|
||||
return fenceGateBehavior;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public interface BehaviourProvider {
|
||||
@Nullable
|
||||
MovingInteractionBehaviour getBehaviour(BlockState state);
|
||||
REGISTRY.registerProvider(AttachedRegistry.Provider.forBlockTag(BlockTags.WOODEN_DOORS, new DoorMovingInteraction()));
|
||||
REGISTRY.registerProvider(AttachedRegistry.Provider.forBlockTag(BlockTags.WOODEN_TRAPDOORS, new TrapdoorMovingInteraction()));
|
||||
REGISTRY.registerProvider(AttachedRegistry.Provider.forBlockTag(BlockTags.FENCE_GATES, new TrapdoorMovingInteraction()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,74 +1,41 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.api.registry.AttachedRegistry;
|
||||
import com.simibubi.create.content.contraptions.behaviour.BellMovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.CampfireMovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.dispenser.DispenserMovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.dispenser.DropperMovementBehaviour;
|
||||
import com.simibubi.create.foundation.utility.AttachedRegistry;
|
||||
import com.tterrag.registrate.util.nullness.NonNullConsumer;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
public class AllMovementBehaviours {
|
||||
private static final AttachedRegistry<Block, MovementBehaviour> BLOCK_BEHAVIOURS = new AttachedRegistry<>(ForgeRegistries.BLOCKS);
|
||||
private static final List<BehaviourProvider> GLOBAL_BEHAVIOURS = new ArrayList<>();
|
||||
|
||||
public static void registerBehaviour(ResourceLocation block, MovementBehaviour behaviour) {
|
||||
BLOCK_BEHAVIOURS.register(block, behaviour);
|
||||
}
|
||||
|
||||
public static void registerBehaviour(Block block, MovementBehaviour behaviour) {
|
||||
BLOCK_BEHAVIOURS.register(block, behaviour);
|
||||
}
|
||||
|
||||
public static void registerBehaviourProvider(BehaviourProvider provider) {
|
||||
GLOBAL_BEHAVIOURS.add(provider);
|
||||
}
|
||||
public static final AttachedRegistry<Block, MovementBehaviour> REGISTRY = AttachedRegistry.create();
|
||||
|
||||
@Nullable
|
||||
public static MovementBehaviour getBehaviour(BlockState state) {
|
||||
MovementBehaviour behaviour = BLOCK_BEHAVIOURS.get(state.getBlock());
|
||||
if (behaviour != null) {
|
||||
return behaviour;
|
||||
return REGISTRY.get(state.getBlock());
|
||||
}
|
||||
|
||||
for (BehaviourProvider provider : GLOBAL_BEHAVIOURS) {
|
||||
behaviour = provider.getBehaviour(state);
|
||||
if (behaviour != null) {
|
||||
return behaviour;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <B extends Block> NonNullConsumer<? super B> movementBehaviour(
|
||||
MovementBehaviour behaviour) {
|
||||
return b -> registerBehaviour(b, behaviour);
|
||||
/**
|
||||
* Creates a consumer that will register a behavior to a block. Useful for Registrate.
|
||||
*/
|
||||
public static <B extends Block> NonNullConsumer<? super B> movementBehaviour(MovementBehaviour behaviour) {
|
||||
return b -> REGISTRY.register(b, behaviour);
|
||||
}
|
||||
|
||||
static void registerDefaults() {
|
||||
registerBehaviour(Blocks.BELL, new BellMovementBehaviour());
|
||||
registerBehaviour(Blocks.CAMPFIRE, new CampfireMovementBehaviour());
|
||||
registerBehaviour(Blocks.SOUL_CAMPFIRE, new CampfireMovementBehaviour());
|
||||
REGISTRY.register(Blocks.BELL, new BellMovementBehaviour());
|
||||
REGISTRY.register(Blocks.CAMPFIRE, new CampfireMovementBehaviour());
|
||||
REGISTRY.register(Blocks.SOUL_CAMPFIRE, new CampfireMovementBehaviour());
|
||||
|
||||
DispenserMovementBehaviour.gatherMovedDispenseItemBehaviours();
|
||||
registerBehaviour(Blocks.DISPENSER, new DispenserMovementBehaviour());
|
||||
registerBehaviour(Blocks.DROPPER, new DropperMovementBehaviour());
|
||||
}
|
||||
|
||||
public interface BehaviourProvider {
|
||||
@Nullable
|
||||
MovementBehaviour getBehaviour(BlockState state);
|
||||
REGISTRY.register(Blocks.DISPENSER, new DispenserMovementBehaviour());
|
||||
REGISTRY.register(Blocks.DROPPER, new DropperMovementBehaviour());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,6 @@ import com.simibubi.create.foundation.data.CreateRegistrate;
|
|||
import com.simibubi.create.foundation.item.ItemDescription;
|
||||
import com.simibubi.create.foundation.item.KineticStats;
|
||||
import com.simibubi.create.foundation.item.TooltipModifier;
|
||||
import com.simibubi.create.foundation.utility.AttachedRegistry;
|
||||
import com.simibubi.create.foundation.utility.CreateNBTProcessors;
|
||||
import com.simibubi.create.infrastructure.command.ServerLagger;
|
||||
import com.simibubi.create.infrastructure.config.AllConfigs;
|
||||
|
@ -48,6 +47,7 @@ import net.minecraft.resources.ResourceLocation;
|
|||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.item.CreativeModeTab;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.common.ForgeMod;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
|
@ -140,8 +140,6 @@ public class Create {
|
|||
// FIXME: some of these registrations are not thread-safe
|
||||
AllMovementBehaviours.registerDefaults();
|
||||
AllInteractionBehaviours.registerDefaults();
|
||||
AllPortalTracks.registerDefaults();
|
||||
AllDisplayBehaviours.registerDefaults();
|
||||
ContraptionMovementSetting.registerDefaults();
|
||||
BogeySizes.init();
|
||||
AllBogeyStyles.init();
|
||||
|
@ -173,9 +171,10 @@ public class Create {
|
|||
// These registrations use Create's registered objects directly so they must run after registration has finished.
|
||||
BuiltinPotatoProjectileTypes.register();
|
||||
BoilerHeaters.registerDefaults();
|
||||
AllPortalTracks.registerDefaults();
|
||||
AllDisplayBehaviours.registerDefaults();
|
||||
// --
|
||||
|
||||
AttachedRegistry.unwrapAll();
|
||||
AllAdvancements.register();
|
||||
AllTriggers.register();
|
||||
});
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.simibubi.create.api.contraption.storage;
|
|||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorageType;
|
||||
import com.simibubi.create.api.contraption.storage.item.MountedItemStorageType;
|
||||
import com.simibubi.create.api.lookup.BlockLookup;
|
||||
import com.simibubi.create.api.registry.AttachedRegistry;
|
||||
import com.simibubi.create.impl.contraption.storage.MountedStorageTypeRegistryImpl;
|
||||
import com.tterrag.registrate.builders.BlockBuilder;
|
||||
import com.tterrag.registrate.util.entry.RegistryEntry;
|
||||
|
@ -12,9 +12,10 @@ import com.tterrag.registrate.util.nullness.NonNullUnaryOperator;
|
|||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
import net.minecraftforge.registries.IForgeRegistry;
|
||||
|
||||
public class MountedStorageTypeRegistry {
|
||||
public class MountedStorageTypeRegistries {
|
||||
public static final ResourceKey<Registry<MountedItemStorageType<?>>> ITEMS = ResourceKey.createRegistryKey(
|
||||
Create.asResource("mounted_item_storage_type")
|
||||
);
|
||||
|
@ -22,16 +23,8 @@ public class MountedStorageTypeRegistry {
|
|||
Create.asResource("mounted_fluid_storage_type")
|
||||
);
|
||||
|
||||
/**
|
||||
* Lookup used for finding the item storage type associated with a block.
|
||||
* @see BlockLookup
|
||||
*/
|
||||
public static final BlockLookup<MountedItemStorageType<?>> ITEM_LOOKUP = MountedStorageTypeRegistryImpl.ITEM_LOOKUP;
|
||||
/**
|
||||
* Lookup used for finding the fluid storage type associated with a block.
|
||||
* @see BlockLookup
|
||||
*/
|
||||
public static final BlockLookup<MountedFluidStorageType<?>> FLUID_LOOKUP = MountedStorageTypeRegistryImpl.FLUID_LOOKUP;
|
||||
public static final AttachedRegistry<Block, MountedItemStorageType<?>> ITEM_STORAGES = MountedStorageTypeRegistryImpl.ITEM_STORAGES;
|
||||
public static final AttachedRegistry<Block, MountedFluidStorageType<?>> FLUID_STORAGES = MountedStorageTypeRegistryImpl.FLUID_STORAGES;
|
||||
|
||||
/**
|
||||
* @throws NullPointerException if called before registry registration
|
||||
|
@ -52,7 +45,7 @@ public class MountedStorageTypeRegistry {
|
|||
* that will register the given MountedItemStorageType to a block when ready.
|
||||
*/
|
||||
public static <B extends Block, P> NonNullUnaryOperator<BlockBuilder<B, P>> mountedItemStorage(RegistryEntry<? extends MountedItemStorageType<?>> type) {
|
||||
return builder -> builder.onRegisterAfter(ITEMS, block -> ITEM_LOOKUP.register(block, type.get()));
|
||||
return builder -> builder.onRegisterAfter(ITEMS, block -> ITEM_STORAGES.register(block, type.get()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,6 +53,6 @@ public class MountedStorageTypeRegistry {
|
|||
* that will register the given MountedFluidStorageType to a block when ready.
|
||||
*/
|
||||
public static <B extends Block, P> NonNullUnaryOperator<BlockBuilder<B, P>> mountedFluidStorage(RegistryEntry<? extends MountedFluidStorageType<?>> type) {
|
||||
return builder -> builder.onRegisterAfter(ITEMS, block -> FLUID_LOOKUP.register(block, type.get()));
|
||||
return builder -> builder.onRegisterAfter(ITEMS, block -> FLUID_STORAGES.register(block, type.get()));
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ package com.simibubi.create.api.contraption.storage.fluid;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistry;
|
||||
import com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistries;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.ExtraCodecs;
|
||||
|
@ -13,7 +13,7 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||
|
||||
public abstract class MountedFluidStorageType<T extends MountedFluidStorage> {
|
||||
public static final Codec<MountedFluidStorageType<?>> CODEC = ExtraCodecs.lazyInitializedCodec(
|
||||
() -> MountedStorageTypeRegistry.getFluidsRegistry().getCodec()
|
||||
() -> MountedStorageTypeRegistries.getFluidsRegistry().getCodec()
|
||||
);
|
||||
|
||||
public final Codec<? extends T> codec;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
package com.simibubi.create.api.contraption.storage.fluid.registrate;
|
||||
|
||||
import com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistry;
|
||||
import com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistries;
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorageType;
|
||||
import com.simibubi.create.api.registry.AttachedRegistry;
|
||||
import com.tterrag.registrate.AbstractRegistrate;
|
||||
import com.tterrag.registrate.builders.AbstractBuilder;
|
||||
import com.tterrag.registrate.builders.BuilderCallback;
|
||||
|
@ -14,17 +15,17 @@ public class MountedFluidStorageTypeBuilder<T extends MountedFluidStorageType<?>
|
|||
private final T type;
|
||||
|
||||
public MountedFluidStorageTypeBuilder(AbstractRegistrate<?> owner, P parent, String name, BuilderCallback callback, T type) {
|
||||
super(owner, parent, name, callback, MountedStorageTypeRegistry.FLUIDS);
|
||||
super(owner, parent, name, callback, MountedStorageTypeRegistries.FLUIDS);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public MountedFluidStorageTypeBuilder<T, P> registerTo(Block block) {
|
||||
MountedStorageTypeRegistry.FLUID_LOOKUP.register(block, this.type);
|
||||
MountedStorageTypeRegistries.FLUID_STORAGES.register(block, this.type);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MountedFluidStorageTypeBuilder<T, P> registerTo(TagKey<Block> tag) {
|
||||
MountedStorageTypeRegistry.FLUID_LOOKUP.registerTag(tag, this.type);
|
||||
MountedStorageTypeRegistries.FLUID_STORAGES.registerProvider(AttachedRegistry.Provider.forBlockTag(tag, this.type));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.simibubi.create.api.contraption.storage.item;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistry;
|
||||
import com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistries;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.ExtraCodecs;
|
||||
|
@ -13,7 +13,7 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||
|
||||
public abstract class MountedItemStorageType<T extends MountedItemStorage> {
|
||||
public static final Codec<MountedItemStorageType<?>> CODEC = ExtraCodecs.lazyInitializedCodec(
|
||||
() -> MountedStorageTypeRegistry.getItemsRegistry().getCodec()
|
||||
() -> MountedStorageTypeRegistries.getItemsRegistry().getCodec()
|
||||
);
|
||||
|
||||
public final Codec<? extends T> codec;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
package com.simibubi.create.api.contraption.storage.item.registrate;
|
||||
|
||||
import com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistry;
|
||||
import com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistries;
|
||||
import com.simibubi.create.api.contraption.storage.item.MountedItemStorageType;
|
||||
import com.simibubi.create.api.registry.AttachedRegistry;
|
||||
import com.tterrag.registrate.AbstractRegistrate;
|
||||
import com.tterrag.registrate.builders.AbstractBuilder;
|
||||
import com.tterrag.registrate.builders.BuilderCallback;
|
||||
|
@ -14,17 +15,17 @@ public class MountedItemStorageTypeBuilder<T extends MountedItemStorageType<?>,
|
|||
private final T type;
|
||||
|
||||
public MountedItemStorageTypeBuilder(AbstractRegistrate<?> owner, P parent, String name, BuilderCallback callback, T type) {
|
||||
super(owner, parent, name, callback, MountedStorageTypeRegistry.ITEMS);
|
||||
super(owner, parent, name, callback, MountedStorageTypeRegistries.ITEMS);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public MountedItemStorageTypeBuilder<T, P> registerTo(Block block) {
|
||||
MountedStorageTypeRegistry.ITEM_LOOKUP.register(block, this.type);
|
||||
MountedStorageTypeRegistries.ITEM_STORAGES.register(block, this.type);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MountedItemStorageTypeBuilder<T, P> registerTo(TagKey<Block> tag) {
|
||||
MountedStorageTypeRegistry.ITEM_LOOKUP.registerTag(tag, this.type);
|
||||
MountedStorageTypeRegistries.ITEM_STORAGES.registerProvider(AttachedRegistry.Provider.forBlockTag(tag, this.type));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,52 +1,49 @@
|
|||
package com.simibubi.create.api.contraption.train;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllInteractionBehaviours;
|
||||
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
|
||||
|
||||
import com.simibubi.create.content.processing.burner.BlockBasedTrainConductorInteractionBehaviour;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllInteractionBehaviours;
|
||||
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
|
||||
import com.simibubi.create.content.processing.burner.BlockBasedTrainConductorInteractionBehaviour;
|
||||
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
|
||||
/**
|
||||
* All required methods to make your block a train conductor similar to the blaze burner
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface TrainConductorHandler {
|
||||
|
||||
@ApiStatus.Internal
|
||||
List<TrainConductorHandler> CONDUCTOR_HANDLERS = new ArrayList<>();
|
||||
|
||||
|
||||
|
||||
boolean isValidConductor(BlockState state);
|
||||
|
||||
private static void registerHandler(TrainConductorHandler handler) {
|
||||
CONDUCTOR_HANDLERS.add(handler);
|
||||
}
|
||||
|
||||
static void registerConductor(ResourceLocation blockRl, Predicate<BlockState> isValidConductor, UpdateScheduleCallback updateScheduleCallback) {
|
||||
AllInteractionBehaviours.registerBehaviour(blockRl, new BlockBasedTrainConductorInteractionBehaviour(isValidConductor, updateScheduleCallback));
|
||||
static void registerConductor(Block block, Predicate<BlockState> isValidConductor, UpdateScheduleCallback updateScheduleCallback) {
|
||||
BlockBasedTrainConductorInteractionBehaviour behavior = new BlockBasedTrainConductorInteractionBehaviour(isValidConductor, updateScheduleCallback);
|
||||
AllInteractionBehaviours.REGISTRY.register(block, behavior);
|
||||
registerHandler(isValidConductor::test);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
static void registerBlazeBurner() {
|
||||
registerConductor(AllBlocks.BLAZE_BURNER.getId(), blockState -> AllBlocks.BLAZE_BURNER.has(blockState)
|
||||
static void registerBlazeBurner(Block block) {
|
||||
registerConductor(block, blockState -> AllBlocks.BLAZE_BURNER.has(blockState)
|
||||
&& blockState.getValue(BlazeBurnerBlock.HEAT_LEVEL) != BlazeBurnerBlock.HeatLevel.NONE, UpdateScheduleCallback.EMPTY);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface UpdateScheduleCallback {
|
||||
|
||||
UpdateScheduleCallback EMPTY = (hasSchedule, blockState, blockStateSetter) -> {};
|
||||
|
||||
void update(boolean hasSchedule, BlockState currentBlockState, Consumer<BlockState> blockStateSetter);
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
package com.simibubi.create.api.contraption.transformable;
|
||||
|
||||
import com.simibubi.create.content.contraptions.StructureTransform;
|
||||
import com.simibubi.create.impl.contraption.transformable.ContraptionTransformableRegistryImpl;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Registry for registering new contraption transformations
|
||||
* to properly place blocks when disassembled after being part of a contraption
|
||||
*/
|
||||
public class ContraptionTransformableRegistry {
|
||||
/**
|
||||
* Register a new transform for a provided block
|
||||
*
|
||||
* @param block The block you want to register a new {@link TransformableBlock} for
|
||||
* @param transformableBlock The transform that should be applied whenever this block is being placed from
|
||||
* contraption disassembly
|
||||
*/
|
||||
public static void registerForBlock(Block block, TransformableBlock transformableBlock) {
|
||||
ContraptionTransformableRegistryImpl.registerForBlock(block, transformableBlock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new transform for a provided block entity type
|
||||
*
|
||||
* @param blockEntityType The blockEntityType you want to register a new {@link TransformableBlockEntity} for
|
||||
* @param transformableBlockEntity The transform that should be applied whenever this block entity type is
|
||||
* being placed from contraption disassembly
|
||||
*/
|
||||
public static void registerForBlockEntity(BlockEntityType<?> blockEntityType, TransformableBlockEntity transformableBlockEntity) {
|
||||
ContraptionTransformableRegistryImpl.registerForBlockEntity(blockEntityType, transformableBlockEntity);
|
||||
}
|
||||
|
||||
// --- Interfaces that provide the context that would be accessible if you implemented the ITransformable* interfaces ---
|
||||
|
||||
@FunctionalInterface
|
||||
public interface TransformableBlock {
|
||||
BlockState transform(Block block, BlockState state, StructureTransform transform);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface TransformableBlockEntity {
|
||||
void transform(BlockEntity blockEntity, StructureTransform transform);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.simibubi.create.api.contraption.transformable;
|
||||
|
||||
import com.simibubi.create.api.registry.AttachedRegistry;
|
||||
import com.simibubi.create.content.contraptions.StructureTransform;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Registry for custom transformations to apply to blocks after they've been moved by a contraption.
|
||||
* These interfaces are alternatives to the {@link ITransformableBlock} and {@link ITransformableBlockEntity} interfaces.
|
||||
*/
|
||||
public class MovedBlockTransformerRegistries {
|
||||
public static final AttachedRegistry<Block, BlockTransformer> BLOCK_TRANSFORMERS = AttachedRegistry.create();
|
||||
public static final AttachedRegistry<BlockEntityType<?>, BlockEntityTransformer> BLOCK_ENTITY_TRANSFORMERS = AttachedRegistry.create();
|
||||
|
||||
@FunctionalInterface
|
||||
public interface BlockTransformer {
|
||||
BlockState transform(Block block, BlockState state, StructureTransform transform);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface BlockEntityTransformer {
|
||||
void transform(BlockEntity be, StructureTransform transform);
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
package com.simibubi.create.api.lookup;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.impl.lookup.BlockLookupImpl;
|
||||
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
/**
|
||||
* Lookup for objects provided by blocks. Values can either be registered directly
|
||||
* or found lazily through providers. Providers are only queried once per block.
|
||||
* If they return a value, that value is cached. If they don't, that block is recorded
|
||||
* as not having a corresponding value.
|
||||
* <p>
|
||||
* Provided values are reset on resource reloads and will be re-queried and re-cached the
|
||||
* next time a block is queried.
|
||||
* <p>
|
||||
* All providers are expected to be registered synchronously during game init.
|
||||
* Adding new ones late is not supported.
|
||||
*/
|
||||
@ApiStatus.NonExtendable
|
||||
public interface BlockLookup<T> {
|
||||
@Nullable
|
||||
T find(Block block);
|
||||
|
||||
/**
|
||||
* Shortcut to avoid calling getBlock() on a BlockState.
|
||||
*/
|
||||
@Nullable
|
||||
T find(BlockState state);
|
||||
|
||||
/**
|
||||
* Register a value to one block.
|
||||
*/
|
||||
void register(Block block, T value);
|
||||
|
||||
/**
|
||||
* Register a value to all entries of a tag.
|
||||
*/
|
||||
void registerTag(TagKey<Block> tag, T value);
|
||||
|
||||
/**
|
||||
* Register a new provider that will be queried.
|
||||
* Providers are queried in reverse-registration order.
|
||||
*/
|
||||
void registerProvider(Provider<T> provider);
|
||||
|
||||
static <T> BlockLookup<T> create() {
|
||||
return new BlockLookupImpl<>();
|
||||
}
|
||||
|
||||
static <T> BlockLookup<T> create(Provider<T> initialProvider) {
|
||||
BlockLookup<T> lookup = new BlockLookupImpl<>();
|
||||
lookup.registerProvider(initialProvider);
|
||||
return lookup;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface Provider<T> {
|
||||
@Nullable
|
||||
T get(Block block);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
package com.simibubi.create.api.registry;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.impl.registry.AttachedRegistryImpl;
|
||||
import com.simibubi.create.impl.registry.TagProviderImpl;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
/**
|
||||
* A mapping of registered objects to something else.
|
||||
* This class is thread-safe, and may be safely used during parallel mod init.
|
||||
*/
|
||||
public interface AttachedRegistry<K, V> {
|
||||
/**
|
||||
* Register an association between a key and a value.
|
||||
* @throws IllegalArgumentException if the object already has an associated value
|
||||
*/
|
||||
void register(K object, V value);
|
||||
|
||||
/**
|
||||
* Add a new provider to this registry. For information on providers, see {@link Provider}.
|
||||
* @throws IllegalArgumentException if the provider has already been registered to this registry
|
||||
*/
|
||||
void registerProvider(Provider<K, V> provider);
|
||||
|
||||
/**
|
||||
* Invalidate the cached values provided by the given provider, so they get re-computed on the next query.
|
||||
* @throws IllegalArgumentException if the provider is not registered to this registry
|
||||
*/
|
||||
void invalidateProvider(Provider<K, V> provider);
|
||||
|
||||
/**
|
||||
* Query the value associated with the given object. May be null if no association is present.
|
||||
*/
|
||||
@Nullable
|
||||
V get(K object);
|
||||
|
||||
static <K, V> AttachedRegistry<K, V> create() {
|
||||
return new AttachedRegistryImpl<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* A provider can provide values to the registry in a lazy fashion. When a key does not have an
|
||||
* associated value, all providers will be queried in reverse-registration order.
|
||||
* <p>
|
||||
* The values returned by providers are cached so that repeated queries always return the same value.
|
||||
* To invalidate the cache of a provider, call {@link AttachedRegistry#invalidateProvider(Provider)}.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
interface Provider<K, V> {
|
||||
@Nullable
|
||||
V get(K object);
|
||||
|
||||
/**
|
||||
* Called by the AttachedRegistry this provider is registered to after it's registered.
|
||||
* This is useful for behavior that should only happen if a provider is actually registered,
|
||||
* such as registering event listeners.
|
||||
*/
|
||||
default void onRegister(AttachedRegistry<K, V> registry) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a provider that will return the same value for all entries in a tag.
|
||||
* The Provider will invalidate itself when tags are reloaded.
|
||||
*/
|
||||
static <K, V> Provider<K, V> forTag(TagKey<K> tag, Function<K, Holder<K>> holderGetter, V value) {
|
||||
return new TagProviderImpl<>(tag, holderGetter, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for {@link #forTag} when the registry's type is Block.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
static <V> Provider<Block, V> forBlockTag(TagKey<Block> tag, V value) {
|
||||
return new TagProviderImpl<>(tag, Block::builtInRegistryHolder, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for {@link #forTag} when the registry's type is Item.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
static <V> Provider<Item, V> forItemTag(TagKey<Item> tag, V value) {
|
||||
return new TagProviderImpl<>(tag, Item::builtInRegistryHolder, value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.simibubi.create.api.schematic.nbt;
|
||||
|
||||
import com.simibubi.create.api.registry.AttachedRegistry;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
|
||||
/**
|
||||
* Registry for safe NBT writers, used for filtering unsafe BlockEntity data out of schematics.
|
||||
* <p>
|
||||
* This is used to exclude specific tags that would result in exploits, ex. signs that execute commands when clicked.
|
||||
* <p>
|
||||
* This is provided as an alternative to {@link IPartialSafeNBT}.
|
||||
*/
|
||||
public class SafeNbtWriterRegistry {
|
||||
public static final AttachedRegistry<BlockEntityType<?>, SafeNbtWriter> REGISTRY = AttachedRegistry.create();
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SafeNbtWriter {
|
||||
/**
|
||||
* Write filtered, safe NBT to the given tag. This is always called on the logical server.
|
||||
* @param tag the NBT tag to write to
|
||||
*/
|
||||
void writeSafe(BlockEntity be, CompoundTag tag);
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package com.simibubi.create.api.schematic.requirement;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.api.registry.AttachedRegistry;
|
||||
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Registries for custom schematic requirements for blocks, block entities, and entities. These requirements determine
|
||||
* the items that are needed for placement into the world through schematics.
|
||||
* <p>
|
||||
* This is provided as an alternative to the following interfaces:
|
||||
* <ul>
|
||||
* <li>{@link ISpecialBlockItemRequirement}</li>
|
||||
* <li>{@link ISpecialBlockEntityItemRequirement}</li>
|
||||
* <li>{@link ISpecialEntityItemRequirement}</li>
|
||||
* </ul>
|
||||
*/
|
||||
public class SchematicRequirementRegistries {
|
||||
public static final AttachedRegistry<Block, BlockRequirement> BLOCKS = AttachedRegistry.create();
|
||||
public static final AttachedRegistry<BlockEntityType<?>, BlockEntityRequirement> BLOCK_ENTITIES = AttachedRegistry.create();
|
||||
public static final AttachedRegistry<EntityType<?>, EntityRequirement> ENTITIES = AttachedRegistry.create();
|
||||
|
||||
@FunctionalInterface
|
||||
public interface BlockRequirement {
|
||||
ItemRequirement getRequiredItems(Block block, BlockState state, @Nullable BlockEntity blockEntity);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface BlockEntityRequirement {
|
||||
ItemRequirement getRequiredItems(BlockEntity blockEntity, BlockState state);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface EntityRequirement {
|
||||
ItemRequirement getRequiredItems(Entity entity);
|
||||
}
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
package com.simibubi.create.api.schematic.requirement;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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(Block, 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(Block, 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(Block block, BlockState state, @Nullable BlockEntity blockEntity);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface BlockEntityRequirement {
|
||||
ItemRequirement getRequiredItems(BlockEntity blockEntity, BlockState state);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface EntityRequirement {
|
||||
ItemRequirement getRequiredItems(Entity entity);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +1,30 @@
|
|||
package com.simibubi.create.content.contraptions;
|
||||
|
||||
import com.simibubi.create.foundation.utility.AttachedRegistry;
|
||||
import java.util.Collection;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.simibubi.create.api.registry.AttachedRegistry;
|
||||
import com.simibubi.create.infrastructure.config.AllConfigs;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
|
||||
import net.minecraftforge.common.extensions.IForgeBlock;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.function.Supplier;
|
||||
import net.minecraftforge.common.extensions.IForgeBlock;
|
||||
|
||||
public enum ContraptionMovementSetting {
|
||||
MOVABLE, NO_PICKUP, UNMOVABLE;
|
||||
|
||||
private static final AttachedRegistry<Block, Supplier<ContraptionMovementSetting>> SETTING_SUPPLIERS = new AttachedRegistry<>(ForgeRegistries.BLOCKS);
|
||||
|
||||
public static void register(ResourceLocation block, Supplier<ContraptionMovementSetting> settingSupplier) {
|
||||
SETTING_SUPPLIERS.register(block, settingSupplier);
|
||||
}
|
||||
|
||||
public static void register(Block block, Supplier<ContraptionMovementSetting> settingSupplier) {
|
||||
SETTING_SUPPLIERS.register(block, settingSupplier);
|
||||
}
|
||||
public static final AttachedRegistry<Block, Supplier<ContraptionMovementSetting>> REGISTRY = AttachedRegistry.create();
|
||||
|
||||
@Nullable
|
||||
public static ContraptionMovementSetting get(Block block) {
|
||||
if (block instanceof IMovementSettingProvider provider)
|
||||
return provider.getContraptionMovementSetting();
|
||||
Supplier<ContraptionMovementSetting> supplier = SETTING_SUPPLIERS.get(block);
|
||||
if (supplier == null)
|
||||
return null;
|
||||
return supplier.get();
|
||||
Supplier<ContraptionMovementSetting> supplier = REGISTRY.get(block);
|
||||
return supplier == null ? null : supplier.get();
|
||||
}
|
||||
|
||||
public static boolean allAre(Collection<StructureTemplate.StructureBlockInfo> blocks, ContraptionMovementSetting are) {
|
||||
|
@ -45,12 +36,12 @@ public enum ContraptionMovementSetting {
|
|||
}
|
||||
|
||||
public static void registerDefaults() {
|
||||
register(Blocks.SPAWNER, () -> AllConfigs.server().kinetics.spawnerMovement.get());
|
||||
register(Blocks.BUDDING_AMETHYST, () -> AllConfigs.server().kinetics.amethystMovement.get());
|
||||
register(Blocks.OBSIDIAN, () -> AllConfigs.server().kinetics.obsidianMovement.get());
|
||||
register(Blocks.CRYING_OBSIDIAN, () -> AllConfigs.server().kinetics.obsidianMovement.get());
|
||||
register(Blocks.RESPAWN_ANCHOR, () -> AllConfigs.server().kinetics.obsidianMovement.get());
|
||||
register(Blocks.REINFORCED_DEEPSLATE, () -> AllConfigs.server().kinetics.reinforcedDeepslateMovement.get());
|
||||
REGISTRY.register(Blocks.SPAWNER, () -> AllConfigs.server().kinetics.spawnerMovement.get());
|
||||
REGISTRY.register(Blocks.BUDDING_AMETHYST, () -> AllConfigs.server().kinetics.amethystMovement.get());
|
||||
REGISTRY.register(Blocks.OBSIDIAN, () -> AllConfigs.server().kinetics.obsidianMovement.get());
|
||||
REGISTRY.register(Blocks.CRYING_OBSIDIAN, () -> AllConfigs.server().kinetics.obsidianMovement.get());
|
||||
REGISTRY.register(Blocks.RESPAWN_ANCHOR, () -> AllConfigs.server().kinetics.obsidianMovement.get());
|
||||
REGISTRY.register(Blocks.REINFORCED_DEEPSLATE, () -> AllConfigs.server().kinetics.reinforcedDeepslateMovement.get());
|
||||
}
|
||||
|
||||
public interface IMovementSettingProvider extends IForgeBlock {
|
||||
|
|
|
@ -17,7 +17,7 @@ import com.google.common.collect.Sets.SetView;
|
|||
import com.mojang.datafixers.util.Pair;
|
||||
import com.simibubi.create.AllPackets;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistry;
|
||||
import com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistries;
|
||||
import com.simibubi.create.api.contraption.storage.SyncedMountedStorage;
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorage;
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorageType;
|
||||
|
@ -144,7 +144,7 @@ public class MountedStorageManager {
|
|||
}
|
||||
|
||||
public void addBlock(Level level, BlockState state, BlockPos globalPos, BlockPos localPos, @Nullable BlockEntity be) {
|
||||
MountedItemStorageType<?> itemType = MountedStorageTypeRegistry.ITEM_LOOKUP.find(state);
|
||||
MountedItemStorageType<?> itemType = MountedStorageTypeRegistries.ITEM_STORAGES.get(state.getBlock());
|
||||
if (itemType != null) {
|
||||
MountedItemStorage storage = itemType.mount(level, state, globalPos, be);
|
||||
if (storage != null) {
|
||||
|
@ -152,7 +152,7 @@ public class MountedStorageManager {
|
|||
}
|
||||
}
|
||||
|
||||
MountedFluidStorageType<?> fluidType = MountedStorageTypeRegistry.FLUID_LOOKUP.find(state);
|
||||
MountedFluidStorageType<?> fluidType = MountedStorageTypeRegistries.FLUID_STORAGES.get(state.getBlock());
|
||||
if (fluidType != null) {
|
||||
MountedFluidStorage storage = fluidType.mount(level, state, globalPos, be);
|
||||
if (storage != null) {
|
||||
|
@ -167,7 +167,7 @@ public class MountedStorageManager {
|
|||
|
||||
MountedItemStorage itemStorage = this.getAllItemStorages().get(localPos);
|
||||
if (itemStorage != null) {
|
||||
MountedItemStorageType<?> expectedType = MountedStorageTypeRegistry.ITEM_LOOKUP.find(state);
|
||||
MountedItemStorageType<?> expectedType = MountedStorageTypeRegistries.ITEM_STORAGES.get(state.getBlock());
|
||||
if (itemStorage.type == expectedType) {
|
||||
itemStorage.unmount(level, state, globalPos, be);
|
||||
}
|
||||
|
@ -175,7 +175,7 @@ public class MountedStorageManager {
|
|||
|
||||
MountedFluidStorage fluidStorage = this.getFluids().storages.get(localPos);
|
||||
if (fluidStorage != null) {
|
||||
MountedFluidStorageType<?> expectedType = MountedStorageTypeRegistry.FLUID_LOOKUP.find(state);
|
||||
MountedFluidStorageType<?> expectedType = MountedStorageTypeRegistries.FLUID_STORAGES.get(state.getBlock());
|
||||
if (fluidStorage.type == expectedType) {
|
||||
fluidStorage.unmount(level, state, globalPos, be);
|
||||
}
|
||||
|
|
|
@ -4,10 +4,11 @@ import static net.minecraft.world.level.block.state.properties.BlockStatePropert
|
|||
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.FACING;
|
||||
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING;
|
||||
|
||||
import com.simibubi.create.api.contraption.transformable.ContraptionTransformableRegistry;
|
||||
import com.simibubi.create.api.contraption.transformable.ITransformableBlock;
|
||||
import com.simibubi.create.api.contraption.transformable.ITransformableBlockEntity;
|
||||
import com.simibubi.create.impl.contraption.transformable.ContraptionTransformableRegistryImpl;
|
||||
import com.simibubi.create.api.contraption.transformable.MovedBlockTransformerRegistries;
|
||||
import com.simibubi.create.api.contraption.transformable.MovedBlockTransformerRegistries.BlockEntityTransformer;
|
||||
import com.simibubi.create.api.contraption.transformable.MovedBlockTransformerRegistries.BlockTransformer;
|
||||
|
||||
import net.createmod.catnip.math.VecHelper;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -133,9 +134,9 @@ public class StructureTransform {
|
|||
}
|
||||
|
||||
public void apply(BlockEntity be) {
|
||||
ContraptionTransformableRegistry.TransformableBlockEntity transformableBlockEntity = ContraptionTransformableRegistryImpl.get(be.getType());
|
||||
if (transformableBlockEntity != null) {
|
||||
transformableBlockEntity.transform(be, this);
|
||||
BlockEntityTransformer transformer = MovedBlockTransformerRegistries.BLOCK_ENTITY_TRANSFORMERS.get(be.getType());
|
||||
if (transformer != null) {
|
||||
transformer.transform(be, this);
|
||||
} else if (be instanceof ITransformableBlockEntity itbe) {
|
||||
itbe.transform(this);
|
||||
}
|
||||
|
@ -148,9 +149,9 @@ public class StructureTransform {
|
|||
*/
|
||||
public BlockState apply(BlockState state) {
|
||||
Block block = state.getBlock();
|
||||
ContraptionTransformableRegistry.TransformableBlock transformableBlock = ContraptionTransformableRegistryImpl.get(block);
|
||||
if (transformableBlock != null) {
|
||||
return transformableBlock.transform(block, state, this);
|
||||
BlockTransformer transformer = MovedBlockTransformerRegistries.BLOCK_TRANSFORMERS.get(block);
|
||||
if (transformer != null) {
|
||||
return transformer.transform(block, state, this);
|
||||
} else if (block instanceof ITransformableBlock transformable) {
|
||||
return transformable.transform(state, this);
|
||||
}
|
||||
|
|
|
@ -1,66 +1,39 @@
|
|||
package com.simibubi.create.content.fluids.tank;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllTags.AllBlockTags;
|
||||
import com.simibubi.create.api.registry.AttachedRegistry;
|
||||
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
|
||||
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock.HeatLevel;
|
||||
import com.simibubi.create.foundation.utility.AttachedRegistry;
|
||||
import com.simibubi.create.foundation.utility.BlockHelper;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
public class BoilerHeaters {
|
||||
private static final AttachedRegistry<Block, Heater> BLOCK_HEATERS = new AttachedRegistry<>(ForgeRegistries.BLOCKS);
|
||||
private static final List<HeaterProvider> GLOBAL_HEATERS = new ArrayList<>();
|
||||
public static final int PASSIVE_HEAT = 0;
|
||||
public static final int NO_HEAT = -1;
|
||||
|
||||
public static void registerHeater(ResourceLocation block, Heater heater) {
|
||||
BLOCK_HEATERS.register(block, heater);
|
||||
}
|
||||
public static final AttachedRegistry<Block, Heater> REGISTRY = AttachedRegistry.create();
|
||||
|
||||
public static void registerHeater(Block block, Heater heater) {
|
||||
BLOCK_HEATERS.register(block, heater);
|
||||
}
|
||||
|
||||
public static void registerHeaterProvider(HeaterProvider provider) {
|
||||
GLOBAL_HEATERS.add(provider);
|
||||
}
|
||||
public static final Heater PASSIVE_HEATER = (level, pos, state) -> BlockHelper.isNotUnheated(state) ? PASSIVE_HEAT : NO_HEAT;
|
||||
|
||||
/**
|
||||
* A return value of {@code -1} represents no heat.
|
||||
* A return value of {@code 0} represents passive heat.
|
||||
* All other positive values are used as the amount of active heat.
|
||||
* Gets the heat at the given location. If a heater is present, queries it for heat. If not, returns {@link #NO_HEAT}.
|
||||
* @see Heater#getActiveHeat(Level, BlockPos, BlockState)
|
||||
*/
|
||||
public static float getActiveHeat(Level level, BlockPos pos, BlockState state) {
|
||||
Heater heater = BLOCK_HEATERS.get(state.getBlock());
|
||||
if (heater != null) {
|
||||
return heater.getActiveHeat(level, pos, state);
|
||||
}
|
||||
|
||||
for (HeaterProvider provider : GLOBAL_HEATERS) {
|
||||
heater = provider.getHeater(level, pos, state);
|
||||
if (heater != null) {
|
||||
return heater.getActiveHeat(level, pos, state);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
Heater heater = REGISTRY.get(state.getBlock());
|
||||
return heater != null ? heater.getActiveHeat(level, pos, state) : NO_HEAT;
|
||||
}
|
||||
|
||||
public static void registerDefaults() {
|
||||
registerHeater(AllBlocks.BLAZE_BURNER.get(), (level, pos, state) -> {
|
||||
REGISTRY.register(AllBlocks.BLAZE_BURNER.get(), (level, pos, state) -> {
|
||||
HeatLevel value = state.getValue(BlazeBurnerBlock.HEAT_LEVEL);
|
||||
if (value == HeatLevel.NONE) {
|
||||
return -1;
|
||||
return NO_HEAT;
|
||||
}
|
||||
if (value == HeatLevel.SEETHING) {
|
||||
return 2;
|
||||
|
@ -68,28 +41,19 @@ public class BoilerHeaters {
|
|||
if (value.isAtLeast(HeatLevel.FADING)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return PASSIVE_HEAT;
|
||||
});
|
||||
|
||||
registerHeaterProvider((level, pos, state) -> {
|
||||
if (AllBlockTags.PASSIVE_BOILER_HEATERS.matches(state) && BlockHelper.isNotUnheated(state)) {
|
||||
return (level1, pos1, state1) -> 0;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
REGISTRY.registerProvider(AttachedRegistry.Provider.forBlockTag(AllBlockTags.PASSIVE_BOILER_HEATERS.tag, PASSIVE_HEATER));
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Heater {
|
||||
/**
|
||||
* A return value of {@code -1} represents no heat.
|
||||
* A return value of {@code 0} represents passive heat.
|
||||
* All other positive values are used as the amount of active heat.
|
||||
* @return the amount of heat to provide.
|
||||
* @see #NO_HEAT
|
||||
* @see #PASSIVE_HEAT
|
||||
*/
|
||||
float getActiveHeat(Level level, BlockPos pos, BlockState state);
|
||||
}
|
||||
|
||||
public interface HeaterProvider {
|
||||
@Nullable
|
||||
Heater getHeater(Level level, BlockPos pos, BlockState state);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import java.util.Map;
|
|||
import javax.annotation.Nullable;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.api.registry.AttachedRegistry;
|
||||
import com.simibubi.create.compat.Mods;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.ComputerDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.DeathCounterDisplaySource;
|
||||
|
@ -19,7 +20,6 @@ import com.simibubi.create.content.redstone.displayLink.source.ScoreboardDisplay
|
|||
import com.simibubi.create.content.redstone.displayLink.target.DisplayTarget;
|
||||
import com.simibubi.create.content.redstone.displayLink.target.LecternDisplayTarget;
|
||||
import com.simibubi.create.content.redstone.displayLink.target.SignDisplayTarget;
|
||||
import com.simibubi.create.foundation.utility.AttachedRegistry;
|
||||
import com.tterrag.registrate.util.nullness.NonNullConsumer;
|
||||
|
||||
import net.createmod.catnip.platform.CatnipServices;
|
||||
|
@ -32,16 +32,17 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
|||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.entity.SignBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
public class AllDisplayBehaviours {
|
||||
public static final Map<ResourceLocation, DisplayBehaviour> GATHERER_BEHAVIOURS = new HashMap<>();
|
||||
|
||||
private static final AttachedRegistry<Block, List<DisplaySource>> SOURCES_BY_BLOCK = new AttachedRegistry<>(ForgeRegistries.BLOCKS);
|
||||
private static final AttachedRegistry<BlockEntityType<?>, List<DisplaySource>> SOURCES_BY_BLOCK_ENTITY = new AttachedRegistry<>(ForgeRegistries.BLOCK_ENTITY_TYPES);
|
||||
private static final AttachedRegistry<Block, List<DisplaySource>> SOURCES_BY_BLOCK = AttachedRegistry.create();
|
||||
private static final AttachedRegistry<BlockEntityType<?>, List<DisplaySource>> SOURCES_BY_BLOCK_ENTITY = AttachedRegistry.create();
|
||||
|
||||
private static final AttachedRegistry<Block, DisplayTarget> TARGETS_BY_BLOCK = new AttachedRegistry<>(ForgeRegistries.BLOCKS);
|
||||
private static final AttachedRegistry<BlockEntityType<?>, DisplayTarget> TARGETS_BY_BLOCK_ENTITY = new AttachedRegistry<>(ForgeRegistries.BLOCK_ENTITY_TYPES);
|
||||
private static final AttachedRegistry<Block, DisplayTarget> TARGETS_BY_BLOCK = AttachedRegistry.create();
|
||||
private static final AttachedRegistry<BlockEntityType<?>, DisplayTarget> TARGETS_BY_BLOCK_ENTITY = AttachedRegistry.create();
|
||||
|
||||
public static DisplayBehaviour register(ResourceLocation id, DisplayBehaviour behaviour) {
|
||||
behaviour.id = id;
|
||||
|
@ -49,34 +50,6 @@ public class AllDisplayBehaviours {
|
|||
return behaviour;
|
||||
}
|
||||
|
||||
public static void assignBlock(DisplayBehaviour behaviour, ResourceLocation block) {
|
||||
if (behaviour instanceof DisplaySource source) {
|
||||
List<DisplaySource> sources = SOURCES_BY_BLOCK.get(block);
|
||||
if (sources == null) {
|
||||
sources = new ArrayList<>();
|
||||
SOURCES_BY_BLOCK.register(block, sources);
|
||||
}
|
||||
sources.add(source);
|
||||
}
|
||||
if (behaviour instanceof DisplayTarget target) {
|
||||
TARGETS_BY_BLOCK.register(block, target);
|
||||
}
|
||||
}
|
||||
|
||||
public static void assignBlockEntity(DisplayBehaviour behaviour, ResourceLocation beType) {
|
||||
if (behaviour instanceof DisplaySource source) {
|
||||
List<DisplaySource> sources = SOURCES_BY_BLOCK_ENTITY.get(beType);
|
||||
if (sources == null) {
|
||||
sources = new ArrayList<>();
|
||||
SOURCES_BY_BLOCK_ENTITY.register(beType, sources);
|
||||
}
|
||||
sources.add(source);
|
||||
}
|
||||
if (behaviour instanceof DisplayTarget target) {
|
||||
TARGETS_BY_BLOCK_ENTITY.register(beType, target);
|
||||
}
|
||||
}
|
||||
|
||||
public static void assignBlock(DisplayBehaviour behaviour, Block block) {
|
||||
if (behaviour instanceof DisplaySource source) {
|
||||
List<DisplaySource> sources = SOURCES_BY_BLOCK.get(block);
|
||||
|
@ -105,6 +78,15 @@ public class AllDisplayBehaviours {
|
|||
}
|
||||
}
|
||||
|
||||
public static void tryAssignBlockEntity(DisplayBehaviour behaviour, ResourceLocation id) {
|
||||
if (ForgeRegistries.BLOCK_ENTITY_TYPES.containsKey(id)) {
|
||||
BlockEntityType<?> type = ForgeRegistries.BLOCK_ENTITY_TYPES.getValue(id);
|
||||
assignBlockEntity(behaviour, type);
|
||||
} else {
|
||||
Create.LOGGER.warn("Block entity for display behavior wasn't found: {}. Outdated compat?", id);
|
||||
}
|
||||
}
|
||||
|
||||
public static <B extends Block> NonNullConsumer<? super B> assignDataBehaviour(DisplayBehaviour behaviour,
|
||||
String... suffix) {
|
||||
return b -> {
|
||||
|
@ -113,7 +95,7 @@ public class AllDisplayBehaviours {
|
|||
if (suffix.length > 0)
|
||||
idSuffix += "_" + suffix[0];
|
||||
assignBlock(register(new ResourceLocation(registryName.getNamespace(), registryName.getPath() + idSuffix),
|
||||
behaviour), registryName);
|
||||
behaviour), b);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -127,7 +109,7 @@ public class AllDisplayBehaviours {
|
|||
assignBlockEntity(
|
||||
register(new ResourceLocation(registryName.getNamespace(), registryName.getPath() + idSuffix),
|
||||
behaviour),
|
||||
registryName);
|
||||
b);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -237,10 +219,10 @@ public class AllDisplayBehaviours {
|
|||
Mods.COMPUTERCRAFT.executeIfInstalled(() -> () -> {
|
||||
DisplayBehaviour computerDisplaySource = register(Create.asResource("computer_display_source"), new ComputerDisplaySource());
|
||||
|
||||
assignBlockEntity(computerDisplaySource, Mods.COMPUTERCRAFT.rl("wired_modem_full"));
|
||||
assignBlockEntity(computerDisplaySource, Mods.COMPUTERCRAFT.rl("computer_normal"));
|
||||
assignBlockEntity(computerDisplaySource, Mods.COMPUTERCRAFT.rl("computer_advanced"));
|
||||
assignBlockEntity(computerDisplaySource, Mods.COMPUTERCRAFT.rl("computer_command"));
|
||||
tryAssignBlockEntity(computerDisplaySource, Mods.COMPUTERCRAFT.rl("wired_modem_full"));
|
||||
tryAssignBlockEntity(computerDisplaySource, Mods.COMPUTERCRAFT.rl("computer_normal"));
|
||||
tryAssignBlockEntity(computerDisplaySource, Mods.COMPUTERCRAFT.rl("computer_advanced"));
|
||||
tryAssignBlockEntity(computerDisplaySource, Mods.COMPUTERCRAFT.rl("computer_command"));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,15 +6,15 @@ import java.util.List;
|
|||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
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.api.schematic.requirement.SchematicRequirementRegistries;
|
||||
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.nbt.NBTProcessors;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.decoration.ArmorStand;
|
||||
|
@ -35,9 +35,8 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
|||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.SlabType;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
public class ItemRequirement {
|
||||
public static final ItemRequirement NONE = new ItemRequirement(Collections.emptyList());
|
||||
|
@ -71,9 +70,9 @@ public class ItemRequirement {
|
|||
Block block = state.getBlock();
|
||||
|
||||
ItemRequirement requirement;
|
||||
SchematicRequirementsRegistry.BlockRequirement blockItemRequirement = SchematicRequirementsRegistryImpl.getRequirementForBlock(block);
|
||||
if (blockItemRequirement != null) {
|
||||
requirement = blockItemRequirement.getRequiredItems(block, state, be);
|
||||
SchematicRequirementRegistries.BlockRequirement blockRequirement = SchematicRequirementRegistries.BLOCKS.get(block);
|
||||
if (blockRequirement != null) {
|
||||
requirement = blockRequirement.getRequiredItems(block, state, be);
|
||||
} else if (block instanceof ISpecialBlockItemRequirement specialBlock) {
|
||||
requirement = specialBlock.getRequiredItems(state, be);
|
||||
} else {
|
||||
|
@ -81,9 +80,9 @@ public class ItemRequirement {
|
|||
}
|
||||
|
||||
if (be != null) {
|
||||
SchematicRequirementsRegistry.BlockEntityRequirement blockEntityItemRequirement = SchematicRequirementsRegistryImpl.getRequirementForBlockEntityType(be.getType());
|
||||
if (blockEntityItemRequirement != null) {
|
||||
requirement = requirement.union(blockEntityItemRequirement.getRequiredItems(be, state));
|
||||
SchematicRequirementRegistries.BlockEntityRequirement beRequirement = SchematicRequirementRegistries.BLOCK_ENTITIES.get(be.getType());
|
||||
if (beRequirement != null) {
|
||||
requirement = requirement.union(beRequirement.getRequiredItems(be, state));
|
||||
} else if (be instanceof ISpecialBlockEntityItemRequirement specialBE) {
|
||||
requirement = requirement.union(specialBE.getRequiredItems(state));
|
||||
} else if (com.simibubi.create.compat.Mods.FRAMEDBLOCKS.contains(block)) {
|
||||
|
@ -134,9 +133,9 @@ public class ItemRequirement {
|
|||
}
|
||||
|
||||
public static ItemRequirement of(Entity entity) {
|
||||
SchematicRequirementsRegistry.EntityRequirement entityItemRequirement = SchematicRequirementsRegistryImpl.getRequirementForEntityType(entity.getType());
|
||||
if (entityItemRequirement != null) {
|
||||
return entityItemRequirement.getRequiredItems(entity);
|
||||
SchematicRequirementRegistries.EntityRequirement requirement = SchematicRequirementRegistries.ENTITIES.get(entity.getType());
|
||||
if (requirement != null) {
|
||||
return requirement.getRequiredItems(entity);
|
||||
} else if (entity instanceof ISpecialEntityItemRequirement specialEntity) {
|
||||
return specialEntity.getRequiredItems();
|
||||
}
|
||||
|
|
|
@ -5,13 +5,13 @@ import java.util.function.Function;
|
|||
import java.util.function.UnaryOperator;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.api.registry.AttachedRegistry;
|
||||
import com.simibubi.create.compat.Mods;
|
||||
import com.simibubi.create.compat.betterend.BetterEndPortalCompat;
|
||||
import com.simibubi.create.content.contraptions.glue.SuperGlueEntity;
|
||||
import com.simibubi.create.foundation.utility.AttachedRegistry;
|
||||
|
||||
import net.createmod.catnip.math.BlockFace;
|
||||
import net.createmod.catnip.data.Pair;
|
||||
import net.createmod.catnip.math.BlockFace;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
|
@ -26,6 +26,7 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.portal.PortalInfo;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
|
||||
import net.minecraftforge.common.util.ITeleporter;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
|
@ -48,27 +49,22 @@ public class AllPortalTracks {
|
|||
/**
|
||||
* Registry mapping portal blocks to their respective {@link PortalTrackProvider}s.
|
||||
*/
|
||||
private static final AttachedRegistry<Block, PortalTrackProvider> PORTAL_BEHAVIOURS =
|
||||
new AttachedRegistry<>(ForgeRegistries.BLOCKS);
|
||||
public static final AttachedRegistry<Block, PortalTrackProvider> REGISTRY = AttachedRegistry.create();
|
||||
|
||||
/**
|
||||
* Registers a portal track integration for a given block identified by its {@link ResourceLocation}.
|
||||
* Registers a portal track integration for a given block identified by its {@link ResourceLocation}, if it exists.
|
||||
* If it does not, a warning will be logged.
|
||||
*
|
||||
* @param block The resource location of the portal block.
|
||||
* @param id The resource location of the portal block.
|
||||
* @param provider The portal track provider for the block.
|
||||
*/
|
||||
public static void registerIntegration(ResourceLocation block, PortalTrackProvider provider) {
|
||||
PORTAL_BEHAVIOURS.register(block, provider);
|
||||
public static void tryRegisterIntegration(ResourceLocation id, PortalTrackProvider provider) {
|
||||
if (ForgeRegistries.BLOCKS.containsKey(id)) {
|
||||
Block block = ForgeRegistries.BLOCKS.getValue(id);
|
||||
REGISTRY.register(block, provider);
|
||||
} else {
|
||||
Create.LOGGER.warn("Portal for integration wasn't found: {}. Compat outdated?", id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a portal track integration for a given {@link Block}.
|
||||
*
|
||||
* @param block The portal block.
|
||||
* @param provider The portal track provider for the block.
|
||||
*/
|
||||
public static void registerIntegration(Block block, PortalTrackProvider provider) {
|
||||
PORTAL_BEHAVIOURS.register(block, provider);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,7 +74,7 @@ public class AllPortalTracks {
|
|||
* @return {@code true} if the block state represents a supported portal; {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isSupportedPortal(BlockState state) {
|
||||
return PORTAL_BEHAVIOURS.get(state.getBlock()) != null;
|
||||
return REGISTRY.get(state.getBlock()) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -92,7 +88,7 @@ public class AllPortalTracks {
|
|||
public static Pair<ServerLevel, BlockFace> getOtherSide(ServerLevel level, BlockFace inboundTrack) {
|
||||
BlockPos portalPos = inboundTrack.getConnectedPos();
|
||||
BlockState portalState = level.getBlockState(portalPos);
|
||||
PortalTrackProvider provider = PORTAL_BEHAVIOURS.get(portalState.getBlock());
|
||||
PortalTrackProvider provider = REGISTRY.get(portalState.getBlock());
|
||||
return provider == null ? null : provider.apply(Pair.of(level, inboundTrack));
|
||||
}
|
||||
|
||||
|
@ -103,11 +99,15 @@ public class AllPortalTracks {
|
|||
* This includes the Nether and the Aether (if loaded).
|
||||
*/
|
||||
public static void registerDefaults() {
|
||||
registerIntegration(Blocks.NETHER_PORTAL, AllPortalTracks::nether);
|
||||
if (Mods.AETHER.isLoaded())
|
||||
registerIntegration(Mods.AETHER.rl("aether_portal"), AllPortalTracks::aether);
|
||||
if (Mods.BETTEREND.isLoaded())
|
||||
registerIntegration(Mods.BETTEREND.rl("end_portal_block"), AllPortalTracks::betterend);
|
||||
REGISTRY.register(Blocks.NETHER_PORTAL, AllPortalTracks::nether);
|
||||
|
||||
if (Mods.AETHER.isLoaded()) {
|
||||
tryRegisterIntegration(Mods.AETHER.rl("aether_portal"), AllPortalTracks::aether);
|
||||
}
|
||||
|
||||
if (Mods.BETTEREND.isLoaded()) {
|
||||
tryRegisterIntegration(Mods.BETTEREND.rl("end_portal_block"), AllPortalTracks::betterend);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -47,6 +47,7 @@ import net.minecraft.world.item.Item;
|
|||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour.Properties;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions;
|
||||
|
@ -106,10 +107,13 @@ public class CreateRegistrate extends AbstractRegistrate<CreateRegistrate> {
|
|||
Builder<R, T, ?, ?> builder, NonNullSupplier<? extends T> creator,
|
||||
NonNullFunction<RegistryObject<T>, ? extends RegistryEntry<T>> entryFactory) {
|
||||
RegistryEntry<T> entry = super.accept(name, type, builder, creator, entryFactory);
|
||||
if (type.equals(Registries.ITEM)) {
|
||||
if (currentTooltipModifierFactory != null) {
|
||||
TooltipModifier.REGISTRY.registerDeferred(entry.getId(), currentTooltipModifierFactory);
|
||||
}
|
||||
if (type.equals(Registries.ITEM) && currentTooltipModifierFactory != null) {
|
||||
// grab the factory here for the lambda, it can change between now and registration
|
||||
Function<Item, TooltipModifier> factory = currentTooltipModifierFactory;
|
||||
this.addRegisterCallback(name, Registries.ITEM, item -> {
|
||||
TooltipModifier modifier = factory.apply(item);
|
||||
TooltipModifier.REGISTRY.register(item, modifier);
|
||||
});
|
||||
}
|
||||
if (currentTab != null) {
|
||||
TAB_LOOKUP.put(entry, currentTab);
|
||||
|
|
|
@ -2,14 +2,15 @@ package com.simibubi.create.foundation.item;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.foundation.utility.AttachedRegistry;
|
||||
import com.simibubi.create.api.registry.AttachedRegistry;
|
||||
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface TooltipModifier {
|
||||
AttachedRegistry<Item, TooltipModifier> REGISTRY = new AttachedRegistry<>(ForgeRegistries.ITEMS);
|
||||
AttachedRegistry<Item, TooltipModifier> REGISTRY = AttachedRegistry.create();
|
||||
|
||||
TooltipModifier EMPTY = new TooltipModifier() {
|
||||
@Override
|
||||
|
|
|
@ -1,146 +0,0 @@
|
|||
package com.simibubi.create.foundation.utility;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.registries.IForgeRegistry;
|
||||
|
||||
public class AttachedRegistry<K, V> {
|
||||
private static final List<AttachedRegistry<?, ?>> ALL = new ArrayList<>();
|
||||
|
||||
protected final IForgeRegistry<K> objectRegistry;
|
||||
protected final Map<ResourceLocation, V> idMap = new HashMap<>();
|
||||
protected final Map<K, V> objectMap = new IdentityHashMap<>();
|
||||
protected final Map<ResourceLocation, Function<K, V>> deferredRegistrations = new HashMap<>();
|
||||
protected boolean unwrapped = false;
|
||||
|
||||
public AttachedRegistry(IForgeRegistry<K> objectRegistry) {
|
||||
this.objectRegistry = objectRegistry;
|
||||
ALL.add(this);
|
||||
}
|
||||
|
||||
public void register(ResourceLocation id, V value) {
|
||||
if (!unwrapped) {
|
||||
idMap.put(id, value);
|
||||
} else {
|
||||
K object = objectRegistry.getValue(id);
|
||||
if (object != null) {
|
||||
objectMap.put(object, value);
|
||||
} else {
|
||||
Create.LOGGER.warn("Could not get object for id '" + id + "' in AttachedRegistry after unwrapping!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void register(K object, V value) {
|
||||
if (unwrapped) {
|
||||
objectMap.put(object, value);
|
||||
} else {
|
||||
ResourceLocation id = objectRegistry.getKey(object);
|
||||
if (id != null) {
|
||||
idMap.put(id, value);
|
||||
} else {
|
||||
Create.LOGGER.warn("Could not get id of object '" + object + "' in AttachedRegistry before unwrapping!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void registerDeferred(ResourceLocation id, Function<K, V> func) {
|
||||
if (!unwrapped) {
|
||||
deferredRegistrations.put(id, func);
|
||||
} else {
|
||||
K object = objectRegistry.getValue(id);
|
||||
if (object != null) {
|
||||
objectMap.put(object, func.apply(object));
|
||||
} else {
|
||||
Create.LOGGER.warn("Could not get object for id '" + id + "' in AttachedRegistry after unwrapping!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void registerDeferred(K object, Function<K, V> func) {
|
||||
if (unwrapped) {
|
||||
objectMap.put(object, func.apply(object));
|
||||
} else {
|
||||
ResourceLocation id = objectRegistry.getKey(object);
|
||||
if (id != null) {
|
||||
deferredRegistrations.put(id, func);
|
||||
} else {
|
||||
Create.LOGGER.warn("Could not get id of object '" + object + "' in AttachedRegistry before unwrapping!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public V get(ResourceLocation id) {
|
||||
if (!unwrapped) {
|
||||
return idMap.get(id);
|
||||
} else {
|
||||
K object = objectRegistry.getValue(id);
|
||||
if (object != null) {
|
||||
return objectMap.get(object);
|
||||
} else {
|
||||
Create.LOGGER.warn("Could not get object for id '" + id + "' in AttachedRegistry after unwrapping!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public V get(K object) {
|
||||
if (unwrapped) {
|
||||
return objectMap.get(object);
|
||||
} else {
|
||||
ResourceLocation id = objectRegistry.getKey(object);
|
||||
if (id != null) {
|
||||
return idMap.get(id);
|
||||
} else {
|
||||
Create.LOGGER.warn("Could not get id of object '" + object + "' in AttachedRegistry before unwrapping!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isUnwrapped() {
|
||||
return unwrapped;
|
||||
}
|
||||
|
||||
protected void unwrap() {
|
||||
deferredRegistrations.forEach((id, func) -> {
|
||||
K object = objectRegistry.getValue(id);
|
||||
if (object != null) {
|
||||
objectMap.put(object, func.apply(object));
|
||||
} else {
|
||||
Create.LOGGER.warn("Could not get object for id '" + id + "' in AttachedRegistry during unwrapping!");
|
||||
}
|
||||
});
|
||||
|
||||
idMap.forEach((id, value) -> {
|
||||
K object = objectRegistry.getValue(id);
|
||||
if (object != null) {
|
||||
objectMap.put(object, value);
|
||||
} else {
|
||||
Create.LOGGER.warn("Could not get object for id '" + id + "' in AttachedRegistry during unwrapping!");
|
||||
}
|
||||
});
|
||||
|
||||
deferredRegistrations.clear();
|
||||
idMap.clear();
|
||||
unwrapped = true;
|
||||
}
|
||||
|
||||
public static void unwrapAll() {
|
||||
for (AttachedRegistry<?, ?> registry : ALL) {
|
||||
registry.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,8 @@ 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.api.schematic.nbt.SafeNbtWriterRegistry;
|
||||
import com.simibubi.create.api.schematic.nbt.SafeNbtWriterRegistry.SafeNbtWriter;
|
||||
import com.simibubi.create.compat.Mods;
|
||||
import com.simibubi.create.compat.framedblocks.FramedBlocksInSchematics;
|
||||
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
|
||||
|
@ -16,7 +17,6 @@ import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
|
|||
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.nbt.NBTProcessors;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -57,6 +57,7 @@ import net.minecraft.world.level.block.state.properties.SlabType;
|
|||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
|
||||
import net.minecraftforge.common.IPlantable;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.level.BlockEvent;
|
||||
|
@ -279,18 +280,19 @@ public class BlockHelper {
|
|||
if (blockEntity == null)
|
||||
return null;
|
||||
|
||||
SchematicSafeNBTRegistry.ContextProvidingPartialSafeNBT safeNBT = SchematicSafeNBTRegistryImpl.getPartialSafeNBT(blockEntity.getType());
|
||||
SafeNbtWriter writer = SafeNbtWriterRegistry.REGISTRY.get(blockEntity.getType());
|
||||
if (AllBlockTags.SAFE_NBT.matches(blockState)) {
|
||||
data = blockEntity.saveWithFullMetadata();
|
||||
} else if (safeNBT != null) {
|
||||
} else if (writer != null) {
|
||||
data = new CompoundTag();
|
||||
safeNBT.writeSafe(blockEntity, data);
|
||||
writer.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);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,15 +3,20 @@ package com.simibubi.create.impl.contraption.storage;
|
|||
import java.util.Objects;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.AllMountedStorageTypes;
|
||||
import com.simibubi.create.AllTags;
|
||||
import com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistry;
|
||||
import com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistries;
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorageType;
|
||||
import com.simibubi.create.api.contraption.storage.item.MountedItemStorageType;
|
||||
import com.simibubi.create.api.lookup.BlockLookup;
|
||||
import com.simibubi.create.api.registry.AttachedRegistry;
|
||||
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.TagsUpdatedEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.registries.IForgeRegistry;
|
||||
|
@ -21,8 +26,12 @@ import net.minecraftforge.registries.RegistryBuilder;
|
|||
@ApiStatus.Internal
|
||||
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
|
||||
public class MountedStorageTypeRegistryImpl {
|
||||
public static final BlockLookup<MountedItemStorageType<?>> ITEM_LOOKUP = BlockLookup.create(MountedStorageTypeRegistryImpl::itemFallback);
|
||||
public static final BlockLookup<MountedFluidStorageType<?>> FLUID_LOOKUP = BlockLookup.create();
|
||||
public static final AttachedRegistry<Block, MountedItemStorageType<?>> ITEM_STORAGES = Util.make(() -> {
|
||||
AttachedRegistry<Block, MountedItemStorageType<?>> registry = AttachedRegistry.create();
|
||||
registry.registerProvider(ItemFallbackProvider.INSTANCE);
|
||||
return registry;
|
||||
});
|
||||
public static final AttachedRegistry<Block, MountedFluidStorageType<?>> FLUID_STORAGES = AttachedRegistry.create();
|
||||
|
||||
private static IForgeRegistry<MountedItemStorageType<?>> itemsRegistry;
|
||||
private static IForgeRegistry<MountedFluidStorageType<?>> fluidsRegistry;
|
||||
|
@ -39,19 +48,34 @@ public class MountedStorageTypeRegistryImpl {
|
|||
public static void registerRegistries(NewRegistryEvent event) {
|
||||
event.create(
|
||||
new RegistryBuilder<MountedItemStorageType<?>>()
|
||||
.setName(MountedStorageTypeRegistry.ITEMS.location()),
|
||||
.setName(MountedStorageTypeRegistries.ITEMS.location()),
|
||||
registry -> itemsRegistry = registry
|
||||
);
|
||||
event.create(
|
||||
new RegistryBuilder<MountedFluidStorageType<?>>()
|
||||
.setName(MountedStorageTypeRegistry.FLUIDS.location()),
|
||||
.setName(MountedStorageTypeRegistries.FLUIDS.location()),
|
||||
registry -> fluidsRegistry = registry
|
||||
);
|
||||
}
|
||||
|
||||
private static MountedItemStorageType<?> itemFallback(Block block) {
|
||||
private enum ItemFallbackProvider implements AttachedRegistry.Provider<Block, MountedItemStorageType<?>> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public MountedItemStorageType<?> get(Block block) {
|
||||
return AllTags.AllBlockTags.FALLBACK_MOUNTED_STORAGE_BLACKLIST.matches(block)
|
||||
? null
|
||||
: AllMountedStorageTypes.FALLBACK.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRegister(AttachedRegistry<Block, MountedItemStorageType<?>> registry) {
|
||||
MinecraftForge.EVENT_BUS.addListener((TagsUpdatedEvent event) -> {
|
||||
if (event.shouldUpdateStaticData()) {
|
||||
registry.invalidateProvider(this);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
package com.simibubi.create.impl.contraption.transformable;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import com.simibubi.create.api.contraption.transformable.ContraptionTransformableRegistry.TransformableBlock;
|
||||
import com.simibubi.create.api.contraption.transformable.ContraptionTransformableRegistry.TransformableBlockEntity;
|
||||
import com.simibubi.create.foundation.utility.AttachedRegistry;
|
||||
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public class ContraptionTransformableRegistryImpl {
|
||||
private static final AttachedRegistry<Block, TransformableBlock> TRANSFORMABLE_BLOCKS = new AttachedRegistry<>(ForgeRegistries.BLOCKS);
|
||||
private static final AttachedRegistry<BlockEntityType<?>, TransformableBlockEntity> TRANSFORMABLE_BLOCK_ENTITIES = new AttachedRegistry<>(ForgeRegistries.BLOCK_ENTITY_TYPES);
|
||||
|
||||
public static void registerForBlock(Block block, TransformableBlock transformableBlock) {
|
||||
TRANSFORMABLE_BLOCKS.register(block, transformableBlock);
|
||||
}
|
||||
|
||||
public static void registerForBlockEntity(BlockEntityType<?> blockEntityType, TransformableBlockEntity transformableBlockEntity) {
|
||||
TRANSFORMABLE_BLOCK_ENTITIES.register(blockEntityType, transformableBlockEntity);
|
||||
}
|
||||
|
||||
public static TransformableBlock get(Block block) {
|
||||
return TRANSFORMABLE_BLOCKS.get(block);
|
||||
}
|
||||
|
||||
public static TransformableBlockEntity get(BlockEntityType<?> blockEntityType) {
|
||||
return TRANSFORMABLE_BLOCK_ENTITIES.get(blockEntityType);
|
||||
}
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
package com.simibubi.create.impl.lookup;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.simibubi.create.api.lookup.BlockLookup;
|
||||
|
||||
import net.minecraftforge.event.TagsUpdatedEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
@ApiStatus.Internal
|
||||
@Mod.EventBusSubscriber
|
||||
public class BlockLookupImpl<T> implements BlockLookup<T> {
|
||||
private static final List<BlockLookupImpl<?>> allLookups = new ArrayList<>();
|
||||
|
||||
private final Map<Block, T> map;
|
||||
private final Map<Block, T> providedValues;
|
||||
private final Set<Block> providedNull;
|
||||
private final List<Provider<T>> providers;
|
||||
|
||||
public BlockLookupImpl() {
|
||||
this.map = new IdentityHashMap<>();
|
||||
this.providedValues = new IdentityHashMap<>();
|
||||
this.providedNull = new HashSet<>();
|
||||
this.providers = new ArrayList<>();
|
||||
allLookups.add(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public T find(BlockState state) {
|
||||
return this.find(state.getBlock());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public T find(Block block) {
|
||||
T registered = this.map.get(block);
|
||||
if (registered != null)
|
||||
return registered;
|
||||
|
||||
if (this.providedNull.contains(block))
|
||||
return null;
|
||||
|
||||
return this.providedValues.computeIfAbsent(block, $ -> {
|
||||
for (Provider<T> provider : this.providers) {
|
||||
T value = provider.get(block);
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
this.providedNull.add(block);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(Block block, T value) {
|
||||
this.map.put(block, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerTag(TagKey<Block> tag, T value) {
|
||||
this.registerProvider(new TagProvider<>(tag, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerProvider(Provider<T> provider) {
|
||||
this.providers.add(0, provider);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onTagsReloaded(TagsUpdatedEvent event) {
|
||||
if (event.getUpdateCause() == TagsUpdatedEvent.UpdateCause.SERVER_DATA_LOAD) {
|
||||
for (BlockLookupImpl<?> lookup : allLookups) {
|
||||
lookup.providedValues.clear();
|
||||
lookup.providedNull.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private record TagProvider<T>(TagKey<Block> tag, T value) implements Provider<T> {
|
||||
@Override
|
||||
@Nullable
|
||||
@SuppressWarnings("deprecation")
|
||||
public T get(Block block) {
|
||||
return block.builtInRegistryHolder().is(this.tag) ? this.value : null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
package com.simibubi.create.impl.registry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.api.registry.AttachedRegistry;
|
||||
|
||||
// methods are synchronized since registrations can happen during parallel mod loading
|
||||
public class AttachedRegistryImpl<K, V> implements AttachedRegistry<K, V> {
|
||||
private static final Object nullMarker = new Object();
|
||||
|
||||
// all of these have identity semantics
|
||||
private final Map<K, V> registrations = new IdentityHashMap<>();
|
||||
private final List<Provider<K, V>> providers = new ArrayList<>();
|
||||
private final Map<Provider<K, V>, Set<K>> providedKeys = new IdentityHashMap<>();
|
||||
private final Map<K, V> providedValues = new IdentityHashMap<>();
|
||||
|
||||
@Override
|
||||
public synchronized void register(K object, V value) {
|
||||
Objects.requireNonNull(object, "object");
|
||||
Objects.requireNonNull(value, "value");
|
||||
|
||||
V existing = this.registrations.get(object);
|
||||
if (existing != null) {
|
||||
String message = String.format("Tried to register duplicate values for object %s: old=%s, new=%s", object, existing, value);
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
|
||||
this.registrations.put(object, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void registerProvider(Provider<K, V> provider) {
|
||||
Objects.requireNonNull(provider);
|
||||
if (this.providers.contains(provider)) {
|
||||
throw new IllegalArgumentException("Tried to register provider twice: " + provider);
|
||||
}
|
||||
|
||||
// add to start of list so it's queried first
|
||||
this.providers.add(0, provider);
|
||||
provider.onRegister(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void invalidateProvider(Provider<K, V> provider) {
|
||||
Objects.requireNonNull(provider);
|
||||
if (!this.providers.contains(provider)) {
|
||||
throw new IllegalArgumentException("Cannot invalidate non-registered provider: " + provider);
|
||||
}
|
||||
|
||||
// discard all the values the provider has provided
|
||||
Set<K> keys = providedKeys.remove(provider);
|
||||
if (keys != null) {
|
||||
keys.forEach(providedValues::remove);
|
||||
}
|
||||
|
||||
// when a provider is invalidated, we need to clear all cached values that evaluated to null, so they can be re-queried
|
||||
this.providedValues.values().removeIf(value -> value == nullMarker);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public synchronized V get(K object) {
|
||||
if (this.registrations.containsKey(object)) {
|
||||
return this.registrations.get(object);
|
||||
} else if (this.providedValues.containsKey(object)) {
|
||||
V provided = this.providedValues.get(object);
|
||||
return provided == nullMarker ? null : provided;
|
||||
}
|
||||
|
||||
// no value known, check providers
|
||||
// descendingSet: go in reverse-registration order
|
||||
for (Provider<K, V> provider : this.providers) {
|
||||
V value = provider.get(object);
|
||||
if (value != null) {
|
||||
this.providedValues.put(object, value);
|
||||
// track which provider provided the value for invalidation
|
||||
this.providedKeys.computeIfAbsent(provider, $ -> identityHashSet()).add(object);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
// no provider returned non-null
|
||||
this.providedValues.put(object, nullMarker());
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> T nullMarker() {
|
||||
return (T) nullMarker;
|
||||
}
|
||||
|
||||
private static <T> Set<T> identityHashSet() {
|
||||
return Collections.newSetFromMap(new IdentityHashMap<>());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.simibubi.create.impl.registry;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.api.registry.AttachedRegistry;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.tags.TagKey;
|
||||
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.TagsUpdatedEvent;
|
||||
|
||||
public class TagProviderImpl<K, V> implements AttachedRegistry.Provider<K, V> {
|
||||
private final TagKey<K> tag;
|
||||
private final Function<K, Holder<K>> holderGetter;
|
||||
private final V value;
|
||||
|
||||
public TagProviderImpl(TagKey<K> tag, Function<K, Holder<K>> holderGetter, V value) {
|
||||
this.tag = tag;
|
||||
this.holderGetter = holderGetter;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public V get(K object) {
|
||||
Holder<K> holder = this.holderGetter.apply(object);
|
||||
return holder.is(this.tag) ? this.value : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRegister(AttachedRegistry<K, V> registry) {
|
||||
MinecraftForge.EVENT_BUS.addListener((TagsUpdatedEvent event) -> {
|
||||
if (event.shouldUpdateStaticData()) {
|
||||
registry.invalidateProvider(this);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
package com.simibubi.create.impl.schematic.nbt;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
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;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public class SchematicSafeNBTRegistryImpl {
|
||||
private static final AttachedRegistry<BlockEntityType<?>, 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);
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
package com.simibubi.create.impl.schematic.requirement;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
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;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public class SchematicRequirementsRegistryImpl {
|
||||
private static final AttachedRegistry<Block, SchematicRequirementsRegistry.BlockRequirement> BLOCK_REQUIREMENTS = new AttachedRegistry<>(ForgeRegistries.BLOCKS);
|
||||
private static final AttachedRegistry<BlockEntityType<?>, SchematicRequirementsRegistry.BlockEntityRequirement> BLOCK_ENTITY_REQUIREMENTS = new AttachedRegistry<>(ForgeRegistries.BLOCK_ENTITY_TYPES);
|
||||
private static final AttachedRegistry<EntityType<?>, 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);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue