diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java index 28d614af0..c56a998aa 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java @@ -19,6 +19,7 @@ import net.momirealms.craftengine.bukkit.compatibility.quickshop.QuickShopItemEx import net.momirealms.craftengine.bukkit.compatibility.region.WorldGuardRegionCondition; import net.momirealms.craftengine.bukkit.compatibility.skript.SkriptHook; import net.momirealms.craftengine.bukkit.compatibility.slimeworld.SlimeFormatStorageAdaptor; +import net.momirealms.craftengine.bukkit.compatibility.tag.CustomNameplateHatSettings; import net.momirealms.craftengine.bukkit.compatibility.tag.CustomNameplateProviders; import net.momirealms.craftengine.bukkit.compatibility.viaversion.ViaVersionUtils; import net.momirealms.craftengine.bukkit.compatibility.worldedit.WorldEditBlockRegister; @@ -97,6 +98,7 @@ public class BukkitCompatibilityManager implements CompatibilityManager { registerTagResolverProvider(new CustomNameplateProviders.Background()); registerTagResolverProvider(new CustomNameplateProviders.Nameplate()); registerTagResolverProvider(new CustomNameplateProviders.Bubble()); + new CustomNameplateHatSettings().register(); logHook("CustomNameplates"); } Key worldGuardRegion = Key.of("worldguard:region"); diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/tag/CustomNameplateHatSettings.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/tag/CustomNameplateHatSettings.java new file mode 100644 index 000000000..232161645 --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/tag/CustomNameplateHatSettings.java @@ -0,0 +1,84 @@ +package net.momirealms.craftengine.bukkit.compatibility.tag; + +import io.papermc.paper.event.entity.EntityEquipmentChangedEvent; +import net.momirealms.craftengine.bukkit.item.BukkitItemManager; +import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; +import net.momirealms.craftengine.core.item.CustomItem; +import net.momirealms.craftengine.core.item.Item; +import net.momirealms.craftengine.core.item.ItemSettings; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.util.CustomDataType; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; +import net.momirealms.craftengine.core.util.VersionHelper; +import net.momirealms.customnameplates.api.CNPlayer; +import net.momirealms.customnameplates.api.CustomNameplates; +import net.momirealms.customnameplates.api.CustomNameplatesAPI; +import net.momirealms.customnameplates.api.feature.tag.TagRenderer; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; + +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +public final class CustomNameplateHatSettings implements Listener { + public static final CustomDataType HAT_HEIGHT = new CustomDataType<>(); + + public void register() { + ItemSettings.Modifiers.registerFactory("hat-height", height -> { + double heightD = ResourceConfigUtils.getAsDouble(height, "hat-height"); + return settings -> settings.addCustomData(HAT_HEIGHT, heightD); + }); + Bukkit.getPluginManager().registerEvents(this, BukkitCraftEngine.instance().javaPlugin()); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void onEquipmentChange(EntityEquipmentChangedEvent event) { + if (!(event.getEntity() instanceof Player player)) return; + Map equipmentChanges = event.getEquipmentChanges(); + EntityEquipmentChangedEvent.EquipmentChange equipmentChange = equipmentChanges.get(EquipmentSlot.HEAD); + if (equipmentChange == null) return; + ItemStack newItem = equipmentChange.newItem(); + updateHatHeight(player, newItem); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onPlayerJoin(PlayerJoinEvent event) { + Player player = event.getPlayer(); + // 稍微延迟一下,可以等待背包同步插件的处理 + if (VersionHelper.isFolia()) { + player.getScheduler().runDelayed(BukkitCraftEngine.instance().javaPlugin(), t1 -> { + if (player.isOnline()) { + updateHatHeight(player, player.getInventory().getItem(EquipmentSlot.HEAD)); + } + }, null, 10); + } else { + CraftEngine.instance().scheduler().sync().runLater(() -> { + if (player.isOnline()) { + updateHatHeight(player, player.getInventory().getItem(EquipmentSlot.HEAD)); + } + }, 10); + } + } + + public void updateHatHeight(Player player, ItemStack newItem) { + CNPlayer cnPlayer = CustomNameplatesAPI.getInstance().getPlayer(player.getUniqueId()); + if (cnPlayer == null) return; + TagRenderer tagRender = CustomNameplates.getInstance().getUnlimitedTagManager().getTagRender(cnPlayer); + if (tagRender == null) return; + Item wrapped = BukkitItemManager.instance().wrap(newItem); + Optional> optionalCustomItem = wrapped.getCustomItem(); + if (optionalCustomItem.isEmpty()) { + tagRender.hatOffset(0d); + return; + } + Double customHeight = optionalCustomItem.get().settings().getCustomData(HAT_HEIGHT); + tagRender.hatOffset(Objects.requireNonNullElse(customHeight, 0d)); + } +}