120 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			120 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.client.multiplayer;
 | |
| 
 | |
| import com.mojang.logging.LogUtils;
 | |
| import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
 | |
| import java.util.Map;
 | |
| import java.util.Optional;
 | |
| import java.util.Map.Entry;
 | |
| import net.fabricmc.api.EnvType;
 | |
| import net.fabricmc.api.Environment;
 | |
| import net.minecraft.advancements.AdvancementHolder;
 | |
| import net.minecraft.advancements.AdvancementNode;
 | |
| import net.minecraft.advancements.AdvancementProgress;
 | |
| import net.minecraft.advancements.AdvancementTree;
 | |
| import net.minecraft.advancements.DisplayInfo;
 | |
| import net.minecraft.client.Minecraft;
 | |
| import net.minecraft.client.gui.components.toasts.AdvancementToast;
 | |
| import net.minecraft.client.telemetry.WorldSessionTelemetryManager;
 | |
| import net.minecraft.network.protocol.game.ClientboundUpdateAdvancementsPacket;
 | |
| import net.minecraft.network.protocol.game.ServerboundSeenAdvancementsPacket;
 | |
| import net.minecraft.resources.ResourceLocation;
 | |
| import org.jetbrains.annotations.Nullable;
 | |
| import org.slf4j.Logger;
 | |
| 
 | |
| @Environment(EnvType.CLIENT)
 | |
| public class ClientAdvancements {
 | |
| 	private static final Logger LOGGER = LogUtils.getLogger();
 | |
| 	private final Minecraft minecraft;
 | |
| 	private final WorldSessionTelemetryManager telemetryManager;
 | |
| 	private final AdvancementTree tree = new AdvancementTree();
 | |
| 	private final Map<AdvancementHolder, AdvancementProgress> progress = new Object2ObjectOpenHashMap<>();
 | |
| 	@Nullable
 | |
| 	private ClientAdvancements.Listener listener;
 | |
| 	@Nullable
 | |
| 	private AdvancementHolder selectedTab;
 | |
| 
 | |
| 	public ClientAdvancements(Minecraft minecraft, WorldSessionTelemetryManager telemetryManager) {
 | |
| 		this.minecraft = minecraft;
 | |
| 		this.telemetryManager = telemetryManager;
 | |
| 	}
 | |
| 
 | |
| 	public void update(ClientboundUpdateAdvancementsPacket packet) {
 | |
| 		if (packet.shouldReset()) {
 | |
| 			this.tree.clear();
 | |
| 			this.progress.clear();
 | |
| 		}
 | |
| 
 | |
| 		this.tree.remove(packet.getRemoved());
 | |
| 		this.tree.addAll(packet.getAdded());
 | |
| 
 | |
| 		for (Entry<ResourceLocation, AdvancementProgress> entry : packet.getProgress().entrySet()) {
 | |
| 			AdvancementNode advancementNode = this.tree.get((ResourceLocation)entry.getKey());
 | |
| 			if (advancementNode != null) {
 | |
| 				AdvancementProgress advancementProgress = (AdvancementProgress)entry.getValue();
 | |
| 				advancementProgress.update(advancementNode.advancement().requirements());
 | |
| 				this.progress.put(advancementNode.holder(), advancementProgress);
 | |
| 				if (this.listener != null) {
 | |
| 					this.listener.onUpdateAdvancementProgress(advancementNode, advancementProgress);
 | |
| 				}
 | |
| 
 | |
| 				if (!packet.shouldReset() && advancementProgress.isDone()) {
 | |
| 					if (this.minecraft.level != null) {
 | |
| 						this.telemetryManager.onAdvancementDone(this.minecraft.level, advancementNode.holder());
 | |
| 					}
 | |
| 
 | |
| 					Optional<DisplayInfo> optional = advancementNode.advancement().display();
 | |
| 					if (packet.shouldShowAdvancements() && optional.isPresent() && ((DisplayInfo)optional.get()).shouldShowToast()) {
 | |
| 						this.minecraft.getToastManager().addToast(new AdvancementToast(advancementNode.holder()));
 | |
| 					}
 | |
| 				}
 | |
| 			} else {
 | |
| 				LOGGER.warn("Server informed client about progress for unknown advancement {}", entry.getKey());
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public AdvancementTree getTree() {
 | |
| 		return this.tree;
 | |
| 	}
 | |
| 
 | |
| 	public void setSelectedTab(@Nullable AdvancementHolder advancement, boolean tellServer) {
 | |
| 		ClientPacketListener clientPacketListener = this.minecraft.getConnection();
 | |
| 		if (clientPacketListener != null && advancement != null && tellServer) {
 | |
| 			clientPacketListener.send(ServerboundSeenAdvancementsPacket.openedTab(advancement));
 | |
| 		}
 | |
| 
 | |
| 		if (this.selectedTab != advancement) {
 | |
| 			this.selectedTab = advancement;
 | |
| 			if (this.listener != null) {
 | |
| 				this.listener.onSelectedTabChanged(advancement);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public void setListener(@Nullable ClientAdvancements.Listener listener) {
 | |
| 		this.listener = listener;
 | |
| 		this.tree.setListener(listener);
 | |
| 		if (listener != null) {
 | |
| 			this.progress.forEach((advancementHolder, advancementProgress) -> {
 | |
| 				AdvancementNode advancementNode = this.tree.get(advancementHolder);
 | |
| 				if (advancementNode != null) {
 | |
| 					listener.onUpdateAdvancementProgress(advancementNode, advancementProgress);
 | |
| 				}
 | |
| 			});
 | |
| 			listener.onSelectedTabChanged(this.selectedTab);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Nullable
 | |
| 	public AdvancementHolder get(ResourceLocation id) {
 | |
| 		AdvancementNode advancementNode = this.tree.get(id);
 | |
| 		return advancementNode != null ? advancementNode.holder() : null;
 | |
| 	}
 | |
| 
 | |
| 	@Environment(EnvType.CLIENT)
 | |
| 	public interface Listener extends AdvancementTree.Listener {
 | |
| 		void onUpdateAdvancementProgress(AdvancementNode advancement, AdvancementProgress advancementProgress);
 | |
| 
 | |
| 		void onSelectedTabChanged(@Nullable AdvancementHolder advancement);
 | |
| 	}
 | |
| }
 |