Skip to content

Commit 7583a8f

Browse files
authored
Add data-driven town advancements, /admintown advancements command (#210)
1 parent 133a2f8 commit 7583a8f

File tree

22 files changed

+1082
-17
lines changed

22 files changed

+1082
-17
lines changed

bukkit/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ dependencies {
55
implementation 'net.kyori:adventure-platform-bukkit:4.3.0'
66
implementation 'io.papermc:paperlib:1.0.8'
77
implementation 'me.lucko:commodore:2.2'
8+
implementation 'net.william278:AdvancementAPI:97a9583413'
89

910
compileOnly 'org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT'
1011
compileOnly 'org.jetbrains:annotations:24.0.1'
@@ -52,4 +53,5 @@ shadowJar {
5253
relocate 'org.bstats', 'net.william278.husktowns.libraries.bstats'
5354
relocate 'io.papermc', 'net.william278.husktowns.libraries.paperlib'
5455
relocate 'me.lucko', 'net.william278.husktowns.libraries'
56+
relocate 'net.roxeez', 'net.william278.husktowns.libraries'
5557
}

bukkit/src/main/java/net/william278/husktowns/BukkitHuskTowns.java

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
package net.william278.husktowns;
22

33
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
4+
import net.roxeez.advancement.AdvancementManager;
5+
import net.roxeez.advancement.display.BackgroundType;
6+
import net.roxeez.advancement.display.FrameType;
7+
import net.roxeez.advancement.trigger.TriggerType;
48
import net.william278.desertwell.Version;
9+
import net.william278.husktowns.advancement.Advancement;
510
import net.william278.husktowns.claim.ClaimWorld;
611
import net.william278.husktowns.claim.Position;
712
import net.william278.husktowns.claim.World;
@@ -30,6 +35,9 @@
3035
import org.bstats.bukkit.Metrics;
3136
import org.bstats.charts.SimplePie;
3237
import org.bukkit.Bukkit;
38+
import org.bukkit.Material;
39+
import org.bukkit.NamespacedKey;
40+
import org.bukkit.advancement.AdvancementProgress;
3341
import org.bukkit.entity.Player;
3442
import org.bukkit.plugin.PluginDescriptionFile;
3543
import org.bukkit.plugin.PluginManager;
@@ -61,6 +69,7 @@ public final class BukkitHuskTowns extends JavaPlugin implements HuskTowns, Plug
6169
private Validator validator;
6270
private OperationHandler operationHandler;
6371
private SpecialTypes specialTypes;
72+
private Advancement advancements;
6473
private Map<UUID, Deque<Invite>> invites = new HashMap<>();
6574
private Map<UUID, Preferences> userPreferences = new HashMap<>();
6675
private Map<UUID, Visualizer> visualizers = new HashMap<>();
@@ -424,6 +433,71 @@ private void initializeMetrics() {
424433
}
425434
}
426435

436+
@Override
437+
public void awardAdvancement(@NotNull Advancement advancement, @NotNull OnlineUser user) {
438+
final NamespacedKey key = NamespacedKey.fromString(advancement.getKey(), this);
439+
if (key == null) {
440+
return;
441+
}
442+
443+
final org.bukkit.advancement.Advancement bukkitAdvancement = Bukkit.getAdvancement(key);
444+
if (bukkitAdvancement == null) {
445+
return;
446+
}
447+
final AdvancementProgress progress = ((BukkitUser)user).getPlayer().getAdvancementProgress(bukkitAdvancement);
448+
if (progress.isDone()) {
449+
return;
450+
}
451+
getPlugin().runSync(() -> bukkitAdvancement.getCriteria().forEach(progress::awardCriteria));
452+
}
453+
454+
@Override
455+
public Optional<Advancement> getAdvancements() {
456+
return Optional.ofNullable(advancements);
457+
}
458+
459+
@Override
460+
public void setAdvancements(@NotNull Advancement advancements) {
461+
this.advancements = advancements;
462+
463+
this.runSync(() -> {
464+
final AdvancementManager manager = new AdvancementManager(this);
465+
registerAdvancement(advancements, manager, null);
466+
manager.createAll(true);
467+
});
468+
}
469+
470+
private void registerAdvancement(@NotNull Advancement advancement, @NotNull AdvancementManager manager,
471+
@Nullable net.roxeez.advancement.Advancement parent) {
472+
final NamespacedKey key = NamespacedKey.fromString(advancement.getKey(), this);
473+
if (key == null) {
474+
return;
475+
}
476+
477+
final net.roxeez.advancement.Advancement bukkitAdvancement = new net.roxeez.advancement.Advancement(key);
478+
manager.register(((context) -> {
479+
bukkitAdvancement.setDisplay(display -> {
480+
display.setTitle(advancement.getTitle());
481+
display.setDescription(advancement.getDescription());
482+
display.setIcon(Optional.ofNullable(Material.matchMaterial(advancement.getIcon())).orElse(Material.STONE));
483+
display.setBackground(BackgroundType.GRANITE);
484+
display.setToast(advancement.doSendNotification());
485+
display.setAnnounce(advancement.doSendNotification());
486+
display.setFrame(switch (advancement.getFrame()) {
487+
case TASK -> FrameType.TASK;
488+
case CHALLENGE -> FrameType.CHALLENGE;
489+
case GOAL -> FrameType.GOAL;
490+
});
491+
});
492+
if (parent != null) {
493+
bukkitAdvancement.setParent(parent.getKey());
494+
}
495+
bukkitAdvancement.addCriteria("husktowns_completed", TriggerType.IMPOSSIBLE, (impossible -> {}));
496+
return bukkitAdvancement;
497+
}));
498+
advancement.getChildren().forEach(child -> registerAdvancement(child, manager, bukkitAdvancement));
499+
}
500+
427501
@Override
428502
@NotNull
429503
public BukkitHuskTowns getPlugin() {

bukkit/src/main/java/net/william278/husktowns/hook/PlaceholderAPIHook.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public PlaceholderAPIHook(@NotNull HuskTowns plugin) {
2727

2828
@Override
2929
protected void onEnable() {
30-
new HuskTownsExpansion(plugin).register();
30+
plugin.runSync(() -> new HuskTownsExpansion(plugin).register());
3131
}
3232

3333
public static class HuskTownsExpansion extends PlaceholderExpansion {

bukkit/src/main/resources/commodore/admintown.commodore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ admintown {
4646
takeover {
4747
town brigadier:string single_word;
4848
}
49+
advancements {
50+
list {
51+
player brigadier:string single_word;
52+
}
53+
reset {
54+
player brigadier:string single_word;
55+
}
56+
}
4957
help {
5058
page brigadier:integer;
5159
}

bukkit/src/test/java/net/william278/husktowns/BukkitPluginTests.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,5 +209,4 @@ private static List<String> readTestData(@NotNull String fileName) {
209209
}
210210
return townNames;
211211
}
212-
213212
}

common/src/main/java/net/william278/husktowns/HuskTowns.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import net.william278.annotaml.Annotaml;
88
import net.william278.desertwell.UpdateChecker;
99
import net.william278.desertwell.Version;
10+
import net.william278.husktowns.advancement.AdvancementTracker;
1011
import net.william278.husktowns.claim.*;
1112
import net.william278.husktowns.config.*;
1213
import net.william278.husktowns.database.Database;
@@ -45,7 +46,7 @@
4546
import java.util.logging.Level;
4647
import java.util.stream.Collectors;
4748

48-
public interface HuskTowns extends TaskRunner, EventDispatcher {
49+
public interface HuskTowns extends TaskRunner, EventDispatcher, AdvancementTracker {
4950

5051
int SPIGOT_RESOURCE_ID = 92672;
5152
int BSTATS_PLUGIN_ID = 11265;
@@ -306,6 +307,9 @@ default void loadConfig() throws RuntimeException {
306307
if (getSettings().doCrossServer()) {
307308
setServer(Annotaml.create(new File(getDataFolder(), "server.yml"), Server.class).get());
308309
}
310+
if (getSettings().doAdvancements()) {
311+
loadAdvancements();
312+
}
309313
} catch (IOException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
310314
log(Level.SEVERE, "Failed to load configuration files", e);
311315
throw new RuntimeException(e);
@@ -416,9 +420,13 @@ default Key getKey(@NotNull String... data) {
416420
return Key.key("husktowns", joined);
417421
}
418422

423+
default GsonBuilder getGsonBuilder() {
424+
return Converters.registerOffsetDateTime(new GsonBuilder().excludeFieldsWithoutExposeAnnotation());
425+
}
426+
419427
@NotNull
420428
default Gson getGson() {
421-
return Converters.registerOffsetDateTime(new GsonBuilder().excludeFieldsWithoutExposeAnnotation()).create();
429+
return getGsonBuilder().create();
422430
}
423431

424432
}

0 commit comments

Comments
 (0)