use tags for mounted item storage attributes (#16)

This commit is contained in:
TropheusJ 2025-02-21 11:05:15 -05:00 committed by GitHub
parent 5281a42d54
commit 30baef1740
Failed to generate hash of commit
15 changed files with 129 additions and 61 deletions

View file

@ -0,0 +1,3 @@
// 1.20.1 2025-02-20T19:36:44.18737762 Create's Mounted Item Storage Type Tags
c65f95f356db09e468847e5799a2cdd8e1417cac data/create/tags/create/mounted_item_storage_type/fuel_blacklist.json
fdadceec842a4cd12dd95f7e271645a52829ec6e data/create/tags/create/mounted_item_storage_type/internal.json

View file

@ -0,0 +1,5 @@
{
"values": [
"create:vault"
]
}

View file

@ -0,0 +1,5 @@
{
"values": [
"create:dispenser"
]
}

View file

@ -9,6 +9,8 @@ import static com.simibubi.create.AllTags.NameSpace.TIC;
import java.util.Collections;
import com.simibubi.create.api.contraption.ContraptionType;
import com.simibubi.create.api.contraption.storage.item.MountedItemStorage;
import com.simibubi.create.api.contraption.storage.item.MountedItemStorageType;
import com.simibubi.create.api.registry.CreateRegistries;
import net.createmod.catnip.lang.Lang;
@ -423,6 +425,31 @@ public class AllTags {
}
}
public enum AllMountedItemStorageTypeTags {
INTERNAL,
FUEL_BLACKLIST;
public final TagKey<MountedItemStorageType<?>> tag;
public final boolean alwaysDatagen;
AllMountedItemStorageTypeTags() {
ResourceLocation tagId = Create.asResource(Lang.asId(this.name()));
this.tag = TagKey.create(CreateRegistries.MOUNTED_ITEM_STORAGE_TYPE, tagId);
this.alwaysDatagen = true;
}
public boolean matches(MountedItemStorage storage) {
return this.matches(storage.type);
}
public boolean matches(MountedItemStorageType<?> type) {
return type.is(this.tag);
}
private static void init() {
}
}
public static void init() {
AllBlockTags.init();
AllItemTags.init();
@ -430,5 +457,6 @@ public class AllTags {
AllEntityTags.init();
AllRecipeSerializerTags.init();
AllContraptionTypeTags.init();
AllMountedItemStorageTypeTags.init();
}
}

View file

@ -8,11 +8,8 @@ import java.util.function.Predicate;
import org.jetbrains.annotations.Nullable;
import com.mojang.serialization.Codec;
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
import com.simibubi.create.api.contraption.storage.item.menu.MountedStorageMenus;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.MountedStorageManager;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.foundation.utility.CreateLang;
import net.minecraft.core.BlockPos;
@ -49,26 +46,6 @@ public abstract class MountedItemStorage implements IItemHandlerModifiable {
*/
public abstract void unmount(Level level, BlockState state, BlockPos pos, @Nullable BlockEntity be);
/**
* Internal mounted storages are not exposed to the larger contraption inventory.
* They are only for internal use, such as access from a {@link MovementBehaviour}.
* Internal storages are still accessible through {@link MovementContext#getItemStorage()}
* as well as {@link MountedStorageManager#getAllItemStorages()}.
* A storage being internal implies that it does not provide fuel either.
* This is only called once on assembly.
*/
public boolean isInternal() {
return false;
}
/**
* Contraptions may search storage for fuel, such as for powering furnace minecarts
* and trains. Return false if this storage should
*/
public boolean providesFuel() {
return true;
}
/**
* Handle a player clicking on this mounted storage. This is always called on the server.
* The default implementation will try to open a generic GUI for standard inventories.

View file

@ -13,6 +13,8 @@ import com.tterrag.registrate.util.nullness.NonNullUnaryOperator;
import net.minecraft.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.tags.TagKey;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
@ -27,9 +29,15 @@ public abstract class MountedItemStorageType<T extends MountedItemStorage> {
});
public final Codec<? extends T> codec;
public final Holder<MountedItemStorageType<?>> holder;
protected MountedItemStorageType(Codec<? extends T> codec) {
this.codec = codec;
this.holder = CreateBuiltInRegistries.MOUNTED_ITEM_STORAGE_TYPE.createIntrusiveHolder(this);
}
public final boolean is(TagKey<MountedItemStorageType<?>> tag) {
return this.holder.is(tag);
}
@Nullable

View file

@ -33,7 +33,7 @@ public class CreateBuiltInRegistries {
public static final Registry<ItemAttributeType> ITEM_ATTRIBUTE_TYPE = simple(CreateRegistries.ITEM_ATTRIBUTE_TYPE);
public static final Registry<DisplaySource> DISPLAY_SOURCE = simple(CreateRegistries.DISPLAY_SOURCE);
public static final Registry<DisplayTarget> DISPLAY_TARGET = simple(CreateRegistries.DISPLAY_TARGET);
public static final Registry<MountedItemStorageType<?>> MOUNTED_ITEM_STORAGE_TYPE = simple(CreateRegistries.MOUNTED_ITEM_STORAGE_TYPE);
public static final Registry<MountedItemStorageType<?>> MOUNTED_ITEM_STORAGE_TYPE = withIntrusiveHolders(CreateRegistries.MOUNTED_ITEM_STORAGE_TYPE);
public static final Registry<MountedFluidStorageType<?>> MOUNTED_FLUID_STORAGE_TYPE = simple(CreateRegistries.MOUNTED_FLUID_STORAGE_TYPE);
public static final Registry<ContraptionType> CONTRAPTION_TYPE = withIntrusiveHolders(CreateRegistries.CONTRAPTION_TYPE);

View file

@ -2,6 +2,7 @@ package com.simibubi.create.api.registry.registrate;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;
import org.jetbrains.annotations.Nullable;
@ -22,21 +23,21 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.material.Fluid;
public class SimpleBuilder<R, T extends R, P> extends AbstractBuilder<R, T, P, SimpleBuilder<R, T, P>> {
private final T value;
private final Supplier<T> value;
private SimpleRegistryAccess<Block, R> byBlock;
private SimpleRegistryAccess<BlockEntityType<?>, R> byBlockEntity;
private SimpleRegistryAccess<EntityType<?>, R> byEntity;
private SimpleRegistryAccess<Fluid, R> byFluid;
public SimpleBuilder(AbstractRegistrate<?> owner, P parent, String name, BuilderCallback callback, ResourceKey<Registry<R>> registryKey, T value) {
public SimpleBuilder(AbstractRegistrate<?> owner, P parent, String name, BuilderCallback callback, ResourceKey<Registry<R>> registryKey, Supplier<T> value) {
super(owner, parent, name, callback, registryKey);
this.value = value;
}
@Override
protected T createEntry() {
return this.value;
return this.value.get();
}
// for setup
@ -91,49 +92,49 @@ public class SimpleBuilder<R, T extends R, P> extends AbstractBuilder<R, T, P, S
public SimpleBuilder<R, T, P> associate(Block block) {
assertPresent(this.byBlock, "Block");
this.byBlock.adder.accept(block, this.value);
this.onRegister(value -> this.byBlock.adder.accept(block, value));
return this;
}
public SimpleBuilder<R, T, P> associateBlockTag(TagKey<Block> tag) {
assertPresent(this.byBlock, "Block");
this.byBlock.tagAdder.accept(tag, this.value);
this.onRegister(value -> this.byBlock.tagAdder.accept(tag, value));
return this;
}
public SimpleBuilder<R, T, P> associate(BlockEntityType<?> type) {
assertPresent(this.byBlockEntity, "BlockEntityType");
this.byBlockEntity.adder.accept(type, this.value);
this.onRegister(value -> this.byBlockEntity.adder.accept(type, value));
return this;
}
public SimpleBuilder<R, T, P> associateBeTag(TagKey<BlockEntityType<?>> tag) {
assertPresent(this.byBlockEntity, "BlockEntityType");
this.byBlockEntity.tagAdder.accept(tag, this.value);
this.onRegister(value -> this.byBlockEntity.tagAdder.accept(tag, value));
return this;
}
public SimpleBuilder<R, T, P> associate(EntityType<?> type) {
assertPresent(this.byEntity, "EntityType");
this.byEntity.adder.accept(type, this.value);
this.onRegister(value -> this.byEntity.adder.accept(type, value));
return this;
}
public SimpleBuilder<R, T, P> associateEntityTag(TagKey<EntityType<?>> tag) {
assertPresent(this.byEntity, "EntityType");
this.byEntity.tagAdder.accept(tag, this.value);
this.onRegister(value -> this.byEntity.tagAdder.accept(tag, value));
return this;
}
public SimpleBuilder<R, T, P> associate(Fluid fluid) {
assertPresent(this.byFluid, "Fluid");
this.byFluid.adder.accept(fluid, this.value);
this.onRegister(value -> this.byFluid.adder.accept(fluid, value));
return this;
}
public SimpleBuilder<R, T, P> associateFluidTag(TagKey<Fluid> tag) {
assertPresent(this.byFluid, "Fluid");
this.byFluid.tagAdder.accept(tag, this.value);
this.onRegister(value -> this.byFluid.tagAdder.accept(tag, value));
return this;
}

View file

@ -16,6 +16,7 @@ import com.google.common.collect.Sets;
import com.google.common.collect.Sets.SetView;
import com.mojang.datafixers.util.Pair;
import com.simibubi.create.AllPackets;
import com.simibubi.create.AllTags.AllMountedItemStorageTypeTags;
import com.simibubi.create.Create;
import com.simibubi.create.api.contraption.storage.SyncedMountedStorage;
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorage;
@ -96,16 +97,12 @@ public class MountedStorageManager {
this.allItemStorages = ImmutableMap.copyOf(this.itemsBuilder);
this.items = new MountedItemStorageWrapper(subMap(
this.allItemStorages, storage -> !storage.isInternal()
));
this.items = new MountedItemStorageWrapper(subMap(this.allItemStorages, this::isExposed));
this.allItems = this.items;
this.itemsBuilder = null;
ImmutableMap<BlockPos, MountedItemStorage> fuelMap = subMap(
this.allItemStorages, storage -> !storage.isInternal() && storage.providesFuel()
);
ImmutableMap<BlockPos, MountedItemStorage> fuelMap = subMap(this.allItemStorages, this::canUseForFuel);
this.fuelItems = fuelMap.isEmpty() ? null : new MountedItemStorageWrapper(fuelMap);
ImmutableMap<BlockPos, MountedFluidStorage> fluids = ImmutableMap.copyOf(this.fluidsBuilder);
@ -118,6 +115,14 @@ public class MountedStorageManager {
this.syncedFluidsBuilder = null;
}
private boolean isExposed(MountedItemStorage storage) {
return !AllMountedItemStorageTypeTags.INTERNAL.matches(storage);
}
private boolean canUseForFuel(MountedItemStorage storage) {
return this.isExposed(storage) && !AllMountedItemStorageTypeTags.FUEL_BLACKLIST.matches(storage);
}
private boolean isInitialized() {
return this.itemsBuilder == null;
}
@ -363,10 +368,7 @@ public class MountedStorageManager {
}
/**
* Gets a map of all MountedItemStorages in the contraption, irrelevant of them
* being internal or providing fuel.
* @see MountedItemStorage#isInternal()
* @see MountedItemStorage#providesFuel()
* Gets a map of all MountedItemStorages in the contraption, irrelevant of them being internal or providing fuel.
*/
public ImmutableMap<BlockPos, MountedItemStorage> getAllItemStorages() {
this.assertInitialized();

View file

@ -59,8 +59,8 @@ public class DropperMovementBehaviour implements MovementBehaviour {
if (stack.getCount() == 1 && stack.getMaxStackSize() != 1) {
stack = tryTopOff(stack, contraptionInventory);
if (stack == null) {
continue;
if (stack != null) {
storage.setStackInSlot(i, stack);
}
}

View file

@ -16,6 +16,7 @@ import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.IItemHandlerModifiable;
@ -30,11 +31,6 @@ public class DispenserMountedStorage extends SimpleMountedStorage {
this(AllMountedStorageTypes.DISPENSER.get(), handler);
}
@Override
public boolean isInternal() {
return true;
}
@Override
@Nullable
protected MenuProvider createMenuProvider(Component name, IItemHandlerModifiable handler,

View file

@ -45,11 +45,6 @@ public class ItemVaultMountedStorage extends WrapperMountedItemStorage<ItemStack
return false;
}
@Override
public boolean providesFuel() {
return false;
}
public static ItemVaultMountedStorage fromVault(ItemVaultBlockEntity vault) {
// Vault inventories have a world-affecting onContentsChanged, copy to a safe one
return new ItemVaultMountedStorage(copyToItemStackHandler(vault.getInventoryOfBlock()));

View file

@ -154,25 +154,25 @@ public class CreateRegistrate extends AbstractRegistrate<CreateRegistrate> {
public <T extends MountedItemStorageType<?>> SimpleBuilder<MountedItemStorageType<?>, T, CreateRegistrate> mountedItemStorage(String name, Supplier<T> supplier) {
return this.entry(name, callback -> new SimpleBuilder<>(
this, this, name, callback, CreateRegistries.MOUNTED_ITEM_STORAGE_TYPE, supplier.get()
this, this, name, callback, CreateRegistries.MOUNTED_ITEM_STORAGE_TYPE, supplier
).byBlock(MountedItemStorageType.REGISTRY));
}
public <T extends MountedFluidStorageType<?>> SimpleBuilder<MountedFluidStorageType<?>, T, CreateRegistrate> mountedFluidStorage(String name, Supplier<T> supplier) {
return this.entry(name, callback -> new SimpleBuilder<>(
this, this, name, callback, CreateRegistries.MOUNTED_FLUID_STORAGE_TYPE, supplier.get()
this, this, name, callback, CreateRegistries.MOUNTED_FLUID_STORAGE_TYPE, supplier
).byBlock(MountedFluidStorageType.REGISTRY));
}
public <T extends DisplaySource> SimpleBuilder<DisplaySource, T, CreateRegistrate> displaySource(String name, Supplier<T> supplier) {
return this.entry(name, callback -> new SimpleBuilder<>(
this, this, name, callback, CreateRegistries.DISPLAY_SOURCE, supplier.get()
this, this, name, callback, CreateRegistries.DISPLAY_SOURCE, supplier
).byBlock(DisplaySource.BY_BLOCK).byBlockEntity(DisplaySource.BY_BLOCK_ENTITY));
}
public <T extends DisplayTarget> SimpleBuilder<DisplayTarget, T, CreateRegistrate> displayTarget(String name, Supplier<T> supplier) {
return this.entry(name, callback -> new SimpleBuilder<>(
this, this, name, callback, CreateRegistries.DISPLAY_TARGET, supplier.get()
this, this, name, callback, CreateRegistries.DISPLAY_TARGET, supplier
).byBlock(DisplayTarget.BY_BLOCK).byBlockEntity(DisplayTarget.BY_BLOCK_ENTITY));
}

View file

@ -44,6 +44,7 @@ public class CreateDatagen {
generator.addProvider(event.includeServer(), new CreateRecipeSerializerTagsProvider(output, lookupProvider, existingFileHelper));
generator.addProvider(event.includeServer(), new CreateContraptionTypeTagsProvider(output, lookupProvider, existingFileHelper));
generator.addProvider(event.includeServer(), new CreateMountedItemStorageTypeTagsProvider(output, lookupProvider, existingFileHelper));
generator.addProvider(event.includeServer(), new DamageTypeTagGen(output, lookupProvider, existingFileHelper));
generator.addProvider(event.includeServer(), new AllAdvancements(output));
generator.addProvider(event.includeServer(), new StandardRecipeGen(output));

View file

@ -0,0 +1,47 @@
package com.simibubi.create.infrastructure.data;
import java.util.concurrent.CompletableFuture;
import org.jetbrains.annotations.Nullable;
import com.simibubi.create.AllMountedStorageTypes;
import com.simibubi.create.AllTags.AllMountedItemStorageTypeTags;
import com.simibubi.create.Create;
import com.simibubi.create.api.contraption.storage.item.MountedItemStorageType;
import com.simibubi.create.api.registry.CreateRegistries;
import net.minecraft.core.HolderLookup.Provider;
import net.minecraft.data.PackOutput;
import net.minecraft.data.tags.TagsProvider;
import net.minecraft.tags.TagEntry;
import net.minecraftforge.common.data.ExistingFileHelper;
public class CreateMountedItemStorageTypeTagsProvider extends TagsProvider<MountedItemStorageType<?>> {
public CreateMountedItemStorageTypeTagsProvider(PackOutput output, CompletableFuture<Provider> lookupProvider, @Nullable ExistingFileHelper existingFileHelper) {
super(output, CreateRegistries.MOUNTED_ITEM_STORAGE_TYPE, lookupProvider, Create.ID, existingFileHelper);
}
@Override
protected void addTags(Provider pProvider) {
tag(AllMountedItemStorageTypeTags.INTERNAL.tag).add(
TagEntry.element(AllMountedStorageTypes.DISPENSER.getId())
);
tag(AllMountedItemStorageTypeTags.FUEL_BLACKLIST.tag).add(
TagEntry.element(AllMountedStorageTypes.VAULT.getId())
);
// VALIDATE
for (AllMountedItemStorageTypeTags tag : AllMountedItemStorageTypeTags.values()) {
if (tag.alwaysDatagen) {
getOrCreateRawBuilder(tag.tag);
}
}
}
@Override
public String getName() {
return "Create's Mounted Item Storage Type Tags";
}
}