PrettyPipes/src/main/java/de/ellpeck/prettypipes/misc/DirectionSelector.java
2024-02-03 15:17:58 +01:00

106 lines
3.7 KiB
Java

package de.ellpeck.prettypipes.misc;
import de.ellpeck.prettypipes.PrettyPipes;
import de.ellpeck.prettypipes.packets.PacketButton;
import de.ellpeck.prettypipes.pipe.PipeBlockEntity;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.neoforge.client.gui.widget.ExtendedButton;
import org.apache.commons.lang3.ArrayUtils;
public class DirectionSelector {
private static final Direction[] ALL = ArrayUtils.addAll(Direction.values(), (Direction) null);
// null means old behavior, which is all directions
private Direction direction;
private boolean modified;
private final ItemStack stack;
private final PipeBlockEntity pipe;
public DirectionSelector(ItemStack stack, PipeBlockEntity pipe) {
this.stack = stack;
this.pipe = pipe;
this.load();
}
@OnlyIn(Dist.CLIENT)
public AbstractWidget getButton(int x, int y) {
return new ExtendedButton(x, y, 100, 20, Component.translatable("info." + PrettyPipes.ID + ".populate"), button ->
PacketButton.sendAndExecute(this.pipe.getBlockPos(), PacketButton.ButtonResult.DIRECTION_SELECTOR)) {
@Override
public Component getMessage() {
var pipe = DirectionSelector.this.pipe;
var dir = DirectionSelector.this.direction;
var msg = Component.translatable("dir." + PrettyPipes.ID + "." + (dir != null ? dir.getName() : "all"));
if (dir != null) {
var blockName = pipe.getItemHandler(dir) != null ? pipe.getLevel().getBlockState(pipe.getBlockPos().relative(dir)).getBlock().getName() : null;
if (blockName != null)
msg = msg.append(" (").append(blockName).append(")");
}
return msg;
}
};
}
public void onButtonPacket() {
var dir = this.direction;
do {
dir = DirectionSelector.ALL[(ArrayUtils.indexOf(DirectionSelector.ALL, dir) + 1) % DirectionSelector.ALL.length];
} while (!this.isDirectionValid(dir));
if (this.direction != dir) {
this.direction = dir;
this.modified = true;
}
}
public void save() {
if (!this.modified)
return;
this.modified = false;
var tag = new CompoundTag();
if (this.direction != null)
tag.putString("direction", this.direction.getName());
this.stack.getOrCreateTag().put("direction_selector", tag);
}
public void load() {
if (this.stack.hasTag()) {
var tag = this.stack.getTag().getCompound("direction_selector");
this.direction = Direction.byName(tag.getString("direction"));
}
}
public Direction[] directions() {
return this.direction != null ? new Direction[]{this.direction} : Direction.values();
}
public boolean has(Direction dir) {
return this.direction == null || this.direction == dir;
}
private boolean isDirectionValid(Direction dir) {
if (dir == null)
return true;
if (this.pipe.getItemHandler(dir) == null)
return false;
return this.pipe.streamModules()
.filter(p -> p.getLeft() != this.stack)
.map(p -> p.getRight().getDirectionSelector(p.getLeft(), this.pipe))
.noneMatch(p -> p != null && p.direction == dir);
}
public interface IDirectionContainer {
DirectionSelector getSelector();
}
}