diff --git a/README.MD b/README.MD index 33bec11..28c0c16 100644 --- a/README.MD +++ b/README.MD @@ -46,6 +46,12 @@ Automatically smelts drops from mined blocks. **Description**: Reduces damage from hitting a wall while flying with elytra. +### Homecoming +**Translation key**: `enchantio.enchantment.homecoming` + +**Description**: +When totem of undying is activated, player is teleported to their spawn point. If spawn point is not set, player is teleported to world spawn. + ## Curses ### Curse of Panic diff --git a/src/main/java/me/youhavetrouble/enchantio/Enchantio.java b/src/main/java/me/youhavetrouble/enchantio/Enchantio.java index 28152a2..1d0762b 100644 --- a/src/main/java/me/youhavetrouble/enchantio/Enchantio.java +++ b/src/main/java/me/youhavetrouble/enchantio/Enchantio.java @@ -37,6 +37,9 @@ public final class Enchantio extends JavaPlugin { if (EnchantioConfig.ENCHANTS.containsKey(AirbagEnchant.KEY)) { getServer().getPluginManager().registerEvents(new AirbagListener(), this); } + if (EnchantioConfig.ENCHANTS.containsKey(HomecomingEnchant.KEY)) { + getServer().getPluginManager().registerEvents(new HomecomingListener(), this); + } if (EnchantioConfig.ENCHANTS.containsKey(PanicEnchant.KEY)) { getServer().getPluginManager().registerEvents(new PanicListener(), this); diff --git a/src/main/java/me/youhavetrouble/enchantio/EnchantioConfig.java b/src/main/java/me/youhavetrouble/enchantio/EnchantioConfig.java index 3487b40..3039121 100644 --- a/src/main/java/me/youhavetrouble/enchantio/EnchantioConfig.java +++ b/src/main/java/me/youhavetrouble/enchantio/EnchantioConfig.java @@ -292,6 +292,36 @@ public class EnchantioConfig { ENCHANTS.put(AirbagEnchant.KEY, airbagEnchant); } + ConfigurationSection homecomingSection = enchantsSection.getConfigurationSection("homecoming"); + if (homecomingSection == null) { + homecomingSection = enchantsSection.createSection("homecoming"); + } + + HomecomingEnchant homecomingEnchant = new HomecomingEnchant( + getInt(homecomingSection, "anvilCost", 1), + getInt(homecomingSection, "weight", 10), + EnchantmentRegistryEntry.EnchantmentCost.of( + getInt(homecomingSection, "minimumCost.base", 40), + getInt(homecomingSection, "minimumCost.additionalPerLevel", 3) + ), + EnchantmentRegistryEntry.EnchantmentCost.of( + getInt(homecomingSection, "maximumCost.base", 65), + getInt(homecomingSection, "maximumCost.additionalPerLevel", 1) + ), + getBoolean(homecomingSection, "canGetFromEnchantingTable", true), + getTagsFromList(getStringList( + homecomingSection, + "supportedItemTags", + List.of( + "minecraft:totem_of_undying" + ) + )) + ); + + if (getBoolean(homecomingSection, "enabled", true)) { + ENCHANTS.put(HomecomingEnchant.KEY, homecomingEnchant); + } + ConfigurationSection cursesSection = configuration.getConfigurationSection("curses"); if (cursesSection == null) { cursesSection = configuration.createSection("curses"); diff --git a/src/main/java/me/youhavetrouble/enchantio/enchants/HomecomingEnchant.java b/src/main/java/me/youhavetrouble/enchantio/enchants/HomecomingEnchant.java new file mode 100644 index 0000000..a486b6e --- /dev/null +++ b/src/main/java/me/youhavetrouble/enchantio/enchants/HomecomingEnchant.java @@ -0,0 +1,97 @@ +package me.youhavetrouble.enchantio.enchants; + +import io.papermc.paper.registry.data.EnchantmentRegistryEntry; +import io.papermc.paper.registry.keys.tags.EnchantmentTagKeys; +import io.papermc.paper.registry.tag.TagKey; +import io.papermc.paper.tag.TagEntry; +import net.kyori.adventure.key.Key; +import net.kyori.adventure.text.Component; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.EquipmentSlotGroup; +import org.bukkit.inventory.ItemType; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +@SuppressWarnings("UnstableApiUsage") +public class HomecomingEnchant implements EnchantioEnchant { + + public static final Key KEY = Key.key("enchantio:homecoming"); + + private final int anvilCost, weight; + private final EnchantmentRegistryEntry.EnchantmentCost minimumCost; + private final EnchantmentRegistryEntry.EnchantmentCost maximumCost; + private final Set> supportedItemTags; + private final Set> enchantTagKeys = new HashSet<>(); + + public HomecomingEnchant( + int anvilCost, + int weight, + EnchantmentRegistryEntry.EnchantmentCost minimumCost, + EnchantmentRegistryEntry.EnchantmentCost maximumCost, + boolean canGetFromEnchantingTable, + Set> supportedItemTags + ) { + this.anvilCost = anvilCost; + this.weight = weight; + this.minimumCost = minimumCost; + this.maximumCost = maximumCost; + this.supportedItemTags = supportedItemTags; + if (canGetFromEnchantingTable) { + enchantTagKeys.add(EnchantmentTagKeys.IN_ENCHANTING_TABLE); + } + } + + @Override + public @NotNull Key getKey() { + return KEY; + } + + @Override + public @NotNull Component getDescription() { + return Component.translatable("enchantio.enchant.homecoming", "Homecoming"); + } + + @Override + public int getAnvilCost() { + return anvilCost; + } + + @Override + public int getMaxLevel() { + return 1; + } + + @Override + public int getWeight() { + return weight; + } + + @Override + public EnchantmentRegistryEntry.@NotNull EnchantmentCost getMinimumCost() { + return minimumCost; + } + + @Override + public EnchantmentRegistryEntry.@NotNull EnchantmentCost getMaximumCost() { + return maximumCost; + } + + @Override + public @NotNull Iterable getActiveSlots() { + return Set.of(EquipmentSlotGroup.HAND); + } + + @Override + public @NotNull Set> getSupportedItems() { + return supportedItemTags; + } + + @Override + public @NotNull Set> getEnchantTagKeys() { + return Collections.unmodifiableSet(enchantTagKeys); + } + +} diff --git a/src/main/java/me/youhavetrouble/enchantio/events/HomecomingEvent.java b/src/main/java/me/youhavetrouble/enchantio/events/HomecomingEvent.java new file mode 100644 index 0000000..816c249 --- /dev/null +++ b/src/main/java/me/youhavetrouble/enchantio/events/HomecomingEvent.java @@ -0,0 +1,58 @@ +package me.youhavetrouble.enchantio.events; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.jetbrains.annotations.NotNull; + +public class HomecomingEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList HANDLERS = new HandlerList(); + + private boolean cancelled = false; + private Location location; + + public HomecomingEvent(@NotNull Player who, @NotNull Location location) { + super(who); + this.location = location; + } + + @Override + public @NotNull HandlerList getHandlers() { + return HANDLERS; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + /** + * Get the location the player is being teleported to. + * @return the location the player is being teleported to + */ + public @NotNull Location getLocation() { + return location; + } + + /** + * Set the location the player is being teleported to. + * @param location the location the player is being teleported to + */ + public void setLocation(@NotNull Location location) { + this.location = location; + } + + @NotNull + public static HandlerList getHandlerList() { + return HANDLERS; + } + +} diff --git a/src/main/java/me/youhavetrouble/enchantio/listeners/HomecomingListener.java b/src/main/java/me/youhavetrouble/enchantio/listeners/HomecomingListener.java new file mode 100644 index 0000000..8d9bf0a --- /dev/null +++ b/src/main/java/me/youhavetrouble/enchantio/listeners/HomecomingListener.java @@ -0,0 +1,55 @@ +package me.youhavetrouble.enchantio.listeners; + +import io.papermc.paper.registry.RegistryAccess; +import io.papermc.paper.registry.RegistryKey; +import me.youhavetrouble.enchantio.enchants.HomecomingEnchant; +import me.youhavetrouble.enchantio.events.HomecomingEvent; +import org.bukkit.Location; +import org.bukkit.Registry; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityResurrectEvent; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; + +public class HomecomingListener implements Listener { + + private final Registry registry = RegistryAccess.registryAccess().getRegistry(RegistryKey.ENCHANTMENT); + private final Enchantment homecoming = registry.get(HomecomingEnchant.KEY); + + @EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL) + public void onHomecoming(EntityResurrectEvent event) { + if (homecoming == null) return; + + if (!(event.getEntity() instanceof Player player)) return; + + EquipmentSlot equipmentSlot = event.getHand(); + if (equipmentSlot == null) return; + + EntityEquipment entityEquipment = event.getEntity().getEquipment(); + if (entityEquipment == null) return; + + ItemStack item = entityEquipment.getItem(equipmentSlot); + + if (!item.containsEnchantment(homecoming)) return; + + Location location = player.getRespawnLocation(); + + if (location == null) { + location = player.getWorld().getSpawnLocation(); + } + + HomecomingEvent homecomingEvent = new HomecomingEvent(player, location); + player.getServer().getPluginManager().callEvent(homecomingEvent); + if (homecomingEvent.isCancelled()) return; + + player.teleportAsync(homecomingEvent.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); + + } + +}