Skip to content
This repository was archived by the owner on Mar 21, 2026. It is now read-only.

Commit 0cb5a88

Browse files
committed
add attribute filters for is fluid and is fluid no nbt
1 parent 3633b30 commit 0cb5a88

9 files changed

Lines changed: 305 additions & 1 deletion

File tree

forge/src/main/java/ru/zznty/create_factory_logistics/CreateFactoryLogistics.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public CreateFactoryLogistics(FMLJavaModLoadingContext context) {
3030
REGISTRATE.registerEventListeners(modEventBus);
3131
FactoryRecipes.REGISTER.register(modEventBus);
3232
FactoryArmInteractionPointTypes.ARM_INTERACTION_POINT_TYPES.register(modEventBus);
33+
FactoryGenericAttributeTypes.REGISTER.register(modEventBus);
3334

3435
modEventBus.addListener(FactoryEntities::registerEntityAttributes);
3536
modEventBus.addListener(FactoryDataGen::gatherData);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package ru.zznty.create_factory_logistics;
2+
3+
import com.simibubi.create.api.registry.CreateBuiltInRegistries;
4+
import com.simibubi.create.content.logistics.item.filter.attribute.ItemAttributeType;
5+
import net.minecraftforge.registries.DeferredRegister;
6+
import net.minecraftforge.registries.RegistryObject;
7+
import ru.zznty.create_factory_logistics.logistics.generic.FluidGenericAttribute;
8+
import ru.zznty.create_factory_logistics.logistics.generic.FluidNoNbtGenericAttribute;
9+
10+
public class FactoryGenericAttributeTypes {
11+
public static final DeferredRegister<ItemAttributeType> REGISTER =
12+
DeferredRegister.create(CreateBuiltInRegistries.ITEM_ATTRIBUTE_TYPE.key(), CreateFactoryLogistics.MODID);
13+
14+
public static final RegistryObject<ItemAttributeType>
15+
IS_FLUID = REGISTER.register("is_fluid", FluidGenericAttribute.Type::new),
16+
IS_FLUID_NO_NBT = REGISTER.register("is_fluid_no_nbt", FluidNoNbtGenericAttribute.Type::new);
17+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package ru.zznty.create_factory_logistics.logistics.generic;
2+
3+
import com.simibubi.create.content.fluids.transfer.GenericItemEmptying;
4+
import com.simibubi.create.content.logistics.item.filter.attribute.ItemAttribute;
5+
import com.simibubi.create.content.logistics.item.filter.attribute.ItemAttributeType;
6+
import net.createmod.catnip.data.Pair;
7+
import net.minecraft.nbt.CompoundTag;
8+
import net.minecraft.world.item.ItemStack;
9+
import net.minecraft.world.level.Level;
10+
import net.minecraft.world.level.material.Fluids;
11+
import net.minecraftforge.common.util.LazyOptional;
12+
import net.minecraftforge.fluids.FluidStack;
13+
import net.minecraftforge.fluids.FluidType;
14+
import net.minecraftforge.fluids.FluidUtil;
15+
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
16+
import org.jetbrains.annotations.NotNull;
17+
import org.jetbrains.annotations.Nullable;
18+
import ru.zznty.create_factory_abstractions.api.generic.key.GenericKeySerializer;
19+
import ru.zznty.create_factory_abstractions.api.generic.stack.GenericStack;
20+
import ru.zznty.create_factory_abstractions.generic.impl.GenericContentExtender;
21+
import ru.zznty.create_factory_abstractions.generic.key.item.ItemKey;
22+
import ru.zznty.create_factory_logistics.FactoryGenericAttributeTypes;
23+
24+
import java.util.ArrayList;
25+
import java.util.List;
26+
27+
public class FluidGenericAttribute implements GenericAttribute {
28+
@Nullable
29+
protected FluidKey fluid;
30+
31+
public FluidGenericAttribute(@Nullable FluidKey fluid) {
32+
this.fluid = fluid;
33+
}
34+
35+
@Override
36+
public boolean appliesTo(GenericStack stack, Level world) {
37+
if (fluid == null) return false;
38+
if (!(stack.key() instanceof FluidKey fluidKey)) return false;
39+
return fluid.equals(fluidKey);
40+
}
41+
42+
@Override
43+
public ItemAttributeType getType() {
44+
return FactoryGenericAttributeTypes.IS_FLUID.get();
45+
}
46+
47+
@Override
48+
public void save(CompoundTag nbt) {
49+
if (fluid == null) return;
50+
GenericContentExtender.REGISTRATIONS.get(FluidKey.class).serializer().write(fluid, nbt);
51+
}
52+
53+
@Override
54+
public void load(CompoundTag nbt) {
55+
GenericKeySerializer<FluidKey> serializer = GenericContentExtender.REGISTRATIONS.get(
56+
FluidKey.class).serializer();
57+
fluid = serializer.read(nbt);
58+
if (fluid.fluid() == Fluids.EMPTY) fluid = null;
59+
}
60+
61+
@Override
62+
public String getTranslationKey() {
63+
return "is_fluid";
64+
}
65+
66+
@Override
67+
public Object[] getTranslationParameters() {
68+
String parameter = "";
69+
if (fluid != null) {
70+
FluidType fluidType = fluid.fluid().getFluidType();
71+
if (fluid.nbt() == null)
72+
parameter = fluidType.getDescription().getString();
73+
else
74+
parameter = fluidType.getDescription(fluid.stack()).getString();
75+
}
76+
return new Object[]{parameter};
77+
}
78+
79+
protected static List<FluidKey> extractFluids(GenericStack stack, Level level) {
80+
if (stack.key() instanceof FluidKey fluidKey) {
81+
return List.of(fluidKey);
82+
}
83+
if ((!(stack.key() instanceof ItemKey itemKey))) return List.of();
84+
LazyOptional<IFluidHandlerItem> fluidHandler = FluidUtil.getFluidHandler(itemKey.stack());
85+
if (fluidHandler.isPresent()) {
86+
List<FluidKey> attributes = new ArrayList<>();
87+
IFluidHandlerItem handlerItem = fluidHandler.orElse(null);
88+
for (int i = 0; i < handlerItem.getTanks(); i++) {
89+
FluidStack fluidInItem = handlerItem.getFluidInTank(i);
90+
if (fluidInItem.getRawFluid() != Fluids.EMPTY) {
91+
attributes.add(new FluidKey(fluidInItem.getRawFluid(), fluidInItem.getTag()));
92+
}
93+
}
94+
return attributes;
95+
}
96+
Pair<FluidStack, ItemStack> emptyResult = GenericItemEmptying.emptyItem(level, itemKey.stack(),
97+
true);
98+
FluidStack resultFluid = emptyResult.getFirst();
99+
if (resultFluid.isEmpty()) return List.of();
100+
return List.of(new FluidKey(resultFluid.getFluid(), resultFluid.getTag()));
101+
}
102+
103+
public static class Type implements GenericAttributeType {
104+
@Override
105+
public @NotNull GenericAttribute create() {
106+
return new FluidGenericAttribute(null);
107+
}
108+
109+
@Override
110+
public List<ItemAttribute> getAllAttributes(GenericStack stack, Level level) {
111+
return extractFluids(stack, level).stream().<ItemAttribute>map(FluidGenericAttribute::new)
112+
.toList();
113+
}
114+
}
115+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package ru.zznty.create_factory_logistics.logistics.generic;
2+
3+
import com.simibubi.create.content.logistics.item.filter.attribute.ItemAttribute;
4+
import com.simibubi.create.content.logistics.item.filter.attribute.ItemAttributeType;
5+
import net.minecraft.world.level.Level;
6+
import org.jetbrains.annotations.NotNull;
7+
import org.jetbrains.annotations.Nullable;
8+
import ru.zznty.create_factory_abstractions.api.generic.stack.GenericStack;
9+
import ru.zznty.create_factory_logistics.FactoryGenericAttributeTypes;
10+
11+
import java.util.List;
12+
13+
public class FluidNoNbtGenericAttribute extends FluidGenericAttribute {
14+
public FluidNoNbtGenericAttribute(@Nullable FluidKey fluid) {
15+
super(fluid);
16+
}
17+
18+
@Override
19+
public boolean appliesTo(GenericStack stack, Level world) {
20+
if (fluid == null) return false;
21+
if (!(stack.key() instanceof FluidKey fluidKey)) return false;
22+
return fluid.fluid().equals(fluidKey.fluid());
23+
}
24+
25+
@Override
26+
public ItemAttributeType getType() {
27+
return FactoryGenericAttributeTypes.IS_FLUID_NO_NBT.get();
28+
}
29+
30+
@Override
31+
public String getTranslationKey() {
32+
return "is_fluid_no_nbt";
33+
}
34+
35+
protected static List<FluidKey> extractUniqueFluids(GenericStack stack, Level level) {
36+
List<FluidKey> fluids = extractFluids(stack, level);
37+
return fluids.stream()
38+
.filter(f -> f.nbt() != null)
39+
.map(f -> new FluidKey(f.fluid(), null))
40+
.distinct()
41+
.toList();
42+
}
43+
44+
public static class Type implements GenericAttributeType {
45+
@Override
46+
public @NotNull GenericAttribute create() {
47+
return new FluidNoNbtGenericAttribute(null);
48+
}
49+
50+
@Override
51+
public List<ItemAttribute> getAllAttributes(GenericStack stack, Level level) {
52+
return extractUniqueFluids(stack, level).stream().<ItemAttribute>map(FluidNoNbtGenericAttribute::new)
53+
.toList();
54+
}
55+
}
56+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package ru.zznty.create_factory_logistics.logistics.generic;
2+
3+
import com.simibubi.create.content.logistics.item.filter.attribute.ItemAttribute;
4+
import net.minecraft.world.item.ItemStack;
5+
import net.minecraft.world.level.Level;
6+
import ru.zznty.create_factory_abstractions.api.generic.stack.GenericStack;
7+
8+
public interface GenericAttribute extends ItemAttribute {
9+
boolean appliesTo(GenericStack stack, Level world);
10+
11+
default boolean appliesTo(ItemStack stack, Level world) {
12+
return appliesTo(GenericStack.wrap(stack), world);
13+
}
14+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package ru.zznty.create_factory_logistics.logistics.generic;
2+
3+
import com.simibubi.create.content.logistics.item.filter.attribute.ItemAttribute;
4+
import com.simibubi.create.content.logistics.item.filter.attribute.ItemAttributeType;
5+
import net.minecraft.world.item.ItemStack;
6+
import net.minecraft.world.level.Level;
7+
import org.jetbrains.annotations.NotNull;
8+
import ru.zznty.create_factory_abstractions.api.generic.stack.GenericStack;
9+
10+
import java.util.List;
11+
12+
public interface GenericAttributeType extends ItemAttributeType {
13+
@NotNull GenericAttribute create();
14+
15+
List<ItemAttribute> getAllAttributes(GenericStack stack, Level level);
16+
17+
default @NotNull ItemAttribute createAttribute() {
18+
return create();
19+
}
20+
21+
default List<ItemAttribute> getAllAttributes(ItemStack stack, Level level) {
22+
return getAllAttributes(GenericStack.wrap(stack), level);
23+
}
24+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package ru.zznty.create_factory_logistics.mixin.logistics.filter;
2+
3+
import com.simibubi.create.content.logistics.filter.FilterItemStack;
4+
import com.simibubi.create.content.logistics.item.filter.attribute.ItemAttribute;
5+
import net.createmod.catnip.data.Pair;
6+
import net.minecraft.world.item.ItemStack;
7+
import net.minecraft.world.level.Level;
8+
import net.minecraftforge.fluids.FluidStack;
9+
import org.spongepowered.asm.mixin.Mixin;
10+
import org.spongepowered.asm.mixin.Overwrite;
11+
import org.spongepowered.asm.mixin.Shadow;
12+
import ru.zznty.create_factory_abstractions.api.generic.stack.GenericStack;
13+
import ru.zznty.create_factory_logistics.logistics.generic.FluidGenericStack;
14+
import ru.zznty.create_factory_logistics.logistics.generic.GenericAttribute;
15+
16+
import java.util.List;
17+
18+
@Mixin(FilterItemStack.AttributeFilterItemStack.class)
19+
public class GenericAttributeFilterItemStackMixin extends FilterItemStack {
20+
@Shadow(remap = false)
21+
public FilterItemStack.AttributeFilterItemStack.WhitelistMode whitelistMode;
22+
23+
@Shadow(remap = false)
24+
public List<Pair<ItemAttribute, Boolean>> attributeTests;
25+
26+
protected GenericAttributeFilterItemStackMixin(ItemStack filter) {
27+
super(filter);
28+
}
29+
30+
@Overwrite(remap = false)
31+
public boolean test(Level world, FluidStack stack, boolean matchNBT) {
32+
if (attributeTests.isEmpty())
33+
return super.test(world, stack, matchNBT);
34+
GenericStack genericStack = FluidGenericStack.wrap(stack);
35+
for (Pair<ItemAttribute, Boolean> test : attributeTests) {
36+
ItemAttribute itemAttribute = test.getFirst();
37+
boolean inverted = test.getSecond();
38+
39+
if (!(itemAttribute instanceof GenericAttribute attribute)) continue;
40+
41+
boolean matches = attribute.appliesTo(genericStack, world) != inverted;
42+
43+
if (matches) {
44+
switch (whitelistMode) {
45+
case BLACKLIST -> {
46+
return false;
47+
}
48+
case WHITELIST_CONJ -> {
49+
continue;
50+
}
51+
case WHITELIST_DISJ -> {
52+
return true;
53+
}
54+
}
55+
} else {
56+
switch (whitelistMode) {
57+
case BLACKLIST, WHITELIST_DISJ -> {
58+
continue;
59+
}
60+
case WHITELIST_CONJ -> {
61+
return false;
62+
}
63+
}
64+
}
65+
}
66+
67+
return switch (whitelistMode) {
68+
case BLACKLIST, WHITELIST_CONJ -> true;
69+
case WHITELIST_DISJ -> false;
70+
};
71+
}
72+
}

forge/src/main/resources/assets/create_factory_logistics/lang/en_us.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,9 @@
2121
"create_factory_logistics.ponder.mixer_upkeep.text_2": "So that blaze burner would be fed only when necessary",
2222
"create_factory_logistics.ponder.mixer_upkeep.text_3": "When order has arrived, the switch will read new state and react",
2323
"create_factory_logistics.gui.factory_fluid_panel.place_fluid_to_monitor": "Place Fluid to Monitor",
24-
"entity.create_factory_logistics.composite_package": "Composite Package"
24+
"entity.create_factory_logistics.composite_package": "Composite Package",
25+
"create.item_attributes.is_fluid": "is %1$s",
26+
"create.item_attributes.is_fluid.inverted": "is not %1$s",
27+
"create.item_attributes.is_fluid_no_nbt": "is %1$s (no NBT)",
28+
"create.item_attributes.is_fluid_no_nbt.inverted": "is not %1$s (no NBT)"
2529
}

forge/src/main/resources/mixins.create_factory_logistics.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"accessor.StockTickerBlockEntityAccessor",
1212
"bugfixes.ArmBlockEntityMixin",
1313
"logistics.composite.CompositePackageSawingMixin",
14+
"logistics.filter.GenericAttributeFilterItemStackMixin",
1415
"logistics.jar.ChainConveyorDropMixin",
1516
"logistics.jar.JarDrainMixin",
1617
"logistics.packager.GenericPackagerBlockEntityMixin",

0 commit comments

Comments
 (0)