package me.youhavetrouble.standin.entity; import io.papermc.paper.datacomponent.item.ResolvableProfile; import io.papermc.paper.dialog.Dialog; import io.papermc.paper.registry.data.dialog.ActionButton; import io.papermc.paper.registry.data.dialog.DialogBase; import io.papermc.paper.registry.data.dialog.action.DialogAction; import io.papermc.paper.registry.data.dialog.input.DialogInput; import io.papermc.paper.registry.data.dialog.type.DialogType; import me.youhavetrouble.standin.converter.EntityConverter; import me.youhavetrouble.standin.converter.MannequinToArmorStandConverter; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.event.ClickCallback; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Entity; import org.bukkit.entity.Mannequin; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import java.time.Duration; import java.util.ArrayList; import java.util.List; import java.util.UUID; @SuppressWarnings("UnstableApiUsage") public class MannequinHandler extends EntityHandler { public MannequinHandler() { super(Mannequin.class); addConverter(new MannequinToArmorStandConverter()); } public Dialog editDialog(@NotNull Player player, Mannequin mannequin) { if (mannequin == null || mannequin.isDead()) return null; if (!canUseAction(player, mannequin, EntityAction.EDIT)) return null; UUID entityId = mannequin.getUniqueId(); UUID playerId = player.getUniqueId(); List inputs = new ArrayList<>(); String name = EntityConverter.getRawEntityName(mannequin); if (name == null) { name = ""; } inputs.add( DialogInput.text("name", Component.text("Name")) .initial(name) .maxLength(1024) .build() ); String profileName = ""; if (mannequin.getProfile().name() != null) { profileName = mannequin.getProfile().name(); } inputs.add( DialogInput.text("profile", Component.text("Skin Profile (Mojang Username)")) .initial(profileName) .build() ); inputs.add( DialogInput.bool("immovable", Component.text("Immovable")) .initial(mannequin.isImmovable()) .build() ); inputs.add( DialogInput.bool("invulnerable", Component.text("Invulnerable")) .initial(mannequin.isInvulnerable()) .build() ); inputs.add( DialogInput.bool("gravity", Component.text("Gravity")) .initial(mannequin.hasGravity()) .build() ); List actions = new ArrayList<>(); ActionButton saveButton = ActionButton.builder(Component.text("Save")).action( DialogAction.customClick((view, audience) -> { if (!(audience instanceof Player callbackPlayer)) return; if (playerId != callbackPlayer.getUniqueId()) return; Entity entity = callbackPlayer.getWorld().getEntity(entityId); if (!(entity instanceof Mannequin mann)) return; if (!canUseAction(callbackPlayer, mann, EntityAction.EDIT)) return; if (mann.isDead()) return; String newName = view.getText("name"); if (newName != null && !newName.isBlank()) { Component displayName = MiniMessage.miniMessage().deserialize(newName); mann.customName(displayName); } else { mann.customName(null); } EntityConverter.saveRawEntityName(mann, newName); mann.setImmovable(Boolean.TRUE.equals(view.getBoolean("immovable"))); mann.setVelocity(mann.getVelocity().zero()); mann.setGravity(Boolean.TRUE.equals(view.getBoolean("gravity"))); mann.setInvulnerable(Boolean.TRUE.equals(view.getBoolean("invulnerable"))); try { String newProfileName = view.getText("profile"); if (newProfileName == null || newProfileName.isBlank()) { newProfileName = null; } mann.setProfile(ResolvableProfile.resolvableProfile().name(newProfileName).build()); } catch (IllegalArgumentException e) { callbackPlayer.sendRichMessage("Profile name not updated: invalid username."); } }, ClickCallback.Options.builder().lifetime(Duration.ofMinutes(5)).uses(1).build()) ).build(); actions.add(saveButton); if (player.hasPermission("standin.change_type.armor_stand")) { ActionButton changeTypeButton = ActionButton.builder(Component.text("Change type")) .action( DialogAction.customClick((view, audience) -> { if (!(audience instanceof Player callbackPlayer)) return; if (playerId != callbackPlayer.getUniqueId()) return; Entity entity = callbackPlayer.getWorld().getEntity(entityId); if (!(entity instanceof Mannequin mann)) return; Dialog dialog = conversionDialog(callbackPlayer, mann); if (dialog == null) return; callbackPlayer.showDialog(dialog); }, ClickCallback.Options.builder().lifetime(Duration.ofMinutes(5)).uses(1).build() ) ).build(); actions.add(changeTypeButton); } return Dialog.create(builder -> builder.empty() .base( DialogBase.builder(Component.text("Armor Stand Editor")) .inputs(inputs) .build() ).type( DialogType.multiAction( actions, ActionButton.builder(Component.text("Cancel")).build(), 1) ) ); } }