mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-03-04 06:44:40 +01:00
double it and give it to the next person
- fluid mounted storage - handling for old data format - a few more docs
This commit is contained in:
parent
5c0b012357
commit
595263e0df
25 changed files with 597 additions and 71 deletions
|
@ -3,6 +3,7 @@ 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.content.redstone.displayLink.AllDisplayBehaviours.assignDataBehaviour;
|
||||
import static com.simibubi.create.foundation.data.BlockStateGen.axisBlock;
|
||||
|
@ -989,6 +990,7 @@ public class AllBlocks {
|
|||
.blockstate(new FluidTankGenerator()::generate)
|
||||
.onRegister(CreateRegistrate.blockModel(() -> FluidTankModel::standard))
|
||||
.onRegister(assignDataBehaviour(new BoilerDisplaySource(), "boiler_status"))
|
||||
.transform(mountedFluidStorage(AllMountedStorageTypes.FLUID_TANK))
|
||||
.addLayer(() -> RenderType::cutoutMipped)
|
||||
.item(FluidTankItem::new)
|
||||
.model(AssetLookup.customBlockItemModel("_", "block_single_window"))
|
||||
|
@ -1004,6 +1006,7 @@ public class AllBlocks {
|
|||
.tag(AllBlockTags.SAFE_NBT.tag)
|
||||
.blockstate(new FluidTankGenerator("creative_")::generate)
|
||||
.onRegister(CreateRegistrate.blockModel(() -> FluidTankModel::creative))
|
||||
.transform(mountedFluidStorage(AllMountedStorageTypes.CREATIVE_FLUID_TANK))
|
||||
.addLayer(() -> RenderType::cutoutMipped)
|
||||
.item(FluidTankItem::new)
|
||||
.properties(p -> p.rarity(Rarity.EPIC))
|
||||
|
|
|
@ -4,29 +4,31 @@ import static com.simibubi.create.Create.REGISTRATE;
|
|||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorageType;
|
||||
import com.simibubi.create.api.contraption.storage.item.MountedItemStorageType;
|
||||
import com.simibubi.create.api.contraption.storage.item.chest.ChestMountedStorageType;
|
||||
import com.simibubi.create.api.contraption.storage.item.simple.SimpleMountedStorageType;
|
||||
import com.simibubi.create.content.contraptions.behaviour.dispenser.storage.DispenserMountedStorageType;
|
||||
import com.simibubi.create.content.equipment.toolbox.ToolboxMountedStorageType;
|
||||
import com.simibubi.create.content.fluids.tank.storage.FluidTankMountedStorageType;
|
||||
import com.simibubi.create.content.fluids.tank.storage.creative.CreativeFluidTankMountedStorageType;
|
||||
import com.simibubi.create.content.logistics.crate.CreativeCrateMountedStorageType;
|
||||
|
||||
import com.simibubi.create.api.contraption.storage.item.simple.SimpleMountedStorageType;
|
||||
|
||||
import com.simibubi.create.content.logistics.vault.ItemVaultMountedStorageType;
|
||||
import com.simibubi.create.impl.contraption.storage.FallbackMountedStorageType;
|
||||
|
||||
import com.tterrag.registrate.util.entry.RegistryEntry;
|
||||
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
|
||||
public class AllMountedStorageTypes {
|
||||
// fallback is special, provider is registered on lookup creation so it's always last
|
||||
public static final RegistryEntry<FallbackMountedStorageType> FALLBACK = simple("fallback", FallbackMountedStorageType::new);
|
||||
public static final RegistryEntry<FallbackMountedStorageType> FALLBACK = simpleItem("fallback", FallbackMountedStorageType::new);
|
||||
|
||||
// registrations for these are handled by the blocks, not the types
|
||||
public static final RegistryEntry<CreativeCrateMountedStorageType> CREATIVE_CRATE = simple("creative_crate", CreativeCrateMountedStorageType::new);
|
||||
public static final RegistryEntry<ItemVaultMountedStorageType> VAULT = simple("vault", ItemVaultMountedStorageType::new);
|
||||
public static final RegistryEntry<ToolboxMountedStorageType> TOOLBOX = simple("toolbox", ToolboxMountedStorageType::new);
|
||||
public static final RegistryEntry<CreativeCrateMountedStorageType> CREATIVE_CRATE = simpleItem("creative_crate", CreativeCrateMountedStorageType::new);
|
||||
public static final RegistryEntry<ItemVaultMountedStorageType> VAULT = simpleItem("vault", ItemVaultMountedStorageType::new);
|
||||
public static final RegistryEntry<ToolboxMountedStorageType> TOOLBOX = simpleItem("toolbox", ToolboxMountedStorageType::new);
|
||||
public static final RegistryEntry<FluidTankMountedStorageType> FLUID_TANK = simpleFluid("fluid_tank", FluidTankMountedStorageType::new);
|
||||
public static final RegistryEntry<CreativeFluidTankMountedStorageType> CREATIVE_FLUID_TANK = simpleFluid("creative_fluid_tank", CreativeFluidTankMountedStorageType::new);
|
||||
|
||||
// these are for external blocks, register associations here
|
||||
public static final RegistryEntry<SimpleMountedStorageType.Impl> SIMPLE = REGISTRATE.mountedItemStorage("simple", SimpleMountedStorageType.Impl::new)
|
||||
|
@ -40,10 +42,14 @@ public class AllMountedStorageTypes {
|
|||
.registerTo(Blocks.DROPPER)
|
||||
.register();
|
||||
|
||||
private static <T extends MountedItemStorageType<?>> RegistryEntry<T> simple(String name, Supplier<T> supplier) {
|
||||
private static <T extends MountedItemStorageType<?>> RegistryEntry<T> simpleItem(String name, Supplier<T> supplier) {
|
||||
return REGISTRATE.mountedItemStorage(name, supplier).register();
|
||||
}
|
||||
|
||||
private static <T extends MountedFluidStorageType<?>> RegistryEntry<T> simpleFluid(String name, Supplier<T> supplier) {
|
||||
return REGISTRATE.mountedFluidStorage(name, supplier).register();
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,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.impl.contraption.storage.MountedStorageTypeRegistryImpl;
|
||||
|
@ -8,22 +9,29 @@ import com.tterrag.registrate.builders.BlockBuilder;
|
|||
import com.tterrag.registrate.util.entry.RegistryEntry;
|
||||
import com.tterrag.registrate.util.nullness.NonNullUnaryOperator;
|
||||
|
||||
import net.minecraftforge.registries.IForgeRegistry;
|
||||
|
||||
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 static final ResourceKey<Registry<MountedItemStorageType<?>>> ITEMS = ResourceKey.createRegistryKey(
|
||||
Create.asResource("mounted_item_storage_type")
|
||||
);
|
||||
public static final ResourceKey<Registry<MountedFluidStorageType<?>>> FLUIDS = ResourceKey.createRegistryKey(
|
||||
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;
|
||||
|
||||
/**
|
||||
* @throws NullPointerException if called before registry registration
|
||||
|
@ -32,6 +40,13 @@ public class MountedStorageTypeRegistry {
|
|||
return MountedStorageTypeRegistryImpl.getItemsRegistry();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException if called before registry registration
|
||||
*/
|
||||
public static IForgeRegistry<MountedFluidStorageType<?>> getFluidsRegistry() {
|
||||
return MountedStorageTypeRegistryImpl.getFluidsRegistry();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility for use with Registrate builders. Creates a builder transformer
|
||||
* that will register the given MountedItemStorageType to a block when ready.
|
||||
|
@ -39,4 +54,12 @@ public class MountedStorageTypeRegistry {
|
|||
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()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility for use with Registrate builders. Creates a builder transformer
|
||||
* 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()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package com.simibubi.create.api.contraption.storage.fluid;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
|
||||
public abstract class MountedFluidStorage implements IFluidHandler {
|
||||
public static final Codec<MountedFluidStorage> CODEC = MountedFluidStorageType.CODEC.dispatch(
|
||||
storage -> storage.type, type -> type.codec
|
||||
);
|
||||
|
||||
public final MountedFluidStorageType<? extends MountedFluidStorage> type;
|
||||
|
||||
protected MountedFluidStorage(MountedFluidStorageType<?> type) {
|
||||
this.type = Objects.requireNonNull(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Un-mount this storage back into the world. The expected storage type of the target
|
||||
* block has already been checked to make sure it matches this storage's type.
|
||||
*/
|
||||
public abstract void unmount(Level level, BlockState state, BlockPos pos, @Nullable BlockEntity be);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
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 net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.ExtraCodecs;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
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()
|
||||
);
|
||||
|
||||
public final Codec<? extends T> codec;
|
||||
|
||||
protected MountedFluidStorageType(Codec<? extends T> codec) {
|
||||
this.codec = codec;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public abstract T mount(Level level, BlockState state, BlockPos pos, @Nullable BlockEntity be);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.simibubi.create.api.contraption.storage.fluid;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.simibubi.create.foundation.fluid.CombinedTankWrapper;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
|
||||
/**
|
||||
* Wrapper around many MountedFluidStorages, providing access to all of them as one storage.
|
||||
* They can still be accessed individually through the map.
|
||||
*/
|
||||
public class MountedFluidStorageWrapper extends CombinedTankWrapper {
|
||||
public final ImmutableMap<BlockPos, MountedFluidStorage> storages;
|
||||
|
||||
public MountedFluidStorageWrapper(ImmutableMap<BlockPos, MountedFluidStorage> storages) {
|
||||
super(storages.values().toArray(IFluidHandler[]::new));
|
||||
this.storages = storages;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package com.simibubi.create.api.contraption.storage.fluid;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
|
||||
/**
|
||||
* Partial implementation of a MountedFluidStorage that wraps a fluid handler.
|
||||
*/
|
||||
public abstract class WrapperMountedFluidStorage<T extends IFluidHandler> extends MountedFluidStorage {
|
||||
protected final T wrapped;
|
||||
|
||||
protected WrapperMountedFluidStorage(MountedFluidStorageType<?> type, T wrapped) {
|
||||
super(type);
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTanks() {
|
||||
return this.wrapped.getTanks();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public FluidStack getFluidInTank(int tank) {
|
||||
return this.wrapped.getFluidInTank(tank);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTankCapacity(int tank) {
|
||||
return this.wrapped.getTankCapacity(tank);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFluidValid(int tank, @NotNull FluidStack stack) {
|
||||
return this.wrapped.isFluidValid(tank, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int fill(FluidStack resource, FluidAction action) {
|
||||
return this.wrapped.fill(resource, action);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public FluidStack drain(FluidStack resource, FluidAction action) {
|
||||
return this.wrapped.drain(resource, action);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public FluidStack drain(int maxDrain, FluidAction action) {
|
||||
return this.wrapped.drain(maxDrain, action);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.simibubi.create.api.contraption.storage.fluid.registrate;
|
||||
|
||||
import com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistry;
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorageType;
|
||||
import com.tterrag.registrate.AbstractRegistrate;
|
||||
import com.tterrag.registrate.builders.AbstractBuilder;
|
||||
import com.tterrag.registrate.builders.BuilderCallback;
|
||||
import com.tterrag.registrate.util.nullness.NonnullType;
|
||||
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
public class MountedFluidStorageTypeBuilder<T extends MountedFluidStorageType<?>, P> extends AbstractBuilder<MountedFluidStorageType<?>, T, P, MountedFluidStorageTypeBuilder<T, P>> {
|
||||
private final T type;
|
||||
|
||||
public MountedFluidStorageTypeBuilder(AbstractRegistrate<?> owner, P parent, String name, BuilderCallback callback, T type) {
|
||||
super(owner, parent, name, callback, MountedStorageTypeRegistry.FLUIDS);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public MountedFluidStorageTypeBuilder<T, P> registerTo(Block block) {
|
||||
MountedStorageTypeRegistry.FLUID_LOOKUP.register(block, this.type);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MountedFluidStorageTypeBuilder<T, P> registerTo(TagKey<Block> tag) {
|
||||
MountedStorageTypeRegistry.FLUID_LOOKUP.registerTag(tag, this.type);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonnullType
|
||||
protected T createEntry() {
|
||||
return this.type;
|
||||
}
|
||||
}
|
|
@ -2,11 +2,14 @@ package com.simibubi.create.api.contraption.storage.item;
|
|||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
||||
/**
|
||||
* Wrapper around many MountedItemStorages, providing access to all of them as one storage.
|
||||
* They can still be accessed individually through the map.
|
||||
*/
|
||||
public class MountedItemStorageWrapper extends CombinedInvWrapper {
|
||||
public final ImmutableMap<BlockPos, MountedItemStorage> storages;
|
||||
|
||||
|
|
|
@ -7,6 +7,9 @@ import net.minecraftforge.items.IItemHandler;
|
|||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
|
||||
/**
|
||||
* Partial implementation of a MountedItemStorage that wraps an item handler.
|
||||
*/
|
||||
public abstract class WrapperMountedItemStorage<T extends IItemHandlerModifiable> extends MountedItemStorage {
|
||||
protected final T wrapped;
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||
import net.minecraft.world.level.block.state.properties.ChestType;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
||||
|
@ -33,7 +32,6 @@ import net.minecraftforge.items.wrapper.InvWrapper;
|
|||
/**
|
||||
* Mounted storage that handles opening a combined GUI for double chests.
|
||||
*/
|
||||
@Mod.EventBusSubscriber
|
||||
public class ChestMountedStorage extends SimpleMountedStorage {
|
||||
public static final Codec<ChestMountedStorage> CODEC = SimpleMountedStorage.codec(ChestMountedStorage::new);
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package com.simibubi.create.api.lookup;
|
||||
|
||||
import com.simibubi.create.impl.lookup.BlockLookupImpl;
|
||||
|
||||
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;
|
||||
|
@ -14,7 +14,10 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||
* 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.
|
||||
* <br>
|
||||
* <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.
|
||||
*/
|
||||
|
|
|
@ -9,11 +9,20 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistry;
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorage;
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorageType;
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorageWrapper;
|
||||
import com.simibubi.create.api.contraption.storage.item.MountedItemStorage;
|
||||
import com.simibubi.create.api.contraption.storage.item.MountedItemStorageType;
|
||||
import com.simibubi.create.api.contraption.storage.item.MountedItemStorageWrapper;
|
||||
import com.simibubi.create.foundation.fluid.CombinedTankWrapper;
|
||||
import com.simibubi.create.content.equipment.toolbox.ToolboxMountedStorage;
|
||||
import com.simibubi.create.content.fluids.tank.storage.FluidTankMountedStorage;
|
||||
import com.simibubi.create.content.fluids.tank.storage.creative.CreativeFluidTankMountedStorage;
|
||||
import com.simibubi.create.content.logistics.crate.CreativeCrateMountedStorage;
|
||||
import com.simibubi.create.content.logistics.vault.ItemVaultMountedStorage;
|
||||
import com.simibubi.create.impl.contraption.storage.FallbackMountedStorage;
|
||||
|
||||
import net.createmod.catnip.utility.NBTHelper;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -24,23 +33,27 @@ import net.minecraft.nbt.NbtUtils;
|
|||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
||||
|
||||
public class MountedStorageManager {
|
||||
|
||||
// builders used during assembly, null afterward
|
||||
private ImmutableMap.Builder<BlockPos, MountedItemStorage> itemsBuilder;
|
||||
private ImmutableMap.Builder<BlockPos, MountedFluidStorage> fluidsBuilder;
|
||||
|
||||
// built data structures after assembly, null before
|
||||
protected ImmutableMap<BlockPos, MountedItemStorage> allItemStorages;
|
||||
|
||||
// different from allItemStorages, does not contain internal ones
|
||||
protected MountedItemStorageWrapper items;
|
||||
@Nullable
|
||||
protected MountedItemStorageWrapper fuelItems;
|
||||
protected MountedFluidStorageWrapper fluids;
|
||||
|
||||
private List<IItemHandlerModifiable> externalHandlers;
|
||||
protected CombinedInvWrapper allItems;
|
||||
|
@ -67,6 +80,10 @@ public class MountedStorageManager {
|
|||
this.allItemStorages, storage -> !storage.isInternal() && storage.providesFuel()
|
||||
);
|
||||
this.fuelItems = fuelMap.isEmpty() ? null : new MountedItemStorageWrapper(fuelMap);
|
||||
|
||||
ImmutableMap<BlockPos, MountedFluidStorage> fluids = this.fluidsBuilder.build();
|
||||
this.fluids = new MountedFluidStorageWrapper(fluids);
|
||||
this.fluidsBuilder = null;
|
||||
}
|
||||
|
||||
private boolean isInitialized() {
|
||||
|
@ -83,30 +100,48 @@ public class MountedStorageManager {
|
|||
this.allItemStorages = null;
|
||||
this.items = null;
|
||||
this.fuelItems = null;
|
||||
this.fluids = null;
|
||||
this.externalHandlers = new ArrayList<>();
|
||||
this.allItems = null;
|
||||
this.itemsBuilder = ImmutableMap.builder();
|
||||
this.fluidsBuilder = ImmutableMap.builder();
|
||||
}
|
||||
|
||||
public void addBlock(Level level, BlockState state, BlockPos globalPos, BlockPos localPos, @Nullable BlockEntity be) {
|
||||
MountedItemStorageType<?> type = MountedStorageTypeRegistry.ITEM_LOOKUP.find(state);
|
||||
if (type == null)
|
||||
return;
|
||||
MountedItemStorageType<?> itemType = MountedStorageTypeRegistry.ITEM_LOOKUP.find(state);
|
||||
if (itemType != null) {
|
||||
MountedItemStorage storage = itemType.mount(level, state, globalPos, be);
|
||||
if (storage != null) {
|
||||
this.itemsBuilder.put(localPos, storage);
|
||||
}
|
||||
}
|
||||
|
||||
MountedItemStorage storage = type.mount(level, state, globalPos, be);
|
||||
if (storage != null) {
|
||||
this.itemsBuilder.put(localPos, storage);
|
||||
MountedFluidStorageType<?> fluidType = MountedStorageTypeRegistry.FLUID_LOOKUP.find(state);
|
||||
if (fluidType != null) {
|
||||
MountedFluidStorage storage = fluidType.mount(level, state, globalPos, be);
|
||||
if (storage != null) {
|
||||
this.fluidsBuilder.put(localPos, storage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void unmount(Level level, StructureBlockInfo info, BlockPos globalPos, @Nullable BlockEntity be) {
|
||||
BlockPos localPos = info.pos();
|
||||
MountedItemStorage storage = this.getAllItemStorages().get(localPos);
|
||||
if (storage != null) {
|
||||
BlockState state = info.state();
|
||||
BlockState state = info.state();
|
||||
|
||||
MountedItemStorage itemStorage = this.getAllItemStorages().get(localPos);
|
||||
if (itemStorage != null) {
|
||||
MountedItemStorageType<?> expectedType = MountedStorageTypeRegistry.ITEM_LOOKUP.find(state);
|
||||
if (storage.type == expectedType) {
|
||||
storage.unmount(level, state, globalPos, be);
|
||||
if (itemStorage.type == expectedType) {
|
||||
itemStorage.unmount(level, state, globalPos, be);
|
||||
}
|
||||
}
|
||||
|
||||
MountedFluidStorage fluidStorage = this.getFluids().storages.get(localPos);
|
||||
if (fluidStorage != null) {
|
||||
MountedFluidStorageType<?> expectedType = MountedStorageTypeRegistry.FLUID_LOOKUP.find(state);
|
||||
if (fluidStorage.type == expectedType) {
|
||||
fluidStorage.unmount(level, state, globalPos, be);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,35 +149,62 @@ public class MountedStorageManager {
|
|||
public void read(CompoundTag nbt) {
|
||||
this.reset();
|
||||
|
||||
NBTHelper.iterateCompoundList(nbt.getList("items", Tag.TAG_COMPOUND), tag -> {
|
||||
BlockPos pos = NbtUtils.readBlockPos(tag.getCompound("pos"));
|
||||
CompoundTag data = tag.getCompound("storage");
|
||||
MountedItemStorage.CODEC.decode(NbtOps.INSTANCE, data)
|
||||
.result()
|
||||
.map(Pair::getFirst)
|
||||
// .or(() -> Optional.ofNullable(parseLegacy(data)))
|
||||
.ifPresent(storage -> this.itemsBuilder.put(pos, storage));
|
||||
});
|
||||
try {
|
||||
NBTHelper.iterateCompoundList(nbt.getList("items", Tag.TAG_COMPOUND), tag -> {
|
||||
BlockPos pos = NbtUtils.readBlockPos(tag.getCompound("pos"));
|
||||
CompoundTag data = tag.getCompound("storage");
|
||||
MountedItemStorage.CODEC.decode(NbtOps.INSTANCE, data)
|
||||
.result()
|
||||
.map(Pair::getFirst)
|
||||
.ifPresent(storage -> this.itemsBuilder.put(pos, storage));
|
||||
});
|
||||
|
||||
// NBTHelper.iterateCompoundList(nbt.getList("FluidStorage", Tag.TAG_COMPOUND), c -> fluidStorage
|
||||
// .put(NbtUtils.readBlockPos(c.getCompound("Pos")), MountedFluidStorage.deserialize(c.getCompound("Data"))));
|
||||
NBTHelper.iterateCompoundList(nbt.getList("fluids", Tag.TAG_COMPOUND), tag -> {
|
||||
BlockPos pos = NbtUtils.readBlockPos(tag.getCompound("pos"));
|
||||
CompoundTag data = tag.getCompound("storage");
|
||||
MountedFluidStorage.CODEC.decode(NbtOps.INSTANCE, data)
|
||||
.result()
|
||||
.map(Pair::getFirst)
|
||||
.ifPresent(storage -> this.fluidsBuilder.put(pos, storage));
|
||||
});
|
||||
|
||||
this.readLegacy(nbt);
|
||||
} catch (Throwable t) {
|
||||
Create.LOGGER.error("Error deserializing mounted storage", t);
|
||||
// an exception will leave the manager in an invalid state, initialize must be called
|
||||
}
|
||||
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
public void write(CompoundTag nbt, boolean clientPacket) {
|
||||
ListTag items = new ListTag();
|
||||
nbt.put("items", items);
|
||||
if (!this.getAllItemStorages().isEmpty()) {
|
||||
ListTag items = new ListTag();
|
||||
this.getAllItemStorages().forEach(
|
||||
(pos, storage) -> MountedItemStorage.CODEC.encodeStart(NbtOps.INSTANCE, storage)
|
||||
.result().ifPresent(encoded -> {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.put("pos", NbtUtils.writeBlockPos(pos));
|
||||
tag.put("storage", encoded);
|
||||
items.add(tag);
|
||||
})
|
||||
);
|
||||
nbt.put("items", items);
|
||||
}
|
||||
|
||||
this.getAllItemStorages().forEach(
|
||||
(pos, storage) -> MountedItemStorage.CODEC.encodeStart(NbtOps.INSTANCE, storage)
|
||||
.result().ifPresent(encoded -> {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.put("pos", NbtUtils.writeBlockPos(pos));
|
||||
tag.put("storage", encoded);
|
||||
items.add(tag);
|
||||
})
|
||||
);
|
||||
if (!this.getFluids().storages.isEmpty()) {
|
||||
ListTag fluids = new ListTag();
|
||||
this.getFluids().storages.forEach(
|
||||
(pos, storage) -> MountedFluidStorage.CODEC.encodeStart(NbtOps.INSTANCE, storage)
|
||||
.result().ifPresent(encoded -> {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.put("pos", NbtUtils.writeBlockPos(pos));
|
||||
tag.put("storage", encoded);
|
||||
fluids.add(tag);
|
||||
})
|
||||
);
|
||||
nbt.put("fluids", fluids);
|
||||
}
|
||||
}
|
||||
|
||||
public void attachExternal(IItemHandlerModifiable externalStorage) {
|
||||
|
@ -198,8 +260,9 @@ public class MountedStorageManager {
|
|||
return this.allItems;
|
||||
}
|
||||
|
||||
public IFluidHandler getFluids() {
|
||||
return new CombinedTankWrapper();
|
||||
public MountedFluidStorageWrapper getFluids() {
|
||||
this.assertInitialized();
|
||||
return this.fluids;
|
||||
}
|
||||
|
||||
public boolean handlePlayerStorageInteraction(Contraption contraption, Player player, BlockPos localPos) {
|
||||
|
@ -217,6 +280,39 @@ public class MountedStorageManager {
|
|||
}
|
||||
}
|
||||
|
||||
private void readLegacy(CompoundTag nbt) {
|
||||
NBTHelper.iterateCompoundList(nbt.getList("Storage", Tag.TAG_COMPOUND), tag -> {
|
||||
BlockPos pos = NbtUtils.readBlockPos(tag.getCompound("Pos"));
|
||||
CompoundTag data = tag.getCompound("Data");
|
||||
|
||||
// note: Synced is ignored, since all are synced
|
||||
if (data.contains("Toolbox")) {
|
||||
this.itemsBuilder.put(pos, ToolboxMountedStorage.fromLegacy(data));
|
||||
} else if (data.contains("NoFuel")) {
|
||||
this.itemsBuilder.put(pos, ItemVaultMountedStorage.fromLegacy(data));
|
||||
} else if (data.contains("Bottomless")) {
|
||||
ItemStack supplied = ItemStack.of(data.getCompound("ProvidedStack"));
|
||||
this.itemsBuilder.put(pos, new CreativeCrateMountedStorage(supplied));
|
||||
} else {
|
||||
// we can create a fallback storage safely, it will be validated before unmounting
|
||||
ItemStackHandler handler = new ItemStackHandler();
|
||||
handler.deserializeNBT(data);
|
||||
this.itemsBuilder.put(pos, new FallbackMountedStorage(handler));
|
||||
}
|
||||
});
|
||||
|
||||
NBTHelper.iterateCompoundList(nbt.getList("FluidStorage", Tag.TAG_COMPOUND), tag -> {
|
||||
BlockPos pos = NbtUtils.readBlockPos(tag.getCompound("Pos"));
|
||||
CompoundTag data = tag.getCompound("Data");
|
||||
|
||||
if (data.contains("Bottomless")) {
|
||||
this.fluidsBuilder.put(pos, CreativeFluidTankMountedStorage.fromLegacy(data));
|
||||
} else {
|
||||
this.fluidsBuilder.put(pos, FluidTankMountedStorage.fromLegacy(data));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static <K, V> ImmutableMap<K, V> subMap(Map<K, V> map, Predicate<V> predicate) {
|
||||
ImmutableMap.Builder<K, V> builder = ImmutableMap.builder();
|
||||
map.forEach((key, value) -> {
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.simibubi.create.content.contraptions.Contraption;
|
|||
import com.simibubi.create.foundation.item.ItemHelper;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
@ -50,4 +51,10 @@ public class ToolboxMountedStorage extends WrapperMountedItemStorage<ToolboxInve
|
|||
copy.filters = toolbox.inventory.filters.stream().map(ItemStack::copy).toList();
|
||||
return new ToolboxMountedStorage(copy);
|
||||
}
|
||||
|
||||
public static ToolboxMountedStorage fromLegacy(CompoundTag nbt) {
|
||||
ToolboxInventory inv = new ToolboxInventory(null);
|
||||
inv.deserializeNBT(nbt);
|
||||
return new ToolboxMountedStorage(inv);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,13 +3,17 @@ package com.simibubi.create.content.fluids.tank;
|
|||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import com.simibubi.create.foundation.fluid.SmartFluidTank;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.ExtraCodecs;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.templates.FluidTank;
|
||||
|
||||
public class CreativeFluidTankBlockEntity extends FluidTankBlockEntity {
|
||||
|
||||
|
@ -21,26 +25,34 @@ public class CreativeFluidTankBlockEntity extends FluidTankBlockEntity {
|
|||
protected SmartFluidTank createInventory() {
|
||||
return new CreativeSmartFluidTank(getCapacityMultiplier(), this::onFluidStackChanged);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class CreativeSmartFluidTank extends SmartFluidTank {
|
||||
public static final Codec<CreativeSmartFluidTank> CODEC = RecordCodecBuilder.create(i -> i.group(
|
||||
FluidStack.CODEC.fieldOf("fluid").forGetter(FluidTank::getFluid),
|
||||
ExtraCodecs.NON_NEGATIVE_INT.fieldOf("capacity").forGetter(FluidTank::getCapacity)
|
||||
).apply(i, (fluid, capacity) -> {
|
||||
CreativeSmartFluidTank tank = new CreativeSmartFluidTank(capacity, $ -> {});
|
||||
tank.setFluid(fluid);
|
||||
return tank;
|
||||
}));
|
||||
|
||||
public CreativeSmartFluidTank(int capacity, Consumer<FluidStack> updateCallback) {
|
||||
super(capacity, updateCallback);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getFluidAmount() {
|
||||
return getFluid().isEmpty() ? 0 : getTankCapacity(0);
|
||||
}
|
||||
|
||||
|
||||
public void setContainedFluid(FluidStack fluidStack) {
|
||||
fluid = fluidStack.copy();
|
||||
if (!fluidStack.isEmpty())
|
||||
if (!fluidStack.isEmpty())
|
||||
fluid.setAmount(getTankCapacity(0));
|
||||
onContentsChanged();
|
||||
}
|
||||
|
|
|
@ -502,7 +502,7 @@ public class FluidTankBlockEntity extends SmartBlockEntity implements IHaveGoggl
|
|||
registerAwardables(behaviours, AllAdvancements.STEAM_ENGINE_MAXED, AllAdvancements.PIPE_ORGAN);
|
||||
}
|
||||
|
||||
public IFluidTank getTankInventory() {
|
||||
public FluidTank getTankInventory() {
|
||||
return tankInventory;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package com.simibubi.create.content.fluids.tank.storage;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.simibubi.create.AllMountedStorageTypes;
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorageType;
|
||||
import com.simibubi.create.api.contraption.storage.fluid.WrapperMountedFluidStorage;
|
||||
import com.simibubi.create.content.fluids.tank.FluidTankBlockEntity;
|
||||
import com.simibubi.create.foundation.utility.CreateCodecs;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.fluids.capability.templates.FluidTank;
|
||||
|
||||
public class FluidTankMountedStorage extends WrapperMountedFluidStorage<FluidTank> {
|
||||
public static final Codec<FluidTankMountedStorage> CODEC = CreateCodecs.FLUID_TANK.xmap(
|
||||
FluidTankMountedStorage::new, storage -> storage.wrapped
|
||||
);
|
||||
|
||||
protected FluidTankMountedStorage(MountedFluidStorageType<?> type, FluidTank wrapped) {
|
||||
super(type, wrapped);
|
||||
}
|
||||
|
||||
protected FluidTankMountedStorage(FluidTank wrapped) {
|
||||
this(AllMountedStorageTypes.FLUID_TANK.get(), wrapped);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unmount(Level level, BlockState state, BlockPos pos, @Nullable BlockEntity be) {
|
||||
if (be instanceof FluidTankBlockEntity tank && tank.isController()) {
|
||||
FluidTank inventory = tank.getTankInventory();
|
||||
// capacity shouldn't change, leave it
|
||||
inventory.setFluid(this.wrapped.getFluid());
|
||||
}
|
||||
}
|
||||
|
||||
public static FluidTankMountedStorage fromTank(FluidTankBlockEntity tank) {
|
||||
// tank has update callbacks, make an isolated copy
|
||||
FluidTank inventory = tank.getTankInventory();
|
||||
FluidTank copy = new FluidTank(inventory.getCapacity());
|
||||
copy.setFluid(inventory.getFluid());
|
||||
return new FluidTankMountedStorage(copy);
|
||||
}
|
||||
|
||||
public static FluidTankMountedStorage fromLegacy(CompoundTag nbt) {
|
||||
int capacity = nbt.getInt("Capacity");
|
||||
FluidTank tank = new FluidTank(capacity);
|
||||
tank.readFromNBT(nbt);
|
||||
return new FluidTankMountedStorage(tank);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.simibubi.create.content.fluids.tank.storage;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorageType;
|
||||
import com.simibubi.create.content.fluids.tank.FluidTankBlockEntity;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class FluidTankMountedStorageType extends MountedFluidStorageType<FluidTankMountedStorage> {
|
||||
public FluidTankMountedStorageType() {
|
||||
super(FluidTankMountedStorage.CODEC);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public FluidTankMountedStorage mount(Level level, BlockState state, BlockPos pos, @Nullable BlockEntity be) {
|
||||
if (be instanceof FluidTankBlockEntity tank && tank.isController()) {
|
||||
return FluidTankMountedStorage.fromTank(tank);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.simibubi.create.content.fluids.tank.storage.creative;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.simibubi.create.AllMountedStorageTypes;
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorageType;
|
||||
import com.simibubi.create.api.contraption.storage.fluid.WrapperMountedFluidStorage;
|
||||
import com.simibubi.create.content.fluids.tank.CreativeFluidTankBlockEntity;
|
||||
import com.simibubi.create.content.fluids.tank.CreativeFluidTankBlockEntity.CreativeSmartFluidTank;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.templates.FluidTank;
|
||||
|
||||
public class CreativeFluidTankMountedStorage extends WrapperMountedFluidStorage<CreativeSmartFluidTank> {
|
||||
public static final Codec<CreativeFluidTankMountedStorage> CODEC = CreativeSmartFluidTank.CODEC.xmap(
|
||||
CreativeFluidTankMountedStorage::new, storage -> storage.wrapped
|
||||
);
|
||||
|
||||
protected CreativeFluidTankMountedStorage(MountedFluidStorageType<?> type, CreativeSmartFluidTank tank) {
|
||||
super(type, tank);
|
||||
}
|
||||
|
||||
protected CreativeFluidTankMountedStorage(CreativeSmartFluidTank tank) {
|
||||
this(AllMountedStorageTypes.CREATIVE_FLUID_TANK.get(), tank);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unmount(Level level, BlockState state, BlockPos pos, @Nullable BlockEntity be) {
|
||||
// no need to do anything, supplied stack can't change while mounted
|
||||
}
|
||||
|
||||
public static CreativeFluidTankMountedStorage fromTank(CreativeFluidTankBlockEntity tank) {
|
||||
// make an isolated copy
|
||||
FluidTank inv = tank.getTankInventory();
|
||||
CreativeSmartFluidTank copy = new CreativeSmartFluidTank(inv.getCapacity(), $ -> {});
|
||||
copy.setContainedFluid(inv.getFluid());
|
||||
return new CreativeFluidTankMountedStorage(copy);
|
||||
}
|
||||
|
||||
public static CreativeFluidTankMountedStorage fromLegacy(CompoundTag nbt) {
|
||||
int capacity = nbt.getInt("Capacity");
|
||||
FluidStack fluid = FluidStack.loadFluidStackFromNBT(nbt.getCompound("ProvidedStack"));
|
||||
CreativeSmartFluidTank tank = new CreativeSmartFluidTank(capacity, $ -> {});
|
||||
tank.setContainedFluid(fluid);
|
||||
return new CreativeFluidTankMountedStorage(tank);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.simibubi.create.content.fluids.tank.storage.creative;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorageType;
|
||||
import com.simibubi.create.content.fluids.tank.CreativeFluidTankBlockEntity;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class CreativeFluidTankMountedStorageType extends MountedFluidStorageType<CreativeFluidTankMountedStorage> {
|
||||
public CreativeFluidTankMountedStorageType() {
|
||||
super(CreativeFluidTankMountedStorage.CODEC);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public CreativeFluidTankMountedStorage mount(Level level, BlockState state, BlockPos pos, @Nullable BlockEntity be) {
|
||||
if (be instanceof CreativeFluidTankBlockEntity tank) {
|
||||
return CreativeFluidTankMountedStorage.fromTank(tank);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ import com.simibubi.create.api.contraption.storage.item.WrapperMountedItemStorag
|
|||
import com.simibubi.create.foundation.utility.CreateCodecs;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
@ -43,4 +44,10 @@ public class ItemVaultMountedStorage extends WrapperMountedItemStorage<ItemStack
|
|||
// Vault inventories have a world-affecting onContentsChanged, copy to a safe one
|
||||
return new ItemVaultMountedStorage(copyToItemStackHandler(vault.getInventoryOfBlock()));
|
||||
}
|
||||
|
||||
public static ItemVaultMountedStorage fromLegacy(CompoundTag nbt) {
|
||||
ItemStackHandler handler = new ItemStackHandler();
|
||||
handler.deserializeNBT(nbt);
|
||||
return new ItemVaultMountedStorage(handler);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,13 +10,13 @@ import java.util.function.Consumer;
|
|||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.api.contraption.storage.item.MountedItemStorageType;
|
||||
|
||||
import com.simibubi.create.api.contraption.storage.item.registrate.MountedItemStorageTypeBuilder;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorageType;
|
||||
import com.simibubi.create.api.contraption.storage.fluid.registrate.MountedFluidStorageTypeBuilder;
|
||||
import com.simibubi.create.api.contraption.storage.item.MountedItemStorageType;
|
||||
import com.simibubi.create.api.contraption.storage.item.registrate.MountedItemStorageTypeBuilder;
|
||||
import com.simibubi.create.content.decoration.encasing.CasingConnectivity;
|
||||
import com.simibubi.create.content.fluids.VirtualFluid;
|
||||
import com.simibubi.create.foundation.block.connected.CTModel;
|
||||
|
@ -148,6 +148,10 @@ public class CreateRegistrate extends AbstractRegistrate<CreateRegistrate> {
|
|||
return this.entry(name, callback -> new MountedItemStorageTypeBuilder<>(this, this, name, callback, supplier.get()));
|
||||
}
|
||||
|
||||
public <T extends MountedFluidStorageType<?>> MountedFluidStorageTypeBuilder<T, CreateRegistrate> mountedFluidStorage(String name, Supplier<T> supplier) {
|
||||
return this.entry(name, callback -> new MountedFluidStorageTypeBuilder<>(this, this, name, callback, supplier.get()));
|
||||
}
|
||||
|
||||
/* Palettes */
|
||||
|
||||
public <T extends Block> BlockBuilder<T, CreateRegistrate> paletteStoneBlock(String name,
|
||||
|
|
|
@ -11,11 +11,14 @@ import com.simibubi.create.foundation.utility.CreateCodecs;
|
|||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
import net.minecraft.util.ExtraCodecs;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
|
||||
/**
|
||||
* Utility class representing non-empty slots in an item inventory.
|
||||
*/
|
||||
public class ItemSlots {
|
||||
public static final Codec<ItemSlots> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||
Codec.unboundedMap(CreateCodecs.boundedIntStr(0), ItemStack.CODEC).fieldOf("items").forGetter(ItemSlots::toBoxedMap),
|
||||
|
|
|
@ -2,11 +2,13 @@ package com.simibubi.create.foundation.utility;
|
|||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.DataResult;
|
||||
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import com.simibubi.create.foundation.item.ItemSlots;
|
||||
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraft.util.ExtraCodecs;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.templates.FluidTank;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
|
||||
public class CreateCodecs {
|
||||
public static final Codec<Integer> INT_STR = Codec.STRING.comapFlatMap(
|
||||
|
@ -24,6 +26,18 @@ public class CreateCodecs {
|
|||
slots -> slots.toHandler(ItemStackHandler::new), ItemSlots::fromHandler
|
||||
);
|
||||
|
||||
/**
|
||||
* Codec for a simple FluidTank with no validator support.
|
||||
*/
|
||||
public static final Codec<FluidTank> FLUID_TANK = RecordCodecBuilder.create(i -> i.group(
|
||||
FluidStack.CODEC.fieldOf("fluid").forGetter(FluidTank::getFluid),
|
||||
ExtraCodecs.NON_NEGATIVE_INT.fieldOf("capacity").forGetter(FluidTank::getCapacity)
|
||||
).apply(i, (fluid, capacity) -> {
|
||||
FluidTank tank = new FluidTank(capacity);
|
||||
tank.setFluid(fluid);
|
||||
return tank;
|
||||
}));
|
||||
|
||||
public static Codec<Integer> boundedIntStr(int min) {
|
||||
return ExtraCodecs.validate(
|
||||
INT_STR,
|
||||
|
|
|
@ -7,6 +7,7 @@ import org.jetbrains.annotations.ApiStatus;
|
|||
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.fluid.MountedFluidStorageType;
|
||||
import com.simibubi.create.api.contraption.storage.item.MountedItemStorageType;
|
||||
import com.simibubi.create.api.lookup.BlockLookup;
|
||||
|
||||
|
@ -21,13 +22,19 @@ import net.minecraftforge.registries.RegistryBuilder;
|
|||
@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();
|
||||
|
||||
private static IForgeRegistry<MountedItemStorageType<?>> itemsRegistry;
|
||||
private static IForgeRegistry<MountedFluidStorageType<?>> fluidsRegistry;
|
||||
|
||||
public static IForgeRegistry<MountedItemStorageType<?>> getItemsRegistry() {
|
||||
return Objects.requireNonNull(itemsRegistry, "Registry accessed too early");
|
||||
}
|
||||
|
||||
public static IForgeRegistry<MountedFluidStorageType<?>> getFluidsRegistry() {
|
||||
return Objects.requireNonNull(fluidsRegistry, "Registry accessed too early");
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void registerRegistries(NewRegistryEvent event) {
|
||||
event.create(
|
||||
|
@ -35,9 +42,14 @@ public class MountedStorageTypeRegistryImpl {
|
|||
.setName(MountedStorageTypeRegistry.ITEMS.location()),
|
||||
registry -> itemsRegistry = registry
|
||||
);
|
||||
event.create(
|
||||
new RegistryBuilder<MountedFluidStorageType<?>>()
|
||||
.setName(MountedStorageTypeRegistry.FLUIDS.location()),
|
||||
registry -> fluidsRegistry = registry
|
||||
);
|
||||
}
|
||||
|
||||
public static MountedItemStorageType<?> itemFallback(Block block) {
|
||||
private static MountedItemStorageType<?> itemFallback(Block block) {
|
||||
return AllTags.AllBlockTags.FALLBACK_MOUNTED_STORAGE_BLACKLIST.matches(block)
|
||||
? null
|
||||
: AllMountedStorageTypes.FALLBACK.get();
|
||||
|
|
Loading…
Add table
Reference in a new issue