mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-01 05:58:00 +01:00
Advancement API
This commit is contained in:
parent
981d247f02
commit
61857bd4b6
@ -3,7 +3,7 @@ package fr.themode.demo;
|
||||
import fr.themode.demo.generator.ChunkGeneratorDemo;
|
||||
import fr.themode.demo.generator.NoiseTestGenerator;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.advancements.FrameType;
|
||||
import net.minestom.server.advancements.*;
|
||||
import net.minestom.server.benchmark.BenchmarkManager;
|
||||
import net.minestom.server.benchmark.ThreadResult;
|
||||
import net.minestom.server.chat.ChatColor;
|
||||
@ -25,7 +25,6 @@ import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.Material;
|
||||
import net.minestom.server.item.metadata.MapMeta;
|
||||
import net.minestom.server.network.ConnectionManager;
|
||||
import net.minestom.server.network.packet.server.play.AdvancementsPacket;
|
||||
import net.minestom.server.ping.ResponseDataConsumer;
|
||||
import net.minestom.server.utils.MathUtils;
|
||||
import net.minestom.server.utils.Position;
|
||||
@ -226,62 +225,21 @@ public class PlayerInit {
|
||||
|
||||
scoreboard.setTitle("test");*/
|
||||
|
||||
// Testing advancements
|
||||
AdvancementsPacket advancementsPacket = new AdvancementsPacket();
|
||||
advancementsPacket.resetAdvancements = true;
|
||||
|
||||
AdvancementsPacket.AdvancementMapping firstMapping = new AdvancementsPacket.AdvancementMapping();
|
||||
{
|
||||
AdvancementsPacket.Advancement firstAdvancement = new AdvancementsPacket.Advancement();
|
||||
firstMapping.key = "minestom:advancement";
|
||||
firstMapping.value = firstAdvancement;
|
||||
AdvancementManager advancementManager = MinecraftServer.getAdvancementManager();
|
||||
AdvancementRoot root = new AdvancementRoot(ColoredText.of("title"), ColoredText.of(ChatColor.BLUE + "description"),
|
||||
Material.APPLE, FrameType.TASK, 0, 0, "minecraft:textures/block/red_wool.png");
|
||||
AdvancementTab tab = advancementManager.createTab("root", root);
|
||||
Advancement advancement = new Advancement(ColoredText.of("adv"), ColoredText.of("desc"),
|
||||
Material.WOODEN_AXE, FrameType.CHALLENGE, 1, 0)
|
||||
.showToast(true).setHidden(false);
|
||||
tab.createAdvancement("second", advancement, root);
|
||||
|
||||
AdvancementsPacket.DisplayData displayData = new AdvancementsPacket.DisplayData();
|
||||
displayData.x = 0.0F;
|
||||
displayData.y = 0.0F;
|
||||
displayData.title = ColoredText.of("Hello");
|
||||
displayData.description = ColoredText.of("Hello");
|
||||
displayData.icon = new ItemStack(Material.DIRT, (byte) 1);
|
||||
displayData.frameType = FrameType.TASK;
|
||||
displayData.flags = 0x1;
|
||||
displayData.backgroundTexture = "minecraft:textures/block/red_wool.png";
|
||||
|
||||
firstAdvancement.displayData = displayData;
|
||||
firstAdvancement.criterions = new String[]{};
|
||||
firstAdvancement.requirements = new AdvancementsPacket.Requirement[]{};
|
||||
tab.addViewer(player);
|
||||
|
||||
advancement.setTitle(ColoredText.of("test ttlechange"));
|
||||
//player.getPlayerConnection().sendPacket(tab.removePacket());
|
||||
}
|
||||
// This advancement will be to the bottom right of the firstAdvancement
|
||||
// The background of this advancement is apparentely ignored!
|
||||
AdvancementsPacket.AdvancementMapping secondMapping = new AdvancementsPacket.AdvancementMapping();
|
||||
{
|
||||
AdvancementsPacket.Advancement secondAdvancement = new AdvancementsPacket.Advancement();
|
||||
secondMapping.key = "minestom:advance";
|
||||
secondMapping.value = secondAdvancement;
|
||||
|
||||
secondAdvancement.parentIdentifier = "minestom:advancement";
|
||||
|
||||
AdvancementsPacket.DisplayData displayData = new AdvancementsPacket.DisplayData();
|
||||
displayData.x = 2.0F;
|
||||
displayData.y = 2.0F;
|
||||
displayData.title = ColoredText.of("Hello World");
|
||||
displayData.description = ColoredText.of("Hello World");
|
||||
displayData.icon = new ItemStack(Material.DIAMOND, (byte) 1);
|
||||
displayData.frameType = FrameType.GOAL;
|
||||
displayData.flags = 0x2;
|
||||
|
||||
secondAdvancement.displayData = displayData;
|
||||
secondAdvancement.criterions = new String[]{};
|
||||
secondAdvancement.requirements = new AdvancementsPacket.Requirement[]{};
|
||||
}
|
||||
|
||||
|
||||
advancementsPacket.identifiersToRemove = new String[]{};
|
||||
advancementsPacket.advancementMappings = new AdvancementsPacket.AdvancementMapping[]{firstMapping, secondMapping};
|
||||
advancementsPacket.progressMappings = new AdvancementsPacket.ProgressMapping[]{};
|
||||
|
||||
|
||||
player.getPlayerConnection().sendPacket(advancementsPacket);
|
||||
});
|
||||
|
||||
player.addEventCallback(PlayerSpawnEvent.class, event -> {
|
||||
|
@ -5,6 +5,7 @@ import com.mojang.authlib.minecraft.MinecraftSessionService;
|
||||
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.minestom.server.advancements.AdvancementManager;
|
||||
import net.minestom.server.benchmark.BenchmarkManager;
|
||||
import net.minestom.server.command.CommandManager;
|
||||
import net.minestom.server.data.DataManager;
|
||||
@ -107,6 +108,7 @@ public class MinecraftServer {
|
||||
private static SchedulerManager schedulerManager;
|
||||
private static BenchmarkManager benchmarkManager;
|
||||
private static DimensionTypeManager dimensionTypeManager;
|
||||
private static AdvancementManager advancementManager;
|
||||
|
||||
private static UpdateManager updateManager;
|
||||
private static MinecraftServer minecraftServer;
|
||||
@ -157,6 +159,7 @@ public class MinecraftServer {
|
||||
schedulerManager = new SchedulerManager();
|
||||
benchmarkManager = new BenchmarkManager();
|
||||
dimensionTypeManager = new DimensionTypeManager();
|
||||
advancementManager = new AdvancementManager();
|
||||
|
||||
updateManager = new UpdateManager();
|
||||
|
||||
@ -277,6 +280,10 @@ public class MinecraftServer {
|
||||
return dimensionTypeManager;
|
||||
}
|
||||
|
||||
public static AdvancementManager getAdvancementManager() {
|
||||
return advancementManager;
|
||||
}
|
||||
|
||||
public static TagManager getTagManager() {
|
||||
return tagManager;
|
||||
}
|
||||
|
209
src/main/java/net/minestom/server/advancements/Advancement.java
Normal file
209
src/main/java/net/minestom/server/advancements/Advancement.java
Normal file
@ -0,0 +1,209 @@
|
||||
package net.minestom.server.advancements;
|
||||
|
||||
import net.minestom.server.chat.ColoredText;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.Material;
|
||||
import net.minestom.server.network.packet.server.play.AdvancementsPacket;
|
||||
|
||||
public class Advancement {
|
||||
|
||||
protected AdvancementTab tab;
|
||||
|
||||
private ColoredText title;
|
||||
private ColoredText description;
|
||||
|
||||
private ItemStack icon;
|
||||
|
||||
private FrameType frameType;
|
||||
|
||||
private String background; // Only on root
|
||||
private boolean toast;
|
||||
private boolean hidden;
|
||||
|
||||
private float x, y;
|
||||
|
||||
private String identifier;
|
||||
private Advancement parent;
|
||||
|
||||
public Advancement(ColoredText title, ColoredText description,
|
||||
ItemStack icon, FrameType frameType,
|
||||
float x, float y) {
|
||||
this.title = title;
|
||||
this.description = description;
|
||||
this.icon = icon;
|
||||
this.frameType = frameType;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public Advancement(ColoredText title, ColoredText description,
|
||||
Material icon, FrameType frameType,
|
||||
float x, float y) {
|
||||
this(title, description, new ItemStack(icon, (byte) 1), frameType, x, y);
|
||||
}
|
||||
|
||||
public AdvancementTab getTab() {
|
||||
return tab;
|
||||
}
|
||||
|
||||
public void setTab(AdvancementTab tab) {
|
||||
this.tab = tab;
|
||||
}
|
||||
|
||||
public ColoredText getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(ColoredText title) {
|
||||
this.title = title;
|
||||
update();
|
||||
}
|
||||
|
||||
public ColoredText getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(ColoredText description) {
|
||||
this.description = description;
|
||||
update();
|
||||
}
|
||||
|
||||
public boolean hasToast() {
|
||||
return toast;
|
||||
}
|
||||
|
||||
public Advancement showToast(boolean toast) {
|
||||
this.toast = toast;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isHidden() {
|
||||
return hidden;
|
||||
}
|
||||
|
||||
public Advancement setHidden(boolean hidden) {
|
||||
this.hidden = hidden;
|
||||
update();
|
||||
return this;
|
||||
}
|
||||
|
||||
public FrameType getFrameType() {
|
||||
return frameType;
|
||||
}
|
||||
|
||||
public void setFrameType(FrameType frameType) {
|
||||
this.frameType = frameType;
|
||||
update();
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(float x) {
|
||||
this.x = x;
|
||||
update();
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(float y) {
|
||||
this.y = y;
|
||||
update();
|
||||
}
|
||||
|
||||
protected void setBackground(String background) {
|
||||
this.background = background;
|
||||
}
|
||||
|
||||
protected String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
protected void setIdentifier(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
protected Advancement getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
protected void setParent(Advancement parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
protected AdvancementsPacket.DisplayData toDisplayData() {
|
||||
AdvancementsPacket.DisplayData displayData = new AdvancementsPacket.DisplayData();
|
||||
displayData.x = x;
|
||||
displayData.y = y;
|
||||
displayData.title = title;
|
||||
displayData.description = description;
|
||||
displayData.icon = icon;
|
||||
displayData.frameType = frameType;
|
||||
displayData.flags = getFlags();
|
||||
if (background != null) {
|
||||
displayData.backgroundTexture = background;
|
||||
}
|
||||
return displayData;
|
||||
}
|
||||
|
||||
protected AdvancementsPacket getUpdatePacket() {
|
||||
AdvancementsPacket advancementsPacket = new AdvancementsPacket();
|
||||
advancementsPacket.resetAdvancements = false;
|
||||
|
||||
AdvancementsPacket.AdvancementMapping mapping = new AdvancementsPacket.AdvancementMapping();
|
||||
{
|
||||
AdvancementsPacket.Advancement adv = new AdvancementsPacket.Advancement();
|
||||
mapping.key = getIdentifier();
|
||||
mapping.value = adv;
|
||||
|
||||
final Advancement parent = getParent();
|
||||
if (parent != null) {
|
||||
final String parentIdentifier = parent.getIdentifier();
|
||||
adv.parentIdentifier = parentIdentifier;
|
||||
}
|
||||
|
||||
adv.displayData = toDisplayData();
|
||||
adv.criterions = new String[]{};
|
||||
adv.requirements = new AdvancementsPacket.Requirement[]{};
|
||||
}
|
||||
|
||||
advancementsPacket.identifiersToRemove = new String[]{};
|
||||
advancementsPacket.advancementMappings = new AdvancementsPacket.AdvancementMapping[]{mapping};
|
||||
advancementsPacket.progressMappings = new AdvancementsPacket.ProgressMapping[]{};
|
||||
|
||||
return advancementsPacket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update this advancement value when a field is modified
|
||||
*/
|
||||
protected void update() {
|
||||
if (tab != null) {
|
||||
// TODO: how to update an advancement without clearing everything
|
||||
//final AdvancementsPacket packet = getUpdatePacket();
|
||||
//tab.sendPacketToViewers(packet);
|
||||
}
|
||||
}
|
||||
|
||||
private int getFlags() {
|
||||
byte result = 0;
|
||||
|
||||
if (background != null) {
|
||||
result |= 0x1;
|
||||
}
|
||||
|
||||
if (hasToast()) {
|
||||
result |= 0x2;
|
||||
}
|
||||
|
||||
if (isHidden()) {
|
||||
result |= 0x4;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package net.minestom.server.advancements;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class AdvancementManager {
|
||||
|
||||
private Map<String, AdvancementTab> advancementTabMap = new HashMap<>();
|
||||
|
||||
public AdvancementTab createTab(String rootIdentifier, AdvancementRoot root) {
|
||||
final AdvancementTab advancementTab = new AdvancementTab(rootIdentifier, root);
|
||||
this.advancementTabMap.put(rootIdentifier, advancementTab);
|
||||
return advancementTab;
|
||||
}
|
||||
|
||||
public AdvancementTab getTab(String rootIdentifier) {
|
||||
return advancementTabMap.get(rootIdentifier);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package net.minestom.server.advancements;
|
||||
|
||||
import net.minestom.server.chat.ColoredText;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.Material;
|
||||
|
||||
public class AdvancementRoot extends Advancement {
|
||||
|
||||
public AdvancementRoot(ColoredText title, ColoredText description,
|
||||
ItemStack icon, FrameType frameType,
|
||||
float x, float y,
|
||||
String background) {
|
||||
super(title, description, icon, frameType, x, y);
|
||||
setBackground(background);
|
||||
}
|
||||
|
||||
public AdvancementRoot(ColoredText title, ColoredText description,
|
||||
Material icon, FrameType frameType,
|
||||
float x, float y,
|
||||
String background) {
|
||||
super(title, description, icon, frameType, x, y);
|
||||
setBackground(background);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
package net.minestom.server.advancements;
|
||||
|
||||
import net.minestom.server.Viewable;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.network.packet.server.play.AdvancementsPacket;
|
||||
import net.minestom.server.network.player.PlayerConnection;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class AdvancementTab implements Viewable {
|
||||
|
||||
private Set<Player> viewers = new HashSet<>();
|
||||
|
||||
private Advancement root;
|
||||
|
||||
// Advancement -> its parent
|
||||
private Map<Advancement, Advancement> advancementMap = new HashMap<>();
|
||||
|
||||
protected AdvancementTab(String rootIdentifier, Advancement root) {
|
||||
this.root = root;
|
||||
cacheAdvancement(rootIdentifier, root, null);
|
||||
}
|
||||
|
||||
public void createAdvancement(String identifier, Advancement advancement, Advancement parent) {
|
||||
Check.stateCondition(!advancementMap.containsKey(parent),
|
||||
"You tried to set a parent which doesn't exist or isn't registered");
|
||||
cacheAdvancement(identifier, advancement, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the packet which build the whole advancement tab
|
||||
*
|
||||
* @return the packet adding this advancement tab and all its advancements
|
||||
*/
|
||||
public AdvancementsPacket createPacket() {
|
||||
AdvancementsPacket advancementsPacket = new AdvancementsPacket();
|
||||
advancementsPacket.resetAdvancements = false;
|
||||
|
||||
List<AdvancementsPacket.AdvancementMapping> mappings = new ArrayList<>();
|
||||
|
||||
for (Advancement advancement : advancementMap.keySet()) {
|
||||
AdvancementsPacket.AdvancementMapping mapping = new AdvancementsPacket.AdvancementMapping();
|
||||
{
|
||||
AdvancementsPacket.Advancement adv = new AdvancementsPacket.Advancement();
|
||||
mapping.key = advancement.getIdentifier();
|
||||
mapping.value = adv;
|
||||
|
||||
final Advancement parent = advancement.getParent();
|
||||
if (parent != null) {
|
||||
final String parentIdentifier = parent.getIdentifier();
|
||||
adv.parentIdentifier = parentIdentifier;
|
||||
}
|
||||
|
||||
adv.displayData = advancement.toDisplayData();
|
||||
adv.criterions = new String[]{};
|
||||
adv.requirements = new AdvancementsPacket.Requirement[]{};
|
||||
}
|
||||
mappings.add(mapping);
|
||||
}
|
||||
|
||||
advancementsPacket.identifiersToRemove = new String[]{};
|
||||
advancementsPacket.advancementMappings = mappings.toArray(new AdvancementsPacket.AdvancementMapping[0]);
|
||||
advancementsPacket.progressMappings = new AdvancementsPacket.ProgressMapping[]{};
|
||||
|
||||
return advancementsPacket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a packet which remove the root advancement
|
||||
* <p>
|
||||
* This does in fact remove the whole advancement tab
|
||||
*
|
||||
* @return the packet which remove the root advancement
|
||||
*/
|
||||
public AdvancementsPacket removePacket() {
|
||||
AdvancementsPacket advancementsPacket = new AdvancementsPacket();
|
||||
advancementsPacket.resetAdvancements = false;
|
||||
advancementsPacket.identifiersToRemove = new String[]{root.getIdentifier()};
|
||||
advancementsPacket.advancementMappings = new AdvancementsPacket.AdvancementMapping[]{};
|
||||
advancementsPacket.progressMappings = new AdvancementsPacket.ProgressMapping[]{};
|
||||
|
||||
return advancementsPacket;
|
||||
}
|
||||
|
||||
private void cacheAdvancement(String identifier, Advancement advancement, Advancement parent) {
|
||||
Check.stateCondition(advancement.getTab() != null,
|
||||
"You tried to add an advancement already linked to a tab");
|
||||
advancement.setTab(this);
|
||||
advancement.setIdentifier(identifier);
|
||||
advancement.setParent(parent);
|
||||
this.advancementMap.put(advancement, parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addViewer(Player player) {
|
||||
final boolean result = viewers.add(player);
|
||||
if (!result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PlayerConnection playerConnection = player.getPlayerConnection();
|
||||
|
||||
// Send the tab to the player
|
||||
playerConnection.sendPacket(createPacket());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeViewer(Player player) {
|
||||
if (!isViewer(player)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PlayerConnection playerConnection = player.getPlayerConnection();
|
||||
|
||||
// Remove the tab
|
||||
playerConnection.sendPacket(removePacket());
|
||||
|
||||
return viewers.remove(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Player> getViewers() {
|
||||
return viewers;
|
||||
}
|
||||
}
|
@ -40,7 +40,7 @@ public class NotificationCenter {
|
||||
* Create the packet responsive for showing the Toast to players
|
||||
*
|
||||
* @param notification the notification
|
||||
* @return the packet to show the Toast
|
||||
* @return the packet used to show the Toast
|
||||
*/
|
||||
private static AdvancementsPacket getCreatePacket(Notification notification) {
|
||||
// For An advancement to be shown, it must have all of it's criteria achieved (progress 100%)
|
||||
|
Loading…
Reference in New Issue
Block a user