119 lines
4.2 KiB
Java
119 lines
4.2 KiB
Java
package net.minecraft.world.item;
|
|
|
|
import com.mojang.serialization.Codec;
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
import java.util.function.Consumer;
|
|
import net.minecraft.ChatFormatting;
|
|
import net.minecraft.advancements.critereon.BlockPredicate;
|
|
import net.minecraft.core.HolderSet;
|
|
import net.minecraft.core.RegistryAccess;
|
|
import net.minecraft.network.RegistryFriendlyByteBuf;
|
|
import net.minecraft.network.chat.Component;
|
|
import net.minecraft.network.codec.ByteBufCodecs;
|
|
import net.minecraft.network.codec.StreamCodec;
|
|
import net.minecraft.util.ExtraCodecs;
|
|
import net.minecraft.world.level.block.Block;
|
|
import net.minecraft.world.level.block.state.pattern.BlockInWorld;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
public class AdventureModePredicate {
|
|
public static final Codec<AdventureModePredicate> CODEC = ExtraCodecs.compactListCodec(
|
|
BlockPredicate.CODEC, ExtraCodecs.nonEmptyList(BlockPredicate.CODEC.listOf())
|
|
)
|
|
.xmap(AdventureModePredicate::new, adventureModePredicate -> adventureModePredicate.predicates);
|
|
public static final StreamCodec<RegistryFriendlyByteBuf, AdventureModePredicate> STREAM_CODEC = StreamCodec.composite(
|
|
BlockPredicate.STREAM_CODEC.apply(ByteBufCodecs.list()), adventureModePredicate -> adventureModePredicate.predicates, AdventureModePredicate::new
|
|
);
|
|
public static final Component CAN_BREAK_HEADER = Component.translatable("item.canBreak").withStyle(ChatFormatting.GRAY);
|
|
public static final Component CAN_PLACE_HEADER = Component.translatable("item.canPlace").withStyle(ChatFormatting.GRAY);
|
|
private static final Component UNKNOWN_USE = Component.translatable("item.canUse.unknown").withStyle(ChatFormatting.GRAY);
|
|
private final List<BlockPredicate> predicates;
|
|
@Nullable
|
|
private List<Component> cachedTooltip;
|
|
@Nullable
|
|
private BlockInWorld lastCheckedBlock;
|
|
private boolean lastResult;
|
|
private boolean checksBlockEntity;
|
|
|
|
public AdventureModePredicate(List<BlockPredicate> predicates) {
|
|
this.predicates = predicates;
|
|
}
|
|
|
|
private static boolean areSameBlocks(BlockInWorld first, @Nullable BlockInWorld second, boolean checkNbt) {
|
|
if (second == null || first.getState() != second.getState()) {
|
|
return false;
|
|
} else if (!checkNbt) {
|
|
return true;
|
|
} else if (first.getEntity() == null && second.getEntity() == null) {
|
|
return true;
|
|
} else if (first.getEntity() != null && second.getEntity() != null) {
|
|
RegistryAccess registryAccess = first.getLevel().registryAccess();
|
|
return Objects.equals(first.getEntity().saveWithId(registryAccess), second.getEntity().saveWithId(registryAccess));
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public boolean test(BlockInWorld block) {
|
|
if (areSameBlocks(block, this.lastCheckedBlock, this.checksBlockEntity)) {
|
|
return this.lastResult;
|
|
} else {
|
|
this.lastCheckedBlock = block;
|
|
this.checksBlockEntity = false;
|
|
|
|
for (BlockPredicate blockPredicate : this.predicates) {
|
|
if (blockPredicate.matches(block)) {
|
|
this.checksBlockEntity = this.checksBlockEntity | blockPredicate.requiresNbt();
|
|
this.lastResult = true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
this.lastResult = false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private List<Component> tooltip() {
|
|
if (this.cachedTooltip == null) {
|
|
this.cachedTooltip = computeTooltip(this.predicates);
|
|
}
|
|
|
|
return this.cachedTooltip;
|
|
}
|
|
|
|
public void addToTooltip(Consumer<Component> tooltipAdder) {
|
|
this.tooltip().forEach(tooltipAdder);
|
|
}
|
|
|
|
private static List<Component> computeTooltip(List<BlockPredicate> predicates) {
|
|
for (BlockPredicate blockPredicate : predicates) {
|
|
if (blockPredicate.blocks().isEmpty()) {
|
|
return List.of(UNKNOWN_USE);
|
|
}
|
|
}
|
|
|
|
return predicates.stream()
|
|
.flatMap(blockPredicatex -> ((HolderSet)blockPredicatex.blocks().orElseThrow()).stream())
|
|
.distinct()
|
|
.map(holder -> ((Block)holder.value()).getName().withStyle(ChatFormatting.DARK_GRAY))
|
|
.toList();
|
|
}
|
|
|
|
public boolean equals(Object object) {
|
|
if (this == object) {
|
|
return true;
|
|
} else {
|
|
return object instanceof AdventureModePredicate adventureModePredicate ? this.predicates.equals(adventureModePredicate.predicates) : false;
|
|
}
|
|
}
|
|
|
|
public int hashCode() {
|
|
return this.predicates.hashCode();
|
|
}
|
|
|
|
public String toString() {
|
|
return "AdventureModePredicate{predicates=" + this.predicates + "}";
|
|
}
|
|
}
|