Add armor stand placement limits per chunk
Implemented functionality to restrict the number of armor stands a player can place in a chunk based on permissions. Added configuration support for customizable limits and proper error handling for edge cases. Registered the LimitArmorStands event listener in the plugin manager.
This commit is contained in:
parent
10449f4a80
commit
7c04361ea5
|
|
@ -5,10 +5,7 @@ import com.alttd.playerutils.commands.playerutils_subcommands.RotateBlock;
|
|||
import com.alttd.playerutils.config.Config;
|
||||
import com.alttd.playerutils.config.KeyStorage;
|
||||
import com.alttd.playerutils.config.Messages;
|
||||
import com.alttd.playerutils.event_listeners.GoatHornEvent;
|
||||
import com.alttd.playerutils.event_listeners.RotateBlockEvent;
|
||||
import com.alttd.playerutils.event_listeners.TeleportEvent;
|
||||
import com.alttd.playerutils.event_listeners.XpBottleEvent;
|
||||
import com.alttd.playerutils.event_listeners.*;
|
||||
import com.alttd.playerutils.util.Logger;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
|
@ -44,6 +41,7 @@ public final class PlayerUtils extends JavaPlugin {
|
|||
pluginManager.registerEvents(new XpBottleEvent(this, logger), this);
|
||||
pluginManager.registerEvents(new TeleportEvent(), this);
|
||||
pluginManager.registerEvents(new GoatHornEvent(logger), this);
|
||||
pluginManager.registerEvents(new LimitArmorStands(this, logger), this);
|
||||
|
||||
RotateBlockEvent rotateBlockEvent = new RotateBlockEvent(logger);
|
||||
pluginManager.registerEvents(rotateBlockEvent, this);
|
||||
|
|
|
|||
|
|
@ -62,4 +62,24 @@ public class Config extends AbstractConfig{
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class ARMOR_STAND_LIMIT {
|
||||
private static final String prefix = "armor_stand_limit.";
|
||||
|
||||
public static HashMap<String, Integer> LIMIT = new HashMap<>();
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static void load() {
|
||||
LIMIT.clear();
|
||||
ConfigurationSection configurationSection = config.getConfigurationSection(prefix.substring(0, prefix.length() - 1));
|
||||
if (configurationSection == null) {
|
||||
config.logger.warning("No limits configured, adding default");
|
||||
config.set(prefix, "default", 10);
|
||||
}
|
||||
Set<String> limits = configurationSection.getKeys(false);
|
||||
for (String key : limits) {
|
||||
LIMIT.put(key, config.getInt(prefix, key, 10));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
package com.alttd.playerutils.event_listeners;
|
||||
|
||||
import com.alttd.playerutils.PlayerUtils;
|
||||
import com.alttd.playerutils.config.Config;
|
||||
import com.alttd.playerutils.util.Logger;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class LimitArmorStands implements Listener {
|
||||
|
||||
private final PlayerUtils playerUtils;
|
||||
private final Logger logger;
|
||||
|
||||
public LimitArmorStands(PlayerUtils playerUtils, Logger logger) {
|
||||
this.playerUtils = playerUtils;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
private interface ArmorStandCountConsumer {
|
||||
void apply(int armorStandCount, @NotNull Player player, @NotNull NamespacedKey namespacedKey,
|
||||
@NotNull PersistentDataContainer persistentDataContainer);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onArmorStandSpawn(PlayerInteractEvent event) {
|
||||
handleArmorStandPlacing(event, (armorStandCount, player, namespacedKey, persistentDataContainer) -> {
|
||||
int max = 0;
|
||||
for (String permission : Config.ARMOR_STAND_LIMIT.LIMIT.keySet()) {
|
||||
if (player.hasPermission("pu.limit." + permission)) {
|
||||
max = Math.max(max, Config.ARMOR_STAND_LIMIT.LIMIT.get(permission));
|
||||
}
|
||||
}
|
||||
if (armorStandCount >= max) {
|
||||
event.setCancelled(true);
|
||||
player.sendRichMessage("<red>You can not place more than <max> armor stands in a chunk</red>",
|
||||
Placeholder.parsed("max", String.valueOf(max)));
|
||||
return;
|
||||
}
|
||||
persistentDataContainer.set(namespacedKey, PersistentDataType.INTEGER, ++armorStandCount);
|
||||
});
|
||||
}
|
||||
|
||||
private void handleArmorStandPlacing(PlayerInteractEvent event, ArmorStandCountConsumer consumer) {
|
||||
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
|
||||
return;
|
||||
}
|
||||
if (!event.getMaterial().equals(Material.ARMOR_STAND)) {
|
||||
return;
|
||||
}
|
||||
if (event.getClickedBlock() == null) {
|
||||
return;
|
||||
}
|
||||
Player player = event.getPlayer();;
|
||||
Chunk chunk = event.getClickedBlock().getChunk();
|
||||
NamespacedKey namespacedKey = NamespacedKey.fromString("armor_stand_count", playerUtils);
|
||||
if (namespacedKey == null) {
|
||||
event.setCancelled(true);
|
||||
logger.warning("Unable to retrieve name spaced key for armor stand count.");
|
||||
player.sendRichMessage("<red>Something went wrong while checking the armor stand count. " +
|
||||
"You will not be able to place this until this is fixed. Please contact a staff member</red>");
|
||||
return;
|
||||
}
|
||||
PersistentDataContainer persistentDataContainer = chunk.getPersistentDataContainer();
|
||||
if (!persistentDataContainer.has(namespacedKey, PersistentDataType.INTEGER)) {
|
||||
persistentDataContainer.set(namespacedKey, PersistentDataType.INTEGER, countArmorStands(chunk));
|
||||
}
|
||||
Integer armorStandCount = persistentDataContainer.get(namespacedKey, PersistentDataType.INTEGER);
|
||||
if (armorStandCount == null) {
|
||||
event.setCancelled(true);
|
||||
logger.warning("Unable to retrieve armor stand count.");
|
||||
player.sendRichMessage("<red>Something went wrong while checking the armor stand count. " +
|
||||
"You will not be able to place this until this is fixed. Please contact a staff member</red>");
|
||||
return;
|
||||
}
|
||||
consumer.apply(armorStandCount, event.getPlayer(), namespacedKey, persistentDataContainer);
|
||||
}
|
||||
|
||||
private int countArmorStands(Chunk chunk) {
|
||||
return (int) Arrays.stream(chunk.getEntities())
|
||||
.filter(entity -> entity.getType().equals(EntityType.ARMOR_STAND))
|
||||
.count();
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user