Create/src/main/java/com/simibubi/create/content/trains/schedule/condition/ItemThresholdCondition.java
simibubi eea8bb2607 Filter code caused global warming
- Contents of a filter are no longer deserialised from item nbt each time a stack is tested
- FilteringBehaviour.getFilter() no longer creates a copy of the item
- MovementContext for contraption actors now have a shortcut to a cached filter from their corresponding BlockEntity
2023-11-02 00:08:34 +01:00

137 lines
4.4 KiB
Java

package com.simibubi.create.content.trains.schedule.condition;
import java.util.List;
import com.google.common.collect.ImmutableList;
import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.filter.FilterItemStack;
import com.simibubi.create.content.trains.entity.Carriage;
import com.simibubi.create.content.trains.entity.Train;
import com.simibubi.create.foundation.gui.ModularGuiLineBuilder;
import com.simibubi.create.foundation.utility.Components;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.ChatFormatting;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.items.IItemHandlerModifiable;
public class ItemThresholdCondition extends CargoThresholdCondition {
private FilterItemStack stack = FilterItemStack.empty();
@Override
protected Component getUnit() {
return Components.literal(inStacks() ? "\u25A4" : "");
}
@Override
protected ItemStack getIcon() {
return stack.item();
}
@Override
protected boolean test(Level level, Train train, CompoundTag context) {
Ops operator = getOperator();
int target = getThreshold();
boolean stacks = inStacks();
int foundItems = 0;
for (Carriage carriage : train.carriages) {
IItemHandlerModifiable items = carriage.storage.getItems();
for (int i = 0; i < items.getSlots(); i++) {
ItemStack stackInSlot = items.getStackInSlot(i);
if (!stack.test(level, stackInSlot))
continue;
if (stacks)
foundItems += stackInSlot.getCount() == stackInSlot.getMaxStackSize() ? 1 : 0;
else
foundItems += stackInSlot.getCount();
}
}
requestStatusToUpdate(foundItems, context);
return operator.test(foundItems, target);
}
@Override
protected void writeAdditional(CompoundTag tag) {
super.writeAdditional(tag);
tag.put("Item", stack.serializeNBT());
}
@Override
protected void readAdditional(CompoundTag tag) {
super.readAdditional(tag);
if (tag.contains("Item"))
stack = FilterItemStack.of(tag.getCompound("Item"));
}
@Override
public boolean tickCompletion(Level level, Train train, CompoundTag context) {
return super.tickCompletion(level, train, context);
}
@Override
public void setItem(int slot, ItemStack stack) {
this.stack = FilterItemStack.of(stack);
}
@Override
public ItemStack getItem(int slot) {
return stack.item();
}
@Override
public List<Component> getTitleAs(String type) {
return ImmutableList.of(
Lang.translateDirect("schedule.condition.threshold.train_holds",
Lang.translateDirect("schedule.condition.threshold." + Lang.asId(getOperator().name()))),
Lang.translateDirect("schedule.condition.threshold.x_units_of_item", getThreshold(),
Lang.translateDirect("schedule.condition.threshold." + (inStacks() ? "stacks" : "items")),
stack.isEmpty() ? Lang.translateDirect("schedule.condition.threshold.anything")
: stack.isFilterItem() ? Lang.translateDirect("schedule.condition.threshold.matching_content")
: stack.item()
.getHoverName())
.withStyle(ChatFormatting.DARK_AQUA));
}
private boolean inStacks() {
return intData("Measure") == 1;
}
@Override
public ResourceLocation getId() {
return Create.asResource("item_threshold");
}
@Override
@OnlyIn(Dist.CLIENT)
public void initConfigurationWidgets(ModularGuiLineBuilder builder) {
super.initConfigurationWidgets(builder);
builder.addSelectionScrollInput(71, 50, (i, l) -> {
i.forOptions(ImmutableList.of(Lang.translateDirect("schedule.condition.threshold.items"),
Lang.translateDirect("schedule.condition.threshold.stacks")))
.titled(Lang.translateDirect("schedule.condition.threshold.item_measure"));
}, "Measure");
}
@Override
public MutableComponent getWaitingStatus(Level level, Train train, CompoundTag tag) {
int lastDisplaySnapshot = getLastDisplaySnapshot(tag);
if (lastDisplaySnapshot == -1)
return Components.empty();
int offset = getOperator() == Ops.LESS ? -1 : getOperator() == Ops.GREATER ? 1 : 0;
return Lang.translateDirect("schedule.condition.threshold.status", lastDisplaySnapshot,
Math.max(0, getThreshold() + offset),
Lang.translateDirect("schedule.condition.threshold." + (inStacks() ? "stacks" : "items")));
}
}