minecraft-src/net/minecraft/advancements/AdvancementTree.java
2025-07-04 01:41:11 +03:00

147 lines
4.2 KiB
Java

package net.minecraft.advancements;
import com.mojang.logging.LogUtils;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
public class AdvancementTree {
private static final Logger LOGGER = LogUtils.getLogger();
private final Map<ResourceLocation, AdvancementNode> nodes = new Object2ObjectOpenHashMap<>();
private final Set<AdvancementNode> roots = new ObjectLinkedOpenHashSet<>();
private final Set<AdvancementNode> tasks = new ObjectLinkedOpenHashSet<>();
@Nullable
private AdvancementTree.Listener listener;
private void remove(AdvancementNode node) {
for (AdvancementNode advancementNode : node.children()) {
this.remove(advancementNode);
}
LOGGER.info("Forgot about advancement {}", node.holder());
this.nodes.remove(node.holder().id());
if (node.parent() == null) {
this.roots.remove(node);
if (this.listener != null) {
this.listener.onRemoveAdvancementRoot(node);
}
} else {
this.tasks.remove(node);
if (this.listener != null) {
this.listener.onRemoveAdvancementTask(node);
}
}
}
public void remove(Set<ResourceLocation> advancements) {
for (ResourceLocation resourceLocation : advancements) {
AdvancementNode advancementNode = (AdvancementNode)this.nodes.get(resourceLocation);
if (advancementNode == null) {
LOGGER.warn("Told to remove advancement {} but I don't know what that is", resourceLocation);
} else {
this.remove(advancementNode);
}
}
}
public void addAll(Collection<AdvancementHolder> advancements) {
List<AdvancementHolder> list = new ArrayList(advancements);
while (!list.isEmpty()) {
if (!list.removeIf(this::tryInsert)) {
LOGGER.error("Couldn't load advancements: {}", list);
break;
}
}
LOGGER.info("Loaded {} advancements", this.nodes.size());
}
private boolean tryInsert(AdvancementHolder advancement) {
Optional<ResourceLocation> optional = advancement.value().parent();
AdvancementNode advancementNode = (AdvancementNode)optional.map(this.nodes::get).orElse(null);
if (advancementNode == null && optional.isPresent()) {
return false;
} else {
AdvancementNode advancementNode2 = new AdvancementNode(advancement, advancementNode);
if (advancementNode != null) {
advancementNode.addChild(advancementNode2);
}
this.nodes.put(advancement.id(), advancementNode2);
if (advancementNode == null) {
this.roots.add(advancementNode2);
if (this.listener != null) {
this.listener.onAddAdvancementRoot(advancementNode2);
}
} else {
this.tasks.add(advancementNode2);
if (this.listener != null) {
this.listener.onAddAdvancementTask(advancementNode2);
}
}
return true;
}
}
public void clear() {
this.nodes.clear();
this.roots.clear();
this.tasks.clear();
if (this.listener != null) {
this.listener.onAdvancementsCleared();
}
}
public Iterable<AdvancementNode> roots() {
return this.roots;
}
public Collection<AdvancementNode> nodes() {
return this.nodes.values();
}
@Nullable
public AdvancementNode get(ResourceLocation id) {
return (AdvancementNode)this.nodes.get(id);
}
@Nullable
public AdvancementNode get(AdvancementHolder advancement) {
return (AdvancementNode)this.nodes.get(advancement.id());
}
public void setListener(@Nullable AdvancementTree.Listener listener) {
this.listener = listener;
if (listener != null) {
for (AdvancementNode advancementNode : this.roots) {
listener.onAddAdvancementRoot(advancementNode);
}
for (AdvancementNode advancementNode : this.tasks) {
listener.onAddAdvancementTask(advancementNode);
}
}
}
public interface Listener {
void onAddAdvancementRoot(AdvancementNode advancement);
void onRemoveAdvancementRoot(AdvancementNode advancement);
void onAddAdvancementTask(AdvancementNode advancement);
void onRemoveAdvancementTask(AdvancementNode advancement);
void onAdvancementsCleared();
}
}