diff --git a/src/main/java/com/laytonsmith/abstraction/bukkit/events/BukkitPlayerEvents.java b/src/main/java/com/laytonsmith/abstraction/bukkit/events/BukkitPlayerEvents.java index eb1ebdf4d..db9b82ebf 100644 --- a/src/main/java/com/laytonsmith/abstraction/bukkit/events/BukkitPlayerEvents.java +++ b/src/main/java/com/laytonsmith/abstraction/bukkit/events/BukkitPlayerEvents.java @@ -7,6 +7,7 @@ import com.laytonsmith.abstraction.MCHumanEntity; import com.laytonsmith.abstraction.MCItemStack; import com.laytonsmith.abstraction.MCLocation; +import com.laytonsmith.abstraction.MCNamespacedKey; import com.laytonsmith.abstraction.MCPlayer; import com.laytonsmith.abstraction.MCWorld; import com.laytonsmith.abstraction.blocks.MCBlock; @@ -16,6 +17,7 @@ import com.laytonsmith.abstraction.bukkit.BukkitMCBookMeta; import com.laytonsmith.abstraction.bukkit.BukkitMCItemStack; import com.laytonsmith.abstraction.bukkit.BukkitMCLocation; +import com.laytonsmith.abstraction.bukkit.BukkitMCNamespacedKey; import com.laytonsmith.abstraction.bukkit.BukkitMCWorld; import com.laytonsmith.abstraction.bukkit.blocks.BukkitMCBlock; import com.laytonsmith.abstraction.bukkit.blocks.BukkitMCMaterial; @@ -31,6 +33,7 @@ import com.laytonsmith.abstraction.enums.MCGameMode; import com.laytonsmith.abstraction.enums.MCResourcePackStatus; import com.laytonsmith.abstraction.enums.MCTeleportCause; +import com.laytonsmith.abstraction.enums.MCVersion; import com.laytonsmith.abstraction.enums.bukkit.BukkitMCAction; import com.laytonsmith.abstraction.enums.bukkit.BukkitMCEnterBedResult; import com.laytonsmith.abstraction.enums.bukkit.BukkitMCFishingState; @@ -40,6 +43,7 @@ import com.laytonsmith.abstraction.events.MCExpChangeEvent; import com.laytonsmith.abstraction.events.MCFoodLevelChangeEvent; import com.laytonsmith.abstraction.events.MCGamemodeChangeEvent; +import com.laytonsmith.abstraction.events.MCPlayerAdvancementDoneEvent; import com.laytonsmith.abstraction.events.MCPlayerBucketEmptyEvent; import com.laytonsmith.abstraction.events.MCPlayerBucketEvent; import com.laytonsmith.abstraction.events.MCPlayerBucketFillEvent; @@ -67,9 +71,11 @@ import com.laytonsmith.abstraction.events.MCPlayerToggleSprintEvent; import com.laytonsmith.abstraction.events.MCWorldChangedEvent; import com.laytonsmith.annotations.abstraction; +import com.laytonsmith.core.Static; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; +import org.bukkit.advancement.AdvancementDisplay; import org.bukkit.block.BlockFace; import org.bukkit.damage.DamageSource; import org.bukkit.damage.DamageType; @@ -78,6 +84,7 @@ import org.bukkit.event.entity.FoodLevelChangeEvent; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerAdvancementDoneEvent; import org.bukkit.event.player.PlayerBedEnterEvent; import org.bukkit.event.player.PlayerBedLeaveEvent; import org.bukkit.event.player.PlayerBucketEmptyEvent; @@ -1147,4 +1154,31 @@ public BukkitMCPlayerBucketEmptyEvent(PlayerBucketEmptyEvent event) { this.pbee = event; } } + + @abstraction(type = Implementation.Type.BUKKIT) + public static class BukkitMCPlayerAdvancementDoneEvent extends BukkitMCPlayerEvent implements MCPlayerAdvancementDoneEvent { + + PlayerAdvancementDoneEvent e; + + public BukkitMCPlayerAdvancementDoneEvent(PlayerAdvancementDoneEvent event) { + super(event); + this.e = event; + } + + @Override + public MCNamespacedKey getAdvancementKey() { + return new BukkitMCNamespacedKey(e.getAdvancement().getKey()); + } + + @Override + public String getTitle() { + if(Static.getServer().getMinecraftVersion().gte(MCVersion.MC1_18_X)) { + AdvancementDisplay display = e.getAdvancement().getDisplay(); + if(display != null) { + return display.getTitle(); + } + } + return null; + } + } } diff --git a/src/main/java/com/laytonsmith/abstraction/bukkit/events/drivers/BukkitPlayerListener.java b/src/main/java/com/laytonsmith/abstraction/bukkit/events/drivers/BukkitPlayerListener.java index 05fd4bd91..aba6efb20 100644 --- a/src/main/java/com/laytonsmith/abstraction/bukkit/events/drivers/BukkitPlayerListener.java +++ b/src/main/java/com/laytonsmith/abstraction/bukkit/events/drivers/BukkitPlayerListener.java @@ -6,6 +6,7 @@ import com.laytonsmith.abstraction.bukkit.events.BukkitPlayerEvents.BukkitMCExpChangeEvent; import com.laytonsmith.abstraction.bukkit.events.BukkitPlayerEvents.BukkitMCFoodLevelChangeEvent; import com.laytonsmith.abstraction.bukkit.events.BukkitPlayerEvents.BukkitMCGamemodeChangeEvent; +import com.laytonsmith.abstraction.bukkit.events.BukkitPlayerEvents.BukkitMCPlayerAdvancementDoneEvent; import com.laytonsmith.abstraction.bukkit.events.BukkitPlayerEvents.BukkitMCPlayerBucketEmptyEvent; import com.laytonsmith.abstraction.bukkit.events.BukkitPlayerEvents.BukkitMCPlayerBucketFillEvent; import com.laytonsmith.abstraction.bukkit.events.BukkitPlayerEvents.BukkitMCPlayerEnterBedEvent; @@ -40,6 +41,7 @@ import org.bukkit.event.block.Action; import org.bukkit.event.entity.FoodLevelChangeEvent; import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerAdvancementDoneEvent; import org.bukkit.event.player.PlayerBedEnterEvent; import org.bukkit.event.player.PlayerBedLeaveEvent; import org.bukkit.event.player.PlayerBucketEmptyEvent; @@ -385,4 +387,10 @@ public void onBucketEmpty(PlayerBucketEmptyEvent event) { BukkitMCPlayerBucketEmptyEvent pbee = new BukkitMCPlayerBucketEmptyEvent(event); EventUtils.TriggerListener(Driver.PLAYER_BUCKET_EMPTY, "player_bucket_empty", pbee); } + + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerAdvancementDoneEvent(PlayerAdvancementDoneEvent event) { + BukkitMCPlayerAdvancementDoneEvent pade = new BukkitMCPlayerAdvancementDoneEvent(event); + EventUtils.TriggerListener(Driver.PLAYER_ADVANCEMENT_DONE, "player_advancement_done", pade); + } } diff --git a/src/main/java/com/laytonsmith/abstraction/events/MCPlayerAdvancementDoneEvent.java b/src/main/java/com/laytonsmith/abstraction/events/MCPlayerAdvancementDoneEvent.java new file mode 100644 index 000000000..cc516d620 --- /dev/null +++ b/src/main/java/com/laytonsmith/abstraction/events/MCPlayerAdvancementDoneEvent.java @@ -0,0 +1,8 @@ +package com.laytonsmith.abstraction.events; + +import com.laytonsmith.abstraction.MCNamespacedKey; + +public interface MCPlayerAdvancementDoneEvent extends MCPlayerEvent { + MCNamespacedKey getAdvancementKey(); + String getTitle(); +} diff --git a/src/main/java/com/laytonsmith/core/events/drivers/PlayerEvents.java b/src/main/java/com/laytonsmith/core/events/drivers/PlayerEvents.java index ad4f94940..0efb800f2 100644 --- a/src/main/java/com/laytonsmith/core/events/drivers/PlayerEvents.java +++ b/src/main/java/com/laytonsmith/core/events/drivers/PlayerEvents.java @@ -24,6 +24,7 @@ import com.laytonsmith.abstraction.events.MCExpChangeEvent; import com.laytonsmith.abstraction.events.MCFoodLevelChangeEvent; import com.laytonsmith.abstraction.events.MCGamemodeChangeEvent; +import com.laytonsmith.abstraction.events.MCPlayerAdvancementDoneEvent; import com.laytonsmith.abstraction.events.MCPlayerBucketEvent; import com.laytonsmith.abstraction.events.MCPlayerEnterBedEvent; import com.laytonsmith.abstraction.events.MCPlayerLeaveBedEvent; @@ -2894,4 +2895,66 @@ public Driver driver() { return Driver.PLAYER_BUCKET_EMPTY; } } + + @api + public static class player_advancement_done extends AbstractEvent { + + @Override + public String getName() { + return "player_advancement_done"; + } + + @Override + public Driver driver() { + return Driver.PLAYER_ADVANCEMENT_DONE; + } + + @Override + public String docs() { + return "{}" + + " Fires when a player completes all criteria to unlock an advancement or recipe." + + " {player | advancement | title: The advancement display title, if one exists (MC 1.18.2+)}" + + " {}" + + " {}"; + } + + @Override + protected PrefilterBuilder getPrefilterBuilder() { + return new PrefilterBuilder() + .set("advancement", "The namespaced key of the advancement completed", new MacroPrefilterMatcher<>() { + @Override + protected String getProperty(MCPlayerAdvancementDoneEvent event) { + return event.getAdvancementKey().toString(); + } + }); + } + + @Override + public Map evaluate(BindableEvent event) throws EventException { + if(event instanceof MCPlayerAdvancementDoneEvent e) { + Map map = new HashMap<>(); + map.put("player", new CString(e.getPlayer().getName(), Target.UNKNOWN)); + map.put("advancement", new CString(e.getAdvancementKey().toString(), Target.UNKNOWN)); + map.put("title", new CString(e.getTitle(), Target.UNKNOWN)); + return map; + } else { + throw new EventException("Event received was not an MCPlayerAdvancementDoneEvent."); + } + } + + @Override + public boolean modifyEvent(String key, Mixed value, BindableEvent event) { + return false; + } + + @Override + public MSVersion since() { + return MSVersion.V3_3_5; + } + + @Override + public BindableEvent convert(CArray manualObject, Target t) { + return null; + } + } }