Mirror von
https://github.com/St3venAU/ArmorStandTools.git
synchronisiert 2024-12-27 12:00:07 +01:00
v4.2.0
Dieser Commit ist enthalten in:
Ursprung
48e2c34902
Commit
74df5da36a
18
README.md
18
README.md
@ -5,20 +5,20 @@ Spigot resource page with plugin download: http://www.spigotmc.org/resources/arm
|
||||
|
||||
Inspiration
|
||||
-----------
|
||||
I wanted to create an armor stand for each kit in my mini-game, and I quickly became frustrated with trying to use commands and numeric values to position the legs, arms, body and head of each armor stand, so I created this plugin which allows you to do all of this with ease. Simply couch/sneak while right clicking an armor stand to open the tools. The plugin can also generate a summon command that will re-create the armor stand at any time.
|
||||
I wanted to create an armor stand for each kit in my mini-game, and I quickly became frustrated with trying to use commands and numeric values to position the legs, arms, body and head of each armor stand, so I created this plugin which allows you to do all of this with ease. Among other features you can create any pose you wish just by holding right click on the tools and moving your cursor up and down on the armor stand. The plugin can also generate a summon command that will re-create the armor stand at any time.
|
||||
|
||||
Compatibility
|
||||
-------------
|
||||
- Armor Stand Tools v4.x.x - Spigot/CraftBukkit 1.17+
|
||||
- Armor Stand Tools v3.x.x - Spigot/CraftBukkit 1.13 - 1.16
|
||||
- Armor Stand Tools v2.4.3 - Spigot/CraftBukkit 1.8, 1.9, 1.10, 1.11, 1.12 (https://www.spigotmc.org/resources/armor-stand-tools.2237/download?version=175162)
|
||||
- Armor Stand Tools v2.4.3 - Spigot/CraftBukkit 1.8 - 1.12
|
||||
|
||||
Features
|
||||
--------
|
||||
- Summon armor stands.
|
||||
- Name armor stands.
|
||||
- Toggle: Gravity, Visibility, Arms, Base, Size, Invulnerability, Equipment Lock.
|
||||
- Manipulate the rotations of the Head, Body, Arms and Legs.
|
||||
- Manipulate the x/y/z rotations of the Head, Body, Arms and Legs. The value depends on how high up the armor stand's body you click with the tool (i.e. click near the feet is one extreme, near the top of the head is the other extreme).
|
||||
- Full control over armor stand's inventory (armor & items in hands).
|
||||
- Pick up and move armor stands.
|
||||
- Armor stand cloning tool.
|
||||
@ -37,18 +37,16 @@ Assigning Commands
|
||||
- If a player is crouching when they right-click the armor stand, the command will not be run.
|
||||
- Warning: Make sure you are careful when assigning console commands. Any player with the astools.ascmd.execute permission will be able to execute the command.
|
||||
- By default, any command assigned to an armor stand will use the default cooldown set in config.yml. This can be set on an individual basis using the /ascmd cooldown <ticks> command.
|
||||
|
||||
Commands
|
||||
--------
|
||||
- /astools or /ast : Give yourself all the armor stand tools (Note: Saves & clears your inventory which is restored by running this command again)
|
||||
- /astools reload : Reload the config file
|
||||
- /ascmd assign console <command> : Assign a console command to the nearest armor stand (within 4 blocks)
|
||||
- /ascmd assign player <command> : Assign a player command to the nearest armor stand
|
||||
- /ascmd remove : Remove the command assigned to the nearest armor stand
|
||||
- /ascmd view : View the command assigned to the nearest armor stand
|
||||
- /ascmd cooldown <ticks> : Sets the cooldown (in ticks) for the command on nearest armor stand (Setting this overrides the default cooldown from config.yml)
|
||||
- /ascmd cooldown remove : Removes the cooldown for the command on nearest armor stand (Default cooldown set in config.yml will be used)
|
||||
- /astools or /ast : Legacy command - instructs player to crouch right-click an armor stand to use AST.
|
||||
- /astools new : Create a new armor stand - will spawn being carried by the player
|
||||
- /astools reload : Reload the plugin (use when changing config files)
|
||||
|
||||
WorldGuard Integration
|
||||
----------------------
|
||||
@ -59,13 +57,13 @@ WorldGuard Integration
|
||||
|
||||
Permissions
|
||||
-----------
|
||||
- astools.use: Permission for using any of the tools, except for those that have a custom permission below
|
||||
- astools.new: Permission to use "/astools new" command to summon a new armor stand
|
||||
- astools.command : Permission for the /astools command
|
||||
- astools.reload : Permission to reload the plugin with /astools reload
|
||||
- astools.use : Permission for using any of the tools
|
||||
- astools.clone: Permission to use the clone tool
|
||||
- astools.head: Permission to use the player head tool (Ability to specify a player head for an armor stand)
|
||||
- astools.summon: Permission to use the summon tool (Summons an armor stand without requiring the materials)
|
||||
- astools.cmdblock: Permission to use the save tool (Creates a command block)
|
||||
- astools.reload: Permission to reload the plugin
|
||||
- astools.ascmd.assign.console: Permission to assign a console command to an armor stand
|
||||
- astools.ascmd.assign.player: Permission to assign a player command to an armor stand
|
||||
- astools.ascmd.remove: Permission to remove a command from an armor stand
|
||||
|
2
pom.xml
2
pom.xml
@ -5,7 +5,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.gmail.St3venAU.plugins</groupId>
|
||||
<artifactId>ArmorStandTools</artifactId>
|
||||
<version>4.1.2</version>
|
||||
<version>4.2.0</version>
|
||||
<name>ArmorStandTools</name>
|
||||
|
||||
<repositories>
|
||||
|
@ -14,12 +14,13 @@ import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
@ -30,24 +31,24 @@ public class AST extends JavaPlugin {
|
||||
|
||||
final static HashMap<UUID, ArmorStandTool> activeTool = new HashMap<>();
|
||||
final static HashMap<UUID, ArmorStand> selectedArmorStand = new HashMap<>();
|
||||
final static ArrayList<UUID> showAdvancedTools = new ArrayList<>();
|
||||
|
||||
public static final HashMap<UUID, ItemStack[]> savedInventories = new HashMap<>();
|
||||
|
||||
static AST plugin;
|
||||
|
||||
@SuppressWarnings({"unchecked", "JavaReflectionInvocation", "rawtypes"})
|
||||
@Override
|
||||
public void onLoad() {
|
||||
if (getServer().getPluginManager().getPlugin("WorldGuard") != null) {
|
||||
try {
|
||||
// Need to do this with reflection for some reason, otherwise plugin load fails when worldguard is not present, even though this code block is not actually executed unless worldguard is present ???
|
||||
WG_AST_FLAG = Class.forName("com.sk89q.worldguard.protection.flags.StateFlag").getConstructor(String.class, boolean.class).newInstance("ast", true);
|
||||
Class worldGuardClass = Class.forName("com.sk89q.worldguard.WorldGuard");
|
||||
Class<?> worldGuardClass = Class.forName("com.sk89q.worldguard.WorldGuard");
|
||||
Object worldGuard = worldGuardClass.getMethod("getInstance").invoke(worldGuardClass);
|
||||
Object flagRegistry = worldGuardClass.getMethod("getFlagRegistry").invoke(worldGuard);
|
||||
flagRegistry.getClass().getMethod("register", Class.forName("com.sk89q.worldguard.protection.flags.Flag")).invoke(flagRegistry, WG_AST_FLAG);
|
||||
getLogger().info("Registered custom WorldGuard flag: ast");
|
||||
} catch (Exception e) {
|
||||
getLogger().info("Failed to register custom WorldGuard flag");
|
||||
getLogger().warning("Failed to register custom WorldGuard flag");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -84,8 +85,8 @@ public class AST extends JavaPlugin {
|
||||
command.setExecutor(cmds);
|
||||
command.setTabCompleter(cmds);
|
||||
}
|
||||
Config.reload(this);
|
||||
|
||||
Config.reload();
|
||||
ArmorStandGUI.init();
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -97,7 +98,7 @@ public class AST extends JavaPlugin {
|
||||
}
|
||||
}
|
||||
}
|
||||
}.runTaskTimer(this, 5L, 5L);
|
||||
}.runTaskTimer(this, 3L, 3L);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -111,9 +112,18 @@ public class AST extends JavaPlugin {
|
||||
activeTool.remove(uuid);
|
||||
}
|
||||
}
|
||||
Player p;
|
||||
for(UUID uuid : savedInventories.keySet()) {
|
||||
p = getServer().getPlayer(uuid);
|
||||
if(p != null && p.isOnline()) {
|
||||
restoreInventory(p);
|
||||
}
|
||||
}
|
||||
savedInventories.clear();
|
||||
}
|
||||
|
||||
static void returnArmorStand(ArmorStand as) {
|
||||
if(as == null) return;
|
||||
if(as.hasMetadata("clone")) {
|
||||
as.remove();
|
||||
return;
|
||||
@ -133,10 +143,51 @@ public class AST extends JavaPlugin {
|
||||
as.remove();
|
||||
}
|
||||
|
||||
static void pickUpArmorStand(ArmorStand as, Player p) {
|
||||
private static void removeAllTools(Player p) {
|
||||
PlayerInventory i = p.getInventory();
|
||||
for(ArmorStandTool t : ArmorStandTool.values()) {
|
||||
i.remove(t.getItem());
|
||||
}
|
||||
}
|
||||
|
||||
void saveInventoryAndClear(Player p) {
|
||||
ItemStack[] inv = p.getInventory().getContents().clone();
|
||||
savedInventories.put(p.getUniqueId(), inv);
|
||||
p.getInventory().clear();
|
||||
}
|
||||
|
||||
static void restoreInventory(Player p) {
|
||||
removeAllTools(p);
|
||||
UUID uuid = p.getUniqueId();
|
||||
ItemStack[] savedInv = savedInventories.get(uuid);
|
||||
if(savedInv == null) return;
|
||||
PlayerInventory plrInv = p.getInventory();
|
||||
ItemStack[] newItems = plrInv.getContents().clone();
|
||||
plrInv.setContents(savedInv);
|
||||
savedInventories.remove(uuid);
|
||||
for(ItemStack i : newItems) {
|
||||
if(i == null) continue;
|
||||
HashMap<Integer, ItemStack> couldntFit = plrInv.addItem(i);
|
||||
for (ItemStack is : couldntFit.values()) {
|
||||
p.getWorld().dropItem(p.getLocation(), is);
|
||||
}
|
||||
}
|
||||
p.sendMessage(ChatColor.GREEN + Config.invReturned);
|
||||
}
|
||||
static ArmorStand getCarryingArmorStand(Player p) {
|
||||
UUID uuid = p.getUniqueId();
|
||||
return ArmorStandTool.MOVE == AST.activeTool.get(uuid) ? AST.selectedArmorStand.get(uuid) : null;
|
||||
}
|
||||
|
||||
static void pickUpArmorStand(ArmorStand as, Player p, boolean newlySummoned) {
|
||||
UUID uuid = p.getUniqueId();
|
||||
ArmorStand carrying = getCarryingArmorStand(p);
|
||||
if(carrying != null && !carrying.isDead()) {
|
||||
returnArmorStand(carrying);
|
||||
}
|
||||
activeTool.put(uuid, ArmorStandTool.MOVE);
|
||||
selectedArmorStand.put(uuid, as);
|
||||
if(newlySummoned) return;
|
||||
as.setMetadata("startLoc", new FixedMetadataValue(AST.plugin, as.getLocation()));
|
||||
}
|
||||
|
||||
@ -204,19 +255,19 @@ public class AST extends JavaPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
static boolean playerHasPermission(Player p, Block b, ArmorStandTool tool) {
|
||||
static boolean playerHasPermission(Player p, Block b, ArmorStandTool tool) {
|
||||
String permNode = tool == null ? "astools.use" : tool.getPermission();
|
||||
boolean enabled = tool == null || tool.isEnabled();
|
||||
boolean hasNode = Utils.hasPermissionNode(p, permNode);
|
||||
boolean blockPerm = checkBlockPermission(p, b);
|
||||
if(Config.debug) {
|
||||
if(Config.showDebugMessages) {
|
||||
AST.debug("Plr: " + p.getName() + ", Tool: " + tool + ", Tool En: " + enabled + ", Perm: " + permNode + ", Has Perm: " + hasNode + ", Location Perm: " + blockPerm);
|
||||
}
|
||||
return enabled && hasNode && blockPerm;
|
||||
}
|
||||
|
||||
static void debug(String msg) {
|
||||
if(!Config.debug) return;
|
||||
if(!Config.showDebugMessages) return;
|
||||
Bukkit.getLogger().log(Level.INFO, "[AST DEBUG] " + msg);
|
||||
}
|
||||
}
|
@ -25,17 +25,22 @@ import java.util.UUID;
|
||||
|
||||
class ArmorStandGUI implements Listener {
|
||||
|
||||
private static final int INV_SLOT_HELMET = 1;
|
||||
private static final int INV_SLOT_CHEST = 10;
|
||||
private static final int INV_SLOT_PANTS = 19;
|
||||
private static final int INV_SLOT_BOOTS = 28;
|
||||
private static final int INV_SLOT_R_HAND = 9;
|
||||
private static final int INV_SLOT_L_HAND = 11;
|
||||
private static final int INV_SLOT_HELMET = 1;
|
||||
private static final int INV_SLOT_CHEST = 10;
|
||||
private static final int INV_SLOT_LEGS = 19;
|
||||
private static final int INV_SLOT_BOOTS = 28;
|
||||
private static final int INV_SLOT_MAIN_HAND = 9;
|
||||
private static final int INV_SLOT_OFF_HAND = 11;
|
||||
|
||||
private static final HashSet<Integer> inUse = new HashSet<>();
|
||||
private static final HashSet<Integer> invSlots = new HashSet<>();
|
||||
private static ItemStack filler;
|
||||
|
||||
private static final HashSet<Material> helmetTypes = new HashSet<>();
|
||||
private static final HashSet<Material> chestTypes = new HashSet<>();
|
||||
private static final HashSet<Material> leggingTypes = new HashSet<>();
|
||||
private static final HashSet<Material> bootTypes = new HashSet<>();
|
||||
|
||||
private Inventory i;
|
||||
private ArmorStand as;
|
||||
|
||||
@ -44,20 +49,6 @@ class ArmorStandGUI implements Listener {
|
||||
p.sendMessage(ChatColor.RED + Config.guiInUse);
|
||||
return;
|
||||
}
|
||||
if(filler == null) {
|
||||
filler = new ItemStack(Material.BLACK_STAINED_GLASS_PANE, 1);
|
||||
ItemMeta im = filler.getItemMeta();
|
||||
if(im != null) {
|
||||
im.setDisplayName(" ");
|
||||
filler.setItemMeta(im);
|
||||
}
|
||||
invSlots.add(INV_SLOT_HELMET);
|
||||
invSlots.add(INV_SLOT_CHEST);
|
||||
invSlots.add(INV_SLOT_PANTS);
|
||||
invSlots.add(INV_SLOT_BOOTS);
|
||||
invSlots.add(INV_SLOT_R_HAND);
|
||||
invSlots.add(INV_SLOT_L_HAND);
|
||||
}
|
||||
AST.plugin.getServer().getPluginManager().registerEvents(this, AST.plugin);
|
||||
this.as = as;
|
||||
String name = as.getCustomName();
|
||||
@ -66,29 +57,58 @@ class ArmorStandGUI implements Listener {
|
||||
} else if(name.length() > 32) {
|
||||
name = name.substring(0, 32);
|
||||
}
|
||||
boolean showAdvancedTools = AST.showAdvancedTools.contains(p.getUniqueId());
|
||||
i = Bukkit.createInventory(null, showAdvancedTools ? 54 : 36, name);
|
||||
i = Bukkit.createInventory(null, 54, name);
|
||||
for(int slot = 0; slot < i.getSize(); slot++) {
|
||||
i.setItem(slot, filler);
|
||||
}
|
||||
for(ArmorStandTool tool : ArmorStandTool.values()) {
|
||||
if(tool.isEnabled() && (!tool.isAdvanced() || showAdvancedTools)) {
|
||||
if(tool.isForGui() && tool.isEnabled()) {
|
||||
i.setItem(tool.getSlot(), tool.updateLore(as));
|
||||
}
|
||||
}
|
||||
EntityEquipment entityEquipment = as.getEquipment();
|
||||
if(entityEquipment != null) {
|
||||
i.setItem(INV_SLOT_R_HAND, entityEquipment.getItemInMainHand());
|
||||
i.setItem(INV_SLOT_L_HAND, entityEquipment.getItemInOffHand());
|
||||
i.setItem(INV_SLOT_HELMET, entityEquipment.getHelmet());
|
||||
i.setItem(INV_SLOT_CHEST, entityEquipment.getChestplate());
|
||||
i.setItem(INV_SLOT_PANTS, entityEquipment.getLeggings());
|
||||
i.setItem(INV_SLOT_BOOTS, entityEquipment.getBoots());
|
||||
i.setItem(INV_SLOT_MAIN_HAND, entityEquipment.getItemInMainHand());
|
||||
i.setItem(INV_SLOT_OFF_HAND, entityEquipment.getItemInOffHand());
|
||||
i.setItem(INV_SLOT_HELMET, entityEquipment.getHelmet());
|
||||
i.setItem(INV_SLOT_CHEST, entityEquipment.getChestplate());
|
||||
i.setItem(INV_SLOT_LEGS, entityEquipment.getLeggings());
|
||||
i.setItem(INV_SLOT_BOOTS, entityEquipment.getBoots());
|
||||
}
|
||||
inUse.add(as.getEntityId());
|
||||
p.openInventory(i);
|
||||
}
|
||||
|
||||
static void init() {
|
||||
filler = new ItemStack(Material.BLACK_STAINED_GLASS_PANE, 1);
|
||||
ItemMeta im = filler.getItemMeta();
|
||||
if(im != null) {
|
||||
im.setDisplayName(" ");
|
||||
filler.setItemMeta(im);
|
||||
}
|
||||
invSlots.add(INV_SLOT_HELMET);
|
||||
invSlots.add(INV_SLOT_CHEST);
|
||||
invSlots.add(INV_SLOT_LEGS);
|
||||
invSlots.add(INV_SLOT_BOOTS);
|
||||
invSlots.add(INV_SLOT_MAIN_HAND);
|
||||
invSlots.add(INV_SLOT_OFF_HAND);
|
||||
String name;
|
||||
for(Material m : Material.values()) {
|
||||
name = m.name();
|
||||
if(name.endsWith("_HELMET")) helmetTypes.add(m);
|
||||
if(name.endsWith("_CHESTPLATE")) chestTypes.add(m);
|
||||
if(name.endsWith("_LEGGINGS")) leggingTypes.add(m);
|
||||
if(name.endsWith("_BOOTS")) bootTypes.add(m);
|
||||
}
|
||||
helmetTypes.add(Material.PLAYER_HEAD);
|
||||
helmetTypes.add(Material.CREEPER_HEAD);
|
||||
helmetTypes.add(Material.DRAGON_HEAD);
|
||||
helmetTypes.add(Material.ZOMBIE_HEAD);
|
||||
helmetTypes.add(Material.SKELETON_SKULL);
|
||||
helmetTypes.add(Material.WITHER_SKELETON_SKULL);
|
||||
helmetTypes.add(Material.JACK_O_LANTERN);
|
||||
}
|
||||
|
||||
static boolean isInUse(ArmorStand as) {
|
||||
return inUse.contains(as.getEntityId());
|
||||
}
|
||||
@ -103,13 +123,11 @@ class ArmorStandGUI implements Listener {
|
||||
@EventHandler
|
||||
public void onInventoryClick(InventoryClickEvent event) {
|
||||
if(!event.getInventory().equals(i) || !(event.getWhoClicked() instanceof Player p)) return;
|
||||
if(event.getClick() == ClickType.SHIFT_LEFT || event.getClick() == ClickType.SHIFT_RIGHT || event.getClick() == ClickType.NUMBER_KEY) {
|
||||
if(event.getClick() == ClickType.SHIFT_RIGHT || event.getClick() == ClickType.NUMBER_KEY) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
boolean rightClick = event.getClick() == ClickType.RIGHT;
|
||||
int slot = event.getRawSlot();
|
||||
if(slot > i.getSize()) return;
|
||||
Location l = as.getLocation();
|
||||
if(invSlots.contains(slot)) {
|
||||
if(AST.checkBlockPermission(p, l.getBlock())) {
|
||||
@ -120,6 +138,38 @@ class ArmorStandGUI implements Listener {
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(event.getClick() == ClickType.SHIFT_LEFT) {
|
||||
event.setCancelled(true);
|
||||
ItemStack item = event.getCurrentItem();
|
||||
if(slot > i.getSize() && item != null && !ArmorStandTool.isTool(item) && event.getClickedInventory() != null) {
|
||||
if (AST.checkBlockPermission(p, l.getBlock())) {
|
||||
Material m = item.getType();
|
||||
int newSlot = -1;
|
||||
if(helmetTypes.contains(m) && slotIsEmpty(INV_SLOT_HELMET)) {
|
||||
newSlot = INV_SLOT_HELMET;
|
||||
} else if(chestTypes.contains(m) && slotIsEmpty(INV_SLOT_CHEST)) {
|
||||
newSlot = INV_SLOT_CHEST;
|
||||
} else if(leggingTypes.contains(m) && slotIsEmpty(INV_SLOT_LEGS)) {
|
||||
newSlot = INV_SLOT_LEGS;
|
||||
} else if(bootTypes.contains(m) && slotIsEmpty(INV_SLOT_BOOTS)) {
|
||||
newSlot = INV_SLOT_BOOTS;
|
||||
} else if(slotIsEmpty(INV_SLOT_MAIN_HAND)) {
|
||||
newSlot = INV_SLOT_MAIN_HAND;
|
||||
} else if(slotIsEmpty(INV_SLOT_OFF_HAND)) {
|
||||
newSlot = INV_SLOT_OFF_HAND;
|
||||
}
|
||||
if(newSlot != -1) {
|
||||
i.setItem(newSlot, item);
|
||||
event.getClickedInventory().setItem(event.getSlot(), null);
|
||||
updateArmorStandInventory();
|
||||
}
|
||||
} else {
|
||||
p.sendMessage(ChatColor.RED + Config.wgNoPerm);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(slot > i.getSize()) return;
|
||||
event.setCancelled(true);
|
||||
if(!(event.getWhoClicked() instanceof Player)) return;
|
||||
ArmorStandTool t = ArmorStandTool.get(event.getCurrentItem());
|
||||
@ -128,13 +178,6 @@ class ArmorStandGUI implements Listener {
|
||||
p.sendMessage(ChatColor.RED + Config.generalNoPerm);
|
||||
return;
|
||||
}
|
||||
UUID uuid = p.getUniqueId();
|
||||
if(t.isAdvanced()) {
|
||||
AST.activeTool.put(uuid, t);
|
||||
AST.selectedArmorStand.put(uuid, as);
|
||||
p.closeInventory();
|
||||
t.showTitle(p);
|
||||
}
|
||||
switch (t) {
|
||||
case HEAD:
|
||||
case BODY:
|
||||
@ -142,6 +185,7 @@ class ArmorStandGUI implements Listener {
|
||||
case RARM:
|
||||
case LLEG:
|
||||
case RLEG:
|
||||
UUID uuid = p.getUniqueId();
|
||||
AST.activeTool.put(uuid, t);
|
||||
AST.selectedArmorStand.put(uuid, as);
|
||||
p.closeInventory();
|
||||
@ -153,15 +197,22 @@ class ArmorStandGUI implements Listener {
|
||||
break;
|
||||
case CLONE:
|
||||
p.closeInventory();
|
||||
AST.pickUpArmorStand(Utils.cloneArmorStand(as), p);
|
||||
AST.pickUpArmorStand(Utils.cloneArmorStand(as), p, true);
|
||||
Utils.title(p, Config.carrying);
|
||||
break;
|
||||
case SAVE:
|
||||
if(Config.requireCreative && p.getGameMode() != GameMode.CREATIVE) {
|
||||
p.sendMessage(ChatColor.RED + Config.creativeRequired);
|
||||
} else {
|
||||
Utils.generateCmdBlock(p.getLocation(), as);
|
||||
Utils.title(p, Config.cbCreated);
|
||||
case GEN_CMD:
|
||||
String command = Utils.createSummonCommand(as);
|
||||
p.sendMessage(command);
|
||||
if(Config.saveToolCreatesCommandBlock) {
|
||||
if(Config.requireCreative && p.getGameMode() != GameMode.CREATIVE) {
|
||||
p.sendMessage(ChatColor.RED + Config.creativeRequired);
|
||||
} else {
|
||||
Utils.generateCmdBlock(p.getLocation(), command);
|
||||
Utils.title(p, Config.cbCreated);
|
||||
}
|
||||
}
|
||||
if(Config.logGeneratedSummonCommands) {
|
||||
Config.logSummonCommand(p.getName(), command);
|
||||
}
|
||||
break;
|
||||
case SIZE:
|
||||
@ -199,56 +250,25 @@ class ArmorStandGUI implements Listener {
|
||||
case MOVE:
|
||||
p.closeInventory();
|
||||
as.removeMetadata("clone", AST.plugin);
|
||||
AST.pickUpArmorStand(as, p);
|
||||
AST.pickUpArmorStand(as, p, false);
|
||||
Utils.title(p, Config.carrying);
|
||||
break;
|
||||
case MOVE_X:
|
||||
case MOVE_Y:
|
||||
case MOVE_Z:
|
||||
double dist = rightClick ? -0.1 : 0.1;
|
||||
l.add(t == ArmorStandTool.MOVE_X ? dist : 0, t == ArmorStandTool.MOVE_Y ? dist : 0,t == ArmorStandTool.MOVE_Z ? dist : 0);
|
||||
if (!AST.playerHasPermission(p, l.getBlock(), null)) {
|
||||
p.closeInventory();
|
||||
p.sendMessage(ChatColor.RED + Config.wgNoPerm);
|
||||
break;
|
||||
}
|
||||
as.setGravity(false);
|
||||
as.teleport(l);
|
||||
break;
|
||||
case ROTATE:
|
||||
float yaw = l.getYaw() + (rightClick ? -5 : 5);
|
||||
l.setYaw(yaw);
|
||||
as.teleport(l);
|
||||
break;
|
||||
case GLOW:
|
||||
boolean glowing = !as.isGlowing();
|
||||
as.setGlowing(glowing);
|
||||
Utils.title(p, Config.glow + ": " + (glowing ? Config.isOn : Config.isOff));
|
||||
break;
|
||||
case ADVANCED:
|
||||
if(AST.showAdvancedTools.contains(uuid)) {
|
||||
AST.showAdvancedTools.remove(uuid);
|
||||
} else {
|
||||
AST.showAdvancedTools.add(uuid);
|
||||
}
|
||||
p.closeInventory();
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(ArmorStandGUI.isInUse(as)) {
|
||||
Utils.title(p, Config.guiInUse);
|
||||
return;
|
||||
}
|
||||
new ArmorStandGUI(as, p);
|
||||
}
|
||||
}.runTaskLater(AST.plugin, 1L);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
i.setItem(t.getSlot(), t.updateLore(as));
|
||||
}
|
||||
|
||||
private boolean slotIsEmpty(int slot) {
|
||||
ItemStack item = i.getItem(slot);
|
||||
return item == null || item.getType() == Material.AIR || item.getAmount() == 0;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryDrag(InventoryDragEvent event) {
|
||||
if(!event.getInventory().equals(i) || !(event.getWhoClicked() instanceof Player p)) return;
|
||||
@ -279,11 +299,11 @@ class ArmorStandGUI implements Listener {
|
||||
public void run() {
|
||||
EntityEquipment equipment = as.getEquipment();
|
||||
if(as == null || i == null || equipment == null) return;
|
||||
equipment.setItemInMainHand(i.getItem(INV_SLOT_R_HAND));
|
||||
equipment.setItemInOffHand(i.getItem(INV_SLOT_L_HAND));
|
||||
equipment.setItemInMainHand(i.getItem(INV_SLOT_MAIN_HAND));
|
||||
equipment.setItemInOffHand(i.getItem(INV_SLOT_OFF_HAND));
|
||||
equipment.setHelmet(i.getItem(INV_SLOT_HELMET));
|
||||
equipment.setChestplate(i.getItem(INV_SLOT_CHEST));
|
||||
equipment.setLeggings(i.getItem(INV_SLOT_PANTS));
|
||||
equipment.setLeggings(i.getItem(INV_SLOT_LEGS));
|
||||
equipment.setBoots(i.getItem(INV_SLOT_BOOTS));
|
||||
}
|
||||
}.runTaskLater(AST.plugin, 1L);
|
||||
|
@ -7,87 +7,77 @@ import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.bukkit.util.EulerAngle;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public enum ArmorStandTool {
|
||||
|
||||
HEAD ("gui_head", Material.WITHER_SKELETON_SKULL, 7, "astools.use", false, false),
|
||||
BODY ("gui_body", Material.NETHERITE_CHESTPLATE, 16, "astools.use", false, false),
|
||||
RARM ("gui_rarm", Material.REDSTONE_TORCH, 15, "astools.use", true, false),
|
||||
LARM ("gui_larm", Material.TORCH, 17, "astools.use", true, false),
|
||||
RLEG ("gui_rleg", Material.BLAZE_ROD, 24, "astools.use", true, false),
|
||||
LLEG ("gui_lleg", Material.BONE, 26, "astools.use", true, false),
|
||||
MOVE ("gui_move", Material.FEATHER, 8, "astools.use", false, false),
|
||||
|
||||
ROTATE ("gui_rotate", Material.ENDER_PEARL, 25, "astools.use", false, false),
|
||||
MOVE_X ("gui_moveX", Material.ORANGE_CANDLE, 33, "astools.use", false, false),
|
||||
MOVE_Y ("gui_moveY", Material.LIGHT_BLUE_CANDLE, 34, "astools.use", false, false),
|
||||
MOVE_Z ("gui_moveZ", Material.LIME_CANDLE, 35, "astools.use", false, false),
|
||||
|
||||
|
||||
NAME ("gui_name", Material.NAME_TAG, 3, "astools.use", false, false),
|
||||
INVIS ("gui_invis", Material.GOLD_NUGGET, 4, "astools.use", false, false),
|
||||
ARMS ("gui_arms", Material.ARROW, 5, "astools.use", false, false),
|
||||
BASE ("gui_base", Material.STONE_SLAB, 12, "astools.use", false, false),
|
||||
SIZE ("gui_size", Material.EMERALD, 14, "astools.use", false, false),
|
||||
GRAV ("gui_grav", Material.GHAST_TEAR, 13, "astools.use", false, false),
|
||||
INVUL ("gui_invul", Material.GLISTERING_MELON_SLICE, 21, "astools.use", false, false),
|
||||
SLOTS ("gui_slots", Material.IRON_HOE, 22, "astools.use", false, false),
|
||||
GLOW ("gui_glow", Material.GLOWSTONE, 23, "astools.glow", false, false),
|
||||
PHEAD ("gui_pHead", Material.PLAYER_HEAD, 30, "astools.head", false, false),
|
||||
SAVE ("gui_save", Material.DIAMOND, 31, "astools.cmdblock",false, false),
|
||||
CLONE ("gui_clone", Material.ARMOR_STAND, 32, "astools.clone", false, false),
|
||||
|
||||
ADVANCED("gui_advanced",Material.NETHER_STAR, 27, "astools.use", false, false),
|
||||
|
||||
RARM_X ("gui_rArmX", Material.REDSTONE_TORCH, 36, "astools.use", false, true),
|
||||
RARM_Y ("gui_rArmY", Material.REDSTONE_TORCH, 37, "astools.use", false, true),
|
||||
RARM_Z ("gui_rArmZ", Material.REDSTONE_TORCH, 38, "astools.use", false, true),
|
||||
LARM_X ("gui_lArmX", Material.TORCH, 39, "astools.use", false, true),
|
||||
LARM_Y ("gui_lArmY", Material.TORCH, 40, "astools.use", false, true),
|
||||
LARM_Z ("gui_lArmZ", Material.TORCH, 41, "astools.use", false, true),
|
||||
HEAD_X ("gui_headX", Material.WITHER_SKELETON_SKULL, 42, "astools.use", false, true),
|
||||
HEAD_Y ("gui_headY", Material.WITHER_SKELETON_SKULL, 43, "astools.use", false, true),
|
||||
HEAD_Z ("gui_headZ", Material.WITHER_SKELETON_SKULL, 44, "astools.use", false, true),
|
||||
|
||||
RLEG_X ("gui_rLegX", Material.BLAZE_ROD, 45, "astools.use", false, true),
|
||||
RLEG_Y ("gui_rLegY", Material.BLAZE_ROD, 46, "astools.use", false, true),
|
||||
RLEG_Z ("gui_rLegZ", Material.BLAZE_ROD, 47, "astools.use", false, true),
|
||||
LLEG_X ("gui_lLegX", Material.BONE, 48, "astools.use", false, true),
|
||||
LLEG_Y ("gui_lLegY", Material.BONE, 49, "astools.use", false, true),
|
||||
LLEG_Z ("gui_lLegZ", Material.BONE, 50, "astools.use", false, true),
|
||||
BODY_X ("gui_bodyX", Material.NETHERITE_CHESTPLATE, 51, "astools.use", false, true),
|
||||
BODY_Y ("gui_bodyY", Material.NETHERITE_CHESTPLATE, 52, "astools.use", false, true),
|
||||
BODY_Z ("gui_bodyZ", Material.NETHERITE_CHESTPLATE, 53, "astools.use", false, true);
|
||||
|
||||
|
||||
HEADX ("headX", Material.JACK_O_LANTERN, 12, false, "astools.use", false),
|
||||
HEADY ("headY", Material.JACK_O_LANTERN, 13, false, "astools.use", false),
|
||||
HEADZ ("headZ", Material.JACK_O_LANTERN, 14, false, "astools.use", false),
|
||||
LARMX ("lArmX", Material.TORCH, 27, false, "astools.use", false),
|
||||
LARMY ("lArmY", Material.TORCH, 28, false, "astools.use", false),
|
||||
LARMZ ("lArmZ", Material.TORCH, 29, false, "astools.use", false),
|
||||
RARMX ("rArmX", Material.REDSTONE_TORCH, 30, false, "astools.use", false),
|
||||
RARMY ("rArmY", Material.REDSTONE_TORCH, 31, false, "astools.use", false),
|
||||
RARMZ ("rArmZ", Material.REDSTONE_TORCH, 32, false, "astools.use", false),
|
||||
MOVEX ("moveX", Material.SHEARS, 3, false, "astools.use", false),
|
||||
MOVEY ("moveY", Material.SHEARS, 4, false, "astools.use", false),
|
||||
MOVEZ ("moveZ", Material.SHEARS, 5, false, "astools.use", false),
|
||||
LLEGX ("lLegX", Material.BONE, 18, false, "astools.use", false),
|
||||
LLEGY ("lLegY", Material.BONE, 19, false, "astools.use", false),
|
||||
LLEGZ ("lLegZ", Material.BONE, 20, false, "astools.use", false),
|
||||
RLEGX ("rLegX", Material.BLAZE_ROD, 21, false, "astools.use", false),
|
||||
RLEGY ("rLegY", Material.BLAZE_ROD, 22, false, "astools.use", false),
|
||||
RLEGZ ("rLegZ", Material.BLAZE_ROD, 23, false, "astools.use", false),
|
||||
BODYX ("bodyX", Material.NETHER_BRICKS, 9, false, "astools.use", false),
|
||||
BODYY ("bodyY", Material.NETHER_BRICKS, 10, false, "astools.use", false),
|
||||
BODYZ ("bodyZ", Material.NETHER_BRICKS, 11, false, "astools.use", false),
|
||||
SUMMON ("summon", Material.ARMOR_STAND, 0, false, "astools.summon", false),
|
||||
GUI ("gui", Material.NETHER_STAR, 1, false, "astools.use", false),
|
||||
ROTAT ("rotat", Material.MAGMA_CREAM, 2, false, "astools.use", false),
|
||||
CLONE ("gui_clone", Material.GLOWSTONE_DUST, 44, true, "astools.clone", false),
|
||||
GEN_CMD ("gui_gen_cmd", Material.COMMAND_BLOCK, 53, true, "astools.cmdblock",false),
|
||||
INVIS ("gui_invis", Material.GOLD_NUGGET, 42, true, "astools.use", false),
|
||||
SIZE ("gui_size", Material.EMERALD, 51, true, "astools.use", false),
|
||||
BASE ("gui_base", Material.STONE_SLAB, 41, true, "astools.use", false),
|
||||
GRAV ("gui_grav", Material.GHAST_TEAR, 49, true, "astools.use", false),
|
||||
ARMS ("gui_arms", Material.ARROW, 40, true, "astools.use", false),
|
||||
NAME ("gui_name", Material.NAME_TAG, 39, true, "astools.use", false),
|
||||
SLOTS ("gui_slots", Material.IRON_HOE, 43, true, "astools.use", false),
|
||||
PHEAD ("gui_pHead", Material.PLAYER_HEAD, 48, true, "astools.head", false),
|
||||
INVUL ("gui_invul", Material.GLISTERING_MELON_SLICE, 50, true, "astools.use", false),
|
||||
MOVE ("gui_move", Material.FEATHER, 25, true, "astools.use", false),
|
||||
GLOW ("gui_glow", Material.GLOWSTONE, 52, true, "astools.glow", false),
|
||||
HEAD ("gui_head", Material.WITHER_SKELETON_SKULL, 7, true, "astools.use", false),
|
||||
BODY ("gui_body", Material.NETHERITE_CHESTPLATE, 16, true, "astools.use", false),
|
||||
RARM ("gui_rarm", Material.REDSTONE_TORCH, 15, true, "astools.use", true),
|
||||
LARM ("gui_larm", Material.TORCH, 17, true, "astools.use", true),
|
||||
RLEG ("gui_rleg", Material.BLAZE_ROD, 24, true, "astools.use", true),
|
||||
LLEG ("gui_lleg", Material.BONE, 26, true, "astools.use", true);
|
||||
|
||||
private final ItemStack item;
|
||||
private final String config_id;
|
||||
private final int slot;
|
||||
private boolean enabled;
|
||||
private final boolean forGui;
|
||||
private final String permission;
|
||||
private final boolean reverseSneaking;
|
||||
private final boolean advanced;
|
||||
|
||||
private String name;
|
||||
|
||||
ArmorStandTool(String config_id, Material m, int slot, String permission, boolean reverseSneaking, boolean advanced) {
|
||||
ArmorStandTool(String config_id, Material m, int slot, boolean forGui, String permission, boolean reverseSneaking) {
|
||||
item = new ItemStack(m);
|
||||
this.config_id = config_id;
|
||||
this.slot = slot;
|
||||
this.enabled = true;
|
||||
this.forGui = forGui;
|
||||
this.permission = permission;
|
||||
this.reverseSneaking = reverseSneaking;
|
||||
this.advanced = advanced;
|
||||
}
|
||||
|
||||
boolean isAdvanced() {
|
||||
return advanced;
|
||||
}
|
||||
|
||||
void showTitle(Player p) {
|
||||
@ -95,23 +85,21 @@ public enum ArmorStandTool {
|
||||
ChatColor offColor = ChatColor.WHITE;
|
||||
ChatColor onColor = ChatColor.YELLOW;
|
||||
ChatColor divColor = ChatColor.BLACK;
|
||||
String msg;
|
||||
if(advanced) {
|
||||
msg = onColor + name +
|
||||
divColor + " | " +
|
||||
offColor + Config.click + ": " + Config.finish;
|
||||
} else {
|
||||
msg = (sneaking ? offColor : onColor) +
|
||||
Config.normal + ": X/" + (reverseSneaking ? "Z" : "Y") +
|
||||
divColor + " | " +
|
||||
(sneaking ? onColor : offColor) +
|
||||
Config.crouch + ": X/" + (reverseSneaking ? "Y" : "Z") +
|
||||
divColor + " | " +
|
||||
offColor + Config.click + ": " + Config.finish;
|
||||
}
|
||||
String msg =
|
||||
(sneaking ? offColor : onColor) +
|
||||
Config.normal + ": X/" + (reverseSneaking ? "Z" : "Y") +
|
||||
divColor + " | " +
|
||||
(sneaking ? onColor : offColor) +
|
||||
Config.crouch + ": X/" + (reverseSneaking ? "Y" : "Z") +
|
||||
divColor + " | " +
|
||||
offColor + Config.click + ": " + Config.finish;
|
||||
p.sendTitle(" ", msg, 0, 600, 0);
|
||||
}
|
||||
|
||||
ItemStack getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
private boolean is(ItemStack is) {
|
||||
return is != null &&
|
||||
is.getType() == item.getType() &&
|
||||
@ -121,6 +109,10 @@ public enum ArmorStandTool {
|
||||
is.getItemMeta().getDisplayName().equals(item.getItemMeta().getDisplayName());
|
||||
}
|
||||
|
||||
boolean isForGui() {
|
||||
return forGui;
|
||||
}
|
||||
|
||||
void setEnabled(FileConfiguration config) {
|
||||
enabled = config.getBoolean("enableTool." + config_id);
|
||||
}
|
||||
@ -151,42 +143,33 @@ public enum ArmorStandTool {
|
||||
}
|
||||
showTitle(p);
|
||||
EulerAngle eulerAngle = switch (this) {
|
||||
case HEAD, HEAD_X, HEAD_Y, HEAD_Z -> as.getHeadPose();
|
||||
case BODY, BODY_X, BODY_Y, BODY_Z -> as.getBodyPose();
|
||||
case LARM, LARM_X, LARM_Y, LARM_Z -> as.getLeftArmPose();
|
||||
case RARM, RARM_X, RARM_Y, RARM_Z -> as.getRightArmPose();
|
||||
case LLEG, LLEG_X, LLEG_Y, LLEG_Z -> as.getLeftLegPose();
|
||||
case RLEG, RLEG_X, RLEG_Y, RLEG_Z -> as.getRightLegPose();
|
||||
case HEAD -> as.getHeadPose();
|
||||
case BODY -> as.getBodyPose();
|
||||
case LARM -> as.getLeftArmPose();
|
||||
case RARM -> as.getRightArmPose();
|
||||
case LLEG -> as.getLeftLegPose();
|
||||
case RLEG -> as.getRightLegPose();
|
||||
default -> null;
|
||||
};
|
||||
if(eulerAngle == null) return;
|
||||
if(advanced) {
|
||||
eulerAngle = switch (this) {
|
||||
case HEAD_X, BODY_X, LARM_X, RARM_X, LLEG_X, RLEG_X -> eulerAngle.setX(getPitch(p, 8));
|
||||
case HEAD_Y, BODY_Y, LARM_Y, RARM_Y, LLEG_Y, RLEG_Y -> eulerAngle.setY(getPitch(p, 8));
|
||||
case HEAD_Z, BODY_Z, LARM_Z, RARM_Z, LLEG_Z, RLEG_Z -> eulerAngle.setZ(getPitch(p, 8));
|
||||
default -> eulerAngle;
|
||||
};
|
||||
} else {
|
||||
eulerAngle = eulerAngle.setX(getPitch(p, 4));
|
||||
boolean sneaking = reverseSneaking != p.isSneaking();
|
||||
double yaw = getRelativeYaw(p, as);
|
||||
eulerAngle = sneaking ? eulerAngle.setZ(yaw) : eulerAngle.setY(yaw);
|
||||
}
|
||||
eulerAngle = eulerAngle.setX(getPitch(p));
|
||||
boolean sneaking = reverseSneaking != p.isSneaking();
|
||||
double yaw = getRelativeYaw(p, as);
|
||||
eulerAngle = sneaking ? eulerAngle.setZ(yaw) : eulerAngle.setY(yaw);
|
||||
switch (this) {
|
||||
case HEAD, HEAD_X, HEAD_Y, HEAD_Z -> as.setHeadPose(eulerAngle);
|
||||
case BODY, BODY_X, BODY_Y, BODY_Z -> as.setBodyPose(eulerAngle);
|
||||
case LARM, LARM_X, LARM_Y, LARM_Z -> as.setLeftArmPose(eulerAngle);
|
||||
case RARM, RARM_X, RARM_Y, RARM_Z -> as.setRightArmPose(eulerAngle);
|
||||
case LLEG, LLEG_X, LLEG_Y, LLEG_Z -> as.setLeftLegPose(eulerAngle);
|
||||
case RLEG, RLEG_X, RLEG_Y, RLEG_Z -> as.setRightLegPose(eulerAngle);
|
||||
case HEAD -> as.setHeadPose(eulerAngle);
|
||||
case BODY -> as.setBodyPose(eulerAngle);
|
||||
case LARM -> as.setLeftArmPose(eulerAngle);
|
||||
case RARM -> as.setRightArmPose(eulerAngle);
|
||||
case LLEG -> as.setLeftLegPose(eulerAngle);
|
||||
case RLEG -> as.setRightLegPose(eulerAngle);
|
||||
}
|
||||
}
|
||||
|
||||
// Get pitch and format as 0 to 2pi radians
|
||||
// Actual pitch multiplied for increased sensitivity
|
||||
private double getPitch(Player p, int multiplier) {
|
||||
double pitch = p.getLocation().getPitch() * multiplier;
|
||||
private double getPitch(Player p) {
|
||||
double pitch = p.getLocation().getPitch() * 4;
|
||||
while(pitch < 0) {
|
||||
pitch += 360;
|
||||
}
|
||||
@ -210,6 +193,23 @@ public enum ArmorStandTool {
|
||||
return yaw * Math.PI / 180.0;
|
||||
}
|
||||
|
||||
static void give(Player p) {
|
||||
PlayerInventory i = p.getInventory();
|
||||
for(ArmorStandTool t : values()) {
|
||||
if(t.enabled && !t.forGui) {
|
||||
i.setItem(t.slot, t.item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isTool(ItemStack is) {
|
||||
return get(is) != null;
|
||||
}
|
||||
|
||||
static boolean isHoldingTool(Player p) {
|
||||
return isTool(p.getInventory().getItemInMainHand());
|
||||
}
|
||||
|
||||
ItemStack updateLore(ArmorStand as) {
|
||||
switch (this) {
|
||||
case INVIS:
|
||||
@ -254,6 +254,10 @@ public enum ArmorStandTool {
|
||||
return meta.getOwningPlayer().getName();
|
||||
}
|
||||
|
||||
static ArmorStandTool get(Player p) {
|
||||
return get(p.getInventory().getItemInMainHand());
|
||||
}
|
||||
|
||||
static ArmorStandTool get(ItemStack is) {
|
||||
if(is == null || is.getItemMeta() == null || !is.getItemMeta().hasDisplayName()) return null;
|
||||
for(ArmorStandTool t : values()) {
|
||||
@ -268,7 +272,15 @@ public enum ArmorStandTool {
|
||||
ItemMeta im = t.item.getItemMeta();
|
||||
if(im != null) {
|
||||
im.setDisplayName(ChatColor.YELLOW + t.name);
|
||||
im.setLore(config.getStringList("tool." + t.config_id + ".lore"));
|
||||
List<String> lore = config.getStringList("tool." + t.config_id + ".lore");
|
||||
if(t == GEN_CMD) {
|
||||
String cmdBlk = lore.size() > 0 ? lore.get(0) : "";
|
||||
String logged = lore.size() > 1 ? lore.get(1) : "";
|
||||
lore.clear();
|
||||
if(cmdBlk.length() > 0 && Config.saveToolCreatesCommandBlock) lore.add(cmdBlk);
|
||||
if(logged.length() > 0 && Config.logGeneratedSummonCommands) lore.add(logged);
|
||||
}
|
||||
im.setLore(lore);
|
||||
t.item.setItemMeta(im);
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,19 @@
|
||||
package com.gmail.st3venau.plugins.armorstandtools;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
class Commands implements CommandExecutor, TabCompleter {
|
||||
|
||||
@ -26,35 +25,32 @@ class Commands implements CommandExecutor, TabCompleter {
|
||||
}
|
||||
String cmd = command.getName().toLowerCase();
|
||||
if(cmd.equals("astools") || cmd.equals("ast")) {
|
||||
if (!Utils.hasPermissionNode(p, "astools.use")) {
|
||||
if (!Utils.hasPermissionNode(p, "astools.command")) {
|
||||
p.sendMessage(ChatColor.RED + Config.noCommandPerm);
|
||||
return true;
|
||||
}
|
||||
if(args.length > 0 && args[0].equalsIgnoreCase("new")) {
|
||||
// astools new
|
||||
if (!Utils.hasPermissionNode(p, "astools.new")) {
|
||||
p.sendMessage(ChatColor.RED + Config.noCommandPerm);
|
||||
return true;
|
||||
}
|
||||
Location l = Utils.getLocationFacing(p.getLocation());
|
||||
if(l.getWorld() == null) {
|
||||
p.sendMessage(ChatColor.RED + Config.error);
|
||||
return true;
|
||||
}
|
||||
ArmorStand as = (ArmorStand) l.getWorld().spawnEntity(l, EntityType.ARMOR_STAND);
|
||||
AST.pickUpArmorStand(as, p);
|
||||
Utils.title(p, Config.carrying);
|
||||
} else if (args.length > 0 && args[0].equalsIgnoreCase("reload")) {
|
||||
if (Utils.hasPermissionNode(p, "astools.reload")) {
|
||||
Config.reload(null);
|
||||
p.sendMessage(ChatColor.GREEN + Config.reloaded);
|
||||
if (args.length == 0) {
|
||||
UUID uuid = p.getUniqueId();
|
||||
if (AST.savedInventories.containsKey(uuid)) {
|
||||
AST.restoreInventory(p);
|
||||
} else {
|
||||
p.sendMessage(ChatColor.RED + Config.noCommandPerm);
|
||||
AST.plugin.saveInventoryAndClear(p);
|
||||
ArmorStandTool.give(p);
|
||||
p.sendMessage(ChatColor.GREEN + Config.giveMsg1);
|
||||
p.sendMessage(ChatColor.AQUA + Config.giveMsg2);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
p.sendMessage(ChatColor.AQUA + Config.instructions1 + ChatColor.GREEN + " /ast new " + ChatColor.AQUA + Config.instructions2);
|
||||
return true;
|
||||
if (args[0].equalsIgnoreCase("reload")) {
|
||||
if (Utils.hasPermissionNode(p, "astools.reload")) {
|
||||
Config.reload();
|
||||
p.sendMessage(ChatColor.GREEN + Config.conReload);
|
||||
return true;
|
||||
} else {
|
||||
p.sendMessage(ChatColor.RED + Config.noRelPerm);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if(cmd.equals("ascmd")) {
|
||||
ArmorStand as = getNearbyArmorStand(p);
|
||||
if(as == null) {
|
||||
|
@ -1,48 +1,75 @@
|
||||
package com.gmail.st3venau.plugins.armorstandtools;
|
||||
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.sql.Timestamp;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
class Config {
|
||||
|
||||
private static AST plugin;
|
||||
private static File languageConfigFile;
|
||||
private static FileConfiguration languageConfig;
|
||||
private static Path summonCommandsLogPath;
|
||||
|
||||
private static final SimpleDateFormat timestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||
|
||||
static WorldGuardPlugin worldGuardPlugin;
|
||||
|
||||
static ItemStack helmet, chest, pants, boots, itemInHand, itemInOffHand;
|
||||
|
||||
static boolean isVisible = true;
|
||||
static boolean isSmall = false;
|
||||
static boolean hasArms = true;
|
||||
static boolean hasBasePlate = false;
|
||||
static boolean hasGravity = false;
|
||||
static String defaultName = "";
|
||||
static boolean invulnerable = false;
|
||||
static boolean equipmentLock = false;
|
||||
static boolean allowMoveWorld = false;
|
||||
static boolean debug = false;
|
||||
static boolean deactivateOnWorldChange = true;
|
||||
static boolean showDebugMessages = false;
|
||||
static boolean requireCreative = false;
|
||||
static boolean ignoreWGForASCmdExecution = false;
|
||||
static int defaultASCmdCooldownTicks = 0;
|
||||
static boolean ignoreWGForASCmdExecution = false;
|
||||
static boolean saveToolCreatesCommandBlock = true;
|
||||
static boolean logGeneratedSummonCommands = false;
|
||||
|
||||
static final ArrayList<String> deniedCommands = new ArrayList<>();
|
||||
|
||||
static String
|
||||
asDropped, asVisible, isTrue, isFalse, carrying,
|
||||
cbCreated, size, small, normal, basePlate, isOn,
|
||||
isOff, gravity, arms, invul, equip, locked,
|
||||
unLocked, notConsole, noAirError, invalidName,
|
||||
wgNoPerm, currently, noCommandPerm, generalNoPerm,
|
||||
armorStand, none, guiInUse, noASNearBy, closestAS,
|
||||
creativeRequired, hasNoCmd, hasCmd, type, command,
|
||||
unassignedCmd, assignedCmdToAS, assignCmdError,
|
||||
ascmdHelp, viewCmd, removeCmd, assignConsole,
|
||||
assignPlayer, executeCmdError, cmdOnCooldown,
|
||||
cooldownRemovedFrom, isAnInvalidCooldown,
|
||||
cooldownSetTo, ticksFor, setCooldown, glow,
|
||||
removeCooldown, instructions1, instructions2,
|
||||
crouch, click, finish, error, reloaded;
|
||||
invReturned, asDropped, asVisible, isTrue, isFalse,
|
||||
carrying, cbCreated, size, small, normal, basePlate,
|
||||
isOn, isOff, gravity, arms, invul, equip, locked,
|
||||
unLocked, notConsole, giveMsg1, giveMsg2, conReload,
|
||||
noRelPerm, noAirError, invalidName, wgNoPerm, currently,
|
||||
noCommandPerm, generalNoPerm, armorStand, none,
|
||||
guiInUse, noASNearBy, closestAS, creativeRequired,
|
||||
hasNoCmd, hasCmd, type, command, unassignedCmd,
|
||||
assignedCmdToAS, assignCmdError, ascmdHelp, viewCmd,
|
||||
removeCmd, assignConsole, assignPlayer, executeCmdError,
|
||||
cmdOnCooldown, cooldownRemovedFrom, isAnInvalidCooldown,
|
||||
cooldownSetTo, ticksFor, setCooldown, removeCooldown,
|
||||
cmdNotAllowed, glow, crouch, click, finish;
|
||||
|
||||
static void reload(AST main) {
|
||||
if(main != null) plugin = main;
|
||||
static void reload() {
|
||||
reloadMainConfig();
|
||||
saveDefaultLanguageConfig();
|
||||
reloadLanguageConfig();
|
||||
@ -50,62 +77,102 @@ class Config {
|
||||
}
|
||||
|
||||
private static void reloadMainConfig() {
|
||||
plugin.saveDefaultConfig();
|
||||
plugin.reloadConfig();
|
||||
FileConfiguration config = plugin.getConfig();
|
||||
AST.plugin.saveDefaultConfig();
|
||||
AST.plugin.reloadConfig();
|
||||
FileConfiguration config = AST.plugin.getConfig();
|
||||
summonCommandsLogPath = Paths.get("AST-generated-summon-commands.log");
|
||||
helmet = toItemStack(config.getString("helmet"));
|
||||
chest = toItemStack(config.getString("chest"));
|
||||
pants = toItemStack(config.getString("pants"));
|
||||
boots = toItemStack(config.getString("boots"));
|
||||
itemInHand = toItemStack(config.getString("inHand"));
|
||||
itemInOffHand = toItemStack(config.getString("inOffHand"));
|
||||
isVisible = config.getBoolean("isVisible");
|
||||
isSmall = config.getBoolean("isSmall");
|
||||
hasArms = config.getBoolean("hasArms");
|
||||
hasBasePlate = config.getBoolean("hasBasePlate");
|
||||
hasGravity = config.getBoolean("hasGravity");
|
||||
defaultName = config.getString("name");
|
||||
invulnerable = config.getBoolean("invulnerable");
|
||||
equipmentLock = config.getBoolean("equipmentLock");
|
||||
allowMoveWorld = config.getBoolean("allowMovingStandsBetweenWorlds");
|
||||
deactivateOnWorldChange = config.getBoolean("deactivateToolsOnWorldChange");
|
||||
requireCreative = config.getBoolean("requireCreativeForSaveAsCmdBlock");
|
||||
defaultASCmdCooldownTicks = config.getInt( "defaultASCmdCooldownTicks");
|
||||
defaultASCmdCooldownTicks = config.getInt("defaultASCmdCooldownTicks");
|
||||
ignoreWGForASCmdExecution = config.getBoolean("bypassWorldguardForASCmdExecution");
|
||||
debug = config.getBoolean("showDebugMessages", false);
|
||||
showDebugMessages = config.getBoolean("showDebugMessages", false);
|
||||
saveToolCreatesCommandBlock = config.getBoolean("saveToolCreatesCommandBlock", true);
|
||||
logGeneratedSummonCommands = config.getBoolean("logGeneratedSummonCommands", false);
|
||||
|
||||
AST.activeTool.clear();
|
||||
AST.selectedArmorStand.clear();
|
||||
|
||||
deniedCommands.clear();
|
||||
for(String deniedCmd : config.getStringList("deniedCommandsWhileUsingTools")) {
|
||||
deniedCmd = deniedCmd.split(" ")[0].toLowerCase();
|
||||
while(deniedCmd.length() > 0 && deniedCmd.charAt(0) == '/') {
|
||||
deniedCmd = deniedCmd.substring(1);
|
||||
}
|
||||
if(deniedCmd.length() > 0) {
|
||||
deniedCommands.add(deniedCmd);
|
||||
}
|
||||
}
|
||||
|
||||
for(ArmorStandTool tool : ArmorStandTool.values()) {
|
||||
tool.setEnabled(config);
|
||||
}
|
||||
|
||||
Plugin plotSquared = plugin.getServer().getPluginManager().getPlugin("PlotSquared");
|
||||
Plugin plotSquared = AST.plugin.getServer().getPluginManager().getPlugin("PlotSquared");
|
||||
if (plotSquared != null && plotSquared.isEnabled()) {
|
||||
try {
|
||||
PlotSquaredHook.init();
|
||||
plugin.getLogger().log(Level.INFO, "PlotSquared plugin was found. PlotSquared support enabled.");
|
||||
AST.plugin.getLogger().log(Level.INFO, "PlotSquared plugin was found. PlotSquared support enabled.");
|
||||
}
|
||||
catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
plugin.getLogger().log(Level.WARNING, "PlotSquared plugin was found, but there was an error initializing PlotSquared support.");
|
||||
AST.plugin.getLogger().log(Level.WARNING, "PlotSquared plugin was found, but there was an error initializing PlotSquared support.");
|
||||
}
|
||||
} else {
|
||||
plugin.getLogger().log(Level.INFO, "PlotSquared plugin not found. Continuing without PlotSquared support.");
|
||||
AST.plugin.getLogger().log(Level.INFO, "PlotSquared plugin not found. Continuing without PlotSquared support.");
|
||||
}
|
||||
|
||||
Plugin wgp = plugin.getServer().getPluginManager().getPlugin("WorldGuard");
|
||||
Plugin wgp = AST.plugin.getServer().getPluginManager().getPlugin("WorldGuard");
|
||||
|
||||
if(wgp instanceof WorldGuardPlugin) {
|
||||
worldGuardPlugin = (WorldGuardPlugin) wgp;
|
||||
}
|
||||
if(config.getBoolean("integrateWithWorldGuard")) {
|
||||
plugin.getLogger().log(Level.INFO, worldGuardPlugin == null ? "WorldGuard plugin not found. Continuing without WorldGuard support." : "WorldGuard plugin found. WorldGuard support enabled.");
|
||||
AST.plugin.getLogger().log(Level.INFO, worldGuardPlugin == null ? "WorldGuard plugin not found. Continuing without WorldGuard support." : "WorldGuard plugin found. WorldGuard support enabled.");
|
||||
} else if(worldGuardPlugin != null) {
|
||||
plugin.getLogger().log(Level.WARNING, "WorldGuard plugin was found, but integrateWithWorldGuard is set to false in config.yml. Continuing without WorldGuard support.");
|
||||
AST.plugin.getLogger().log(Level.WARNING, "WorldGuard plugin was found, but integrateWithWorldGuard is set to false in config.yml. Continuing without WorldGuard support.");
|
||||
worldGuardPlugin = null;
|
||||
}
|
||||
}
|
||||
|
||||
static void logSummonCommand(String playerName, String command) {
|
||||
List<String> lines = Collections.singletonList("<" + timestampFormat.format(new Timestamp(System.currentTimeMillis())) + " " + playerName + "> " + command);
|
||||
try {
|
||||
Files.write(summonCommandsLogPath, lines, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.APPEND);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void saveDefaultLanguageConfig() {
|
||||
languageConfigFile = new File(plugin.getDataFolder(), "language.yml");
|
||||
languageConfigFile = new File(AST.plugin.getDataFolder(), "language.yml");
|
||||
if (!languageConfigFile.exists()) {
|
||||
plugin.saveResource("language.yml", false);
|
||||
AST.plugin.saveResource("language.yml", false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void reloadLanguageConfig() {
|
||||
languageConfigFile = new File(plugin.getDataFolder(), "language.yml");
|
||||
languageConfigFile = new File(AST.plugin.getDataFolder(), "language.yml");
|
||||
languageConfig = YamlConfiguration.loadConfiguration(languageConfigFile);
|
||||
InputStream defConfigStream = plugin.getResource("language.yml");
|
||||
InputStream defConfigStream = AST.plugin.getResource("language.yml");
|
||||
if (defConfigStream != null) {
|
||||
languageConfig.setDefaults(YamlConfiguration.loadConfiguration(new InputStreamReader(defConfigStream, StandardCharsets.UTF_8)));
|
||||
}
|
||||
invReturned = languageConfig.getString("invReturned");
|
||||
asDropped = languageConfig.getString("asDropped");
|
||||
asVisible = languageConfig.getString("asVisible");
|
||||
isTrue = languageConfig.getString("isTrue");
|
||||
@ -125,6 +192,10 @@ class Config {
|
||||
locked = languageConfig.getString("locked");
|
||||
unLocked = languageConfig.getString("unLocked");
|
||||
notConsole = languageConfig.getString("notConsole");
|
||||
giveMsg1 = languageConfig.getString("giveMsg1");
|
||||
giveMsg2 = languageConfig.getString("giveMsg2");
|
||||
conReload = languageConfig.getString("conReload");
|
||||
noRelPerm = languageConfig.getString("noRelPerm");
|
||||
noAirError = languageConfig.getString("noAirError");
|
||||
invalidName = languageConfig.getString("invalidName");
|
||||
wgNoPerm = languageConfig.getString("wgNoPerm");
|
||||
@ -158,14 +229,25 @@ class Config {
|
||||
setCooldown = languageConfig.getString("setCooldown");
|
||||
removeCooldown = languageConfig.getString("removeCooldown");
|
||||
ticksFor = languageConfig.getString("ticksFor");
|
||||
cmdNotAllowed = languageConfig.getString("cmdNotAllowed");
|
||||
glow = languageConfig.getString("glow");
|
||||
instructions1 = languageConfig.getString("instructions1");
|
||||
instructions2 = languageConfig.getString("instructions2");
|
||||
crouch = languageConfig.getString("crouch");
|
||||
click = languageConfig.getString("click");
|
||||
finish = languageConfig.getString("finish");
|
||||
error = languageConfig.getString("error");
|
||||
reloaded = languageConfig.getString("reloaded");
|
||||
}
|
||||
|
||||
private static ItemStack toItemStack(String s) {
|
||||
if(s == null || s.length() == 0) {
|
||||
return new ItemStack(Material.AIR);
|
||||
}
|
||||
Material m;
|
||||
try {
|
||||
m = Material.valueOf(s.toUpperCase());
|
||||
} catch(IllegalArgumentException iae) {
|
||||
AST.plugin.getLogger().warning("Error in config.yml: Invalid material name specifed (" + s + "). Continuing using AIR instead.");
|
||||
return new ItemStack(Material.AIR);
|
||||
}
|
||||
return new ItemStack(m, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,55 +2,119 @@ package com.gmail.st3venau.plugins.armorstandtools;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.GameRule;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.inventory.CraftItemEvent;
|
||||
import org.bukkit.event.inventory.InventoryAction;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
import org.bukkit.event.player.PlayerDropItemEvent;
|
||||
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.inventory.CraftingInventory;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@SuppressWarnings("CommentedOutCode")
|
||||
public class MainListener implements Listener {
|
||||
|
||||
private static final Pattern MC_USERNAME_PATTERN = Pattern.compile("^[a-zA-Z0-9_]{3,16}$");
|
||||
private final Pattern MC_USERNAME_PATTERN = Pattern.compile("^[a-zA-Z0-9_]{1,16}$");
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerInteractAtEntity(PlayerInteractAtEntityEvent event) {
|
||||
Player p = event.getPlayer();
|
||||
if(!(event.getRightClicked() instanceof ArmorStand as)) return;
|
||||
boolean hasAstPerm = Utils.hasPermissionNode(p, "astools.use");
|
||||
AST.debug(p.getName() + " right-clicked " + as.getName() + ", Crouching: " + p.isSneaking() + ", Has astools.use perm: " + hasAstPerm);
|
||||
if(p.isSneaking() && hasAstPerm) {
|
||||
if (ArmorStandGUI.isInUse(as)) {
|
||||
Utils.title(p, Config.guiInUse);
|
||||
event.setCancelled(true);
|
||||
AST.debug("Interaction cancelled as Armor Stand GUI is in use");
|
||||
return;
|
||||
}
|
||||
if (!AST.playerHasPermission(p, as.getLocation().getBlock(), null)) {
|
||||
p.sendMessage(ChatColor.RED + Config.generalNoPerm);
|
||||
return;
|
||||
}
|
||||
new ArmorStandGUI(as, p);
|
||||
Player p = event.getPlayer();
|
||||
if(!event.isCancelled() && ArmorStandGUI.isInUse(as)) {
|
||||
Utils.title(p, Config.guiInUse);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if(!event.isCancelled() && stopEditing(p, false)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
ArmorStandTool tool = ArmorStandTool.get(p);
|
||||
if(!event.isCancelled() && tool != null) {
|
||||
if (!AST.playerHasPermission(p, as.getLocation().getBlock(), tool)) {
|
||||
p.sendMessage(ChatColor.RED + Config.generalNoPerm);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
double num = event.getClickedPosition().getY() - 0.05;
|
||||
if (num < 0) {
|
||||
num = 0;
|
||||
} else if (num > 2) {
|
||||
num = 2;
|
||||
}
|
||||
num = 2.0 - num;
|
||||
double angle = num * Math.PI;
|
||||
boolean cancel = true;
|
||||
|
||||
switch (tool) {
|
||||
case HEADX -> as.setHeadPose(as.getHeadPose().setX(angle));
|
||||
case HEADY -> as.setHeadPose(as.getHeadPose().setY(angle));
|
||||
case HEADZ -> as.setHeadPose(as.getHeadPose().setZ(angle));
|
||||
case LARMX -> as.setLeftArmPose(as.getLeftArmPose().setX(angle));
|
||||
case LARMY -> as.setLeftArmPose(as.getLeftArmPose().setY(angle));
|
||||
case LARMZ -> as.setLeftArmPose(as.getLeftArmPose().setZ(angle));
|
||||
case RARMX -> as.setRightArmPose(as.getRightArmPose().setX(angle));
|
||||
case RARMY -> as.setRightArmPose(as.getRightArmPose().setY(angle));
|
||||
case RARMZ -> as.setRightArmPose(as.getRightArmPose().setZ(angle));
|
||||
case LLEGX -> as.setLeftLegPose(as.getLeftLegPose().setX(angle));
|
||||
case LLEGY -> as.setLeftLegPose(as.getLeftLegPose().setY(angle));
|
||||
case LLEGZ -> as.setLeftLegPose(as.getLeftLegPose().setZ(angle));
|
||||
case RLEGX -> as.setRightLegPose(as.getRightLegPose().setX(angle));
|
||||
case RLEGY -> as.setRightLegPose(as.getRightLegPose().setY(angle));
|
||||
case RLEGZ -> as.setRightLegPose(as.getRightLegPose().setZ(angle));
|
||||
case BODYX -> as.setBodyPose(as.getBodyPose().setX(angle));
|
||||
case BODYY -> as.setBodyPose(as.getBodyPose().setY(angle));
|
||||
case BODYZ -> as.setBodyPose(as.getBodyPose().setZ(angle));
|
||||
case MOVEX -> as.teleport(as.getLocation().add(0.05 * (p.isSneaking() ? -1 : 1), 0.0, 0.0));
|
||||
case MOVEY -> as.teleport(as.getLocation().add(0.0, 0.05 * (p.isSneaking() ? -1 : 1), 0.0));
|
||||
case MOVEZ -> as.teleport(as.getLocation().add(0.0, 0.0, 0.05 * (p.isSneaking() ? -1 : 1)));
|
||||
case ROTAT -> {
|
||||
Location l = as.getLocation();
|
||||
l.setYaw(((float) num) * 180F);
|
||||
as.teleport(l);
|
||||
}
|
||||
case GUI -> new ArmorStandGUI(as, p);
|
||||
default -> cancel = tool == ArmorStandTool.SUMMON || tool == ArmorStandTool.GEN_CMD || event.isCancelled();
|
||||
}
|
||||
event.setCancelled(cancel);
|
||||
return;
|
||||
}
|
||||
if((Config.ignoreWGForASCmdExecution || !event.isCancelled()) && !p.isSneaking()) {
|
||||
ArmorStandCmd asCmd = new ArmorStandCmd(as);
|
||||
if (asCmd.getCommand() != null) {
|
||||
@ -64,16 +128,26 @@ public class MainListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
ArmorStand getCarryingArmorStand(Player p) {
|
||||
UUID uuid = p.getUniqueId();
|
||||
return ArmorStandTool.MOVE == AST.activeTool.get(uuid) ? AST.selectedArmorStand.get(uuid) : null;
|
||||
@EventHandler
|
||||
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
|
||||
if (event.getRightClicked() instanceof ItemFrame && ArmorStandTool.isHoldingTool(event.getPlayer())) {
|
||||
event.setCancelled(true);
|
||||
event.getPlayer().updateInventory();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockPlace(BlockPlaceEvent event) {
|
||||
if (ArmorStandTool.isHoldingTool(event.getPlayer())) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerTeleport(PlayerTeleportEvent event) {
|
||||
if(event.getTo() == null || event.getFrom().getWorld() == event.getTo().getWorld()) return;
|
||||
if(event.getTo() == null || event.getTo().getWorld() == null || event.getTo().getWorld().equals(event.getFrom().getWorld())) return;
|
||||
final Player p = event.getPlayer();
|
||||
final ArmorStand as = getCarryingArmorStand(p);
|
||||
final ArmorStand as = AST.getCarryingArmorStand(p);
|
||||
if (as == null || as.isDead()) {
|
||||
stopEditing(p,false);
|
||||
return;
|
||||
@ -82,16 +156,24 @@ public class MainListener implements Listener {
|
||||
AST.returnArmorStand(as);
|
||||
stopEditing(p, true);
|
||||
}
|
||||
if(Config.deactivateOnWorldChange && AST.savedInventories.containsKey(p.getUniqueId())) {
|
||||
AST.restoreInventory(p);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
stopEditing(event.getPlayer(), true);
|
||||
Player p = event.getPlayer();
|
||||
stopEditing(p, true);
|
||||
if(AST.savedInventories.containsKey(p.getUniqueId())) {
|
||||
AST.restoreInventory(event.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
boolean stopEditing(Player p, boolean force) {
|
||||
ArmorStand carrying = getCarryingArmorStand(p);
|
||||
ArmorStand carrying = AST.getCarryingArmorStand(p);
|
||||
if(carrying != null && !carrying.isDead()) {
|
||||
p.setMetadata("lastEvent", new FixedMetadataValue(AST.plugin, System.currentTimeMillis()));
|
||||
if (AST.playerHasPermission(p, carrying.getLocation().getBlock(), null)) {
|
||||
Utils.title(p, Config.asDropped);
|
||||
carrying.removeMetadata("clone", AST.plugin);
|
||||
@ -108,6 +190,7 @@ public class MainListener implements Listener {
|
||||
AST.selectedArmorStand.remove(uuid);
|
||||
boolean editing = AST.activeTool.containsKey(uuid);
|
||||
if(editing) {
|
||||
p.setMetadata("lastEvent", new FixedMetadataValue(AST.plugin, System.currentTimeMillis()));
|
||||
AST.activeTool.remove(uuid);
|
||||
Utils.title(p, "");
|
||||
}
|
||||
@ -115,22 +198,112 @@ public class MainListener implements Listener {
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
Player p = event.getPlayer();
|
||||
if(stopEditing(p, false)) {
|
||||
event.setCancelled(true);
|
||||
public void onPlayerDeath(PlayerDeathEvent event) {
|
||||
final Player p = event.getEntity();
|
||||
List<ItemStack> drops = event.getDrops();
|
||||
for(ArmorStandTool t : ArmorStandTool.values()) {
|
||||
drops.remove(t.getItem());
|
||||
}
|
||||
if(Boolean.TRUE.equals(p.getWorld().getGameRuleValue(GameRule.KEEP_INVENTORY))) return;
|
||||
if(Bukkit.getServer().getPluginManager().getPermission("essentials.keepinv") != null && Utils.hasPermissionNode(p, "essentials.keepinv")) return;
|
||||
if(AST.savedInventories.containsKey(p.getUniqueId())) {
|
||||
drops.addAll(Arrays.asList(AST.savedInventories.get(p.getUniqueId())));
|
||||
AST.savedInventories.remove(p.getUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onCraftItem(CraftItemEvent event) {
|
||||
if (event.isCancelled()) return;
|
||||
final Player p = (Player) event.getWhoClicked();
|
||||
CraftingInventory inventory = event.getInventory();
|
||||
for(ItemStack is : inventory.getContents()) {
|
||||
if(ArmorStandTool.isTool(is)) {
|
||||
event.setCancelled(true);
|
||||
p.updateInventory();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryClick(InventoryClickEvent event) {
|
||||
if (event.isCancelled() || !(event.getWhoClicked() instanceof final Player p)) return;
|
||||
ItemStack item = event.getCurrentItem();
|
||||
if(event.getInventory().getHolder() != p && ArmorStandTool.isTool(item)) {
|
||||
event.setCancelled(true);
|
||||
p.updateInventory();
|
||||
return;
|
||||
}
|
||||
if(event.getAction() == InventoryAction.HOTBAR_SWAP || event.getAction() == InventoryAction.HOTBAR_MOVE_AND_READD) {
|
||||
if(Utils.hasAnyTools(p)) {
|
||||
event.setCancelled(true);
|
||||
p.updateInventory();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryDrag(InventoryDragEvent event) {
|
||||
if (event.isCancelled() || !(event.getWhoClicked() instanceof final Player p)) return;
|
||||
if (event.getInventory().getHolder() != p && Utils.containsItems(event.getNewItems().values())) {
|
||||
event.setCancelled(true);
|
||||
p.updateInventory();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerDropItem(final PlayerDropItemEvent event) {
|
||||
if (ArmorStandTool.isTool(event.getItemDrop().getItemStack())) {
|
||||
event.getItemDrop().remove();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
if(event.getHand() == EquipmentSlot.OFF_HAND) return;
|
||||
final Player p = event.getPlayer();
|
||||
if(stopEditing(p, false)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
ArmorStandTool tool = ArmorStandTool.get(event.getItem());
|
||||
if(tool == null) return;
|
||||
event.setCancelled(true);
|
||||
Action action = event.getAction();
|
||||
if(action == Action.LEFT_CLICK_AIR || action == Action.LEFT_CLICK_BLOCK) {
|
||||
Utils.cycleInventory(p);
|
||||
} else if((action == Action.RIGHT_CLICK_BLOCK || action == Action.RIGHT_CLICK_AIR) && tool == ArmorStandTool.SUMMON) {
|
||||
if (!AST.playerHasPermission(p, event.getClickedBlock(), tool)) {
|
||||
p.sendMessage(ChatColor.RED + Config.generalNoPerm);
|
||||
return;
|
||||
}
|
||||
Location l = Utils.getLocationFacing(p.getLocation());
|
||||
AST.pickUpArmorStand(spawnArmorStand(l), p, true);
|
||||
Utils.title(p, Config.carrying);
|
||||
}
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
p.updateInventory();
|
||||
}
|
||||
}.runTaskLater(AST.plugin, 1L);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
|
||||
if(event.getEntity() instanceof ArmorStand as) {
|
||||
if(event.getDamager() instanceof Player && stopEditing((Player) event.getDamager(), false)) {
|
||||
if(!(event.getEntity() instanceof ArmorStand as)) return;
|
||||
if(ArmorStandGUI.isInUse(as) || as.isInvulnerable()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
if(event.getDamager() instanceof Player p) {
|
||||
if(stopEditing(p, false)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if(ArmorStandGUI.isInUse(as) || as.isInvulnerable()) {
|
||||
if(ArmorStandTool.isHoldingTool(p)) {
|
||||
event.setCancelled(true);
|
||||
Utils.cycleInventory(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -144,6 +317,33 @@ public class MainListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
private ArmorStand spawnArmorStand(Location l) {
|
||||
World w = l.getWorld();
|
||||
assert w != null;
|
||||
ArmorStand as = (ArmorStand) w.spawnEntity(l, EntityType.ARMOR_STAND);
|
||||
EntityEquipment equipment = as.getEquipment();
|
||||
if(equipment != null) {
|
||||
equipment.setHelmet(Config.helmet);
|
||||
equipment.setChestplate(Config.chest);
|
||||
equipment.setLeggings(Config.pants);
|
||||
equipment.setBoots(Config.boots);
|
||||
equipment.setItemInMainHand(Config.itemInHand);
|
||||
equipment.setItemInOffHand(Config.itemInOffHand);
|
||||
}
|
||||
as.setVisible(Config.isVisible);
|
||||
as.setSmall(Config.isSmall);
|
||||
as.setArms(Config.hasArms);
|
||||
as.setBasePlate(Config.hasBasePlate);
|
||||
as.setGravity(Config.hasGravity);
|
||||
as.setInvulnerable(Config.invulnerable);
|
||||
if(Config.defaultName.length() > 0) {
|
||||
as.setCustomName(Config.defaultName);
|
||||
as.setCustomNameVisible(true);
|
||||
}
|
||||
Utils.setSlotsDisabled(as, Config.equipmentLock);
|
||||
return as;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockBreak(BlockBreakEvent event) {
|
||||
Block b = event.getBlock();
|
||||
@ -210,6 +410,19 @@ public class MainListener implements Listener {
|
||||
return item;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerCommand(final PlayerCommandPreprocessEvent event) {
|
||||
Player p = event.getPlayer();
|
||||
String cmd = event.getMessage().split(" ")[0].toLowerCase();
|
||||
while(cmd.length() > 0 && cmd.charAt(0) == '/') {
|
||||
cmd = cmd.substring(1);
|
||||
}
|
||||
if(cmd.length() > 0 && Config.deniedCommands.contains(cmd) && Utils.hasAnyTools(p)) {
|
||||
event.setCancelled(true);
|
||||
p.sendMessage(ChatColor.RED + Config.cmdNotAllowed);
|
||||
}
|
||||
}
|
||||
|
||||
private ArmorStand getArmorStand(Block b) {
|
||||
UUID uuid = null;
|
||||
for (MetadataValue value : b.getMetadata("armorStand")) {
|
||||
@ -233,6 +446,7 @@ public class MainListener implements Listener {
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
Player p = event.getPlayer();
|
||||
PermissionAttachment attachment = p.addAttachment(AST.plugin);
|
||||
attachment.setPermission("astools.command", true);
|
||||
attachment.setPermission("astools.use", true);
|
||||
attachment.setPermission("astools.summon", true);
|
||||
attachment.setPermission("astools.clone", true);
|
||||
@ -243,9 +457,8 @@ public class MainListener implements Listener {
|
||||
attachment.setPermission("astools.ascmd.remove", true);
|
||||
attachment.setPermission("astools.ascmd.assign.player", true);
|
||||
attachment.setPermission("astools.ascmd.assign.console", true);
|
||||
attachment.setPermission("astools.ascmd.cooldown", true);
|
||||
attachment.setPermission("astools.ascmd.execute", true);
|
||||
attachment.setPermission("astools.new", true);
|
||||
attachment.setPermission("astools.ascmd.cooldown", true);
|
||||
//attachment.setPermission("astools.bypass-wg-flag", true);
|
||||
}*/
|
||||
|
||||
|
@ -10,7 +10,7 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
class PlotSquaredHook {
|
||||
public class PlotSquaredHook {
|
||||
|
||||
public static PlotAPI api = null;
|
||||
|
||||
|
@ -6,20 +6,24 @@ import org.bukkit.block.Block;
|
||||
import org.bukkit.block.CommandBlock;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.LeatherArmorMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.util.EulerAngle;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
class Utils {
|
||||
@ -182,6 +186,14 @@ class Utils {
|
||||
return l;
|
||||
}
|
||||
|
||||
static boolean containsItems(Collection<ItemStack> items) {
|
||||
for(ItemStack i : items) {
|
||||
if(ArmorStandTool.get(i) != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static private String getItemStackTags(ItemStack is) {
|
||||
if(is == null) {
|
||||
@ -260,11 +272,11 @@ class Utils {
|
||||
return "";
|
||||
}
|
||||
return "ArmorItems:["
|
||||
+ itemInfo(e.getBoots()) + ","
|
||||
+ itemInfo(e.getLeggings()) + ","
|
||||
+ itemInfo(e.getChestplate()) + ","
|
||||
+ itemInfo(e.getHelmet())
|
||||
+ "],";
|
||||
+ itemInfo(e.getBoots()) + ","
|
||||
+ itemInfo(e.getLeggings()) + ","
|
||||
+ itemInfo(e.getChestplate()) + ","
|
||||
+ itemInfo(e.getHelmet())
|
||||
+ "],";
|
||||
}
|
||||
|
||||
static private String handItems(EntityEquipment e) {
|
||||
@ -272,9 +284,9 @@ class Utils {
|
||||
return "";
|
||||
}
|
||||
return "HandItems:["
|
||||
+ itemInfo(e.getItemInMainHand()) + ","
|
||||
+ itemInfo(e.getItemInOffHand())
|
||||
+ "],";
|
||||
+ itemInfo(e.getItemInMainHand()) + ","
|
||||
+ itemInfo(e.getItemInOffHand())
|
||||
+ "],";
|
||||
}
|
||||
|
||||
static private String angleInfo(EulerAngle ea) {
|
||||
@ -282,17 +294,17 @@ class Utils {
|
||||
}
|
||||
|
||||
static private String pose(ArmorStand as) {
|
||||
return "Pose:{"
|
||||
+ "Body:" + angleInfo(as.getBodyPose()) + ","
|
||||
+ "Head:" + angleInfo(as.getHeadPose()) + ","
|
||||
+ "LeftLeg:" + angleInfo(as.getLeftLegPose()) + ","
|
||||
+ "RightLeg:" + angleInfo(as.getRightLegPose()) + ","
|
||||
+ "LeftArm:" + angleInfo(as.getLeftArmPose()) + ","
|
||||
+ "RightArm:" + angleInfo(as.getRightArmPose())
|
||||
+ "}";
|
||||
return "Pose:{"
|
||||
+ "Body:" + angleInfo(as.getBodyPose()) + ","
|
||||
+ "Head:" + angleInfo(as.getHeadPose()) + ","
|
||||
+ "LeftLeg:" + angleInfo(as.getLeftLegPose()) + ","
|
||||
+ "RightLeg:" + angleInfo(as.getRightLegPose()) + ","
|
||||
+ "LeftArm:" + angleInfo(as.getLeftArmPose()) + ","
|
||||
+ "RightArm:" + angleInfo(as.getRightArmPose())
|
||||
+ "}";
|
||||
}
|
||||
|
||||
static private String createSummonCommand(ArmorStand as) {
|
||||
static String createSummonCommand(ArmorStand as) {
|
||||
Location asLocation = as.getLocation();
|
||||
EntityEquipment e = as.getEquipment();
|
||||
StringBuilder sb = new StringBuilder("summon minecraft:armor_stand ");
|
||||
@ -300,33 +312,33 @@ class Utils {
|
||||
sb.append(twoDec(asLocation.getY())).append(" ");
|
||||
sb.append(twoDec(asLocation.getZ())).append(" ");
|
||||
sb.append("{");
|
||||
if(!as.isVisible()) sb.append("Invisible:1,");
|
||||
if(!as.hasBasePlate()) sb.append("NoBasePlate:1,");
|
||||
if(!as.hasGravity()) sb.append("NoGravity:1,");
|
||||
if(as.hasArms()) sb.append("ShowArms:1,");
|
||||
if(as.isSmall()) sb.append("Small:1,");
|
||||
if(as.isInvulnerable()) sb.append("Invulnerable:1,");
|
||||
if(as.isGlowing()) sb.append("Glowing:1,");
|
||||
if(hasDisabledSlots(as)) sb.append("DisabledSlots:").append(disabledSlotsAsInteger(as)).append(",");
|
||||
if(as.isCustomNameVisible()) sb.append("CustomNameVisible:1,");
|
||||
if(as.getCustomName() != null) sb.append("CustomName:\"\\\"").append(as.getCustomName()).append("\\\"\",");
|
||||
if(as.getLocation().getYaw() != 0F) sb.append("Rotation:[").append(twoDec(as.getLocation().getYaw())).append("f],");
|
||||
sb.append(armorItems(e));
|
||||
sb.append(handItems(e));
|
||||
sb.append(pose(as));
|
||||
if(!as.isVisible()) sb.append("Invisible:1,");
|
||||
if(!as.hasBasePlate()) sb.append("NoBasePlate:1,");
|
||||
if(!as.hasGravity()) sb.append("NoGravity:1,");
|
||||
if(as.hasArms()) sb.append("ShowArms:1,");
|
||||
if(as.isSmall()) sb.append("Small:1,");
|
||||
if(as.isInvulnerable()) sb.append("Invulnerable:1,");
|
||||
if(as.isGlowing()) sb.append("Glowing:1,");
|
||||
if(hasDisabledSlots(as)) sb.append("DisabledSlots:").append(disabledSlotsAsInteger(as)).append(",");
|
||||
if(as.isCustomNameVisible()) sb.append("CustomNameVisible:1,");
|
||||
if(as.getCustomName() != null) sb.append("CustomName:\"\\\"").append(as.getCustomName()).append("\\\"\",");
|
||||
if(as.getLocation().getYaw() != 0F) sb.append("Rotation:[").append(twoDec(as.getLocation().getYaw())).append("f],");
|
||||
sb.append(armorItems(e));
|
||||
sb.append(handItems(e));
|
||||
sb.append(pose(as));
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
static void generateCmdBlock(Location l, ArmorStand as) {
|
||||
static void generateCmdBlock(Location l, String command) {
|
||||
Block b = l.getBlock();
|
||||
b.setType(Material.COMMAND_BLOCK);
|
||||
CommandBlock cb = (CommandBlock) b.getState();
|
||||
cb.setCommand(createSummonCommand(as));
|
||||
cb.setCommand(command);
|
||||
cb.update();
|
||||
}
|
||||
|
||||
private static String twoDec(double d) {
|
||||
static String twoDec(double d) {
|
||||
if(twoDec == null) {
|
||||
twoDec = new DecimalFormat("0.0#");
|
||||
DecimalFormatSymbols symbols = new DecimalFormatSymbols();
|
||||
@ -340,4 +352,39 @@ class Utils {
|
||||
return twoDec(d * 180.0 / Math.PI);
|
||||
}
|
||||
|
||||
static boolean hasAnyTools(Player p) {
|
||||
for(ItemStack i : p.getInventory()) {
|
||||
if(ArmorStandTool.isTool(i)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean onCooldown(Entity e) {
|
||||
for(MetadataValue meta : e.getMetadata("lastEvent")) {
|
||||
if(AST.plugin.equals(meta.getOwningPlugin())) {
|
||||
return System.currentTimeMillis() - meta.asLong() < 100;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void cycleInventory(Player p) {
|
||||
if(onCooldown(p)) return;
|
||||
Inventory i = p.getInventory();
|
||||
ItemStack temp;
|
||||
for (int n = 0; n < 9; n++) {
|
||||
temp = i.getItem(n);
|
||||
i.setItem(n, i.getItem(27 + n));
|
||||
i.setItem(27 + n, i.getItem(18 + n));
|
||||
i.setItem(18 + n, i.getItem(9 + n));
|
||||
i.setItem(9 + n, temp);
|
||||
}
|
||||
p.updateInventory();
|
||||
p.setMetadata("lastEvent", new FixedMetadataValue(AST.plugin, System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -9,36 +9,38 @@
|
||||
# config to allow it to be re-created. There may be new config options)
|
||||
#
|
||||
# Features:
|
||||
# - Manipulate the position of the Head, Body, Arms and Legs
|
||||
# - Toggle: Gravity, Visibility, Arms, Base plate, Size, Invulnerability, Equipment Lock, Glow
|
||||
# - Summon armor stands
|
||||
# - Name armor stands
|
||||
# - Full control over armor stand's inventory (armor & items in both hands)
|
||||
# - Create exact clones of armor stands
|
||||
# - Create a command block with the command to summon the same armor stand
|
||||
# - Set's an armor stand's head to the head of a specified player.
|
||||
# - Toggle: Gravity, Visibility, Arms, Base, Size, Invulnerability, Equipment Lock
|
||||
# - Manipulate the position of the Head, Body, Arms and Legs
|
||||
# - Full control over armor stand's inventory (armor & items in hands)
|
||||
# - Clone armor stand tool
|
||||
# - Create command block tool: Creates a command block with the command that will summon this
|
||||
# armor stand in its current state
|
||||
# - Player head tool: Set's an armor stand's head to the head of a specified player.
|
||||
# - Support for WorldGuard regions.
|
||||
# - User customizable language config.
|
||||
#
|
||||
# Commands:
|
||||
# /astools Give yourself all of the armor stand tools (Note: Clears your inventory)
|
||||
# /astools reload Reload the armor stand tools plugin config file
|
||||
# /ast Alias for the /astools
|
||||
# /ascmd assign console <command> Assign a console command to the nearest armor stand (within 4 blocks)
|
||||
# /ascmd assign player <command> Assign a player command to the nearest armor stand
|
||||
# /ascmd remove Remove the command assigned to the nearest armor stand
|
||||
# /ascmd view View the command assigned to the nearest armor stand
|
||||
# /ascmd cooldown <ticks> Set the cooldown for the command on nearest armor stand (Setting this overrides the default cooldown from config.yml)
|
||||
# /ascmd cooldown remove Remove the cooldown for the command on nearest armor stand (Default cooldown set in config.yml will be used)
|
||||
# /astools or /ast Legacy command - now gives instructions for player to crouch right-click an armor stand
|
||||
# /astools new Create a new armor stand - will spawn being carried by the player
|
||||
# /astools reload Reload the plugin (use when changing config files)
|
||||
# Note: Armor stand commands may include a %player% placeholder, which will get replaced by the executing player's name at time of execution.
|
||||
# Note: Commands may include a %player% placeholder, which will get replaced by the executing player's name at time of execution.
|
||||
#
|
||||
# Permissions:
|
||||
# astools.use Permission to using any of the tools, except the ones below that have their own separate permissions (see below)
|
||||
# astools.new Permission to use "/astools new" command to summon a new armor stand
|
||||
# astools.command Permission for the /astools command
|
||||
# astools.reload Permission to reload the plugin with /astools reload
|
||||
# astools.use Permission for using any of the tools (except the ones below that have their own separate permissions)
|
||||
# astools.clone Permission to use the clone tool (Clones an armor stand without requiring the materials)
|
||||
# astools.summon Permission to use the summon tool (Summons an armor stand without requiring the materials)
|
||||
# astools.head Permission to use the player head tool (Ability to specify a player head for an armor stand)
|
||||
# astools.cmdblock Permission to use the save tool (Creates a command block)
|
||||
# astools.reload Permission to reload the plugin
|
||||
# astools.ascmd.assign.console Permission to assign a console command to an armor stand
|
||||
# astools.ascmd.assign.player Permission to assign a player command to an armor stand
|
||||
# astools.ascmd.remove Permission to remove a command from an armor stand
|
||||
@ -55,15 +57,68 @@
|
||||
# this permission can use AST in worldguard regions even if the ast flag for that region is set to Deny.
|
||||
# - The ast worldguard flag is also ignored for players that have op.
|
||||
#
|
||||
showDebugMessages: false
|
||||
|
||||
# General config
|
||||
integrateWithWorldGuard: true
|
||||
allowMovingStandsBetweenWorlds: false
|
||||
deactivateToolsOnWorldChange: true
|
||||
requireCreativeForSaveAsCmdBlock: false
|
||||
defaultASCmdCooldownTicks: 0
|
||||
bypassWorldguardForASCmdExecution: false
|
||||
saveToolCreatesCommandBlock: true
|
||||
logGeneratedSummonCommands: false
|
||||
showDebugMessages: false
|
||||
|
||||
# Uncomment the section below to deny players access to commands of your choice when they have any AST tools in their inventory
|
||||
# Add as many command as you wish. Only the first word of each command is needed, anything after the first space is ignored.
|
||||
|
||||
#deniedCommandsWhileUsingTools:
|
||||
# - sell
|
||||
|
||||
# These are the defaults for spawning new armor stands with the /astools (or /ast) armor stand
|
||||
helmet: AIR
|
||||
chest: AIR
|
||||
pants: AIR
|
||||
boots: AIR
|
||||
inHand: AIR
|
||||
inOffHand: AIR
|
||||
isVisible: true
|
||||
isSmall: false
|
||||
hasArms: true
|
||||
hasBasePlate: false
|
||||
hasGravity: false
|
||||
name: ''
|
||||
invulnerable: false
|
||||
equipmentLock: false
|
||||
|
||||
# Enable/Disable Tools
|
||||
enableTool:
|
||||
headX: true
|
||||
headY: true
|
||||
headZ: true
|
||||
lArmX: true
|
||||
lArmY: true
|
||||
lArmZ: true
|
||||
rArmX: true
|
||||
rArmY: true
|
||||
rArmZ: true
|
||||
moveX: true
|
||||
moveY: true
|
||||
moveZ: true
|
||||
lLegX: true
|
||||
lLegY: true
|
||||
lLegZ: true
|
||||
rLegX: true
|
||||
rLegY: true
|
||||
rLegZ: true
|
||||
bodyX: true
|
||||
bodyY: true
|
||||
bodyZ: true
|
||||
summon: true
|
||||
gui: true
|
||||
rotat: true
|
||||
gui_clone: true
|
||||
gui_save: true
|
||||
gui_gen_cmd: true
|
||||
gui_invis: true
|
||||
gui_size: true
|
||||
gui_base: true
|
||||
@ -74,10 +129,6 @@ enableTool:
|
||||
gui_pHead: true
|
||||
gui_invul: true
|
||||
gui_move: true
|
||||
gui_rotate: true
|
||||
gui_moveX: true
|
||||
gui_moveY: true
|
||||
gui_moveZ: true
|
||||
gui_glow: true
|
||||
gui_head: true
|
||||
gui_body: true
|
||||
@ -85,22 +136,3 @@ enableTool:
|
||||
gui_rarm: true
|
||||
gui_lleg: true
|
||||
gui_rleg: true
|
||||
gui_advanced: true
|
||||
gui_lArmX: true
|
||||
gui_lArmY: true
|
||||
gui_lArmZ: true
|
||||
gui_rArmX: true
|
||||
gui_rArmY: true
|
||||
gui_rArmZ: true
|
||||
gui_headX: true
|
||||
gui_headY: true
|
||||
gui_headZ: true
|
||||
gui_lLegX: true
|
||||
gui_lLegY: true
|
||||
gui_lLegZ: true
|
||||
gui_rLegX: true
|
||||
gui_rLegY: true
|
||||
gui_rLegZ: true
|
||||
gui_bodyX: true
|
||||
gui_bodyY: true
|
||||
gui_bodyZ: true
|
||||
|
@ -27,6 +27,7 @@
|
||||
####################
|
||||
# General Messages #
|
||||
####################
|
||||
invReturned: 'Inventory contents returned'
|
||||
asDropped: 'Armor stand dropped'
|
||||
asVisible: 'Visible'
|
||||
isTrue: 'True'
|
||||
@ -48,6 +49,10 @@ locked: 'Locked'
|
||||
unLocked: 'Un-Locked'
|
||||
currently: 'Currently'
|
||||
notConsole: 'This command can not be run from console'
|
||||
giveMsg1: 'Given armor stand tools. L-click any tool to cycle through tools.'
|
||||
giveMsg2: 'Run this command again to return your inventory.'
|
||||
conReload: 'Armor Stand Tools config reloaded'
|
||||
noRelPerm: 'You do not have permission to reload the plugin'
|
||||
noAirError: 'Error: Failed to find a near-by air block. Move and try again.'
|
||||
invalidName: 'is not a valid minecraft username'
|
||||
wgNoPerm: 'No permission to alter an armor stand in this region'
|
||||
@ -83,39 +88,150 @@ setCooldown: 'Set the cooldown for the command'
|
||||
removeCooldown: 'Remove the cooldown for the command'
|
||||
# New since v3.4.1
|
||||
glow: 'Glow'
|
||||
cmdNotAllowed: 'That command is not allowed while using Armor Stand Tools'
|
||||
#New since v4.0.0
|
||||
crouch: 'Crouch'
|
||||
click: 'Click'
|
||||
finish: 'Finish'
|
||||
#New since v4.0.2
|
||||
instructions1: 'Crouch + right-click an armor stand to edit, or use command'
|
||||
instructions2: 'to summon a new armor stand'
|
||||
error: 'An error occured. Try again.'
|
||||
#New since v4.1.0
|
||||
reloaded : 'Armor Stand Tools reloaded'
|
||||
#
|
||||
#############################
|
||||
# Tool names & descriptions #
|
||||
#############################
|
||||
tool:
|
||||
summon:
|
||||
name: 'Summon Armor Stand'
|
||||
lore:
|
||||
- 'R-Click to summon an armor stand and pick it up'
|
||||
- 'Any click will drop it'
|
||||
gui:
|
||||
name: 'GUI Multi-Tool'
|
||||
lore:
|
||||
- 'R-Click armor stand to open a GUI to tweak'
|
||||
- 'the attributes of the armor stand or change'
|
||||
- 'its armor and items'
|
||||
rotat:
|
||||
name: 'Rotation'
|
||||
lore:
|
||||
- 'R-Click armor stand to change its Rotation'
|
||||
- 'Value depends on how high up the body you click'
|
||||
headX:
|
||||
name: 'Head X'
|
||||
lore:
|
||||
- 'R-Click armor stand to change Head X Value'
|
||||
- 'Value depends on how high up the body you click'
|
||||
headY:
|
||||
name: 'Head Y'
|
||||
lore:
|
||||
- 'R-Click armor stand to change Head Y Value'
|
||||
- 'Value depends on how high up the body you click'
|
||||
headZ:
|
||||
name: 'Head Z'
|
||||
lore:
|
||||
- 'R-Click armor stand to change Head Z Value'
|
||||
- 'Value depends on how high up the body you click'
|
||||
lArmX:
|
||||
name: 'Left Arm X'
|
||||
lore:
|
||||
- 'R-Click armor stand to change Left Arm X Value'
|
||||
- 'Value depends on how high up the body you click'
|
||||
lArmY:
|
||||
name: 'Left Arm Y'
|
||||
lore:
|
||||
- 'R-Click armor stand to change Left Arm Y Value'
|
||||
- 'Value depends on how high up the body you click'
|
||||
lArmZ:
|
||||
name: 'Left Arm Z'
|
||||
lore:
|
||||
- 'R-Click armor stand to change Left Arm Z Value'
|
||||
- 'Value depends on how high up the body you click'
|
||||
rArmX:
|
||||
name: 'Right Arm X'
|
||||
lore:
|
||||
- 'R-Click armor stand to change Right Arm X Value'
|
||||
- 'Value depends on how high up the body you click'
|
||||
rArmY:
|
||||
name: 'Right Arm Y'
|
||||
lore:
|
||||
- 'R-Click armor stand to change Right Arm Y Value'
|
||||
- 'Value depends on how high up the body you click'
|
||||
rArmZ:
|
||||
name: 'Right Arm Z'
|
||||
lore:
|
||||
- 'R-Click armor stand to change Right Arm Z Value'
|
||||
- 'Value depends on how high up the body you click'
|
||||
moveX:
|
||||
name: 'Move X'
|
||||
lore:
|
||||
- 'R-Click armor stand to move +0.1 X'
|
||||
- 'Crouch R-Click for -0.1 X'
|
||||
moveY:
|
||||
name: 'Move Y'
|
||||
lore:
|
||||
- 'R-Click armor stand to move +0.1 Y'
|
||||
- 'Crouch R-Click for -0.1 Y'
|
||||
moveZ:
|
||||
name: 'Move Z'
|
||||
lore:
|
||||
- 'R-Click armor stand to move +0.1 Z'
|
||||
- 'Crouch R-Click for -0.1 Z'
|
||||
lLegX:
|
||||
name: 'Left Leg X'
|
||||
lore:
|
||||
- 'R-Click armor stand to change Left Leg X'
|
||||
- 'Value depends on how high up the body you click'
|
||||
lLegY:
|
||||
name: 'Left Leg Y'
|
||||
lore:
|
||||
- 'R-Click armor stand to change Left Leg Y'
|
||||
- 'Value depends on how high up the body you click'
|
||||
lLegZ:
|
||||
name: 'Left Leg Z'
|
||||
lore:
|
||||
- 'R-Click armor stand to change Left Leg Z'
|
||||
- 'Value depends on how high up the body you click'
|
||||
rLegX:
|
||||
name: 'Right Leg X'
|
||||
lore:
|
||||
- 'R-Click armor stand to change Right Leg X'
|
||||
- 'Value depends on how high up the body you click'
|
||||
rLegY:
|
||||
name: 'Right Leg Y'
|
||||
lore:
|
||||
- 'R-Click armor stand to change Right Leg Y'
|
||||
- 'Value depends on how high up the body you click'
|
||||
rLegZ:
|
||||
name: 'Right Leg Z'
|
||||
lore:
|
||||
- 'R-Click armor stand to change Right Leg Z'
|
||||
- 'Value depends on how high up the body you click'
|
||||
bodyX:
|
||||
name: 'Body X'
|
||||
lore:
|
||||
- 'R-Click armor stand to change Body X'
|
||||
- 'Value depends on how high up the body you click'
|
||||
bodyY:
|
||||
name: 'Body Y'
|
||||
lore:
|
||||
- 'R-Click armor stand to change Body Y'
|
||||
- 'Value depends on how high up the body you click'
|
||||
bodyZ:
|
||||
name: 'Body Z'
|
||||
lore:
|
||||
- 'R-Click armor stand to change Body Z'
|
||||
- 'Value depends on how high up the body you click'
|
||||
gui_move:
|
||||
name: 'Pick Up (Move)'
|
||||
lore:
|
||||
- 'Pick up this armor stand to move it'
|
||||
gui_rotate:
|
||||
name: 'Rotate'
|
||||
lore:
|
||||
- 'Left click: Rotate clockwise 5°'
|
||||
- 'Right click: Rotate anti-clockwise 5°'
|
||||
gui_clone:
|
||||
name: 'Clone'
|
||||
lore:
|
||||
- 'Clone this armor stand and pick it up'
|
||||
gui_save:
|
||||
name: 'Create Command Block'
|
||||
gui_gen_cmd:
|
||||
name: 'Generate Summon Command'
|
||||
lore:
|
||||
- 'Create command block to'
|
||||
- 'summon this armor stand'
|
||||
- 'Command block will be created'
|
||||
- 'Summon command will be logged'
|
||||
gui_invis:
|
||||
name: 'Toggle Visibility'
|
||||
lore:
|
||||
@ -164,95 +280,3 @@ tool:
|
||||
gui_rleg:
|
||||
name: 'Move Right Leg'
|
||||
lore: 'Change the right leg position'
|
||||
gui_moveX:
|
||||
name: 'Move X (East/West)'
|
||||
lore:
|
||||
- 'Left click: Move East (+0.1 X)'
|
||||
- 'Right click: Move West (-0.1 X)'
|
||||
- '(Automatically disables gravity)'
|
||||
gui_moveY:
|
||||
name: 'Move Y (Up/Down)'
|
||||
lore:
|
||||
- 'Left click: Move Up (+0.1 Y)'
|
||||
- 'Right click: Move Down (-0.1 Y)'
|
||||
- '(Automatically disables gravity)'
|
||||
gui_moveZ:
|
||||
name: 'Move Z (South/North)'
|
||||
lore:
|
||||
- 'Left click: Move South (+0.1 Z)'
|
||||
- 'Right click: Move North (-0.1 Z)'
|
||||
- '(Automatically disables gravity)'
|
||||
gui_advanced:
|
||||
name: 'Show/Hide Advanced Tools'
|
||||
gui_headX:
|
||||
name: 'Head X'
|
||||
lore:
|
||||
- 'Change head X position'
|
||||
gui_headY:
|
||||
name: 'Head Y'
|
||||
lore:
|
||||
- 'Change head Y position'
|
||||
gui_headZ:
|
||||
name: 'Head Z'
|
||||
lore:
|
||||
- 'Change head Z position'
|
||||
gui_lArmX:
|
||||
name: 'Left Arm X'
|
||||
lore:
|
||||
- 'Change left arm X position'
|
||||
gui_lArmY:
|
||||
name: 'Left Arm Y'
|
||||
lore:
|
||||
- 'Change left arm Y Position'
|
||||
gui_lArmZ:
|
||||
name: 'Left Arm Z'
|
||||
lore:
|
||||
- 'Change left arm Z Position'
|
||||
gui_rArmX:
|
||||
name: 'Right Arm X'
|
||||
lore:
|
||||
- 'Change right arm X position'
|
||||
gui_rArmY:
|
||||
name: 'Right Arm Y'
|
||||
lore:
|
||||
- 'Change right arm Y position'
|
||||
gui_rArmZ:
|
||||
name: 'Right Arm Z'
|
||||
lore:
|
||||
- 'Change right arm Z position'
|
||||
gui_lLegX:
|
||||
name: 'Left Leg X'
|
||||
lore:
|
||||
- 'Change left leg X position'
|
||||
gui_lLegY:
|
||||
name: 'Left Leg Y'
|
||||
lore:
|
||||
- 'Change left leg Y position'
|
||||
gui_lLegZ:
|
||||
name: 'Left Leg Z'
|
||||
lore:
|
||||
- 'Change left leg Z position'
|
||||
gui_rLegX:
|
||||
name: 'Right Leg X'
|
||||
lore:
|
||||
- 'Change right leg X position'
|
||||
gui_rLegY:
|
||||
name: 'Right Leg Y'
|
||||
lore:
|
||||
- 'Change right leg Y position'
|
||||
gui_rLegZ:
|
||||
name: 'Right Leg Z'
|
||||
lore:
|
||||
- 'Change right leg Z position'
|
||||
gui_bodyX:
|
||||
name: 'Body X'
|
||||
lore:
|
||||
- 'Change body X position'
|
||||
gui_bodyY:
|
||||
name: 'Body Y'
|
||||
lore:
|
||||
- 'Change body Y position'
|
||||
gui_bodyZ:
|
||||
name: 'Body Z'
|
||||
lore:
|
||||
- 'Change body Z position'
|
||||
|
@ -7,9 +7,9 @@ description: Armor stand manipulation tools
|
||||
softdepend: [WorldGuard, PlotSquared]
|
||||
commands:
|
||||
astools:
|
||||
description: Provides player instructions on how to use AST
|
||||
description: Give yourself the armor stand tools
|
||||
aliases: ast
|
||||
usage: Usage /astools or /ast, /ast new, /ast reload
|
||||
usage: Usage /astools or /astools reload
|
||||
ascmd:
|
||||
description: View/Remove/Assign the command assigned to the nearest armor stand
|
||||
usage: Usage /ascmd view, /ascmd remove, /ascmd assign <player/console> <command>
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren