2020-08-05 10:56:16 +02:00
|
|
|
package net.minestom.server.advancements;
|
|
|
|
|
2021-03-03 20:27:33 +01:00
|
|
|
import net.kyori.adventure.text.Component;
|
2020-08-05 10:56:16 +02:00
|
|
|
import net.minestom.server.item.ItemStack;
|
|
|
|
import net.minestom.server.item.Material;
|
|
|
|
import net.minestom.server.network.packet.server.play.AdvancementsPacket;
|
2020-11-09 18:29:30 +01:00
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
import org.jetbrains.annotations.Nullable;
|
2020-08-05 10:56:16 +02:00
|
|
|
|
2021-11-30 17:49:41 +01:00
|
|
|
import java.util.List;
|
2020-08-06 07:42:00 +02:00
|
|
|
|
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Represents an advancement located in an {@link AdvancementTab}.
|
2020-10-11 14:58:19 +02:00
|
|
|
* <p>
|
2020-10-15 21:16:31 +02:00
|
|
|
* All fields are dynamic, changing one will update the advancement in the specific {@link AdvancementTab}.
|
2020-08-06 07:42:00 +02:00
|
|
|
*/
|
2020-08-05 10:56:16 +02:00
|
|
|
public class Advancement {
|
|
|
|
|
|
|
|
protected AdvancementTab tab;
|
|
|
|
|
2020-08-06 07:42:00 +02:00
|
|
|
private boolean achieved;
|
|
|
|
|
2021-03-03 20:27:33 +01:00
|
|
|
private Component title;
|
|
|
|
private Component description;
|
2020-08-05 10:56:16 +02:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2020-08-06 07:42:00 +02:00
|
|
|
// Packet
|
|
|
|
private AdvancementsPacket.Criteria criteria;
|
|
|
|
|
2021-03-03 20:27:33 +01:00
|
|
|
public Advancement(@NotNull Component title, Component description,
|
|
|
|
@NotNull ItemStack icon, @NotNull FrameType frameType,
|
|
|
|
float x, float y) {
|
2020-08-05 10:56:16 +02:00
|
|
|
this.title = title;
|
|
|
|
this.description = description;
|
|
|
|
this.icon = icon;
|
|
|
|
this.frameType = frameType;
|
|
|
|
this.x = x;
|
|
|
|
this.y = y;
|
|
|
|
}
|
|
|
|
|
2021-03-03 20:27:33 +01:00
|
|
|
public Advancement(@NotNull Component title, @NotNull Component description,
|
2020-11-09 18:29:30 +01:00
|
|
|
@NotNull Material icon, @NotNull FrameType frameType,
|
2020-08-05 10:56:16 +02:00
|
|
|
float x, float y) {
|
2021-04-02 23:41:06 +02:00
|
|
|
this(title, description, ItemStack.of(icon), frameType, x, y);
|
2020-08-05 10:56:16 +02:00
|
|
|
}
|
|
|
|
|
2020-08-06 07:42:00 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Gets if the advancement is achieved.
|
2020-08-06 07:42:00 +02:00
|
|
|
*
|
|
|
|
* @return true if the advancement is achieved
|
|
|
|
*/
|
|
|
|
public boolean isAchieved() {
|
|
|
|
return achieved;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Makes the advancement achieved.
|
2020-08-06 07:42:00 +02:00
|
|
|
*
|
|
|
|
* @param achieved true to make it achieved
|
|
|
|
* @return this advancement
|
|
|
|
*/
|
|
|
|
public Advancement setAchieved(boolean achieved) {
|
|
|
|
this.achieved = achieved;
|
|
|
|
update();
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2020-08-05 18:25:11 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Gets the advancement tab linked to this advancement.
|
2020-08-05 18:25:11 +02:00
|
|
|
*
|
2020-11-09 18:29:30 +01:00
|
|
|
* @return the {@link AdvancementTab} linked to this advancement, null if not linked to anything yet
|
2020-08-05 18:25:11 +02:00
|
|
|
*/
|
2021-07-27 06:55:08 +02:00
|
|
|
public @Nullable AdvancementTab getTab() {
|
2020-08-05 10:56:16 +02:00
|
|
|
return tab;
|
|
|
|
}
|
|
|
|
|
2020-11-09 18:29:30 +01:00
|
|
|
protected void setTab(@NotNull AdvancementTab tab) {
|
2020-08-05 10:56:16 +02:00
|
|
|
this.tab = tab;
|
|
|
|
}
|
|
|
|
|
2021-03-03 20:27:33 +01:00
|
|
|
/**
|
|
|
|
* Gets the title of the advancement.
|
|
|
|
*
|
|
|
|
* @return the title
|
|
|
|
*/
|
|
|
|
public Component getTitle() {
|
|
|
|
return title;
|
|
|
|
}
|
|
|
|
|
2020-08-05 18:25:11 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Changes the advancement title.
|
2020-08-05 18:25:11 +02:00
|
|
|
*
|
|
|
|
* @param title the new title
|
|
|
|
*/
|
2021-03-03 20:27:33 +01:00
|
|
|
public void setTitle(@NotNull Component title) {
|
2020-08-05 10:56:16 +02:00
|
|
|
this.title = title;
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
2020-08-05 18:25:11 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Gets the description of the advancement.
|
2020-08-05 18:25:11 +02:00
|
|
|
*
|
|
|
|
* @return the description title
|
|
|
|
*/
|
2021-07-27 06:55:08 +02:00
|
|
|
public @NotNull Component getDescription() {
|
2020-08-05 10:56:16 +02:00
|
|
|
return description;
|
|
|
|
}
|
|
|
|
|
2020-08-05 18:25:11 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Changes the description title.
|
2020-08-05 18:25:11 +02:00
|
|
|
*
|
|
|
|
* @param description the new description
|
|
|
|
*/
|
2021-03-03 20:27:33 +01:00
|
|
|
public void setDescription(@NotNull Component description) {
|
2020-08-05 10:56:16 +02:00
|
|
|
this.description = description;
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
2020-08-05 18:25:11 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Gets the advancement icon.
|
2020-08-05 18:25:11 +02:00
|
|
|
*
|
|
|
|
* @return the advancement icon
|
|
|
|
*/
|
2021-07-27 06:55:08 +02:00
|
|
|
public @NotNull ItemStack getIcon() {
|
2020-08-05 18:25:11 +02:00
|
|
|
return icon;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Changes the advancement icon.
|
2020-08-05 18:25:11 +02:00
|
|
|
*
|
|
|
|
* @param icon the new advancement icon
|
|
|
|
*/
|
2020-11-09 18:29:30 +01:00
|
|
|
public void setIcon(@NotNull ItemStack icon) {
|
2020-08-05 18:25:11 +02:00
|
|
|
this.icon = icon;
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Gets if this advancement has a toast.
|
2020-08-05 18:25:11 +02:00
|
|
|
*
|
|
|
|
* @return true if the advancement has a toast
|
|
|
|
*/
|
2020-08-05 10:56:16 +02:00
|
|
|
public boolean hasToast() {
|
|
|
|
return toast;
|
|
|
|
}
|
|
|
|
|
2020-08-05 18:25:11 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Makes this argument a toast.
|
2020-08-05 18:25:11 +02:00
|
|
|
*
|
|
|
|
* @param toast true to make this advancement a toast
|
|
|
|
* @return this advancement
|
|
|
|
*/
|
2020-08-05 10:56:16 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2020-08-05 18:25:11 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Gets the advancement frame type.
|
2020-08-05 18:25:11 +02:00
|
|
|
*
|
|
|
|
* @return this advancement frame type
|
|
|
|
*/
|
2020-11-09 18:29:30 +01:00
|
|
|
@NotNull
|
2020-08-05 10:56:16 +02:00
|
|
|
public FrameType getFrameType() {
|
|
|
|
return frameType;
|
|
|
|
}
|
|
|
|
|
2020-08-05 18:25:11 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Changes the advancement frame type.
|
2020-08-05 18:25:11 +02:00
|
|
|
*
|
|
|
|
* @param frameType the new frame type
|
|
|
|
*/
|
2020-08-05 10:56:16 +02:00
|
|
|
public void setFrameType(FrameType frameType) {
|
|
|
|
this.frameType = frameType;
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
2020-08-05 18:25:11 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Gets the X position of this advancement.
|
2020-08-05 18:25:11 +02:00
|
|
|
*
|
|
|
|
* @return this advancement X
|
|
|
|
*/
|
2020-08-05 10:56:16 +02:00
|
|
|
public float getX() {
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
2020-08-05 18:25:11 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Changes this advancement X coordinate.
|
2020-08-05 18:25:11 +02:00
|
|
|
*
|
|
|
|
* @param x the new X coordinate
|
|
|
|
*/
|
2020-08-05 10:56:16 +02:00
|
|
|
public void setX(float x) {
|
|
|
|
this.x = x;
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
2020-08-05 18:25:11 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Gets the Y position of this advancement.
|
2020-08-05 18:25:11 +02:00
|
|
|
*
|
|
|
|
* @return this advancement Y
|
|
|
|
*/
|
2020-08-05 10:56:16 +02:00
|
|
|
public float getY() {
|
|
|
|
return y;
|
|
|
|
}
|
|
|
|
|
2020-08-05 18:25:11 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Changes this advancement Y coordinate.
|
2020-08-05 18:25:11 +02:00
|
|
|
*
|
|
|
|
* @param y the new Y coordinate
|
|
|
|
*/
|
2020-08-05 10:56:16 +02:00
|
|
|
public void setY(float y) {
|
|
|
|
this.y = y;
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
2020-10-11 14:58:19 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Sets the background.
|
2020-10-11 14:58:19 +02:00
|
|
|
* <p>
|
2020-10-15 21:16:31 +02:00
|
|
|
* Only available for {@link AdvancementRoot}.
|
2020-10-11 14:58:19 +02:00
|
|
|
*
|
|
|
|
* @param background the new background
|
|
|
|
*/
|
2020-08-05 10:56:16 +02:00
|
|
|
protected void setBackground(String background) {
|
|
|
|
this.background = background;
|
|
|
|
}
|
|
|
|
|
2020-10-11 14:58:19 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Gets the identifier of this advancement, used to register the advancement, use it as a parent and to retrieve it later
|
|
|
|
* in the {@link AdvancementTab}.
|
2020-10-11 14:58:19 +02:00
|
|
|
*
|
|
|
|
* @return the advancement identifier
|
|
|
|
*/
|
2020-08-05 10:56:16 +02:00
|
|
|
protected String getIdentifier() {
|
|
|
|
return identifier;
|
|
|
|
}
|
|
|
|
|
2020-10-11 14:58:19 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Changes the advancement identifier.
|
2020-10-11 14:58:19 +02:00
|
|
|
* <p>
|
2020-10-15 21:16:31 +02:00
|
|
|
* WARNING: unsafe, only used by {@link AdvancementTab} to initialize the advancement.
|
2020-10-11 14:58:19 +02:00
|
|
|
*
|
|
|
|
* @param identifier the new advancement identifier
|
|
|
|
*/
|
2020-08-05 10:56:16 +02:00
|
|
|
protected void setIdentifier(String identifier) {
|
|
|
|
this.identifier = identifier;
|
|
|
|
}
|
|
|
|
|
2020-10-11 14:58:19 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Gets the advancement parent.
|
2020-10-11 14:58:19 +02:00
|
|
|
*
|
|
|
|
* @return the advancement parent, null for {@link AdvancementRoot}
|
|
|
|
*/
|
2020-11-09 18:29:30 +01:00
|
|
|
@Nullable
|
2020-08-05 10:56:16 +02:00
|
|
|
protected Advancement getParent() {
|
|
|
|
return parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void setParent(Advancement parent) {
|
|
|
|
this.parent = parent;
|
|
|
|
}
|
|
|
|
|
2021-11-30 17:49:41 +01:00
|
|
|
protected @NotNull AdvancementsPacket.ProgressMapping toProgressMapping() {
|
|
|
|
final var advancementProgress = new AdvancementsPacket.AdvancementProgress(List.of(criteria));
|
|
|
|
return new AdvancementsPacket.ProgressMapping(identifier, advancementProgress);
|
2020-08-06 07:42:00 +02:00
|
|
|
}
|
|
|
|
|
2021-11-30 17:49:41 +01:00
|
|
|
protected @NotNull AdvancementsPacket.DisplayData toDisplayData() {
|
|
|
|
return new AdvancementsPacket.DisplayData(title, description, icon,
|
|
|
|
frameType, getFlags(), background, x, y);
|
2020-08-05 10:56:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Converts this advancement to an {@link AdvancementsPacket.AdvancementMapping}.
|
2020-08-05 14:28:15 +02:00
|
|
|
*
|
2020-08-06 02:37:58 +02:00
|
|
|
* @return the mapping of this advancement
|
2020-08-05 14:28:15 +02:00
|
|
|
*/
|
2021-11-30 17:49:41 +01:00
|
|
|
protected @NotNull AdvancementsPacket.AdvancementMapping toMapping() {
|
|
|
|
final Advancement parent = getParent();
|
|
|
|
final String parentIdentifier = parent != null ? parent.getIdentifier() : null;
|
|
|
|
AdvancementsPacket.Advancement adv = new AdvancementsPacket.Advancement(parentIdentifier, toDisplayData(),
|
|
|
|
List.of(criteria.criterionIdentifier()),
|
2021-12-01 22:41:59 +01:00
|
|
|
List.of(new AdvancementsPacket.Requirement(List.of(criteria.criterionIdentifier()))));
|
2021-11-30 17:49:41 +01:00
|
|
|
return new AdvancementsPacket.AdvancementMapping(getIdentifier(), adv);
|
2020-08-06 02:37:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Gets the packet used to add this advancement to the already existing tab.
|
2020-08-06 02:37:58 +02:00
|
|
|
*
|
|
|
|
* @return the packet to add this advancement
|
|
|
|
*/
|
|
|
|
protected AdvancementsPacket getUpdatePacket() {
|
2021-11-30 17:49:41 +01:00
|
|
|
return new AdvancementsPacket(false, List.of(toMapping()),
|
|
|
|
List.of(), List.of(toProgressMapping()));
|
2020-08-05 14:28:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Sends update to all tab viewers if one of the advancement value changes.
|
2020-08-05 10:56:16 +02:00
|
|
|
*/
|
|
|
|
protected void update() {
|
2020-08-06 07:42:00 +02:00
|
|
|
updateCriteria();
|
2020-08-05 10:56:16 +02:00
|
|
|
if (tab != null) {
|
2022-05-10 10:07:55 +02:00
|
|
|
tab.sendPacketsToViewers(tab.removePacket, tab.createPacket());
|
2020-08-05 10:56:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-06 07:42:00 +02:00
|
|
|
protected void updateCriteria() {
|
2021-12-01 22:41:59 +01:00
|
|
|
final Long achievedDate = achieved ? System.currentTimeMillis() : null;
|
2021-11-30 17:49:41 +01:00
|
|
|
final var progress = new AdvancementsPacket.CriterionProgress(achievedDate);
|
|
|
|
this.criteria = new AdvancementsPacket.Criteria(identifier, progress);
|
2020-08-06 07:42:00 +02:00
|
|
|
}
|
|
|
|
|
2020-08-05 10:56:16 +02:00
|
|
|
private int getFlags() {
|
|
|
|
byte result = 0;
|
2021-12-01 22:41:59 +01:00
|
|
|
if (background != null) result |= 0x1;
|
|
|
|
if (hasToast()) result |= 0x2;
|
|
|
|
if (isHidden()) result |= 0x4;
|
2020-08-05 10:56:16 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|