mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-01 05:58:00 +01:00
Merge pull request #24 from Minestom/advancements
Added Advancements and Advancement Toasties.
This commit is contained in:
commit
251fbbda32
@ -28,6 +28,7 @@ import net.minestom.server.inventory.InventoryType;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.Material;
|
||||
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;
|
||||
@ -227,6 +228,63 @@ public class PlayerInit {
|
||||
scoreboard.updateLineContent("id3", "I HAVE BEEN UPDATED");
|
||||
|
||||
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 -> {
|
||||
|
@ -1,10 +1,17 @@
|
||||
package fr.themode.demo.commands;
|
||||
|
||||
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.CommandSender;
|
||||
import net.minestom.server.entity.Player;
|
||||
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;
|
||||
|
||||
public class SimpleCommand implements CommandProcessor {
|
||||
@ -58,6 +65,12 @@ public class SimpleCommand implements CommandProcessor {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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(ClientTeleportConfirmPacket.class, TeleportListener::listener);
|
||||
setListener(ClientResourcePackStatusPacket.class, ResourcePackListener::listener);
|
||||
setListener(ClientAdvancementTabPacket.class, AdvancementTabListener::listener);
|
||||
}
|
||||
|
||||
public <T extends ClientPlayPacket> void process(T packet, Player player) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.minestom.server.chat.ColoredText;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.network.packet.PacketWriter;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
@ -20,7 +21,6 @@ public class AdvancementsPacket implements ServerPacket {
|
||||
for (AdvancementMapping advancementMapping : advancementMappings) {
|
||||
advancementMapping.write(writer);
|
||||
}
|
||||
|
||||
writer.writeStringArray(identifiersToRemove);
|
||||
|
||||
writer.writeVarInt(progressMappings.length);
|
||||
@ -34,10 +34,28 @@ public class AdvancementsPacket implements ServerPacket {
|
||||
return ServerPacketIdentifier.ADVANCEMENTS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the frame around the Advancement.
|
||||
* Also describes the type of advancement it is for "toast" notifications.
|
||||
*/
|
||||
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 String key;
|
||||
@ -51,22 +69,21 @@ public class AdvancementsPacket implements ServerPacket {
|
||||
}
|
||||
|
||||
public static class Advancement {
|
||||
|
||||
public boolean hasParent;
|
||||
public String identifier;
|
||||
public boolean hasDisplay;
|
||||
public String parentIdentifier;
|
||||
public DisplayData displayData;
|
||||
public String[] criterions;
|
||||
public Requirement[] requirements;
|
||||
|
||||
private void write(PacketWriter writer) {
|
||||
writer.writeBoolean(hasParent);
|
||||
if (identifier != null) {
|
||||
writer.writeSizedString(identifier);
|
||||
// hasParent
|
||||
writer.writeBoolean(parentIdentifier != null);
|
||||
if (parentIdentifier != null) {
|
||||
writer.writeSizedString(parentIdentifier);
|
||||
}
|
||||
|
||||
writer.writeBoolean(hasDisplay);
|
||||
if (hasDisplay) {
|
||||
// hasDisplay
|
||||
writer.writeBoolean(displayData != null);
|
||||
if (displayData != null) {
|
||||
displayData.write(writer);
|
||||
}
|
||||
|
||||
@ -81,8 +98,8 @@ public class AdvancementsPacket implements ServerPacket {
|
||||
}
|
||||
|
||||
public static class DisplayData {
|
||||
public String title;
|
||||
public String description;
|
||||
public ColoredText title;
|
||||
public ColoredText description;
|
||||
public ItemStack icon;
|
||||
public FrameType frameType;
|
||||
public int flags;
|
||||
@ -91,8 +108,8 @@ public class AdvancementsPacket implements ServerPacket {
|
||||
public float y;
|
||||
|
||||
private void write(PacketWriter writer) {
|
||||
writer.writeSizedString(title);
|
||||
writer.writeSizedString(description);
|
||||
writer.writeSizedString(title.toString());
|
||||
writer.writeSizedString(description.toString());
|
||||
writer.writeItemStack(icon);
|
||||
writer.writeVarInt(frameType.ordinal());
|
||||
writer.writeInt(flags);
|
||||
|
Loading…
Reference in New Issue
Block a user