Initial RS-MobStand commit
This commit is contained in:
commit
73f9d3a155
27 files changed
+5203
No files matched your search
@@ -0,0 +1,94 @@
|
||||
package com.rsscripting.mobstand;
|
||||
|
||||
import com.rsscripting.mobstand.commands.RSMSCommand;
|
||||
import com.rsscripting.mobstand.commands.RSMSTabCompleter;
|
||||
import com.rsscripting.mobstand.tasks.SlaughterTask;
|
||||
import com.rsscripting.mobstand.config.ConfigManager;
|
||||
import com.rsscripting.mobstand.listeners.ChunkLoadListener;
|
||||
import com.rsscripting.mobstand.listeners.ArmorStandBreakListener;
|
||||
import com.rsscripting.mobstand.listeners.ArmorStandListener;
|
||||
import com.rsscripting.mobstand.listeners.MenuListener;
|
||||
import com.rsscripting.mobstand.managers.StandManager;
|
||||
import com.rsscripting.mobstand.utils.VersionChecker;
|
||||
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class RSMobStandPlugin extends JavaPlugin {
|
||||
|
||||
private StandManager standManager;
|
||||
private ConfigManager configManager;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
|
||||
saveDefaultConfig();
|
||||
|
||||
this.standManager = new StandManager(this);
|
||||
|
||||
this.configManager = new ConfigManager(this);
|
||||
|
||||
getCommand("rsms").setExecutor(
|
||||
new RSMSCommand(this)
|
||||
);
|
||||
|
||||
getCommand("rsms").setTabCompleter(
|
||||
new RSMSTabCompleter()
|
||||
);
|
||||
|
||||
getServer().getPluginManager().registerEvents(
|
||||
new ArmorStandListener(
|
||||
this,
|
||||
standManager
|
||||
),
|
||||
this
|
||||
);
|
||||
|
||||
getServer().getPluginManager().registerEvents(
|
||||
new ArmorStandBreakListener(this),
|
||||
this
|
||||
);
|
||||
|
||||
getServer().getPluginManager().registerEvents(
|
||||
new MenuListener(this),
|
||||
this
|
||||
);
|
||||
|
||||
long scanInterval = getConfig().getLong("scan-interval");
|
||||
|
||||
new SlaughterTask(this).runTaskTimer(
|
||||
this,
|
||||
20L,
|
||||
scanInterval
|
||||
);
|
||||
|
||||
getServer().getPluginManager().registerEvents(
|
||||
new ChunkLoadListener(standManager),
|
||||
this
|
||||
);
|
||||
|
||||
new VersionChecker(this).checkVersion();
|
||||
|
||||
getLogger().info("RS Mob Stand enabled.");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
|
||||
getLogger().info("RS Mob Stand disabled.");
|
||||
|
||||
}
|
||||
|
||||
public StandManager getStandManager() {
|
||||
|
||||
return standManager;
|
||||
|
||||
}
|
||||
|
||||
public ConfigManager getConfigManager() {
|
||||
|
||||
return configManager;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.rsscripting.mobstand.commands;
|
||||
|
||||
import com.rsscripting.mobstand.RSMobStandPlugin;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public class RSMSCommand implements CommandExecutor {
|
||||
|
||||
private final RSMobStandPlugin plugin;
|
||||
|
||||
public RSMSCommand(
|
||||
RSMobStandPlugin plugin
|
||||
) {
|
||||
|
||||
this.plugin = plugin;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(
|
||||
CommandSender sender,
|
||||
Command command,
|
||||
String label,
|
||||
String[] args
|
||||
) {
|
||||
|
||||
if (!sender.hasPermission(
|
||||
"rsmobstand.admin"
|
||||
)) {
|
||||
|
||||
sender.sendMessage(
|
||||
ChatColor.RED
|
||||
+ "You do not have permission."
|
||||
);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
if (args.length == 0) {
|
||||
|
||||
sender.sendMessage(
|
||||
ChatColor.YELLOW
|
||||
+ "/rsms reload"
|
||||
);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
if (args[0].equalsIgnoreCase(
|
||||
"reload"
|
||||
)) {
|
||||
|
||||
plugin.reloadConfig();
|
||||
|
||||
plugin.getConfigManager()
|
||||
.loadConfigs();
|
||||
|
||||
sender.sendMessage(
|
||||
ChatColor.GREEN
|
||||
+ "RS MobStand configuration reloaded."
|
||||
);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
sender.sendMessage(
|
||||
ChatColor.RED
|
||||
+ "Unknown subcommand."
|
||||
);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.rsscripting.mobstand.commands;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class RSMSTabCompleter implements TabCompleter {
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(
|
||||
CommandSender sender,
|
||||
Command command,
|
||||
String alias,
|
||||
String[] args
|
||||
) {
|
||||
|
||||
List<String> completions =
|
||||
new ArrayList<>();
|
||||
|
||||
if (args.length == 1) {
|
||||
|
||||
completions.add("reload");
|
||||
|
||||
}
|
||||
|
||||
return completions;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
package com.rsscripting.mobstand.config;
|
||||
|
||||
import com.rsscripting.mobstand.RSMobStandPlugin;
|
||||
import com.rsscripting.mobstand.data.MobFilterData;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ConfigManager {
|
||||
|
||||
private final RSMobStandPlugin plugin;
|
||||
|
||||
private final Map<String, MobFilterData> adultMobData =
|
||||
new HashMap<>();
|
||||
|
||||
private final Map<String, MobFilterData> babyMobData =
|
||||
new HashMap<>();
|
||||
|
||||
private FileConfiguration adultConfig;
|
||||
|
||||
private FileConfiguration babyConfig;
|
||||
|
||||
public ConfigManager(RSMobStandPlugin plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
|
||||
loadConfigs();
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Loads all plugin configs.
|
||||
|
||||
public void loadConfigs() {
|
||||
|
||||
File configFolder = new File(
|
||||
plugin.getDataFolder(),
|
||||
"configs"
|
||||
);
|
||||
|
||||
if (!configFolder.exists()) {
|
||||
|
||||
if (!configFolder.mkdirs()) {
|
||||
|
||||
plugin.getLogger().warning(
|
||||
"Failed to create configs folder."
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
loadAdultConfig();
|
||||
loadAdultMobData();
|
||||
|
||||
loadBabyConfig();
|
||||
loadBabyMobData();
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Loads adult mob config.
|
||||
|
||||
private void loadAdultConfig() {
|
||||
|
||||
File file = new File(
|
||||
plugin.getDataFolder(),
|
||||
"configs/adult-mobs.yml"
|
||||
);
|
||||
|
||||
if (!file.exists()) {
|
||||
|
||||
plugin.saveResource("configs/adult-mobs.yml", false);
|
||||
|
||||
}
|
||||
|
||||
adultConfig = YamlConfiguration.loadConfiguration(file);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Loads baby mob config.
|
||||
|
||||
private void loadBabyConfig() {
|
||||
|
||||
File file = new File(
|
||||
plugin.getDataFolder(),
|
||||
"configs/baby-mobs.yml"
|
||||
);
|
||||
|
||||
if (!file.exists()) {
|
||||
|
||||
plugin.saveResource("configs/baby-mobs.yml", false);
|
||||
|
||||
}
|
||||
|
||||
babyConfig = YamlConfiguration.loadConfiguration(file);
|
||||
|
||||
}
|
||||
|
||||
// Gets allowed adult mobs.
|
||||
|
||||
public void loadBabyMobData() {
|
||||
|
||||
babyMobData.clear();
|
||||
|
||||
ConfigurationSection section =
|
||||
babyConfig.getConfigurationSection(
|
||||
"baby-mobs"
|
||||
);
|
||||
|
||||
if (section == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (String mobName : section.getKeys(false)) {
|
||||
|
||||
String path =
|
||||
"baby-mobs." + mobName;
|
||||
|
||||
String iconName =
|
||||
babyConfig.getString(
|
||||
path + ".icon"
|
||||
);
|
||||
|
||||
boolean enabled =
|
||||
babyConfig.getBoolean(
|
||||
path + ".enabled-by-default"
|
||||
);
|
||||
|
||||
boolean killAll =
|
||||
babyConfig.getBoolean(
|
||||
path + ".kill-all",
|
||||
false
|
||||
);
|
||||
|
||||
if (iconName == null) {
|
||||
|
||||
plugin.getLogger().warning(
|
||||
"Missing icon for mob: "
|
||||
+ mobName
|
||||
);
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
Material icon =
|
||||
Material.matchMaterial(iconName);
|
||||
|
||||
if (icon == null) {
|
||||
|
||||
plugin.getLogger().warning(
|
||||
"Invalid icon material for mob: "
|
||||
+ mobName
|
||||
);
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
babyMobData.put(
|
||||
mobName,
|
||||
new MobFilterData(
|
||||
icon,
|
||||
enabled,
|
||||
killAll
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Gets allowed adult mobs.
|
||||
|
||||
public void loadAdultMobData() {
|
||||
|
||||
adultMobData.clear();
|
||||
|
||||
ConfigurationSection section =
|
||||
adultConfig.getConfigurationSection(
|
||||
"adult-mobs"
|
||||
);
|
||||
|
||||
if (section == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (String mobName : section.getKeys(false)) {
|
||||
|
||||
String path =
|
||||
"adult-mobs." + mobName;
|
||||
|
||||
String iconName =
|
||||
adultConfig.getString(
|
||||
path + ".icon"
|
||||
);
|
||||
|
||||
boolean enabled =
|
||||
adultConfig.getBoolean(
|
||||
path + ".enabled-by-default"
|
||||
);
|
||||
|
||||
boolean killAll =
|
||||
adultConfig.getBoolean(
|
||||
path + ".kill-all",
|
||||
false
|
||||
);
|
||||
|
||||
if (iconName == null) {
|
||||
|
||||
plugin.getLogger().warning(
|
||||
"Missing icon for mob: "
|
||||
+ mobName
|
||||
);
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
Material icon =
|
||||
Material.matchMaterial(iconName);
|
||||
|
||||
if (icon == null) {
|
||||
|
||||
plugin.getLogger().warning(
|
||||
"Invalid icon material for mob: "
|
||||
+ mobName
|
||||
);
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
adultMobData.put(
|
||||
mobName,
|
||||
new MobFilterData(
|
||||
icon,
|
||||
enabled,
|
||||
killAll
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Gets allowed baby mobs.
|
||||
|
||||
public List<String> getBabyMobs() {
|
||||
|
||||
return babyConfig.getStringList("baby-mobs");
|
||||
|
||||
}
|
||||
|
||||
public Map<String, MobFilterData> getAdultMobData() {
|
||||
|
||||
return adultMobData;
|
||||
|
||||
}
|
||||
|
||||
public Map<String, MobFilterData> getBabyMobData() {
|
||||
|
||||
return babyMobData;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.rsscripting.mobstand.data;
|
||||
|
||||
import org.bukkit.Material;
|
||||
|
||||
public class MobFilterData {
|
||||
|
||||
private final Material icon;
|
||||
|
||||
private final boolean enabledByDefault;
|
||||
|
||||
private final boolean killAll;
|
||||
|
||||
public MobFilterData(
|
||||
Material icon,
|
||||
boolean enabledByDefault,
|
||||
boolean killAll
|
||||
) {
|
||||
|
||||
this.icon = icon;
|
||||
|
||||
this.enabledByDefault = enabledByDefault;
|
||||
|
||||
this.killAll = killAll;
|
||||
|
||||
}
|
||||
|
||||
public Material getIcon() {
|
||||
|
||||
return icon;
|
||||
|
||||
}
|
||||
|
||||
public boolean isKillAll() {
|
||||
|
||||
return killAll;
|
||||
|
||||
}
|
||||
|
||||
public boolean isEnabledByDefault() {
|
||||
|
||||
return enabledByDefault;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,326 @@
|
||||
package com.rsscripting.mobstand.gui;
|
||||
|
||||
import com.rsscripting.mobstand.RSMobStandPlugin;
|
||||
import com.rsscripting.mobstand.data.MobFilterData;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AdultFilterMenu {
|
||||
|
||||
public static final String MENU_TITLE =
|
||||
ChatColor.BLUE + "Adult Filters";
|
||||
|
||||
private static final int ITEMS_PER_PAGE = 45;
|
||||
|
||||
public static void open(
|
||||
RSMobStandPlugin plugin,
|
||||
Player player,
|
||||
ArmorStand armorStand,
|
||||
int page
|
||||
) {
|
||||
|
||||
Map<String, MobFilterData> mobData =
|
||||
plugin.getConfigManager()
|
||||
.getAdultMobData();
|
||||
|
||||
List<String> mobs =
|
||||
new ArrayList<>(mobData.keySet());
|
||||
|
||||
Collections.sort(mobs);
|
||||
|
||||
List<String> disabledMobs =
|
||||
plugin.getStandManager()
|
||||
.getDisabledAdultMobs(
|
||||
armorStand
|
||||
);
|
||||
|
||||
int startIndex =
|
||||
page * ITEMS_PER_PAGE;
|
||||
|
||||
int endIndex =
|
||||
Math.min(
|
||||
startIndex + ITEMS_PER_PAGE,
|
||||
mobs.size()
|
||||
);
|
||||
|
||||
int visibleItemCount =
|
||||
endIndex - startIndex;
|
||||
|
||||
int contentRows =
|
||||
(int) Math.ceil(
|
||||
visibleItemCount / 9.0
|
||||
);
|
||||
|
||||
contentRows =
|
||||
Math.max(contentRows, 1);
|
||||
|
||||
int totalRows =
|
||||
contentRows + 1;
|
||||
|
||||
int inventorySize =
|
||||
totalRows * 9;
|
||||
|
||||
Inventory inventory =
|
||||
Bukkit.createInventory(
|
||||
new RSMenuHolder(
|
||||
"ADULTFILTER"
|
||||
),
|
||||
inventorySize,
|
||||
MENU_TITLE
|
||||
+ " (Page "
|
||||
+ (page + 1)
|
||||
+ ")"
|
||||
);
|
||||
|
||||
ItemStack filler =
|
||||
new ItemStack(Material.WHITE_STAINED_GLASS_PANE);
|
||||
|
||||
ItemMeta fillerMeta =
|
||||
filler.getItemMeta();
|
||||
|
||||
if (fillerMeta != null) {
|
||||
|
||||
fillerMeta.setDisplayName(" ");
|
||||
|
||||
filler.setItemMeta(fillerMeta);
|
||||
|
||||
}
|
||||
|
||||
for (int i = 0; i < inventory.getSize(); i++) {
|
||||
|
||||
inventory.setItem(i, filler);
|
||||
|
||||
}
|
||||
|
||||
List<ItemStack> filterItems =
|
||||
new ArrayList<>();
|
||||
|
||||
for (int i = startIndex; i < endIndex; i++) {
|
||||
|
||||
String mobName = mobs.get(i);
|
||||
|
||||
MobFilterData data =
|
||||
mobData.get(mobName);
|
||||
|
||||
boolean forcedEnabled =
|
||||
data.isKillAll();
|
||||
|
||||
boolean enabled =
|
||||
forcedEnabled
|
||||
|| !disabledMobs.contains(
|
||||
mobName
|
||||
);
|
||||
|
||||
ItemStack item =
|
||||
new ItemStack(
|
||||
enabled
|
||||
? data.getIcon()
|
||||
: Material.RED_STAINED_GLASS_PANE
|
||||
);
|
||||
|
||||
ItemMeta meta =
|
||||
item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
|
||||
meta.setDisplayName(
|
||||
enabled
|
||||
? ChatColor.GREEN + mobName
|
||||
: ChatColor.YELLOW
|
||||
+ mobName
|
||||
+ " (Disabled)"
|
||||
);
|
||||
|
||||
java.util.List<String> lore =
|
||||
new java.util.ArrayList<>();
|
||||
|
||||
if (forcedEnabled) {
|
||||
|
||||
lore.add(
|
||||
ChatColor.YELLOW
|
||||
+ "Overridden by Server Admin"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
meta.setLore(lore);
|
||||
|
||||
item.setItemMeta(meta);
|
||||
|
||||
}
|
||||
|
||||
filterItems.add(item);
|
||||
|
||||
}
|
||||
|
||||
int currentRow = 0;
|
||||
int rowStart = 0;
|
||||
|
||||
while (rowStart < filterItems.size()) {
|
||||
|
||||
int remainingItems =
|
||||
filterItems.size() - rowStart;
|
||||
|
||||
int itemsThisRow =
|
||||
Math.min(9, remainingItems);
|
||||
|
||||
boolean isLastPartialRow =
|
||||
itemsThisRow < 9;
|
||||
|
||||
int rowBaseSlot =
|
||||
currentRow * 9;
|
||||
|
||||
List<Integer> rowSlots =
|
||||
new ArrayList<>();
|
||||
|
||||
if (isLastPartialRow) {
|
||||
|
||||
if (itemsThisRow % 2 == 0) {
|
||||
|
||||
switch (itemsThisRow) {
|
||||
|
||||
case 2 -> rowSlots = List.of(3, 5);
|
||||
|
||||
case 4 -> rowSlots = List.of(2, 3, 5, 6);
|
||||
|
||||
case 6 -> rowSlots = List.of(1, 2, 3, 5, 6, 7);
|
||||
|
||||
case 8 -> rowSlots = List.of(0, 1, 2, 3, 5, 6, 7, 8);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
int startSlot =
|
||||
(9 - itemsThisRow) / 2;
|
||||
|
||||
for (int i = 0; i < itemsThisRow; i++) {
|
||||
|
||||
rowSlots.add(startSlot + i);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
|
||||
rowSlots.add(i);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (int i = 0; i < itemsThisRow; i++) {
|
||||
|
||||
inventory.setItem(
|
||||
rowBaseSlot + rowSlots.get(i),
|
||||
filterItems.get(rowStart + i)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
rowStart += itemsThisRow;
|
||||
currentRow++;
|
||||
|
||||
}
|
||||
|
||||
int navigationRow =
|
||||
inventorySize - 9;
|
||||
|
||||
// Previous page
|
||||
if (page > 0) {
|
||||
|
||||
ItemStack previous =
|
||||
new ItemStack(Material.ARROW);
|
||||
|
||||
ItemMeta previousMeta =
|
||||
previous.getItemMeta();
|
||||
|
||||
if (previousMeta != null) {
|
||||
|
||||
previousMeta.setDisplayName(
|
||||
ChatColor.YELLOW
|
||||
+ "Previous Page"
|
||||
);
|
||||
|
||||
previous.setItemMeta(previousMeta);
|
||||
|
||||
}
|
||||
|
||||
inventory.setItem(
|
||||
navigationRow,
|
||||
previous
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Back button
|
||||
ItemStack back =
|
||||
new ItemStack(Material.OAK_DOOR);
|
||||
|
||||
ItemMeta backMeta =
|
||||
back.getItemMeta();
|
||||
|
||||
if (backMeta != null) {
|
||||
|
||||
backMeta.setDisplayName(
|
||||
ChatColor.YELLOW + "Back"
|
||||
);
|
||||
|
||||
back.setItemMeta(backMeta);
|
||||
|
||||
}
|
||||
|
||||
inventory.setItem(
|
||||
navigationRow + 4,
|
||||
back
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Next page
|
||||
if (endIndex < mobs.size()) {
|
||||
|
||||
ItemStack next =
|
||||
new ItemStack(Material.ARROW);
|
||||
|
||||
ItemMeta nextMeta =
|
||||
next.getItemMeta();
|
||||
|
||||
if (nextMeta != null) {
|
||||
|
||||
nextMeta.setDisplayName(
|
||||
ChatColor.YELLOW
|
||||
+ "Next Page"
|
||||
);
|
||||
|
||||
next.setItemMeta(nextMeta);
|
||||
|
||||
}
|
||||
|
||||
inventory.setItem(
|
||||
navigationRow + 8,
|
||||
next
|
||||
);
|
||||
|
||||
}
|
||||
player.openInventory(inventory);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,326 @@
|
||||
package com.rsscripting.mobstand.gui;
|
||||
|
||||
import com.rsscripting.mobstand.RSMobStandPlugin;
|
||||
import com.rsscripting.mobstand.data.MobFilterData;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BabyFilterMenu {
|
||||
|
||||
public static final String MENU_TITLE =
|
||||
ChatColor.BLUE + "Baby Filters";
|
||||
|
||||
private static final int ITEMS_PER_PAGE = 45;
|
||||
|
||||
public static void open(
|
||||
RSMobStandPlugin plugin,
|
||||
Player player,
|
||||
ArmorStand armorStand,
|
||||
int page
|
||||
) {
|
||||
|
||||
Map<String, MobFilterData> mobData =
|
||||
plugin.getConfigManager()
|
||||
.getBabyMobData();
|
||||
|
||||
List<String> mobs =
|
||||
new ArrayList<>(mobData.keySet());
|
||||
|
||||
Collections.sort(mobs);
|
||||
|
||||
List<String> disabledMobs =
|
||||
plugin.getStandManager()
|
||||
.getDisabledBabyMobs(
|
||||
armorStand
|
||||
);
|
||||
|
||||
int startIndex =
|
||||
page * ITEMS_PER_PAGE;
|
||||
|
||||
int endIndex =
|
||||
Math.min(
|
||||
startIndex + ITEMS_PER_PAGE,
|
||||
mobs.size()
|
||||
);
|
||||
|
||||
int visibleItemCount =
|
||||
endIndex - startIndex;
|
||||
|
||||
int contentRows =
|
||||
(int) Math.ceil(
|
||||
visibleItemCount / 9.0
|
||||
);
|
||||
|
||||
contentRows =
|
||||
Math.max(contentRows, 1);
|
||||
|
||||
int totalRows =
|
||||
contentRows + 1;
|
||||
|
||||
int inventorySize =
|
||||
totalRows * 9;
|
||||
|
||||
Inventory inventory =
|
||||
Bukkit.createInventory(
|
||||
new RSMenuHolder(
|
||||
"BABYFILTER"
|
||||
),
|
||||
inventorySize,
|
||||
MENU_TITLE
|
||||
+ " (Page "
|
||||
+ (page + 1)
|
||||
+ ")"
|
||||
);
|
||||
|
||||
ItemStack filler =
|
||||
new ItemStack(Material.WHITE_STAINED_GLASS_PANE);
|
||||
|
||||
ItemMeta fillerMeta =
|
||||
filler.getItemMeta();
|
||||
|
||||
if (fillerMeta != null) {
|
||||
|
||||
fillerMeta.setDisplayName(" ");
|
||||
|
||||
filler.setItemMeta(fillerMeta);
|
||||
|
||||
}
|
||||
|
||||
for (int i = 0; i < inventory.getSize(); i++) {
|
||||
|
||||
inventory.setItem(i, filler);
|
||||
|
||||
}
|
||||
|
||||
List<ItemStack> filterItems =
|
||||
new ArrayList<>();
|
||||
|
||||
for (int i = startIndex; i < endIndex; i++) {
|
||||
|
||||
String mobName = mobs.get(i);
|
||||
|
||||
MobFilterData data =
|
||||
mobData.get(mobName);
|
||||
|
||||
boolean forcedEnabled =
|
||||
data.isKillAll();
|
||||
|
||||
boolean enabled =
|
||||
forcedEnabled
|
||||
|| !disabledMobs.contains(
|
||||
mobName
|
||||
);
|
||||
|
||||
ItemStack item =
|
||||
new ItemStack(
|
||||
enabled
|
||||
? data.getIcon()
|
||||
: Material.RED_STAINED_GLASS_PANE
|
||||
);
|
||||
|
||||
ItemMeta meta =
|
||||
item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
|
||||
meta.setDisplayName(
|
||||
enabled
|
||||
? ChatColor.GREEN + mobName
|
||||
: ChatColor.YELLOW
|
||||
+ mobName
|
||||
+ " (Disabled)"
|
||||
);
|
||||
|
||||
java.util.List<String> lore =
|
||||
new java.util.ArrayList<>();
|
||||
|
||||
if (forcedEnabled) {
|
||||
|
||||
lore.add(
|
||||
ChatColor.YELLOW
|
||||
+ "Overridden by Server Admin"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
meta.setLore(lore);
|
||||
|
||||
item.setItemMeta(meta);
|
||||
|
||||
}
|
||||
|
||||
filterItems.add(item);
|
||||
|
||||
}
|
||||
|
||||
int currentRow = 0;
|
||||
int rowStart = 0;
|
||||
|
||||
while (rowStart < filterItems.size()) {
|
||||
|
||||
int remainingItems =
|
||||
filterItems.size() - rowStart;
|
||||
|
||||
int itemsThisRow =
|
||||
Math.min(9, remainingItems);
|
||||
|
||||
boolean isLastPartialRow =
|
||||
itemsThisRow < 9;
|
||||
|
||||
int rowBaseSlot =
|
||||
currentRow * 9;
|
||||
|
||||
List<Integer> rowSlots =
|
||||
new ArrayList<>();
|
||||
|
||||
if (isLastPartialRow) {
|
||||
|
||||
if (itemsThisRow % 2 == 0) {
|
||||
|
||||
switch (itemsThisRow) {
|
||||
|
||||
case 2 -> rowSlots = List.of(3, 5);
|
||||
|
||||
case 4 -> rowSlots = List.of(2, 3, 5, 6);
|
||||
|
||||
case 6 -> rowSlots = List.of(1, 2, 3, 5, 6, 7);
|
||||
|
||||
case 8 -> rowSlots = List.of(0, 1, 2, 3, 5, 6, 7, 8);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
int startSlot =
|
||||
(9 - itemsThisRow) / 2;
|
||||
|
||||
for (int i = 0; i < itemsThisRow; i++) {
|
||||
|
||||
rowSlots.add(startSlot + i);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
|
||||
rowSlots.add(i);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (int i = 0; i < itemsThisRow; i++) {
|
||||
|
||||
inventory.setItem(
|
||||
rowBaseSlot + rowSlots.get(i),
|
||||
filterItems.get(rowStart + i)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
rowStart += itemsThisRow;
|
||||
currentRow++;
|
||||
|
||||
}
|
||||
|
||||
int navigationRow =
|
||||
inventorySize - 9;
|
||||
|
||||
// Previous page
|
||||
if (page > 0) {
|
||||
|
||||
ItemStack previous =
|
||||
new ItemStack(Material.ARROW);
|
||||
|
||||
ItemMeta previousMeta =
|
||||
previous.getItemMeta();
|
||||
|
||||
if (previousMeta != null) {
|
||||
|
||||
previousMeta.setDisplayName(
|
||||
ChatColor.YELLOW
|
||||
+ "Previous Page"
|
||||
);
|
||||
|
||||
previous.setItemMeta(previousMeta);
|
||||
|
||||
}
|
||||
|
||||
inventory.setItem(
|
||||
navigationRow,
|
||||
previous
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Back button
|
||||
ItemStack back =
|
||||
new ItemStack(Material.OAK_DOOR);
|
||||
|
||||
ItemMeta backMeta =
|
||||
back.getItemMeta();
|
||||
|
||||
if (backMeta != null) {
|
||||
|
||||
backMeta.setDisplayName(
|
||||
ChatColor.YELLOW + "Back"
|
||||
);
|
||||
|
||||
back.setItemMeta(backMeta);
|
||||
|
||||
}
|
||||
|
||||
inventory.setItem(
|
||||
navigationRow + 4,
|
||||
back
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Next page
|
||||
if (endIndex < mobs.size()) {
|
||||
|
||||
ItemStack next =
|
||||
new ItemStack(Material.ARROW);
|
||||
|
||||
ItemMeta nextMeta =
|
||||
next.getItemMeta();
|
||||
|
||||
if (nextMeta != null) {
|
||||
|
||||
nextMeta.setDisplayName(
|
||||
ChatColor.YELLOW
|
||||
+ "Next Page"
|
||||
);
|
||||
|
||||
next.setItemMeta(nextMeta);
|
||||
|
||||
}
|
||||
|
||||
inventory.setItem(
|
||||
navigationRow + 8,
|
||||
next
|
||||
);
|
||||
|
||||
}
|
||||
player.openInventory(inventory);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.rsscripting.mobstand.gui;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public class ConversionMenu {
|
||||
|
||||
public static final String MENU_TITLE =
|
||||
ChatColor.BLUE
|
||||
+ "Convert to RS-MobStand";
|
||||
|
||||
public static void open(Player player) {
|
||||
|
||||
Inventory inventory =
|
||||
Bukkit.createInventory(
|
||||
new RSMenuHolder(
|
||||
"CONVERT"
|
||||
),
|
||||
9,
|
||||
MENU_TITLE
|
||||
);
|
||||
|
||||
ItemStack filler =
|
||||
new ItemStack(Material.WHITE_STAINED_GLASS_PANE);
|
||||
|
||||
ItemMeta fillerMeta =
|
||||
filler.getItemMeta();
|
||||
|
||||
if (fillerMeta != null) {
|
||||
|
||||
fillerMeta.setDisplayName(" ");
|
||||
|
||||
filler.setItemMeta(fillerMeta);
|
||||
|
||||
}
|
||||
|
||||
for (int i = 0; i < inventory.getSize(); i++) {
|
||||
|
||||
inventory.setItem(i, filler);
|
||||
|
||||
}
|
||||
|
||||
ItemStack convertItem = new ItemStack(Material.CRAFTING_TABLE);
|
||||
|
||||
ItemMeta meta = convertItem.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
|
||||
meta.setDisplayName(ChatColor.GREEN + "Convert to RS MobStand");
|
||||
|
||||
meta.setLore(Collections.singletonList(
|
||||
ChatColor.YELLOW + "Convert this armor stand into an RS MobStand."
|
||||
));
|
||||
|
||||
meta.addItemFlags(
|
||||
ItemFlag.HIDE_ATTRIBUTES
|
||||
);
|
||||
|
||||
convertItem.setItemMeta(meta);
|
||||
|
||||
}
|
||||
|
||||
inventory.setItem(4, convertItem);
|
||||
|
||||
player.openInventory(inventory);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
package com.rsscripting.mobstand.gui;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LeaveAliveMenu {
|
||||
|
||||
public static final String MENU_TITLE =
|
||||
ChatColor.BLUE
|
||||
+ "Leave Alive: ";
|
||||
|
||||
public void open(
|
||||
Player player,
|
||||
int leaveAlive
|
||||
) {
|
||||
|
||||
Inventory inventory =
|
||||
Bukkit.createInventory(
|
||||
new RSMenuHolder(
|
||||
"LEAVEALIVE"
|
||||
),
|
||||
18,
|
||||
MENU_TITLE
|
||||
+ leaveAlive
|
||||
);
|
||||
|
||||
ItemStack filler =
|
||||
new ItemStack(Material.WHITE_STAINED_GLASS_PANE);
|
||||
|
||||
ItemMeta fillerMeta =
|
||||
filler.getItemMeta();
|
||||
|
||||
if (fillerMeta != null) {
|
||||
|
||||
fillerMeta.setDisplayName(" ");
|
||||
|
||||
filler.setItemMeta(fillerMeta);
|
||||
|
||||
}
|
||||
|
||||
for (int i = 0; i < inventory.getSize(); i++) {
|
||||
|
||||
inventory.setItem(i, filler);
|
||||
|
||||
}
|
||||
|
||||
inventory.setItem(
|
||||
4,
|
||||
createItem(
|
||||
Material.OAK_DOOR,
|
||||
"§eBack",
|
||||
List.of(
|
||||
"§7Return to previous menu."
|
||||
),
|
||||
1
|
||||
)
|
||||
);
|
||||
|
||||
inventory.setItem(
|
||||
10,
|
||||
createItem(
|
||||
Material.RED_WOOL,
|
||||
"§cRemove 10",
|
||||
List.of(
|
||||
"§7Decrease by 10."
|
||||
),
|
||||
10
|
||||
)
|
||||
);
|
||||
|
||||
inventory.setItem(
|
||||
11,
|
||||
createItem(
|
||||
Material.RED_WOOL,
|
||||
"§cRemove 5",
|
||||
List.of(
|
||||
"§7Decrease by 5."
|
||||
),
|
||||
5
|
||||
)
|
||||
);
|
||||
|
||||
inventory.setItem(
|
||||
12,
|
||||
createItem(
|
||||
Material.RED_WOOL,
|
||||
"§cRemove 1",
|
||||
List.of(
|
||||
"§7Decrease by 1."
|
||||
),
|
||||
1
|
||||
)
|
||||
);
|
||||
|
||||
inventory.setItem(
|
||||
13,
|
||||
createItem(
|
||||
Material.GRAY_STAINED_GLASS_PANE,
|
||||
" ",
|
||||
List.of(),
|
||||
1
|
||||
)
|
||||
);
|
||||
|
||||
inventory.setItem(
|
||||
14,
|
||||
createItem(
|
||||
Material.GREEN_WOOL,
|
||||
"§aAdd 1",
|
||||
List.of(
|
||||
"§7Increase by 1."
|
||||
),
|
||||
1
|
||||
)
|
||||
);
|
||||
|
||||
inventory.setItem(
|
||||
15,
|
||||
createItem(
|
||||
Material.GREEN_WOOL,
|
||||
"§aAdd 5",
|
||||
List.of(
|
||||
"§7Increase by 5."
|
||||
),
|
||||
5
|
||||
)
|
||||
);
|
||||
|
||||
inventory.setItem(
|
||||
16,
|
||||
createItem(
|
||||
Material.GREEN_WOOL,
|
||||
"§aAdd 10",
|
||||
List.of(
|
||||
"§7Increase by 10."
|
||||
),
|
||||
10
|
||||
)
|
||||
);
|
||||
|
||||
player.openInventory(inventory);
|
||||
|
||||
}
|
||||
|
||||
private ItemStack createItem(
|
||||
Material material,
|
||||
String name,
|
||||
List<String> lore,
|
||||
int amount
|
||||
) {
|
||||
|
||||
ItemStack item =
|
||||
new ItemStack(
|
||||
material,
|
||||
amount
|
||||
);
|
||||
|
||||
ItemMeta meta =
|
||||
item.getItemMeta();
|
||||
|
||||
if (meta == null) {
|
||||
return item;
|
||||
}
|
||||
|
||||
meta.setDisplayName(name);
|
||||
|
||||
meta.setLore(lore);
|
||||
|
||||
item.setItemMeta(meta);
|
||||
|
||||
return item;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
package com.rsscripting.mobstand.gui;
|
||||
|
||||
import com.rsscripting.mobstand.RSMobStandPlugin;
|
||||
import com.rsscripting.mobstand.utils.VersionChecker;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public class RSAdminMenu {
|
||||
|
||||
public static final String MENU_TITLE =
|
||||
ChatColor.GOLD + "Admin";
|
||||
|
||||
public static void open(
|
||||
Player player
|
||||
) {
|
||||
|
||||
Inventory inventory =
|
||||
Bukkit.createInventory(
|
||||
new RSMenuHolder(
|
||||
"ADMIN"
|
||||
),
|
||||
18,
|
||||
MENU_TITLE
|
||||
);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| FILLER
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
ItemStack filler =
|
||||
new ItemStack(
|
||||
Material.WHITE_STAINED_GLASS_PANE
|
||||
);
|
||||
|
||||
ItemMeta fillerMeta =
|
||||
filler.getItemMeta();
|
||||
|
||||
if (fillerMeta != null) {
|
||||
|
||||
fillerMeta.setDisplayName(" ");
|
||||
|
||||
filler.setItemMeta(fillerMeta);
|
||||
|
||||
}
|
||||
|
||||
for (int i = 0; i < inventory.getSize(); i++) {
|
||||
|
||||
inventory.setItem(i, filler);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| RELOAD CONFIG
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
ItemStack reloadItem =
|
||||
new ItemStack(
|
||||
Material.ENCHANTED_BOOK
|
||||
);
|
||||
|
||||
ItemMeta reloadMeta =
|
||||
reloadItem.getItemMeta();
|
||||
|
||||
if (reloadMeta != null) {
|
||||
|
||||
reloadMeta.setDisplayName(
|
||||
ChatColor.GREEN
|
||||
+ "Reload Config"
|
||||
);
|
||||
|
||||
reloadMeta.setLore(
|
||||
Collections.singletonList(
|
||||
ChatColor.GRAY
|
||||
+ "Reload plugin configuration."
|
||||
)
|
||||
);
|
||||
|
||||
reloadMeta.addItemFlags(
|
||||
ItemFlag.HIDE_ENCHANTS
|
||||
);
|
||||
|
||||
reloadItem.setItemMeta(
|
||||
reloadMeta
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
inventory.setItem(
|
||||
12,
|
||||
reloadItem
|
||||
);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Back Button
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
ItemStack backItem =
|
||||
new ItemStack(
|
||||
Material.OAK_DOOR
|
||||
);
|
||||
|
||||
ItemMeta backMeta =
|
||||
backItem.getItemMeta();
|
||||
|
||||
if (backMeta != null) {
|
||||
|
||||
backMeta.setDisplayName(
|
||||
ChatColor.YELLOW
|
||||
+ "Back"
|
||||
);
|
||||
|
||||
backItem.setItemMeta(
|
||||
backMeta
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
inventory.setItem(
|
||||
4,
|
||||
backItem
|
||||
);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| VERSION
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
ItemStack versionItem =
|
||||
new ItemStack(
|
||||
Material.BOOK
|
||||
);
|
||||
|
||||
ItemMeta versionMeta =
|
||||
versionItem.getItemMeta();
|
||||
|
||||
if (versionMeta != null) {
|
||||
|
||||
versionMeta.setDisplayName(
|
||||
ChatColor.AQUA
|
||||
+ "Plugin Version"
|
||||
);
|
||||
|
||||
String currentVersion =
|
||||
Bukkit.getPluginManager()
|
||||
.getPlugin("RS-MobStand")
|
||||
.getDescription() .getVersion();
|
||||
|
||||
String latestVersion =
|
||||
VersionChecker.getLatestVersion();
|
||||
|
||||
java.util.List<String> lore =
|
||||
new java.util.ArrayList<>();
|
||||
|
||||
lore.add(
|
||||
ChatColor.GRAY
|
||||
+ "Current Version: "
|
||||
+ ChatColor.WHITE
|
||||
+ currentVersion
|
||||
);
|
||||
|
||||
if (!currentVersion.equalsIgnoreCase(
|
||||
latestVersion
|
||||
)) {
|
||||
|
||||
lore.add(
|
||||
ChatColor.GRAY
|
||||
+ "Latest Version: "
|
||||
+ ChatColor.WHITE
|
||||
+ latestVersion
|
||||
);
|
||||
|
||||
lore.add("");
|
||||
|
||||
lore.add(
|
||||
ChatColor.GREEN
|
||||
+ "Update Available!"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
lore.add(
|
||||
ChatColor.YELLOW
|
||||
+ "Plugin Up To Date"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
versionMeta.setLore(lore);
|
||||
|
||||
versionItem.setItemMeta(
|
||||
versionMeta
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
inventory.setItem(
|
||||
14,
|
||||
versionItem
|
||||
);
|
||||
|
||||
player.openInventory(
|
||||
inventory
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.rsscripting.mobstand.gui;
|
||||
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
||||
public class RSMenuHolder
|
||||
implements InventoryHolder {
|
||||
|
||||
private final String menuId;
|
||||
|
||||
public RSMenuHolder(
|
||||
String menuId
|
||||
) {
|
||||
|
||||
this.menuId = menuId;
|
||||
|
||||
}
|
||||
|
||||
public String getMenuId() {
|
||||
|
||||
return menuId;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Inventory getInventory() {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
package com.rsscripting.mobstand.gui;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class RadiusMenu {
|
||||
public static final String MENU_TITLE =
|
||||
ChatColor.BLUE
|
||||
+ "Radius: ";
|
||||
|
||||
public void open(
|
||||
Player player,
|
||||
int radius
|
||||
) {
|
||||
|
||||
Inventory inventory =
|
||||
Bukkit.createInventory(
|
||||
new RSMenuHolder(
|
||||
"RADIUS"
|
||||
),
|
||||
18,
|
||||
MENU_TITLE + radius
|
||||
);
|
||||
|
||||
ItemStack filler =
|
||||
new ItemStack(Material.WHITE_STAINED_GLASS_PANE);
|
||||
|
||||
ItemMeta fillerMeta =
|
||||
filler.getItemMeta();
|
||||
|
||||
if (fillerMeta != null) {
|
||||
|
||||
fillerMeta.setDisplayName(" ");
|
||||
|
||||
filler.setItemMeta(fillerMeta);
|
||||
|
||||
}
|
||||
|
||||
for (int i = 0; i < inventory.getSize(); i++) {
|
||||
|
||||
inventory.setItem(i, filler);
|
||||
|
||||
}
|
||||
|
||||
inventory.setItem(
|
||||
4,
|
||||
createItem(
|
||||
Material.OAK_DOOR,
|
||||
"§eBack",
|
||||
List.of(
|
||||
"§7Return to previous menu."
|
||||
),
|
||||
1
|
||||
)
|
||||
);
|
||||
|
||||
inventory.setItem(
|
||||
10,
|
||||
createItem(
|
||||
Material.RED_WOOL,
|
||||
"§cRemove 10",
|
||||
List.of(
|
||||
"§7Decrease radius by 10."
|
||||
),
|
||||
10
|
||||
)
|
||||
);
|
||||
|
||||
inventory.setItem(
|
||||
11,
|
||||
createItem(
|
||||
Material.RED_WOOL,
|
||||
"§cRemove 5",
|
||||
List.of(
|
||||
"§7Decrease radius by 5."
|
||||
),
|
||||
5
|
||||
)
|
||||
);
|
||||
|
||||
inventory.setItem(
|
||||
12,
|
||||
createItem(
|
||||
Material.RED_WOOL,
|
||||
"§cRemove 1",
|
||||
List.of(
|
||||
"§7Decrease radius by 1."
|
||||
),
|
||||
1
|
||||
)
|
||||
);
|
||||
|
||||
inventory.setItem(
|
||||
13,
|
||||
createItem(
|
||||
Material.GRAY_STAINED_GLASS_PANE,
|
||||
" ",
|
||||
List.of(),
|
||||
1
|
||||
)
|
||||
);
|
||||
|
||||
inventory.setItem(
|
||||
14,
|
||||
createItem(
|
||||
Material.GREEN_WOOL,
|
||||
"§aAdd 1",
|
||||
List.of(
|
||||
"§7Increase radius by 1."
|
||||
),
|
||||
1
|
||||
)
|
||||
);
|
||||
|
||||
inventory.setItem(
|
||||
15,
|
||||
createItem(
|
||||
Material.GREEN_WOOL,
|
||||
"§aAdd 5",
|
||||
List.of(
|
||||
"§7Increase radius by 5."
|
||||
),
|
||||
5
|
||||
)
|
||||
);
|
||||
|
||||
inventory.setItem(
|
||||
16,
|
||||
createItem(
|
||||
Material.GREEN_WOOL,
|
||||
"§aAdd 10",
|
||||
List.of(
|
||||
"§7Increase radius by 10."
|
||||
),
|
||||
10
|
||||
)
|
||||
);
|
||||
|
||||
player.openInventory(inventory);
|
||||
|
||||
}
|
||||
|
||||
private ItemStack createItem(
|
||||
Material material,
|
||||
String name,
|
||||
List<String> lore,
|
||||
int amount
|
||||
) {
|
||||
|
||||
ItemStack item =
|
||||
new ItemStack(
|
||||
material,
|
||||
amount
|
||||
);
|
||||
|
||||
ItemMeta meta =
|
||||
item.getItemMeta();
|
||||
|
||||
if (meta == null) {
|
||||
return item;
|
||||
}
|
||||
|
||||
meta.setDisplayName(name);
|
||||
|
||||
meta.setLore(lore);
|
||||
|
||||
item.setItemMeta(meta);
|
||||
|
||||
return item;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,369 @@
|
||||
package com.rsscripting.mobstand.gui;
|
||||
|
||||
import com.rsscripting.mobstand.RSMobStandPlugin;
|
||||
import com.rsscripting.mobstand.managers.StandManager;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class StandMenu {
|
||||
|
||||
public static final String MENU_TITLE =
|
||||
ChatColor.BLUE + "RS MobStand";
|
||||
|
||||
public static void open(
|
||||
RSMobStandPlugin plugin,
|
||||
Player player,
|
||||
ArmorStand armorStand
|
||||
) {
|
||||
|
||||
Inventory inventory =
|
||||
Bukkit.createInventory(
|
||||
new RSMenuHolder(
|
||||
"MAIN"
|
||||
),
|
||||
18,
|
||||
MENU_TITLE
|
||||
);
|
||||
|
||||
StandManager standManager =
|
||||
plugin.getStandManager();
|
||||
|
||||
double radius =
|
||||
standManager.getRadius(armorStand);
|
||||
|
||||
int maxRadius =
|
||||
plugin.getConfig()
|
||||
.getInt(
|
||||
"max-player-scan-radius"
|
||||
);
|
||||
|
||||
radius =
|
||||
Math.min(
|
||||
radius,
|
||||
maxRadius
|
||||
);
|
||||
|
||||
standManager.setRadius(
|
||||
armorStand,
|
||||
radius
|
||||
);
|
||||
|
||||
boolean gravity =
|
||||
standManager.hasGravity(armorStand);
|
||||
|
||||
boolean paused =
|
||||
standManager.isPaused(armorStand);
|
||||
|
||||
ItemStack filler =
|
||||
new ItemStack(Material.WHITE_STAINED_GLASS_PANE);
|
||||
|
||||
ItemMeta fillerMeta =
|
||||
filler.getItemMeta();
|
||||
|
||||
if (fillerMeta != null) {
|
||||
|
||||
fillerMeta.setDisplayName(" ");
|
||||
|
||||
filler.setItemMeta(fillerMeta);
|
||||
|
||||
}
|
||||
|
||||
for (int i = 0; i < inventory.getSize(); i++) {
|
||||
|
||||
inventory.setItem(i, filler);
|
||||
|
||||
}
|
||||
|
||||
// Convert back item
|
||||
ItemStack revertItem =
|
||||
new ItemStack(Material.COMPOSTER);
|
||||
|
||||
ItemMeta revertMeta =
|
||||
revertItem.getItemMeta();
|
||||
|
||||
if (revertMeta != null) {
|
||||
|
||||
revertMeta.setDisplayName(
|
||||
ChatColor.RED
|
||||
+ "Convert Back to Armor Stand"
|
||||
);
|
||||
|
||||
revertMeta.setLore(
|
||||
Collections.singletonList(
|
||||
ChatColor.GRAY
|
||||
+ "Remove MobStand functionality."
|
||||
)
|
||||
);
|
||||
|
||||
revertItem.setItemMeta(revertMeta);
|
||||
|
||||
}
|
||||
|
||||
inventory.setItem(2, revertItem);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| ADMIN MENU
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
if (player.isOp()) {
|
||||
|
||||
ItemStack adminItem =
|
||||
new ItemStack(
|
||||
Material.COMMAND_BLOCK
|
||||
);
|
||||
|
||||
ItemMeta adminMeta =
|
||||
adminItem.getItemMeta();
|
||||
|
||||
if (adminMeta != null) {
|
||||
|
||||
adminMeta.setDisplayName(
|
||||
ChatColor.GOLD
|
||||
+ "Admin"
|
||||
);
|
||||
|
||||
adminMeta.setLore(
|
||||
java.util.Collections.singletonList(
|
||||
"§7Administrative options."
|
||||
)
|
||||
);
|
||||
|
||||
adminItem.setItemMeta(
|
||||
adminMeta
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
inventory.setItem(
|
||||
4,
|
||||
adminItem
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
// Pause item
|
||||
ItemStack pauseItem =
|
||||
new ItemStack(
|
||||
paused
|
||||
? Material.RED_DYE
|
||||
: Material.GREEN_DYE
|
||||
);
|
||||
|
||||
ItemMeta pauseMeta =
|
||||
pauseItem.getItemMeta();
|
||||
|
||||
if (pauseMeta != null) {
|
||||
|
||||
pauseMeta.setDisplayName(
|
||||
paused
|
||||
? ChatColor.GREEN + "Enable Processing"
|
||||
: ChatColor.RED + "Disable Processing"
|
||||
);
|
||||
|
||||
pauseMeta.setLore(List.of(
|
||||
paused
|
||||
? ChatColor.GRAY
|
||||
+ "Click to resume processing."
|
||||
: ChatColor.GRAY
|
||||
+ "Click to pause processing."
|
||||
));
|
||||
|
||||
pauseMeta.addItemFlags(
|
||||
ItemFlag.HIDE_ATTRIBUTES
|
||||
);
|
||||
|
||||
pauseItem.setItemMeta(pauseMeta);
|
||||
|
||||
}
|
||||
|
||||
inventory.setItem(6, pauseItem);
|
||||
|
||||
|
||||
|
||||
|
||||
// Adult filters item
|
||||
ItemStack adultFilters =
|
||||
new ItemStack(Material.BEEF);
|
||||
|
||||
ItemMeta adultMeta =
|
||||
adultFilters.getItemMeta();
|
||||
|
||||
if (adultMeta != null) {
|
||||
|
||||
adultMeta.setDisplayName(
|
||||
ChatColor.YELLOW
|
||||
+ "Adult Filters"
|
||||
);
|
||||
|
||||
adultMeta.setLore(List.of(
|
||||
ChatColor.YELLOW
|
||||
+ "Configure adult mob filters."
|
||||
));
|
||||
|
||||
adultFilters.setItemMeta(adultMeta);
|
||||
|
||||
}
|
||||
|
||||
inventory.setItem(15, adultFilters);
|
||||
|
||||
// Baby filters item
|
||||
ItemStack babyFilters =
|
||||
new ItemStack(Material.BEE_SPAWN_EGG);
|
||||
|
||||
ItemMeta babyMeta =
|
||||
babyFilters.getItemMeta();
|
||||
|
||||
if (babyMeta != null) {
|
||||
|
||||
babyMeta.setDisplayName(
|
||||
ChatColor.YELLOW
|
||||
+ "Baby Filters"
|
||||
);
|
||||
|
||||
babyMeta.setLore(List.of(
|
||||
ChatColor.YELLOW
|
||||
+ "Configure baby mob filters."
|
||||
));
|
||||
|
||||
babyFilters.setItemMeta(babyMeta);
|
||||
|
||||
}
|
||||
|
||||
inventory.setItem(17, babyFilters);
|
||||
|
||||
|
||||
// Leave Alive item
|
||||
int leaveAlive =
|
||||
standManager.getLeaveAlive(
|
||||
armorStand
|
||||
);
|
||||
|
||||
ItemStack leaveAliveItem =
|
||||
new ItemStack(
|
||||
Material.TOTEM_OF_UNDYING
|
||||
);
|
||||
|
||||
ItemMeta leaveAliveMeta =
|
||||
leaveAliveItem.getItemMeta();
|
||||
|
||||
if (leaveAliveMeta != null) {
|
||||
|
||||
leaveAliveMeta.setDisplayName(
|
||||
ChatColor.YELLOW
|
||||
+ "Leave Alive:"
|
||||
);
|
||||
|
||||
leaveAliveMeta.setLore(List.of(
|
||||
ChatColor.GRAY
|
||||
+ "Current: "
|
||||
+ ChatColor.WHITE
|
||||
+ leaveAlive,
|
||||
"",
|
||||
ChatColor.YELLOW
|
||||
+ "Click to adjust."
|
||||
));
|
||||
|
||||
leaveAliveItem.setItemMeta(leaveAliveMeta);
|
||||
|
||||
}
|
||||
|
||||
inventory.setItem(13, leaveAliveItem);
|
||||
|
||||
|
||||
|
||||
// Radius item
|
||||
ItemStack radiusItem =
|
||||
new ItemStack(
|
||||
Material.COMPASS
|
||||
);
|
||||
|
||||
ItemMeta radiusMeta =
|
||||
radiusItem.getItemMeta();
|
||||
|
||||
if (radiusMeta != null) {
|
||||
|
||||
radiusMeta.setDisplayName(
|
||||
ChatColor.YELLOW
|
||||
+ "Scan Radius"
|
||||
);
|
||||
|
||||
radiusMeta.setLore(List.of(
|
||||
ChatColor.GRAY
|
||||
+ "Current: "
|
||||
+ ChatColor.WHITE
|
||||
+ (int) radius,
|
||||
"",
|
||||
ChatColor.YELLOW
|
||||
+ "Click to adjust radius."
|
||||
));
|
||||
|
||||
radiusItem.setItemMeta(radiusMeta);
|
||||
|
||||
}
|
||||
|
||||
inventory.setItem(9, radiusItem);
|
||||
|
||||
ItemStack gravityItem =
|
||||
new ItemStack(Material.FEATHER);
|
||||
|
||||
ItemMeta gravityMeta =
|
||||
gravityItem.getItemMeta();
|
||||
|
||||
if (gravityMeta != null) {
|
||||
|
||||
gravityMeta.setDisplayName(
|
||||
(gravity
|
||||
? ChatColor.GREEN
|
||||
: ChatColor.RED)
|
||||
+ "Gravity"
|
||||
);
|
||||
|
||||
gravityMeta.setLore(List.of(
|
||||
ChatColor.GRAY + "Current: "
|
||||
+ (gravity
|
||||
? ChatColor.GREEN + "Enabled"
|
||||
: ChatColor.RED + "Disabled"),
|
||||
"",
|
||||
ChatColor.YELLOW + "Left Click: Toggle"
|
||||
));
|
||||
|
||||
// Add enchant glow if gravity enabled
|
||||
if (gravity) {
|
||||
|
||||
gravityMeta.addEnchant(
|
||||
Enchantment.UNBREAKING,
|
||||
1,
|
||||
true
|
||||
);
|
||||
|
||||
gravityMeta.addItemFlags(
|
||||
ItemFlag.HIDE_ENCHANTS
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
gravityItem.setItemMeta(gravityMeta);
|
||||
|
||||
}
|
||||
|
||||
inventory.setItem(11, gravityItem);
|
||||
|
||||
player.openInventory(inventory);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.rsscripting.mobstand.listeners;
|
||||
|
||||
import com.rsscripting.mobstand.RSMobStandPlugin;
|
||||
import com.rsscripting.mobstand.managers.StandManager;
|
||||
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
|
||||
public class ArmorStandBreakListener implements Listener {
|
||||
|
||||
private final StandManager standManager;
|
||||
|
||||
public ArmorStandBreakListener(RSMobStandPlugin plugin) {
|
||||
|
||||
this.standManager = plugin.getStandManager();
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onArmorStandDamage(EntityDamageEvent event) {
|
||||
|
||||
// Must be armor stand
|
||||
if (!(event.getEntity() instanceof ArmorStand armorStand)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only manage MobStands
|
||||
if (!standManager.isMobStand(armorStand)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Completely block ALL vanilla damage
|
||||
event.setCancelled(true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package com.rsscripting.mobstand.listeners;
|
||||
|
||||
import com.rsscripting.mobstand.RSMobStandPlugin;
|
||||
import com.rsscripting.mobstand.gui.ConversionMenu;
|
||||
import com.rsscripting.mobstand.gui.StandMenu;
|
||||
import com.rsscripting.mobstand.managers.StandManager;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class ArmorStandListener implements Listener {
|
||||
|
||||
private final StandManager standManager;
|
||||
|
||||
private final RSMobStandPlugin plugin;
|
||||
|
||||
public ArmorStandListener(
|
||||
RSMobStandPlugin plugin,
|
||||
StandManager standManager
|
||||
) {
|
||||
|
||||
this.plugin = plugin;
|
||||
|
||||
this.standManager = standManager;
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onArmorStandInteract(PlayerInteractAtEntityEvent event) {
|
||||
|
||||
// Only armor stands
|
||||
if (!(event.getRightClicked() instanceof ArmorStand armorStand)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
|
||||
// Must be sneaking
|
||||
if (!player.isSneaking()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack item =
|
||||
player.getInventory()
|
||||
.getItemInMainHand();
|
||||
|
||||
if (item == null ||
|
||||
item.getType() != Material.STICK) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Existing MobStand
|
||||
if (standManager.isMobStand(armorStand)) {
|
||||
|
||||
// Track selected stand
|
||||
standManager.setSelectedArmorStand(
|
||||
player.getUniqueId(),
|
||||
armorStand.getUniqueId()
|
||||
);
|
||||
|
||||
// Owner check
|
||||
if (!standManager.isOwner(
|
||||
armorStand,
|
||||
player
|
||||
)
|
||||
&& !player.hasPermission(
|
||||
"rsmobstand.admin"
|
||||
)) {
|
||||
|
||||
player.sendMessage(
|
||||
ChatColor.RED
|
||||
+ "You do not own this MobStand."
|
||||
);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// Cancel normal interaction
|
||||
event.setCancelled(true);
|
||||
|
||||
StandMenu.open(
|
||||
plugin,
|
||||
player,
|
||||
armorStand
|
||||
);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// Track selected stand
|
||||
standManager.setSelectedArmorStand(
|
||||
player.getUniqueId(),
|
||||
armorStand.getUniqueId()
|
||||
);
|
||||
|
||||
// Cancel normal interaction
|
||||
event.setCancelled(true);
|
||||
|
||||
// Open conversion menu
|
||||
ConversionMenu.open(player);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.rsscripting.mobstand.listeners;
|
||||
|
||||
import com.rsscripting.mobstand.managers.StandManager;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
|
||||
public class ChunkLoadListener implements Listener {
|
||||
|
||||
private final StandManager standManager;
|
||||
|
||||
public ChunkLoadListener(StandManager standManager) {
|
||||
|
||||
this.standManager = standManager;
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onChunkLoad(ChunkLoadEvent event) {
|
||||
|
||||
Chunk chunk = event.getChunk();
|
||||
|
||||
for (Entity entity : chunk.getEntities()) {
|
||||
|
||||
if (!(entity instanceof ArmorStand armorStand)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!standManager.isMobStand(armorStand)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
armorStand.setInvulnerable(true);
|
||||
|
||||
standManager.getActiveStands().add(
|
||||
armorStand.getUniqueId()
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,794 @@
|
||||
package com.rsscripting.mobstand.managers;
|
||||
|
||||
import com.rsscripting.mobstand.RSMobStandPlugin;
|
||||
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class StandManager {
|
||||
|
||||
private final RSMobStandPlugin plugin;
|
||||
|
||||
private final NamespacedKey mobStandKey;
|
||||
|
||||
private final NamespacedKey ownerKey;
|
||||
|
||||
private final NamespacedKey radiusKey;
|
||||
|
||||
private final NamespacedKey gravityKey;
|
||||
|
||||
private final NamespacedKey pausedKey;
|
||||
|
||||
private final NamespacedKey disabledAdultMobsKey;
|
||||
|
||||
private final NamespacedKey disabledBabyMobsKey;
|
||||
|
||||
private final Map<UUID, UUID> selectedArmorStands = new HashMap<>();
|
||||
|
||||
private final NamespacedKey leaveAliveKey;
|
||||
|
||||
private final Set<UUID> activeStands = new HashSet<>();
|
||||
|
||||
public StandManager(RSMobStandPlugin plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
|
||||
this.mobStandKey = new NamespacedKey(plugin, "mobstand");
|
||||
|
||||
this.ownerKey = new NamespacedKey(plugin, "owner");
|
||||
|
||||
this.radiusKey = new NamespacedKey(plugin, "radius");
|
||||
|
||||
this.leaveAliveKey = new NamespacedKey(plugin, "leaveAlive");
|
||||
|
||||
this.gravityKey = new NamespacedKey(plugin, "gravity");
|
||||
|
||||
this.pausedKey = new NamespacedKey(plugin, "paused");
|
||||
|
||||
this.disabledAdultMobsKey =
|
||||
new NamespacedKey(
|
||||
plugin,
|
||||
"disabled_adult_mobs"
|
||||
);
|
||||
|
||||
this.disabledBabyMobsKey =
|
||||
new NamespacedKey(
|
||||
plugin,
|
||||
"disabled_baby_mobs"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
// counts stands on server.
|
||||
public int getPlayerStandCount(UUID ownerUUID) {
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (UUID standUUID : activeStands) {
|
||||
|
||||
Entity entity =
|
||||
Bukkit.getEntity(standUUID);
|
||||
|
||||
if (!(entity instanceof ArmorStand armorStand)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
UUID standOwner =
|
||||
getOwnerUUID(armorStand);
|
||||
|
||||
if (ownerUUID.equals(standOwner)) {
|
||||
count++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return count;
|
||||
|
||||
}
|
||||
|
||||
// Converts an armor stand into a MobStand.
|
||||
|
||||
public boolean convertToMobStand(ArmorStand armorStand, Player owner) {
|
||||
|
||||
if (!isArmorStandEmpty(armorStand)) {
|
||||
|
||||
owner.sendMessage(
|
||||
ChatColor.RED
|
||||
+ "Remove all equipment first."
|
||||
);
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (!owner.hasPermission(
|
||||
"rsmobstand.bypasslimits"
|
||||
)) {
|
||||
|
||||
// Server limit
|
||||
int maxTotalStands =
|
||||
plugin.getConfig()
|
||||
.getInt(
|
||||
"max-total-stands"
|
||||
);
|
||||
|
||||
if (maxTotalStands > 0 &&
|
||||
activeStands.size()
|
||||
>= maxTotalStands) {
|
||||
|
||||
owner.sendMessage(
|
||||
ChatColor.RED
|
||||
+ "Server mob stand limit reached."
|
||||
);
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
// Player limit
|
||||
int maxPlayerStands =
|
||||
plugin.getConfig()
|
||||
.getInt(
|
||||
"max-stands-per-player"
|
||||
);
|
||||
|
||||
int playerStandCount =
|
||||
getPlayerStandCount(
|
||||
owner.getUniqueId()
|
||||
);
|
||||
|
||||
if (maxPlayerStands > 0 &&
|
||||
playerStandCount
|
||||
>= maxPlayerStands) {
|
||||
|
||||
owner.sendMessage(
|
||||
ChatColor.RED
|
||||
+ "You have reached your mob stand limit."
|
||||
);
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
armorStand.getPersistentDataContainer().set(
|
||||
pausedKey,
|
||||
PersistentDataType.BYTE,
|
||||
(byte) 0
|
||||
);
|
||||
|
||||
armorStand.getPersistentDataContainer().set(
|
||||
mobStandKey,
|
||||
PersistentDataType.BYTE,
|
||||
(byte) 1
|
||||
);
|
||||
|
||||
armorStand.getPersistentDataContainer().set(
|
||||
ownerKey,
|
||||
PersistentDataType.STRING,
|
||||
owner.getUniqueId().toString()
|
||||
);
|
||||
|
||||
double defaultRadius = plugin.getConfig().getDouble(
|
||||
"default-scan-radius"
|
||||
);
|
||||
|
||||
armorStand.getPersistentDataContainer().set(
|
||||
radiusKey,
|
||||
PersistentDataType.DOUBLE,
|
||||
defaultRadius
|
||||
);
|
||||
|
||||
boolean defaultGravity = plugin.getConfig().getBoolean(
|
||||
"default-gravity"
|
||||
);
|
||||
|
||||
int defaultLeaveAlive =
|
||||
plugin.getConfig().getInt(
|
||||
"default-leave-alive"
|
||||
);
|
||||
|
||||
armorStand.getPersistentDataContainer().set(
|
||||
leaveAliveKey,
|
||||
PersistentDataType.INTEGER,
|
||||
defaultLeaveAlive
|
||||
);
|
||||
|
||||
armorStand.getPersistentDataContainer().set(
|
||||
gravityKey,
|
||||
PersistentDataType.BYTE,
|
||||
(byte) (defaultGravity ? 1 : 0)
|
||||
);
|
||||
|
||||
armorStand.setGravity(defaultGravity);
|
||||
|
||||
armorStand.setCustomName("§cRS MobStand");
|
||||
armorStand.setCustomNameVisible(true);
|
||||
armorStand.setInvulnerable(true);
|
||||
activeStands.add(armorStand.getUniqueId());
|
||||
|
||||
// Initialize adult disabled filters
|
||||
List<String> disabledAdultMobs =
|
||||
new ArrayList<>();
|
||||
|
||||
plugin.getConfigManager()
|
||||
.getAdultMobData()
|
||||
.forEach((mobName, data) -> {
|
||||
|
||||
if (!data.isEnabledByDefault()) {
|
||||
|
||||
disabledAdultMobs.add(
|
||||
mobName
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
setDisabledAdultMobs(
|
||||
armorStand,
|
||||
disabledAdultMobs
|
||||
);
|
||||
|
||||
// Initialize baby disabled filters
|
||||
List<String> disabledBabyMobs =
|
||||
new ArrayList<>();
|
||||
|
||||
plugin.getConfigManager()
|
||||
.getBabyMobData()
|
||||
.forEach((mobName, data) -> {
|
||||
|
||||
if (!data.isEnabledByDefault()) {
|
||||
|
||||
disabledBabyMobs.add(
|
||||
mobName
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
setDisabledBabyMobs(
|
||||
armorStand,
|
||||
disabledBabyMobs
|
||||
);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Removes MobStand data.
|
||||
|
||||
public void revertToNormalStand(ArmorStand armorStand) {
|
||||
|
||||
armorStand.getPersistentDataContainer().remove(mobStandKey);
|
||||
|
||||
armorStand.getPersistentDataContainer().remove(radiusKey);
|
||||
|
||||
armorStand.getPersistentDataContainer().remove(gravityKey);
|
||||
|
||||
armorStand.getPersistentDataContainer().remove(pausedKey);
|
||||
|
||||
armorStand.getPersistentDataContainer().remove(leaveAliveKey);
|
||||
|
||||
armorStand.getPersistentDataContainer().remove(disabledAdultMobsKey);
|
||||
|
||||
armorStand.getPersistentDataContainer().remove(disabledBabyMobsKey);
|
||||
|
||||
clearOwnership(armorStand);
|
||||
|
||||
activeStands.remove(armorStand.getUniqueId());
|
||||
|
||||
armorStand.setInvulnerable(false);
|
||||
|
||||
armorStand.setCustomName(null);
|
||||
|
||||
armorStand.setCustomNameVisible(false);
|
||||
|
||||
armorStand.setGravity(true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Checks if armor stand is a MobStand.
|
||||
|
||||
public boolean isMobStand(ArmorStand armorStand) {
|
||||
|
||||
Byte value = armorStand.getPersistentDataContainer().get(
|
||||
mobStandKey,
|
||||
PersistentDataType.BYTE
|
||||
);
|
||||
|
||||
return value != null && value == (byte) 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Stores selected armor stand for player.
|
||||
|
||||
public void setSelectedArmorStand(UUID playerUUID, UUID armorStandUUID) {
|
||||
|
||||
selectedArmorStands.put(playerUUID, armorStandUUID);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Gets selected armor stand UUID.
|
||||
|
||||
public UUID getSelectedArmorStand(UUID playerUUID) {
|
||||
|
||||
return selectedArmorStands.get(playerUUID);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Removes selected armor stand tracking.
|
||||
|
||||
public void clearSelectedArmorStand(UUID playerUUID) {
|
||||
|
||||
selectedArmorStands.remove(playerUUID);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Checks if player owns this stand.
|
||||
|
||||
public boolean isOwner(ArmorStand armorStand, Player player) {
|
||||
|
||||
String ownerUUID = armorStand.getPersistentDataContainer().get(
|
||||
ownerKey,
|
||||
PersistentDataType.STRING
|
||||
);
|
||||
|
||||
if (ownerUUID == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ownerUUID.equals(player.getUniqueId().toString());
|
||||
|
||||
}
|
||||
|
||||
public UUID getOwnerUUID(
|
||||
ArmorStand armorStand
|
||||
) {
|
||||
|
||||
String ownerUUID =
|
||||
armorStand
|
||||
.getPersistentDataContainer()
|
||||
.get(
|
||||
ownerKey,
|
||||
PersistentDataType.STRING
|
||||
);
|
||||
|
||||
if (ownerUUID == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return UUID.fromString(ownerUUID);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Removes ownership data.
|
||||
|
||||
public void clearOwnership(ArmorStand armorStand) {
|
||||
|
||||
armorStand.getPersistentDataContainer().remove(ownerKey);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Gets all active Mob stands.
|
||||
|
||||
public Set<UUID> getActiveStands() {
|
||||
|
||||
return activeStands;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Reloads all MobStands from loaded worlds.
|
||||
|
||||
public void loadExistingStands() {
|
||||
|
||||
activeStands.clear();
|
||||
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
|
||||
for (Entity entity : world.getEntities()) {
|
||||
|
||||
// Must be armor stand
|
||||
if (!(entity instanceof ArmorStand armorStand)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Byte storedValue = armorStand.getPersistentDataContainer().get(
|
||||
mobStandKey,
|
||||
PersistentDataType.BYTE
|
||||
);
|
||||
|
||||
// Must be MobStand
|
||||
if (!isMobStand(armorStand)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Restore invulnerability
|
||||
armorStand.setInvulnerable(true);
|
||||
|
||||
// Re-register stand
|
||||
activeStands.add(armorStand.getUniqueId());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
plugin.getLogger().info(
|
||||
"Recovered "
|
||||
+ activeStands.size()
|
||||
+ " MobStands."
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public int getLeaveAlive(
|
||||
ArmorStand armorStand
|
||||
) {
|
||||
|
||||
Integer leaveAlive =
|
||||
armorStand
|
||||
.getPersistentDataContainer()
|
||||
.get(
|
||||
leaveAliveKey,
|
||||
PersistentDataType.INTEGER
|
||||
);
|
||||
|
||||
if (leaveAlive == null) {
|
||||
|
||||
return plugin.getConfig().getInt(
|
||||
"default-leave-alive"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
return leaveAlive;
|
||||
|
||||
}
|
||||
|
||||
public double getRadius(ArmorStand armorStand) {
|
||||
|
||||
Double radius = armorStand.getPersistentDataContainer().get(
|
||||
radiusKey,
|
||||
PersistentDataType.DOUBLE
|
||||
);
|
||||
|
||||
if (radius == null) {
|
||||
|
||||
return plugin.getConfig().getDouble(
|
||||
"default-scan-radius"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
return radius;
|
||||
|
||||
}
|
||||
|
||||
public void setRadius(
|
||||
ArmorStand armorStand,
|
||||
double radius
|
||||
) {
|
||||
|
||||
double maxRadius = plugin.getConfig().getDouble(
|
||||
"max-player-scan-radius"
|
||||
);
|
||||
|
||||
// Clamp radius
|
||||
if (radius < 0) {
|
||||
radius = 0;
|
||||
}
|
||||
|
||||
if (radius > maxRadius) {
|
||||
radius = maxRadius;
|
||||
}
|
||||
|
||||
armorStand.getPersistentDataContainer().set(
|
||||
radiusKey,
|
||||
PersistentDataType.DOUBLE,
|
||||
radius
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public void setLeaveAlive(
|
||||
ArmorStand armorStand,
|
||||
int leaveAlive
|
||||
) {
|
||||
|
||||
int minLeaveAlive =
|
||||
plugin.getConfig()
|
||||
.getInt(
|
||||
"min-leave-alive"
|
||||
);
|
||||
|
||||
int maxLeaveAlive =
|
||||
plugin.getConfig()
|
||||
.getInt(
|
||||
"max-leave-alive"
|
||||
);
|
||||
|
||||
// Clamp leaveAlive
|
||||
if (leaveAlive < minLeaveAlive) {
|
||||
leaveAlive = minLeaveAlive;
|
||||
}
|
||||
|
||||
if (leaveAlive > maxLeaveAlive) {
|
||||
leaveAlive = maxLeaveAlive;
|
||||
}
|
||||
|
||||
armorStand.getPersistentDataContainer().set(
|
||||
leaveAliveKey,
|
||||
PersistentDataType.INTEGER,
|
||||
leaveAlive
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public boolean hasGravity(ArmorStand armorStand) {
|
||||
|
||||
Byte value = armorStand.getPersistentDataContainer().get(
|
||||
gravityKey,
|
||||
PersistentDataType.BYTE
|
||||
);
|
||||
|
||||
if (value == null) {
|
||||
|
||||
return plugin.getConfig().getBoolean(
|
||||
"default-gravity"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
return value == (byte) 1;
|
||||
|
||||
}
|
||||
|
||||
public void setGravity(
|
||||
ArmorStand armorStand,
|
||||
boolean gravity
|
||||
) {
|
||||
|
||||
armorStand.getPersistentDataContainer().set(
|
||||
gravityKey,
|
||||
PersistentDataType.BYTE,
|
||||
(byte) (gravity ? 1 : 0)
|
||||
);
|
||||
|
||||
armorStand.setGravity(gravity);
|
||||
|
||||
}
|
||||
|
||||
public boolean isPaused(ArmorStand armorStand) {
|
||||
|
||||
Byte value = armorStand.getPersistentDataContainer().get(
|
||||
pausedKey,
|
||||
PersistentDataType.BYTE
|
||||
);
|
||||
|
||||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return value == (byte) 1;
|
||||
|
||||
}
|
||||
|
||||
public void setPaused(
|
||||
ArmorStand armorStand,
|
||||
boolean paused
|
||||
) {
|
||||
|
||||
armorStand.getPersistentDataContainer().set(
|
||||
pausedKey,
|
||||
PersistentDataType.BYTE,
|
||||
(byte) (paused ? 1 : 0)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
// Get disabled Adult Mobs
|
||||
public List<String> getDisabledAdultMobs(
|
||||
ArmorStand armorStand
|
||||
) {
|
||||
|
||||
String stored =
|
||||
armorStand
|
||||
.getPersistentDataContainer()
|
||||
.get(
|
||||
disabledAdultMobsKey,
|
||||
PersistentDataType.STRING
|
||||
);
|
||||
|
||||
if (stored == null || stored.isEmpty()) {
|
||||
|
||||
return new ArrayList<>();
|
||||
|
||||
}
|
||||
|
||||
return new ArrayList<>(
|
||||
Arrays.asList(
|
||||
stored.split(",")
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public List<String> getDisabledBabyMobs(
|
||||
ArmorStand armorStand
|
||||
) {
|
||||
|
||||
String stored =
|
||||
armorStand
|
||||
.getPersistentDataContainer()
|
||||
.get(
|
||||
disabledBabyMobsKey,
|
||||
PersistentDataType.STRING
|
||||
);
|
||||
|
||||
if (stored == null || stored.isEmpty()) {
|
||||
|
||||
return new ArrayList<>();
|
||||
|
||||
}
|
||||
|
||||
return new ArrayList<>(
|
||||
Arrays.asList(
|
||||
stored.split(",")
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public void setDisabledAdultMobs(
|
||||
ArmorStand armorStand,
|
||||
List<String> mobs
|
||||
) {
|
||||
|
||||
String stored =
|
||||
String.join(",", mobs);
|
||||
|
||||
armorStand
|
||||
.getPersistentDataContainer()
|
||||
.set(
|
||||
disabledAdultMobsKey,
|
||||
PersistentDataType.STRING,
|
||||
stored
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public void setDisabledBabyMobs(
|
||||
ArmorStand armorStand,
|
||||
List<String> mobs
|
||||
) {
|
||||
|
||||
String stored =
|
||||
String.join(",", mobs);
|
||||
|
||||
armorStand
|
||||
.getPersistentDataContainer()
|
||||
.set(
|
||||
disabledBabyMobsKey,
|
||||
PersistentDataType.STRING,
|
||||
stored
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public void toggleAdultMobFilter(
|
||||
ArmorStand armorStand,
|
||||
String mobName
|
||||
) {
|
||||
|
||||
List<String> disabled =
|
||||
getDisabledAdultMobs(
|
||||
armorStand
|
||||
);
|
||||
|
||||
if (disabled.contains(mobName)) {
|
||||
|
||||
disabled.remove(mobName);
|
||||
|
||||
} else {
|
||||
|
||||
disabled.add(mobName);
|
||||
|
||||
}
|
||||
|
||||
setDisabledAdultMobs(
|
||||
armorStand,
|
||||
disabled
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
private boolean isArmorStandEmpty(
|
||||
ArmorStand armorStand
|
||||
) {
|
||||
|
||||
return armorStand.getEquipment()
|
||||
.getHelmet()
|
||||
.getType()
|
||||
.isAir()
|
||||
|
||||
&& armorStand.getEquipment()
|
||||
.getChestplate()
|
||||
.getType()
|
||||
.isAir()
|
||||
|
||||
&& armorStand.getEquipment()
|
||||
.getLeggings()
|
||||
.getType()
|
||||
.isAir()
|
||||
|
||||
&& armorStand.getEquipment()
|
||||
.getBoots()
|
||||
.getType()
|
||||
.isAir()
|
||||
|
||||
&& armorStand.getEquipment()
|
||||
.getItemInMainHand()
|
||||
.getType()
|
||||
.isAir()
|
||||
|
||||
&& armorStand.getEquipment()
|
||||
.getItemInOffHand()
|
||||
.getType()
|
||||
.isAir();
|
||||
|
||||
}
|
||||
|
||||
public void toggleBabyMobFilter(
|
||||
ArmorStand armorStand,
|
||||
String mobName
|
||||
) {
|
||||
|
||||
List<String> disabled =
|
||||
getDisabledBabyMobs(
|
||||
armorStand
|
||||
);
|
||||
|
||||
if (disabled.contains(mobName)) {
|
||||
|
||||
disabled.remove(mobName);
|
||||
|
||||
} else {
|
||||
|
||||
disabled.add(mobName);
|
||||
|
||||
}
|
||||
|
||||
setDisabledBabyMobs(
|
||||
armorStand,
|
||||
disabled
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,380 @@
|
||||
package com.rsscripting.mobstand.tasks;
|
||||
|
||||
import com.rsscripting.mobstand.RSMobStandPlugin;
|
||||
import com.rsscripting.mobstand.managers.StandManager;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.entity.Ageable;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.List;
|
||||
|
||||
public class SlaughterTask extends BukkitRunnable {
|
||||
|
||||
private final RSMobStandPlugin plugin;
|
||||
|
||||
private final StandManager standManager;
|
||||
|
||||
public SlaughterTask(RSMobStandPlugin plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
|
||||
this.standManager = plugin.getStandManager();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
long start = System.nanoTime();
|
||||
|
||||
boolean debugEnabled =
|
||||
plugin.getConfig().getBoolean("debug.enabled");
|
||||
|
||||
boolean performanceLogging =
|
||||
plugin.getConfig().getBoolean(
|
||||
"debug.logging.performance"
|
||||
);
|
||||
|
||||
boolean entityKillLogging =
|
||||
plugin.getConfig().getBoolean(
|
||||
"debug.logging.entity-kills"
|
||||
);
|
||||
|
||||
Integer killedThisCycle =
|
||||
entityKillLogging ? 0 : null;
|
||||
|
||||
Location lastStandLocation = null;
|
||||
|
||||
var configManager = plugin.getConfigManager();
|
||||
|
||||
var adultMobs =
|
||||
configManager
|
||||
.getAdultMobData()
|
||||
.keySet();
|
||||
|
||||
var babyMobs =
|
||||
configManager
|
||||
.getBabyMobData()
|
||||
.keySet();
|
||||
|
||||
for (UUID uuid : standManager.getActiveStands()) {
|
||||
|
||||
Entity entity = Bukkit.getEntity(uuid);
|
||||
|
||||
// Stand no longer exists
|
||||
if (!(entity instanceof ArmorStand armorStand)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip paused stands
|
||||
if (standManager.isPaused(armorStand)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Scan nearby entities
|
||||
double radius = standManager.getRadius(armorStand);
|
||||
|
||||
int leaveAlive =
|
||||
standManager.getLeaveAlive(
|
||||
armorStand
|
||||
);
|
||||
|
||||
lastStandLocation =
|
||||
armorStand.getLocation();
|
||||
|
||||
java.util.Map<String, List<LivingEntity>> adultTargets =
|
||||
new java.util.HashMap<>();
|
||||
|
||||
java.util.Map<String, List<LivingEntity>> babyTargets =
|
||||
new java.util.HashMap<>();
|
||||
|
||||
List<LivingEntity> killAllTargets =
|
||||
new java.util.ArrayList<>();
|
||||
|
||||
for (Entity nearby : armorStand.getNearbyEntities(
|
||||
radius,
|
||||
radius,
|
||||
radius
|
||||
)) {
|
||||
|
||||
// Ignore players
|
||||
if (nearby instanceof Player) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore armor stands
|
||||
if (nearby instanceof ArmorStand) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Must be living entity
|
||||
if (!(nearby instanceof LivingEntity livingEntity)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
EntityType entityType = livingEntity.getType();
|
||||
|
||||
String entityName = entityType.name();
|
||||
|
||||
boolean killAll = false;
|
||||
|
||||
boolean shouldKill;
|
||||
|
||||
// Ageable mobs
|
||||
if (livingEntity instanceof Ageable ageable) {
|
||||
|
||||
// Adult mob
|
||||
if (ageable.isAdult()) {
|
||||
|
||||
List<String> disabledAdultMobs =
|
||||
standManager.getDisabledAdultMobs(
|
||||
armorStand
|
||||
);
|
||||
|
||||
shouldKill =
|
||||
!disabledAdultMobs.contains(
|
||||
entityName
|
||||
);
|
||||
|
||||
if (configManager
|
||||
.getAdultMobData()
|
||||
.containsKey(entityName)) {
|
||||
|
||||
killAll =
|
||||
configManager
|
||||
.getAdultMobData()
|
||||
.get(entityName)
|
||||
.isKillAll();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Baby mob
|
||||
else {
|
||||
|
||||
List<String> disabledBabyMobs =
|
||||
standManager.getDisabledBabyMobs(
|
||||
armorStand
|
||||
);
|
||||
|
||||
shouldKill =
|
||||
!disabledBabyMobs.contains(
|
||||
entityName
|
||||
);
|
||||
|
||||
if (configManager
|
||||
.getBabyMobData()
|
||||
.containsKey(entityName)) {
|
||||
|
||||
killAll =
|
||||
configManager
|
||||
.getBabyMobData()
|
||||
.get(entityName)
|
||||
.isKillAll();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Non-ageable mobs
|
||||
else {
|
||||
|
||||
List<String> disabledAdultMobs =
|
||||
standManager.getDisabledAdultMobs(
|
||||
armorStand
|
||||
);
|
||||
|
||||
shouldKill =
|
||||
!disabledAdultMobs.contains(
|
||||
entityName
|
||||
);
|
||||
|
||||
if (configManager
|
||||
.getAdultMobData()
|
||||
.containsKey(entityName)) {
|
||||
|
||||
killAll =
|
||||
configManager
|
||||
.getAdultMobData()
|
||||
.get(entityName)
|
||||
.isKillAll();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Not allowed
|
||||
if (!shouldKill) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore named mobs
|
||||
if (livingEntity.customName() != null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (killAll) {
|
||||
|
||||
killAllTargets.add(livingEntity);
|
||||
|
||||
} else {
|
||||
|
||||
if (livingEntity instanceof Ageable ageable) {
|
||||
|
||||
if (ageable.isAdult()) {
|
||||
|
||||
adultTargets
|
||||
.computeIfAbsent(
|
||||
entityName,
|
||||
k -> new java.util.ArrayList<>()
|
||||
)
|
||||
.add(livingEntity);
|
||||
|
||||
} else {
|
||||
|
||||
babyTargets
|
||||
.computeIfAbsent(
|
||||
entityName,
|
||||
k -> new java.util.ArrayList<>()
|
||||
)
|
||||
.add(livingEntity);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
adultTargets
|
||||
.computeIfAbsent(
|
||||
entityName,
|
||||
k -> new java.util.ArrayList<>()
|
||||
)
|
||||
.add(livingEntity);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Damage amount
|
||||
double damage =
|
||||
plugin.getConfig()
|
||||
.getDouble(
|
||||
"damage-amount"
|
||||
);
|
||||
|
||||
// Kill all targets first
|
||||
for (LivingEntity target : killAllTargets) {
|
||||
|
||||
target.damage(damage);
|
||||
|
||||
if (entityKillLogging) {
|
||||
killedThisCycle++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Leave alive logic
|
||||
// Adult targets
|
||||
for (List<LivingEntity> mobList : adultTargets.values()) {
|
||||
|
||||
int allowedKills =
|
||||
mobList.size() - leaveAlive;
|
||||
|
||||
if (allowedKills > 0) {
|
||||
|
||||
for (int i = 0; i < allowedKills; i++) {
|
||||
|
||||
LivingEntity target =
|
||||
mobList.get(i);
|
||||
|
||||
target.damage(damage);
|
||||
|
||||
if (entityKillLogging) {
|
||||
killedThisCycle++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Baby targets
|
||||
for (List<LivingEntity> mobList : babyTargets.values()) {
|
||||
|
||||
int allowedKills =
|
||||
mobList.size() - leaveAlive;
|
||||
|
||||
if (allowedKills > 0) {
|
||||
|
||||
for (int i = 0; i < allowedKills; i++) {
|
||||
|
||||
LivingEntity target =
|
||||
mobList.get(i);
|
||||
|
||||
target.damage(damage);
|
||||
|
||||
if (entityKillLogging) {
|
||||
killedThisCycle++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
long duration = System.nanoTime() - start;
|
||||
double ms = duration / 1_000_000.0;
|
||||
|
||||
if (debugEnabled && performanceLogging) {
|
||||
|
||||
if (ms >= 5.0) {
|
||||
|
||||
Location location =
|
||||
lastStandLocation;
|
||||
|
||||
if (location == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.getLogger().warning(
|
||||
"Slow cycle: "
|
||||
+ String.format("%.2f", ms)
|
||||
+ "ms"
|
||||
+ (
|
||||
entityKillLogging
|
||||
? " | Killed: " + killedThisCycle
|
||||
: ""
|
||||
)
|
||||
+ " | "
|
||||
+ location.getWorld().getName()
|
||||
+ " "
|
||||
+ location.getBlockX()
|
||||
+ " "
|
||||
+ location.getBlockY()
|
||||
+ " "
|
||||
+ location.getBlockZ()
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package com.rsscripting.mobstand.utils;
|
||||
|
||||
import com.rsscripting.mobstand.RSMobStandPlugin;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
|
||||
public class VersionChecker {
|
||||
|
||||
private final RSMobStandPlugin plugin;
|
||||
|
||||
private static String latestVersion =
|
||||
"Unknown";
|
||||
|
||||
private static final String VERSION_URL =
|
||||
"https://raw.githubusercontent.com/russelburgraymond/RS-MobStand/main/version.txt";
|
||||
|
||||
public VersionChecker(
|
||||
RSMobStandPlugin plugin
|
||||
) {
|
||||
|
||||
this.plugin = plugin;
|
||||
|
||||
}
|
||||
|
||||
public void checkVersion() {
|
||||
|
||||
plugin.getServer()
|
||||
.getScheduler()
|
||||
.runTaskAsynchronously(
|
||||
|
||||
plugin,
|
||||
|
||||
() -> {
|
||||
|
||||
try {
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| READ VERSION FILE
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
URL url =
|
||||
new URL(
|
||||
VERSION_URL
|
||||
);
|
||||
|
||||
BufferedReader reader =
|
||||
new BufferedReader(
|
||||
new InputStreamReader(
|
||||
url.openStream()
|
||||
)
|
||||
);
|
||||
|
||||
latestVersion =
|
||||
reader.readLine();
|
||||
|
||||
reader.close();
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| CURRENT VERSION
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
String currentVersion =
|
||||
plugin.getDescription()
|
||||
.getVersion();
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| UPDATE AVAILABLE
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
if (!currentVersion.equalsIgnoreCase(
|
||||
latestVersion
|
||||
)) {
|
||||
|
||||
plugin.getLogger().warning(
|
||||
"================================================="
|
||||
);
|
||||
|
||||
plugin.getLogger().warning(
|
||||
"A new version of RS-MobStand is available!"
|
||||
);
|
||||
|
||||
plugin.getLogger().warning(
|
||||
"Current Version: "
|
||||
+ currentVersion
|
||||
);
|
||||
|
||||
plugin.getLogger().warning(
|
||||
"Latest Version: "
|
||||
+ latestVersion
|
||||
);
|
||||
|
||||
plugin.getLogger().warning(
|
||||
"================================================="
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| UP TO DATE
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
else {
|
||||
|
||||
plugin.getLogger().info(
|
||||
"RS-MobStand is up to date."
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| FAILED
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
catch (Exception exception) {
|
||||
|
||||
plugin.getLogger().warning(
|
||||
"Could not check for updates."
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public static String getLatestVersion() {
|
||||
|
||||
return latestVersion;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
# =========================================
|
||||
# RS MobStand Configuration
|
||||
# RS MobStand by Big_Pappa
|
||||
# =========================================
|
||||
|
||||
config-version: 1
|
||||
|
||||
|
||||
##########################################################
|
||||
# Plugin Settings #
|
||||
##########################################################
|
||||
|
||||
# How often MobStands scan for mobs. Measured in ticks.
|
||||
# 20 ticks = 1 second
|
||||
scan-interval: 1200
|
||||
|
||||
# Default gravity state for new MobStands.
|
||||
# true = Stand will fall until sitting on top of a block
|
||||
# false = Stand will not fall if block below it is broken.
|
||||
default-gravity: true
|
||||
|
||||
# Damage dealt to mobs.
|
||||
damage-amount: 1000.0
|
||||
|
||||
|
||||
##########################################################
|
||||
# Scan Settings #
|
||||
# Recommended maximum radius: #
|
||||
# 32 for normal servers #
|
||||
# 48 for large/high-performance servers #
|
||||
##########################################################
|
||||
|
||||
# Default radius new MobStands begin with.
|
||||
default-scan-radius: 10
|
||||
|
||||
# Maximum radius players may set their MobStand to.
|
||||
# Recommended maximum radius:
|
||||
# 32 for normal servers
|
||||
# 48 for large/high-performance servers
|
||||
# Excessive values may impact performance heavily.
|
||||
max-player-scan-radius: 32
|
||||
|
||||
|
||||
##########################################################
|
||||
# Stand Count Settings #
|
||||
##########################################################
|
||||
|
||||
# Maximum number of stands a player may place at one time.
|
||||
# 0 = Unlimited
|
||||
max-stands-per-player: 5
|
||||
|
||||
# Maximum number of stands that may be placed on the server at one time.
|
||||
# 0 = Unlimited
|
||||
max-total-stands: 200
|
||||
|
||||
|
||||
##########################################################
|
||||
# Settings below are for leaving mobs alive by default. #
|
||||
##########################################################
|
||||
|
||||
# Default setting when new stands are created.
|
||||
default-leave-alive: 2
|
||||
|
||||
# Minimum amount users may set their stands to leave alive each
|
||||
# scan and kill cycle. NOTE: Named mobs DO NOT count as the
|
||||
# RS Mob Stand ignores those completely.
|
||||
min-leave-alive: 0
|
||||
|
||||
# Minimum amount users may set their stands to leave alive each
|
||||
# scan and kill cycle. NOTE: Named mobs DO NOT count as the
|
||||
# RS Mob Stand ignores those completely.
|
||||
max-leave-alive: 30
|
||||
|
||||
|
||||
##########################################################
|
||||
# Debugging #
|
||||
# Debugging options below this line are intended for #
|
||||
# development/testing and should be left disabled on #
|
||||
# production servers. #
|
||||
##########################################################
|
||||
|
||||
debug:
|
||||
enabled: false # Override all options below.
|
||||
|
||||
logging:
|
||||
performance: true # Enables performance log entries
|
||||
entity-kills: true # Adds kill count to performance entries (Requires performance: true)
|
||||
|
||||
performance:
|
||||
warning-ms: 100.0
|
||||
summary-interval-seconds: 300
|
||||
@@ -0,0 +1,131 @@
|
||||
# =========================================
|
||||
# RS MobStand Adult Mob Settings
|
||||
# =========================================
|
||||
# Add as many as you like. The menus will
|
||||
# Center, add rows, and pagenate them
|
||||
# automatically.
|
||||
# =========================================
|
||||
|
||||
#==========================================
|
||||
# available items
|
||||
# icon: icon that will show for that mob in the menu
|
||||
# enabled-by-default: wether or not will be killed by default
|
||||
# kill-all: true Kills all these mob types regardless of user settings
|
||||
# - Named mobs will still be ignored
|
||||
#================================================================
|
||||
# Kills all these mob types regardless of user settings
|
||||
# kill-all: true
|
||||
# - Named mobs will still be ignored
|
||||
#================================================================
|
||||
adult-mobs:
|
||||
|
||||
BLAZE:
|
||||
icon: BLAZE_ROD
|
||||
enabled-by-default: true
|
||||
# true: Stand will kill all regardless of settings.
|
||||
# false: (or not existing for mob) will follow players setting.
|
||||
# Ignores per-stand settings.
|
||||
kill-all: false
|
||||
CAVE_SPIDER:
|
||||
icon: SPIDER_EYE
|
||||
enabled-by-default: true
|
||||
|
||||
CHICKEN:
|
||||
icon: FEATHER
|
||||
enabled-by-default: true
|
||||
|
||||
COW:
|
||||
icon: LEATHER
|
||||
enabled-by-default: true
|
||||
|
||||
CREEPER:
|
||||
icon: GUNPOWDER
|
||||
enabled-by-default: true
|
||||
|
||||
DROWNED:
|
||||
icon: COPPER_INGOT
|
||||
enabled-by-default: true
|
||||
|
||||
ENDERMAN:
|
||||
icon: ENDER_PEARL
|
||||
enabled-by-default: true
|
||||
|
||||
GHAST:
|
||||
icon: GHAST_TEAR
|
||||
enabled-by-default: true
|
||||
|
||||
GUARDIAN:
|
||||
icon: PRISMARINE_SHARD
|
||||
enabled-by-default: true
|
||||
|
||||
HOGLIN:
|
||||
icon: PORKCHOP
|
||||
enabled-by-default: true
|
||||
|
||||
HUSK:
|
||||
icon: ROTTEN_FLESH
|
||||
enabled-by-default: true
|
||||
|
||||
MAGMA_CUBE:
|
||||
icon: MAGMA_CREAM
|
||||
enabled-by-default: true
|
||||
|
||||
PHANTOM:
|
||||
icon: PHANTOM_MEMBRANE
|
||||
enabled-by-default: true
|
||||
|
||||
PIG:
|
||||
icon: PORKCHOP
|
||||
enabled-by-default: true
|
||||
|
||||
PIGLIN:
|
||||
icon: GOLD_NUGGET
|
||||
enabled-by-default: true
|
||||
|
||||
RABBIT:
|
||||
icon: RABBIT_HIDE
|
||||
enabled-by-default: true
|
||||
|
||||
SHEEP:
|
||||
icon: WHITE_WOOL
|
||||
enabled-by-default: true
|
||||
|
||||
SHULKER:
|
||||
icon: SHULKER_SHELL
|
||||
enabled-by-default: true
|
||||
|
||||
SILVERFISH:
|
||||
icon: STONE
|
||||
enabled-by-default: true
|
||||
|
||||
SKELETON:
|
||||
icon: BONE
|
||||
enabled-by-default: true
|
||||
|
||||
SLIME:
|
||||
icon: SLIME_BALL
|
||||
enabled-by-default: true
|
||||
|
||||
SPIDER:
|
||||
icon: STRING
|
||||
enabled-by-default: true
|
||||
|
||||
WITCH:
|
||||
icon: GLASS_BOTTLE
|
||||
enabled-by-default: true
|
||||
|
||||
ZOGLIN:
|
||||
icon: ROTTEN_FLESH
|
||||
enabled-by-default: true
|
||||
|
||||
ZOMBIE:
|
||||
icon: ROTTEN_FLESH
|
||||
enabled-by-default: true
|
||||
|
||||
ZOMBIE_VILLAGER:
|
||||
icon: EMERALD
|
||||
enabled-by-default: true
|
||||
|
||||
ZOMBIFIED_PIGLIN:
|
||||
icon: GOLD_INGOT
|
||||
enabled-by-default: true
|
||||
@@ -0,0 +1,73 @@
|
||||
# =========================================
|
||||
# RS MobStand baby Mob Settings
|
||||
# =========================================
|
||||
# Add as many as you like. The menus will
|
||||
# Center, add rows, and pagenate them
|
||||
# automatically.
|
||||
# =========================================
|
||||
|
||||
#==========================================
|
||||
# available items
|
||||
# icon: icon that will show for that mob in the menu
|
||||
# enabled-by-default: wether or not will be killed by default
|
||||
# kill-all: Kills all these mob types regardless of user settings
|
||||
# - Named mobs will still be ignored
|
||||
#================================================================
|
||||
|
||||
baby-mobs:
|
||||
|
||||
CHICKEN:
|
||||
icon: FEATHER
|
||||
enabled-by-default: false
|
||||
# true: Stand will kill all regardless of players settings.
|
||||
# false: (or not existing for mob) will follow players setting.
|
||||
# Ignores per-stand settings.
|
||||
kill-all: false
|
||||
|
||||
COW:
|
||||
icon: LEATHER
|
||||
enabled-by-default: false
|
||||
|
||||
DROWNED:
|
||||
icon: COPPER_INGOT
|
||||
enabled-by-default: true
|
||||
|
||||
HOGLIN:
|
||||
icon: PORKCHOP
|
||||
enabled-by-default: true
|
||||
|
||||
HUSK:
|
||||
icon: ROTTEN_FLESH
|
||||
enabled-by-default: true
|
||||
|
||||
PIG:
|
||||
icon: PORKCHOP
|
||||
enabled-by-default: false
|
||||
|
||||
PIGLIN:
|
||||
icon: GOLD_NUGGET
|
||||
enabled-by-default: true
|
||||
|
||||
RABBIT:
|
||||
icon: RABBIT_HIDE
|
||||
enabled-by-default: false
|
||||
|
||||
SHEEP:
|
||||
icon: WHITE_WOOL
|
||||
enabled-by-default: false
|
||||
|
||||
ZOGLIN:
|
||||
icon: ROTTEN_FLESH
|
||||
enabled-by-default: true
|
||||
|
||||
ZOMBIE:
|
||||
icon: ROTTEN_FLESH
|
||||
enabled-by-default: true
|
||||
|
||||
ZOMBIE_VILLAGER:
|
||||
icon: EMERALD
|
||||
enabled-by-default: true
|
||||
|
||||
ZOMBIFIED_PIGLIN:
|
||||
icon: GOLD_INGOT
|
||||
enabled-by-default: true
|
||||
@@ -0,0 +1,27 @@
|
||||
name: RS-MobStand
|
||||
prefix: RS-MobStand
|
||||
version: 1.0.0
|
||||
main: com.rsscripting.mobstand.RSMobStandPlugin
|
||||
api-version: '1.21'
|
||||
|
||||
author: RSScripting
|
||||
|
||||
commands:
|
||||
rsms:
|
||||
description: RS MobStand main command
|
||||
usage: /rsms reload
|
||||
permission: rsmobstand.admin
|
||||
|
||||
permissions:
|
||||
|
||||
rsmobstand.use:
|
||||
description: Allows use of RS MobStand
|
||||
default: true
|
||||
|
||||
rsmobstand.admin:
|
||||
description: Admin access for RS MobStand
|
||||
default: op
|
||||
|
||||
rsmobstand.bypasslimits:
|
||||
description: Bypass MobStand placement limits
|
||||
default: op
|
||||
@@ -0,0 +1,15 @@
|
||||
=========================================
|
||||
1.0.0 (05/28/2026)
|
||||
=========================================
|
||||
|
||||
[ADDED]
|
||||
- Added kill-all support to adult and baby configs.
|
||||
|
||||
[FIXED]
|
||||
- Fixed admin reload not reloading mob configs.
|
||||
- Fixed adult/baby filters toggle bug.
|
||||
- Fixed kill-all mobs appearing disabled in menus.
|
||||
|
||||
[CHANGED]
|
||||
- Kill-all mobs now remain visually enabled.
|
||||
- Added admin override lore to forced-enabled mobs.
|
||||
Reference in new issue
Block a user