mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-06 00:17:58 +01:00
Added Advancements and Advancement Toasties.
This commit is contained in:
parent
485089078d
commit
30ff313cad
@ -28,6 +28,7 @@ import net.minestom.server.inventory.InventoryType;
|
|||||||
import net.minestom.server.item.ItemStack;
|
import net.minestom.server.item.ItemStack;
|
||||||
import net.minestom.server.item.Material;
|
import net.minestom.server.item.Material;
|
||||||
import net.minestom.server.network.ConnectionManager;
|
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.ping.ResponseDataConsumer;
|
||||||
import net.minestom.server.utils.MathUtils;
|
import net.minestom.server.utils.MathUtils;
|
||||||
import net.minestom.server.utils.Position;
|
import net.minestom.server.utils.Position;
|
||||||
@ -227,6 +228,63 @@ public class PlayerInit {
|
|||||||
scoreboard.updateLineContent("id3", "I HAVE BEEN UPDATED");
|
scoreboard.updateLineContent("id3", "I HAVE BEEN UPDATED");
|
||||||
|
|
||||||
scoreboard.setTitle("test");*/
|
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;
|
||||||
|
|
||||||
|
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 = AdvancementsPacket.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[]{};
|
||||||
|
|
||||||
|
}
|
||||||
|
// 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 = AdvancementsPacket.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 -> {
|
player.addEventCallback(PlayerSpawnEvent.class, event -> {
|
||||||
|
@ -1,10 +1,17 @@
|
|||||||
package fr.themode.demo.commands;
|
package fr.themode.demo.commands;
|
||||||
|
|
||||||
import fr.themode.demo.entity.ChickenCreature;
|
import fr.themode.demo.entity.ChickenCreature;
|
||||||
|
import net.minestom.server.advancements.notifications.AdvancementNotification;
|
||||||
|
import net.minestom.server.advancements.notifications.AdvancementNotificationManager;
|
||||||
|
import net.minestom.server.chat.ChatColor;
|
||||||
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.minestom.server.command.CommandProcessor;
|
import net.minestom.server.command.CommandProcessor;
|
||||||
import net.minestom.server.command.CommandSender;
|
import net.minestom.server.command.CommandSender;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.instance.Instance;
|
import net.minestom.server.instance.Instance;
|
||||||
|
import net.minestom.server.item.ItemStack;
|
||||||
|
import net.minestom.server.item.Material;
|
||||||
|
import net.minestom.server.network.packet.server.play.AdvancementsPacket;
|
||||||
import net.minestom.server.utils.Position;
|
import net.minestom.server.utils.Position;
|
||||||
|
|
||||||
public class SimpleCommand implements CommandProcessor {
|
public class SimpleCommand implements CommandProcessor {
|
||||||
@ -58,6 +65,12 @@ public class SimpleCommand implements CommandProcessor {
|
|||||||
|
|
||||||
chickenCreature.setPathTo(player.getPosition());
|
chickenCreature.setPathTo(player.getPosition());
|
||||||
|
|
||||||
|
new AdvancementNotificationManager().sendAdvancementNotification(
|
||||||
|
new AdvancementNotification(
|
||||||
|
ColoredText.of(ChatColor.BRIGHT_GREEN + "Welcome to Minestom!"),
|
||||||
|
new ItemStack(Material.ACACIA_BOAT, (byte) 1), AdvancementsPacket.FrameType.GOAL)
|
||||||
|
, player
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
package net.minestom.server.advancements.notifications;
|
||||||
|
|
||||||
|
import net.minestom.server.chat.ColoredText;
|
||||||
|
import net.minestom.server.item.ItemStack;
|
||||||
|
import net.minestom.server.network.packet.server.play.AdvancementsPacket;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Lukas Mansour (Articdive)
|
||||||
|
*/
|
||||||
|
public class AdvancementNotification {
|
||||||
|
private final ColoredText title;
|
||||||
|
private final ItemStack icon;
|
||||||
|
private final AdvancementsPacket.FrameType frameType;
|
||||||
|
|
||||||
|
public AdvancementNotification(@NotNull ColoredText title, @NotNull ItemStack icon, @NotNull AdvancementsPacket.FrameType frameType) {
|
||||||
|
this.title = title;
|
||||||
|
this.icon = icon;
|
||||||
|
this.frameType = frameType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public ColoredText getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public ItemStack getIcon() {
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public AdvancementsPacket.FrameType getFrameType() {
|
||||||
|
return frameType;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,101 @@
|
|||||||
|
package net.minestom.server.advancements.notifications;
|
||||||
|
|
||||||
|
import net.minestom.server.chat.ColoredText;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.network.packet.server.play.AdvancementsPacket;
|
||||||
|
|
||||||
|
import java.sql.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Lukas Mansour
|
||||||
|
*/
|
||||||
|
public class AdvancementNotificationManager {
|
||||||
|
public AdvancementNotificationManager() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendAdvancementNotification(AdvancementNotification advancementNotification, Player player) {
|
||||||
|
// Sending
|
||||||
|
{
|
||||||
|
// For An advancement to be shown, it must have all of it's criteria achieved (progress 100%)
|
||||||
|
// Create a Criteria that we can set to 100% achieved.
|
||||||
|
// Criteria
|
||||||
|
|
||||||
|
AdvancementsPacket.Criteria criteria = new AdvancementsPacket.Criteria();
|
||||||
|
{
|
||||||
|
AdvancementsPacket.CriterionProgress progress = new AdvancementsPacket.CriterionProgress();
|
||||||
|
progress.achieved = true;
|
||||||
|
progress.dateOfAchieving = new Date(System.currentTimeMillis()).getTime();
|
||||||
|
criteria.criterionProgress = progress;
|
||||||
|
criteria.criterionIdentifier = "minestom:some_criteria";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now create an AdvancementsPacket that we can send:
|
||||||
|
AdvancementsPacket advancementsPacket = new AdvancementsPacket();
|
||||||
|
advancementsPacket.resetAdvancements = false;
|
||||||
|
|
||||||
|
AdvancementsPacket.AdvancementMapping mapping = new AdvancementsPacket.AdvancementMapping();
|
||||||
|
{
|
||||||
|
// Get the advancement
|
||||||
|
AdvancementsPacket.Advancement advancement = new AdvancementsPacket.Advancement();
|
||||||
|
// Setup display data for the advancement
|
||||||
|
AdvancementsPacket.DisplayData displayData = new AdvancementsPacket.DisplayData();
|
||||||
|
{
|
||||||
|
displayData.title = advancementNotification.getTitle();
|
||||||
|
// Description is required, but never shown/seen so, small Easter egg.
|
||||||
|
displayData.description = ColoredText.of("Articdive was here. #Minestom");
|
||||||
|
displayData.icon = advancementNotification.getIcon();
|
||||||
|
displayData.frameType = advancementNotification.getFrameType();
|
||||||
|
displayData.flags = 0x6;
|
||||||
|
// No background texture required as we are using 0x6
|
||||||
|
displayData.x = 0.0F;
|
||||||
|
displayData.y = 0.0F;
|
||||||
|
}
|
||||||
|
advancement.displayData = displayData;
|
||||||
|
// Add the criteria to the advancement
|
||||||
|
advancement.criterions = new String[]{criteria.criterionIdentifier};
|
||||||
|
// Add the requirement of the criteria to the advancement
|
||||||
|
AdvancementsPacket.Requirement requirement = new AdvancementsPacket.Requirement();
|
||||||
|
{
|
||||||
|
requirement.requirements = new String[]{criteria.criterionIdentifier};
|
||||||
|
}
|
||||||
|
advancement.requirements = new AdvancementsPacket.Requirement[]{requirement};
|
||||||
|
|
||||||
|
mapping.key = "minestom:advancement_login";
|
||||||
|
mapping.value = advancement;
|
||||||
|
}
|
||||||
|
// Add the mapping to the main packet
|
||||||
|
advancementsPacket.advancementMappings = new AdvancementsPacket.AdvancementMapping[]{mapping};
|
||||||
|
|
||||||
|
|
||||||
|
// We have no identifiers to remove.
|
||||||
|
advancementsPacket.identifiersToRemove = new String[]{};
|
||||||
|
|
||||||
|
// Now we need to set the player's progress for the criteria.
|
||||||
|
AdvancementsPacket.ProgressMapping progressMapping = new AdvancementsPacket.ProgressMapping();
|
||||||
|
{
|
||||||
|
AdvancementsPacket.AdvancementProgress advancementProgress = new AdvancementsPacket.AdvancementProgress();
|
||||||
|
advancementProgress.criteria = new AdvancementsPacket.Criteria[]{criteria};
|
||||||
|
|
||||||
|
progressMapping.key = "minestom:advancement_login";
|
||||||
|
progressMapping.value = advancementProgress;
|
||||||
|
}
|
||||||
|
advancementsPacket.progressMappings = new AdvancementsPacket.ProgressMapping[]{progressMapping};
|
||||||
|
|
||||||
|
// Now let's send the the tasty toast.
|
||||||
|
player.getPlayerConnection().sendPacket(advancementsPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we should send a packet telling the player to remove that advancement
|
||||||
|
// Removing
|
||||||
|
{
|
||||||
|
AdvancementsPacket advancementsPacket = new AdvancementsPacket();
|
||||||
|
advancementsPacket.resetAdvancements = false;
|
||||||
|
advancementsPacket.identifiersToRemove = new String[]{"minestom:advancement_login"};
|
||||||
|
advancementsPacket.advancementMappings = new AdvancementsPacket.AdvancementMapping[]{};
|
||||||
|
advancementsPacket.progressMappings = new AdvancementsPacket.ProgressMapping[]{};
|
||||||
|
player.getPlayerConnection().sendPacket(advancementsPacket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package net.minestom.server.listener;
|
||||||
|
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.network.packet.client.play.ClientAdvancementTabPacket;
|
||||||
|
|
||||||
|
public class AdvancementTabListener {
|
||||||
|
|
||||||
|
public static void listener(ClientAdvancementTabPacket packet, Player player) {
|
||||||
|
// Currentely unused and don't see much usage for an API
|
||||||
|
// TODO: Create an Event?
|
||||||
|
}
|
||||||
|
}
|
@ -45,6 +45,7 @@ public class PacketListenerManager {
|
|||||||
setListener(ClientPlayerAbilitiesPacket.class, AbilitiesListener::listener);
|
setListener(ClientPlayerAbilitiesPacket.class, AbilitiesListener::listener);
|
||||||
setListener(ClientTeleportConfirmPacket.class, TeleportListener::listener);
|
setListener(ClientTeleportConfirmPacket.class, TeleportListener::listener);
|
||||||
setListener(ClientResourcePackStatusPacket.class, ResourcePackListener::listener);
|
setListener(ClientResourcePackStatusPacket.class, ResourcePackListener::listener);
|
||||||
|
setListener(ClientAdvancementTabPacket.class, AdvancementTabListener::listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends ClientPlayPacket> void process(T packet, Player player) {
|
public <T extends ClientPlayPacket> void process(T packet, Player player) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.minestom.server.network.packet.server.play;
|
package net.minestom.server.network.packet.server.play;
|
||||||
|
|
||||||
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.minestom.server.item.ItemStack;
|
import net.minestom.server.item.ItemStack;
|
||||||
import net.minestom.server.network.packet.PacketWriter;
|
import net.minestom.server.network.packet.PacketWriter;
|
||||||
import net.minestom.server.network.packet.server.ServerPacket;
|
import net.minestom.server.network.packet.server.ServerPacket;
|
||||||
@ -20,7 +21,6 @@ public class AdvancementsPacket implements ServerPacket {
|
|||||||
for (AdvancementMapping advancementMapping : advancementMappings) {
|
for (AdvancementMapping advancementMapping : advancementMappings) {
|
||||||
advancementMapping.write(writer);
|
advancementMapping.write(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.writeStringArray(identifiersToRemove);
|
writer.writeStringArray(identifiersToRemove);
|
||||||
|
|
||||||
writer.writeVarInt(progressMappings.length);
|
writer.writeVarInt(progressMappings.length);
|
||||||
@ -34,10 +34,28 @@ public class AdvancementsPacket implements ServerPacket {
|
|||||||
return ServerPacketIdentifier.ADVANCEMENTS;
|
return ServerPacketIdentifier.ADVANCEMENTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes the frame around the Advancement.
|
||||||
|
* Also describes the type of advancement it is for "toast" notifications.
|
||||||
|
*/
|
||||||
public enum FrameType {
|
public enum FrameType {
|
||||||
TASK, CHALLENGE, GOAL
|
/**
|
||||||
|
* A simple rounded square as the frame.
|
||||||
|
*/
|
||||||
|
TASK,
|
||||||
|
/**
|
||||||
|
* A spike in all 8 directions as the frame.
|
||||||
|
*/
|
||||||
|
CHALLENGE,
|
||||||
|
/**
|
||||||
|
* A square with a outward rounded edge on the top and bottom as the frame.
|
||||||
|
*/
|
||||||
|
GOAL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AdvancementMapping maps the namespaced ID to the Advancement.
|
||||||
|
*/
|
||||||
public static class AdvancementMapping {
|
public static class AdvancementMapping {
|
||||||
|
|
||||||
public String key;
|
public String key;
|
||||||
@ -51,22 +69,21 @@ public class AdvancementsPacket implements ServerPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Advancement {
|
public static class Advancement {
|
||||||
|
public String parentIdentifier;
|
||||||
public boolean hasParent;
|
|
||||||
public String identifier;
|
|
||||||
public boolean hasDisplay;
|
|
||||||
public DisplayData displayData;
|
public DisplayData displayData;
|
||||||
public String[] criterions;
|
public String[] criterions;
|
||||||
public Requirement[] requirements;
|
public Requirement[] requirements;
|
||||||
|
|
||||||
private void write(PacketWriter writer) {
|
private void write(PacketWriter writer) {
|
||||||
writer.writeBoolean(hasParent);
|
// hasParent
|
||||||
if (identifier != null) {
|
writer.writeBoolean(parentIdentifier != null);
|
||||||
writer.writeSizedString(identifier);
|
if (parentIdentifier != null) {
|
||||||
|
writer.writeSizedString(parentIdentifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.writeBoolean(hasDisplay);
|
// hasDisplay
|
||||||
if (hasDisplay) {
|
writer.writeBoolean(displayData != null);
|
||||||
|
if (displayData != null) {
|
||||||
displayData.write(writer);
|
displayData.write(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,8 +98,8 @@ public class AdvancementsPacket implements ServerPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class DisplayData {
|
public static class DisplayData {
|
||||||
public String title;
|
public ColoredText title;
|
||||||
public String description;
|
public ColoredText description;
|
||||||
public ItemStack icon;
|
public ItemStack icon;
|
||||||
public FrameType frameType;
|
public FrameType frameType;
|
||||||
public int flags;
|
public int flags;
|
||||||
@ -91,8 +108,8 @@ public class AdvancementsPacket implements ServerPacket {
|
|||||||
public float y;
|
public float y;
|
||||||
|
|
||||||
private void write(PacketWriter writer) {
|
private void write(PacketWriter writer) {
|
||||||
writer.writeSizedString(title);
|
writer.writeSizedString(title.toString());
|
||||||
writer.writeSizedString(description);
|
writer.writeSizedString(description.toString());
|
||||||
writer.writeItemStack(icon);
|
writer.writeItemStack(icon);
|
||||||
writer.writeVarInt(frameType.ordinal());
|
writer.writeVarInt(frameType.ordinal());
|
||||||
writer.writeInt(flags);
|
writer.writeInt(flags);
|
||||||
|
Loading…
Reference in New Issue
Block a user