Minestom/src/main/java/net/minestom/server/advancements/Advancement.java

342 lines
8.7 KiB
Java
Raw Normal View History

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()),
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) {
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() {
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;
if (background != null) result |= 0x1;
if (hasToast()) result |= 0x2;
if (isHidden()) result |= 0x4;
2020-08-05 10:56:16 +02:00
return result;
}
}