basic armor stand edit screen interaction

This commit is contained in:
2025-11-22 15:26:48 +01:00
parent 08a18794eb
commit e6eefc995b
3 changed files with 109 additions and 11 deletions
@@ -1,5 +1,6 @@
package me.youhavetrouble.standin;
import me.youhavetrouble.standin.stand.StandinInteractionListener;
import org.bukkit.NamespacedKey;
import org.bukkit.plugin.java.JavaPlugin;
@@ -9,12 +10,7 @@ public final class StandIn extends JavaPlugin {
@Override
public void onEnable() {
// Plugin startup logic
getServer().getPluginManager().registerEvents(new StandinInteractionListener(), this);
}
@Override
public void onDisable() {
// Plugin shutdown logic
}
}
@@ -8,7 +8,7 @@ import io.papermc.paper.registry.data.dialog.input.DialogInput;
import io.papermc.paper.registry.data.dialog.type.DialogType;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickCallback;
import net.kyori.adventure.util.TriState;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
@@ -30,9 +30,14 @@ public class StandinDialog {
List<DialogInput> inputs = new ArrayList<>();
String currentName = "";
if (armorStand.customName() != null) {
currentName = PlainTextComponentSerializer.plainText().serialize(armorStand.name());
}
inputs.add(
DialogInput.text("name", Component.text("Display name"))
.labelVisible(true)
.initial(currentName)
.build()
);
inputs.add(
@@ -42,8 +47,20 @@ public class StandinDialog {
);
inputs.add(
DialogInput.bool("onFire", Component.text("On fire"))
.initial(Boolean.TRUE.equals(armorStand.getVisualFire().toBoolean()))
DialogInput.bool("basePlate", Component.text("Base plate"))
.initial(armorStand.hasBasePlate())
.build()
);
inputs.add(
DialogInput.bool("arms", Component.text("Arms"))
.initial(armorStand.hasArms())
.build()
);
inputs.add(
DialogInput.bool("small", Component.text("Small"))
.initial(armorStand.isSmall())
.build()
);
@@ -53,8 +70,16 @@ public class StandinDialog {
Entity entity = callbackPlayer.getWorld().getEntity(armorStandId);
if (!(entity instanceof ArmorStand stand)) return;
if (stand.isDead()) return;
String customName = view.getText("name");
if (customName == null || customName.isEmpty()) {
stand.customName(null);
} else {
stand.customName(Component.text(customName));
}
stand.setInvisible(Boolean.TRUE.equals(view.getBoolean("invisible")));
stand.setVisualFire(TriState.byBoolean(Boolean.TRUE.equals(view.getBoolean("onFire"))));
stand.setBasePlate(Boolean.TRUE.equals(view.getBoolean("basePlate")));
stand.setArms(Boolean.TRUE.equals(view.getBoolean("arms")));
stand.setSmall(Boolean.TRUE.equals(view.getBoolean("small")));
}, ClickCallback.Options.builder().lifetime(Duration.ofHours(1)).uses(1).build())
).build();
@@ -0,0 +1,77 @@
package me.youhavetrouble.standin.stand;
import me.youhavetrouble.standin.StandinDialog;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeInstance;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
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.PlayerInteractAtEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.util.RayTraceResult;
import org.jetbrains.annotations.NotNull;
public class StandinInteractionListener implements Listener {
private boolean handleInteraction(@NotNull Player player, Entity entity) {
if (entity == null) return false;
if (!player.isOnline()) return false;
if (entity instanceof ArmorStand armorStand) {
StandinDialog.openArmorStandDialog(player, armorStand);
return true;
}
return false;
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = false)
public void onInteractWithDisplays(PlayerInteractEvent event) {
if (!event.getPlayer().isSneaking()) return;
if (event.getHand() == EquipmentSlot.OFF_HAND) return;
Player player = event.getPlayer();
AttributeInstance instance = player.getAttribute(Attribute.ENTITY_INTERACTION_RANGE);
if (instance == null) return;
double interactionRange = instance.getValue();
RayTraceResult result = player.getWorld().rayTraceEntities(
player.getEyeLocation(),
player.getEyeLocation().getDirection(),
interactionRange,
0.5,
(entity -> {
switch (entity.getType()) {
case TEXT_DISPLAY,
BLOCK_DISPLAY,
ITEM_DISPLAY -> {
if (entity.getVehicle() == null) return true;
return !player.getUniqueId().equals(entity.getVehicle().getUniqueId());
}
default -> {
return false;
}
}
})
);
if (result == null) return;
Entity entity = result.getHitEntity();
if (!handleInteraction(player, entity)) return;
event.setCancelled(true);
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onInteractWithStands(PlayerInteractAtEntityEvent event) {
if (!event.getPlayer().isSneaking()) return;
if (!handleInteraction(event.getPlayer(), event.getRightClicked())) return;
event.setCancelled(true);
}
}