minecraft-src/net/minecraft/world/item/AdventureModePredicate.java
2025-07-04 03:45:38 +03:00

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 + "}";
}
}