Skip to content

Advancement Visibility System

fren_gor edited this page Nov 22, 2021 · 5 revisions

Introduction

As stated in Advancements page, advancement visibility is handled through the method

public boolean isVisible(TeamProgression progression),

which returns true if and only if the advancement is visible to the team passed as parameter.

By default, any advancement is visible (so isVisible(...) returns true).
Since RootAdvancements are always visible for minecrafty reasons, RootAdvancement#isVisible(...) has been made final and always returns true.
Instead, isVisible(...) is overridable extending BaseAdvancement. Thus, every advancement but the root can be made hidden.

However, overriding isVisible(...) is not the only way to customize the advancement visibility on non-root advancements.
As a project grows more and more, some way to resuse the visibility code is needed, and this is the argument of the next section.

The IVisibility Interface

In Java 8, default methods in interfaces were introduced, meaning that interfaces can contains code. Hence, it should be nice to have the visibility code in some interfaces implemented by the various advancement classes, and this is exactly what the advancement visibility system tries to accomplish.

It founds on the IVisibility interface, which provides the method

boolean isVisible(Advancement advancement, TeamProgression progression).

It works exactly like the Advancement class' one: it should returns true if and only if the advancement passed as parameter is visible to the team passed as second parameter.

IVisibility#isVisible(...) method is not default though, but IVisibility can be extended by another interface and it can be made defualt.
Interfaces that provides a default implementation to the isVisible(...) method can be implemented by advancement classes to change their visibility.

However, to actually accomplish this, there must be a way to call the interface method instead of the Advancement class' one.
It has been decided it's the Advancemet#isVisible(TeamProgression progression) method that should call the interface's one: when instantiating the advancement, the Advancement class constructor will search for the first implemented interface extending IVisibility which has a default isVisible(...) method. If it is found, then the Advancement#isVisible(...) method will call it. Otherwise, it will return true.

When extending BaseAdvancement, it must be made sure that the Advancement#isVisible(...) super method is called if the advancement visibility system is needed.

Built-in Visibilities

There are a few useful visibilities interfaces included in the com.fren_gor.ultimateAdvancementAPI.visibilities package:

  • HiddenVisibility - Advancement is visible only if progression is greater than 0;
  • ParentGrantedVisibility - Advancement is visible only if progression is greater than 0 or the parent advancement is granted;
  • VanillaVisibility - Advancement is visible only if progression is greater than 0 or either the parent or grandparent advancement is granted.