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();
 | |
| 	}
 | |
| }
 |