Implemented a moblimiter (#95)

* Update WhoHasCMD.java

Added functionality that clears all players with a specified item

* Added functionality that clears all players with a specified item

* Altered tab completion to include "clear" argument

* Update WhoHasCMD.java

* Implemented a mob limiter that can be configured via a command

* Fixed some imports

* Refined tab complete

* Implemented reviewed changes

---------

Co-authored-by: Telesphoreo <me@telesphoreo.me>
This commit is contained in:
james
2024-05-31 21:41:14 +01:00
committed by GitHub
parent 5f12a1532f
commit 23611e218b
5 changed files with 139 additions and 0 deletions

View File

@ -0,0 +1,96 @@
package dev.plex.command.impl;
import dev.plex.command.PlexCommand;
import dev.plex.command.annotation.CommandParameters;
import dev.plex.command.annotation.CommandPermissions;
import dev.plex.command.source.RequiredCommandSource;
import dev.plex.util.PlexUtils;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@CommandParameters(name = "moblimit", usage = "/<command> [on/off/setmax <limit>]", aliases = "entitylimit", description = "Manages the mob limit per chunk.")
@CommandPermissions(permission = "plex.moblimit", source = RequiredCommandSource.ANY)
public class MobLimitCMD extends PlexCommand
{
@Override
protected Component execute(@NotNull CommandSender sender, @Nullable Player playerSender, String[] args)
{
if (args.length == 0)
{
Chunk chunk = playerSender != null ? playerSender.getLocation().getChunk() : Bukkit.getWorlds().get(0).getChunkAt(0, 0);
int currentLimit = plugin.config.getInt("entity_limit.max_mobs_per_chunk");
int currentMobCount = (int) Arrays.stream(chunk.getEntities())
.filter(entity -> entity instanceof LivingEntity && !(entity instanceof Player))
.count();
String status = plugin.config.getBoolean("entity_limit.mob_limit_enabled") ? "<green>Enabled" : "<red>Disabled";
return PlexUtils.messageComponent("mobLimitStatus", status, currentMobCount, currentLimit, chunk.getX(), chunk.getZ());
}
switch (args[0].toLowerCase())
{
case "on":
plugin.config.set("entity_limit.mob_limit_enabled", true);
plugin.config.save();
return PlexUtils.messageComponent("mobLimitToggle", "enabled");
case "off":
plugin.config.set("entity_limit.mob_limit_enabled", false);
plugin.config.save();
return PlexUtils.messageComponent("mobLimitToggle", "disabled");
case "setmax":
try
{
if (args.length != 2) return usage();
int newLimit = Integer.parseInt(args[1]);
if (newLimit < 0) throw new NumberFormatException();
int limitCeiling = plugin.config.getInt("entity_limit.mob_limit_ceiling");
if (newLimit > limitCeiling)
{
newLimit = limitCeiling;
sender.sendMessage(PlexUtils.messageComponent("mobLimitCeiling"));
}
plugin.config.set("entity_limit.max_mobs_per_chunk", newLimit);
plugin.config.save();
return PlexUtils.messageComponent("mobLimitSet", newLimit);
}
catch (NumberFormatException e)
{
return PlexUtils.messageComponent("unableToParseNumber", args[1]);
}
default:
return usage();
}
}
@Override
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
if (silentCheckPermission(sender, this.getPermission()))
{
if (args.length == 1)
{
return Arrays.asList("on", "off", "setmax");
}
if (args.length == 2 && args[0].equals("setmax"))
{
return Collections.emptyList();
}
return Collections.emptyList();
}
return Collections.emptyList();
}
}

View File

@ -3,6 +3,7 @@ package dev.plex.listener.impl;
import dev.plex.listener.PlexListener;
import dev.plex.util.BlockUtils;
import dev.plex.util.PlexUtils;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
@ -11,6 +12,7 @@ import org.bukkit.entity.Ageable;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@ -70,6 +72,17 @@ public class MobListener extends PlexListener
Collection<Player> coll = location.getNearbyEntitiesByType(Player.class, 10);
PlexUtils.disabledEffectMultiple(coll.toArray(new Player[coll.size()]), location); // dont let intellij auto correct toArray to an empty array (for efficiency)
}
if (plugin.config.getBoolean("entity_limit.mob_limit_enabled"))
{
Location location = event.getLocation();
Chunk chunk = location.getChunk();
if (isEntityLimitReached(chunk, plugin.config.getInt("entity_limit.max_mobs_per_chunk")))
{
event.setCancelled(true);
}
}
}
@EventHandler
@ -135,4 +148,11 @@ public class MobListener extends PlexListener
}
}
}
public static boolean isEntityLimitReached(Chunk chunk, int limit)
{
return Arrays.stream(chunk.getEntities())
.filter(entity -> entity instanceof LivingEntity && !(entity instanceof Player))
.count() >= limit;
}
}

View File

@ -15,10 +15,12 @@ import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.command.Command;
import org.bukkit.command.PluginCommandYamlParser;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;