147 lines
4.2 KiB
Java
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();
|
|
}
|
|
}
|