From e95f520399898a0a11135ca6c588da8f79d572fa Mon Sep 17 00:00:00 2001 From: Ryandw11 <6239385+ryandw11@users.noreply.github.com> Date: Sat, 27 Jun 2020 23:18:48 -0700 Subject: [PATCH] Create Structure In-Game - Added a command to create structure files from the game. (#50) - Mobs will now not immediately despawn after spawning in. (#57) - Added tab completion to the command. - This is Release Candidate 1 for version 1.5. --- .../ryandw11/structure/CustomStructures.java | 2 + .../ryandw11/structure/SchematicHandeler.java | 10 ++- .../ryandw11/structure/commands/SCommand.java | 72 ++++++++++++++++++- .../structure/commands/SCommandTab.java | 37 ++++++++++ .../ryandw11/structure/utils/CSConstants.java | 4 +- .../structure/utils/StructurePicker.java | 4 +- src/plugin.yml | 2 +- 7 files changed, 124 insertions(+), 7 deletions(-) create mode 100644 src/com/ryandw11/structure/commands/SCommandTab.java diff --git a/src/com/ryandw11/structure/CustomStructures.java b/src/com/ryandw11/structure/CustomStructures.java index c367225..99cac7a 100644 --- a/src/com/ryandw11/structure/CustomStructures.java +++ b/src/com/ryandw11/structure/CustomStructures.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.util.*; +import com.ryandw11.structure.commands.SCommandTab; import com.ryandw11.structure.loottables.customitems.CustomItemManager; import com.ryandw11.structure.structure.StructureBuilder; import com.ryandw11.structure.structure.StructureHandler; @@ -139,6 +140,7 @@ private void loadManager() { Bukkit.getServer().getPluginManager().registerEvents(new ChunkLoad(), this); Bukkit.getServer().getPluginManager().registerEvents(new PlayerJoin(), this); getCommand("customstructure").setExecutor(new SCommand(this)); + getCommand("customstructure").setTabCompleter(new SCommandTab()); } private void registerConfig() { diff --git a/src/com/ryandw11/structure/SchematicHandeler.java b/src/com/ryandw11/structure/SchematicHandeler.java index 1f50819..a7bc4ea 100644 --- a/src/com/ryandw11/structure/SchematicHandeler.java +++ b/src/com/ryandw11/structure/SchematicHandeler.java @@ -6,6 +6,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Random; import com.ryandw11.structure.structure.Structure; @@ -20,7 +21,9 @@ import com.sk89q.worldedit.regions.Region; import org.bukkit.*; import org.bukkit.block.*; +import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.inventory.BrewerInventory; import org.bukkit.inventory.FurnaceInventory; @@ -289,9 +292,14 @@ private void replaceSignWithMob(Location location) { if (firstLine.equalsIgnoreCase("[mob]")) { try { - location.getWorld().spawnEntity(location, EntityType.valueOf(secondLine.toUpperCase())); + Entity ent = Objects.requireNonNull(location.getWorld()).spawnEntity(location, EntityType.valueOf(secondLine.toUpperCase())); + if(ent instanceof LivingEntity){ + LivingEntity livingEntity = (LivingEntity) ent; + livingEntity.setRemoveWhenFarAway(false); + } location.getBlock().setType(Material.AIR); } catch (IllegalArgumentException e) { + plugin.getLogger().warning("Invalid mob type on structure sign."); } } if (firstLine.equalsIgnoreCase("[mythicmob]") || firstLine.equalsIgnoreCase("[mythicalmob]")) { diff --git a/src/com/ryandw11/structure/commands/SCommand.java b/src/com/ryandw11/structure/commands/SCommand.java index eb64429..d10e4dc 100644 --- a/src/com/ryandw11/structure/commands/SCommand.java +++ b/src/com/ryandw11/structure/commands/SCommand.java @@ -2,6 +2,12 @@ import com.ryandw11.structure.SchematicHandeler; import com.ryandw11.structure.structure.Structure; +import com.ryandw11.structure.structure.StructureBuilder; +import com.ryandw11.structure.structure.properties.BlockLevelLimit; +import com.ryandw11.structure.structure.properties.StructureLimitations; +import com.ryandw11.structure.structure.properties.StructureLocation; +import com.ryandw11.structure.structure.properties.StructureProperties; +import com.ryandw11.structure.utils.RandomCollection; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.command.Command; @@ -12,6 +18,13 @@ import com.ryandw11.structure.CustomStructures; import org.bukkit.inventory.ItemStack; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Objects; + public class SCommand implements CommandExecutor { private CustomStructures plugin; @@ -103,7 +116,7 @@ public boolean onCommand(CommandSender sender, Command cmd, String s, String[] a p.sendMessage(ChatColor.RED + "You must be holding an item to use this command!"); return true; } - for(String items : plugin.getCustomItemManager().getConfig().getConfigurationSection("").getKeys(false)){ + for(String items : Objects.requireNonNull(plugin.getCustomItemManager().getConfig().getConfigurationSection("")).getKeys(false)){ if(item.isSimilar(plugin.getCustomItemManager().getItem(items))){ p.sendMessage(ChatColor.GREEN + "The item you are holding has a key of: " + ChatColor.GOLD + items); return true; @@ -160,6 +173,61 @@ else if(args.length == 2 && args[0].equalsIgnoreCase("createschem")){ p.sendMessage(ChatColor.RED + "The world edit region seems to be incomplete! Try making a selection first!"); } } + else if( args.length != 0 && args.length < 3 && args[0].equalsIgnoreCase("create")){ + if(!sender.hasPermission("customstructures.create")){ + sender.sendMessage(ChatColor.RED + "You do not have permission for this command!"); + return true; + } + sender.sendMessage(ChatColor.RED + "You must specify the name and schematic of a structure!"); + } + else if(args.length == 3 && args[0].equalsIgnoreCase("create")){ + if(!sender.hasPermission("customstructures.create")){ + sender.sendMessage(ChatColor.RED + "You do not have permission for this command!"); + return true; + } + String name = args[1]; + String schematic = args[2].replace(".schem", ""); + if(schematic.equals("")){ + sender.sendMessage(ChatColor.RED + "Invalid schematic!"); + return true; + } + if(plugin.getStructureHandler().getStructure(name) != null){ + sender.sendMessage(ChatColor.RED + "A structure with that name already exists!"); + return true; + } + File f = new File(plugin.getDataFolder() + File.separator + "structures" + File.separator + name + ".yml"); + try{ + if(!f.exists()) + f.createNewFile(); + }catch(IOException ex){ + sender.sendMessage(ChatColor.RED + "An error occurred while creating a structure file!"); + plugin.getLogger().severe("Could not create structure file!"); + if(plugin.isDebug()) + ex.printStackTrace(); + return true; + } + StructureBuilder builder = new StructureBuilder(name, schematic + ".schem"); + builder.setChance(1, 1000); + builder.setLootTables(new RandomCollection<>()); + builder.setStructureProperties(new StructureProperties()); + builder.setStructureLocation(new StructureLocation()); + builder.setStructureLimitations(new StructureLimitations(new ArrayList<>(), new BlockLevelLimit(), new HashMap<>())); + try { + builder.save(f); + } catch (IOException e) { + sender.sendMessage(ChatColor.RED + "An error occurred while saving the structure file!"); + plugin.getLogger().severe("Could not save structure file!"); + if(plugin.isDebug()) + e.printStackTrace(); + return true; + } + List structs = plugin.getConfig().getStringList("Structures"); + structs.add(name); + plugin.getConfig().set("Structures", structs); + plugin.saveConfig(); + sender.sendMessage(ChatColor.GREEN + "Successfully created the structure " + ChatColor.GOLD + name + ChatColor.GREEN + "!"); + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&aRun the &6/cstructure reload &ato load in the new structure and changes.")); + } else { if (sender.hasPermission("customstructures.info")) { sender.sendMessage(ChatColor.translateAlternateColorCodes('&', @@ -183,6 +251,8 @@ else if(args.length == 2 && args[0].equalsIgnoreCase("createschem")){ "&3/cstructure getItem {key} - &2Get the item of the key specified.")); sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&3/cstructure createschem {name} - &2Create a schematic from the current worldedit selection (This is automatically save to the CustomStructures schematic folder).")); + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', + "&3/cstructure create {name} {schematic} - &2Create a structure using the default settings.")); } else { sender.sendMessage(ChatColor.RED + "You do not have permission for this command."); } diff --git a/src/com/ryandw11/structure/commands/SCommandTab.java b/src/com/ryandw11/structure/commands/SCommandTab.java new file mode 100644 index 0000000..1750a96 --- /dev/null +++ b/src/com/ryandw11/structure/commands/SCommandTab.java @@ -0,0 +1,37 @@ +package com.ryandw11.structure.commands; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class SCommandTab implements TabCompleter { + @Override + public List onTabComplete(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String s, String[] args) { + List completions = new ArrayList<>(); + if (args.length < 2) { + completions = new ArrayList<>(Arrays.asList("reload", "test", "list", "additem", "checkkey", "getitem", "createschem", "create")); + completions = getAppliableTabCompleters(args.length == 1 ? args[0] : "", completions); + } + Collections.sort(completions); + return completions; + } + + public List getAppliableTabCompleters(String arg, List completions) { + if (arg == null || arg.equalsIgnoreCase("")) { + return completions; + } + ArrayList valid = new ArrayList<>(); + for (String posib : completions) { + if (posib.startsWith(arg)) { + valid.add(posib); + } + } + return valid; + } +} diff --git a/src/com/ryandw11/structure/utils/CSConstants.java b/src/com/ryandw11/structure/utils/CSConstants.java index ac4b337..4d0e5ad 100644 --- a/src/com/ryandw11/structure/utils/CSConstants.java +++ b/src/com/ryandw11/structure/utils/CSConstants.java @@ -13,7 +13,7 @@ * */ public class CSConstants { - public static List leafBlocks = new ArrayList<>(Arrays.asList(Material.GRASS, Material.ACACIA_LEAVES, Material.BIRCH_LEAVES, + public static List plantBlocks = new ArrayList<>(Arrays.asList(Material.GRASS, Material.ACACIA_LEAVES, Material.BIRCH_LEAVES, Material.DARK_OAK_LEAVES, Material.JUNGLE_LEAVES, Material.OAK_LEAVES, Material.SPRUCE_LEAVES, Material.VINE, Material.ACACIA_LOG, - Material.BIRCH_LOG, Material.DARK_OAK_LOG, Material.JUNGLE_LOG, Material.OAK_LOG, Material.SPRUCE_LOG, Material.TALL_GRASS)); + Material.BIRCH_LOG, Material.DARK_OAK_LOG, Material.JUNGLE_LOG, Material.OAK_LOG, Material.SPRUCE_LOG)); } diff --git a/src/com/ryandw11/structure/utils/StructurePicker.java b/src/com/ryandw11/structure/utils/StructurePicker.java index 714bf4b..a9daca8 100644 --- a/src/com/ryandw11/structure/utils/StructurePicker.java +++ b/src/com/ryandw11/structure/utils/StructurePicker.java @@ -72,9 +72,9 @@ public void run() { } // Allows the structures to no longer spawn on plant life. - if (structure.getStructureProperties().isIgnoringPlants() && CSConstants.leafBlocks.contains(bl.getType())) { + if (structure.getStructureProperties().isIgnoringPlants() && CSConstants.plantBlocks.contains(bl.getType())) { for (int i = bl.getY(); i <= 4; i--) { - if (!CSConstants.leafBlocks.contains(ch.getBlock(0, i, 0).getType())) { + if (!CSConstants.plantBlocks.contains(ch.getBlock(0, i, 0).getType())) { bl = ch.getBlock(0, i, 0); break; } diff --git a/src/plugin.yml b/src/plugin.yml index 23346c7..2aaaf2e 100644 --- a/src/plugin.yml +++ b/src/plugin.yml @@ -1,5 +1,5 @@ name: CustomStructures -version: 1.5 +version: 1.5-RC1 main: com.ryandw11.structure.CustomStructures author: Ryandw11 description: A plugin which allows you to spawn in custom structures!