diff --git a/src/net/TheDgtl/StargateCommand/SGCListener.java b/src/net/TheDgtl/StargateCommand/SGCListener.java index f4f6b3b..8cdb52e 100644 --- a/src/net/TheDgtl/StargateCommand/SGCListener.java +++ b/src/net/TheDgtl/StargateCommand/SGCListener.java @@ -1,79 +1,94 @@ -package net.TheDgtl.StargateCommand; - -import net.TheDgtl.Stargate.Gate; -import net.TheDgtl.StargateCommand.StargateCommand.Action; - -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.Event.Result; -import org.bukkit.event.player.PlayerInteractEvent; - -public class SGCListener implements Listener { - StargateCommand sgc; - public SGCListener(StargateCommand plugin) { - sgc = plugin; - } - - @EventHandler - public void onPlayerInteract(PlayerInteractEvent event) { - // We want right-click block only - if (event.getAction() != org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK) return; - - Player player = event.getPlayer(); - Block block = event.getClickedBlock(); - SGCPlayer sPlayer = sgc.players.get(player); - if (sPlayer == null || block == null) return; - if (sPlayer.action == Action.IMPORT) { - event.setCancelled(true); - event.setUseInteractedBlock(Result.DENY); - event.setUseItemInHand(Result.DENY); - // First block - if (sPlayer.blocks.size() == 0) { - sPlayer.blocks.add(block); - StargateCommand.sendMessage(player, "Please select a second block by right-clicking it", false); - return; - } else { - Block fb = sPlayer.blocks.poll(); - int modX = fb.getX() - block.getX(); - int modZ = fb.getZ() - block.getZ(); - int modY = fb.getY() - block.getY(); - if (modY != 0 || modX > 1 || modX < -1 || modZ > 1 || modZ < -1 || (modX != 0 && modZ != 0)) { - StargateCommand.sendMessage(player, "The blocks you selected were not next to eachother. Exiting", true); - sgc.players.remove(player); - return; - } - Gate gate = Gate.getGateByName(sPlayer.args[1] + ".gate"); - boolean force = false; - if (sPlayer.args.length > 2 && sPlayer.args[2].equalsIgnoreCase("force")) force = true; - sgc.importGate(player, gate, fb, modX, modZ, force); - sgc.players.remove(player); - } - } else if (sPlayer.action == Action.EXPORT) { - event.setCancelled(true); - event.setUseInteractedBlock(Result.DENY); - event.setUseItemInHand(Result.DENY); - if (sPlayer.blocks.size() == 0) { - sPlayer.blocks.add(block); - StargateCommand.sendMessage(player, "Please select the button location", false); - } else if (sPlayer.blocks.size() == 1) { - sPlayer.blocks.add(block); - StargateCommand.sendMessage(player, "Please select the exit location", false); - } else if (sPlayer.blocks.size() == 2) { - sPlayer.blocks.add(block); - StargateCommand.sendMessage(player, "Please select the top-left block of the bedrock frame", false); - } else if (sPlayer.blocks.size() == 3) { - // First we find the dimensions of the frame - if (block.getType() != Material.BEDROCK) { - StargateCommand.sendMessage(player, "You did not select bedrock, exiting export mode", true); - sgc.players.remove(player); - return; - } - sgc.exportGate(player, block); - sgc.players.remove(player); - } - } - } -} +package net.TheDgtl.StargateCommand; + +import net.TheDgtl.Stargate.Gate; +import net.TheDgtl.Stargate.event.StargateActivateEvent; +import net.TheDgtl.StargateCommand.StargateCommand.Action; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.Event.Result; +import org.bukkit.event.player.PlayerInteractEvent; + +public class SGCListener implements Listener { + StargateCommand sgc; + public SGCListener(StargateCommand plugin) { + sgc = plugin; + } + + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) { + // We want right-click block only + if (event.getAction() != org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK) return; + + Player player = event.getPlayer(); + Block block = event.getClickedBlock(); + SGCPlayer sPlayer = sgc.players.get(player); + if (sPlayer == null || block == null) return; + if (sPlayer.action == Action.IMPORT) { + event.setCancelled(true); + event.setUseInteractedBlock(Result.DENY); + event.setUseItemInHand(Result.DENY); + // First block + if (sPlayer.blocks.size() == 0) { + sPlayer.blocks.add(block); + StargateCommand.sendMessage(player, "Please select a second block by right-clicking it", false); + return; + } else { + Block fb = sPlayer.blocks.poll(); + int modX = fb.getX() - block.getX(); + int modZ = fb.getZ() - block.getZ(); + int modY = fb.getY() - block.getY(); + if (modY != 0 || modX > 1 || modX < -1 || modZ > 1 || modZ < -1 || (modX != 0 && modZ != 0)) { + StargateCommand.sendMessage(player, "The blocks you selected were not next to eachother. Exiting", true); + sgc.players.remove(player); + return; + } + Gate gate = Gate.getGateByName(sPlayer.args[1] + ".gate"); + boolean force = false; + if (sPlayer.args.length > 2 && sPlayer.args[2].equalsIgnoreCase("force")) force = true; + sgc.importGate(player, gate, fb, modX, modZ, force); + sgc.players.remove(player); + } + } else if (sPlayer.action == Action.EXPORT) { + event.setCancelled(true); + event.setUseInteractedBlock(Result.DENY); + event.setUseItemInHand(Result.DENY); + if (sPlayer.blocks.size() == 0) { + sPlayer.blocks.add(block); + StargateCommand.sendMessage(player, "Please select the button location", false); + } else if (sPlayer.blocks.size() == 1) { + sPlayer.blocks.add(block); + StargateCommand.sendMessage(player, "Please select the exit location", false); + } else if (sPlayer.blocks.size() == 2) { + sPlayer.blocks.add(block); + StargateCommand.sendMessage(player, "Please select the top-left block of the bedrock frame", false); + } else if (sPlayer.blocks.size() == 3) { + // First we find the dimensions of the frame + if (block.getType() != Material.BEDROCK) { + StargateCommand.sendMessage(player, "You did not select bedrock, exiting export mode", true); + sgc.players.remove(player); + return; + } + sgc.exportGate(player, block); + sgc.players.remove(player); + } + } + } + + @EventHandler + public void onStargateActivate(StargateActivateEvent event) { + Player player = event.getPlayer(); + SGCPlayer sPlayer = sgc.players.get(player); + if (sPlayer == null) return; + if (sPlayer.action != Action.DIAL) return; + if (event.getDestinations().contains(sPlayer.args[0])) { + event.setDestination(sPlayer.args[0]); + } else { + StargateCommand.sendMessage(player, "The specified destination does not exist for this gate. Exiting", true); + sgc.players.remove(player); + } + } +} diff --git a/src/net/TheDgtl/StargateCommand/StargateCommand.java b/src/net/TheDgtl/StargateCommand/StargateCommand.java index dbbfa20..706532f 100644 --- a/src/net/TheDgtl/StargateCommand/StargateCommand.java +++ b/src/net/TheDgtl/StargateCommand/StargateCommand.java @@ -1,341 +1,390 @@ -package net.TheDgtl.StargateCommand; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.logging.Logger; - -import net.TheDgtl.Stargate.Blox; -import net.TheDgtl.Stargate.Gate; -import net.TheDgtl.Stargate.Stargate; - -import org.bukkit.ChatColor; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Server; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.plugin.PluginManager; -import org.bukkit.plugin.java.JavaPlugin; - -public class StargateCommand extends JavaPlugin { - private Logger log; - private Server server; - private PluginManager pm; - - private Stargate sg = null; - - public HashMap players = new HashMap(); - - public void onEnable() { - this.server = getServer(); - this.pm = server.getPluginManager(); - this.log = server.getLogger(); - - sg = (Stargate)pm.getPlugin("Stargate"); - - if (sg == null) { - log.severe("[SGC] Error, Stargate not found. Disabling"); - pm.disablePlugin(this); - return; - } - - pm.registerEvents(new SGCListener(this), this); - } - - public void onDisable() { - - } - - public void importGate(Player player, Gate gate, Block baseBlock, int modX, int modZ, boolean force) { - if (gate == null) { - StargateCommand.sendMessage(player, "The gate specified does not exist", true); - return; - } - - Blox topLeft = new Blox(baseBlock.getLocation().add(0, gate.getLayout().length, 0)); - - if (!drawGate(topLeft, gate, modX, modZ, force)) { - StargateCommand.sendMessage(player, "Gate interfered with existing terrain. Import cancelled. User force to ignore", true); - return; - } - sendMessage(player, "Your gate has been imported successfully", false); - } - - public boolean drawGate(Blox topleft, Gate gate, int modX, int modZ, boolean force) { - Character[][] layout = gate.getLayout(); - HashMap types = gate.getTypes(); - HashMap metadata = gate.getMetaData(); - int closedType = gate.getPortalBlockClosed(); - - // Queue used incase we need to undo - ArrayList blockQueue = new ArrayList(); - - for (int y = 0; y < layout.length; y++) { - for (int x = 0; x < layout[y].length; x++) { - int id = types.get(layout[y][x]); - Integer mData = metadata.get(layout[y][x]); - - if (id == Gate.ANYTHING) { - continue; - } - - if (id == Gate.ENTRANCE || id == Gate.EXIT) { - id = closedType; - } - - Blox block = topleft.modRelative(x, y, 0, modX, 1, modZ); - if (block.getType() != Material.AIR.getId() && !force) { - return false; - } - - BlockChange bc = new BlockChange(); - bc.block = block; - bc.newType = id; - bc.newData = mData; - blockQueue.add(bc); - } - } - - for(BlockChange bc : blockQueue) { - bc.block.setType(bc.newType); - if (bc.newData != null) - bc.block.setData(bc.newData); - } - return true; - } - - private boolean checkOffset(Location a, Location b, int modX, int modZ, int width, int height) { - int offX = Math.abs(a.getBlockX() - b.getBlockX()); - int offY = Math.abs(a.getBlockY() - b.getBlockY()); - int offZ = Math.abs(a.getBlockZ() - b.getBlockZ()); - if (modX == 0 && (offX != 0 || offZ > width)) return false; - if (modZ == 0 && (offZ != 0 || offX > width)) return false; - if (offY > height) return false; - return true; - } - - public void exportGate(Player player, Block topleft) { - SGCPlayer sPlayer = players.get(player); - // Determine facing - int tmp = 0; - int modX = 0; - int modZ = 0; - if (topleft.getRelative(BlockFace.EAST).getType() == Material.BEDROCK) { - modZ = -1; - tmp++; - } - if (topleft.getRelative(BlockFace.WEST).getType() == Material.BEDROCK) { - modZ = 1; - tmp++; - } - if (topleft.getRelative(BlockFace.NORTH).getType() == Material.BEDROCK) { - modX = -1; - tmp++; - } - if (topleft.getRelative(BlockFace.SOUTH).getType() == Material.BEDROCK) { - modX = 1; - tmp++; - } - if (tmp != 1 || topleft.getRelative(BlockFace.DOWN).getType() != Material.BEDROCK) { - StargateCommand.sendMessage(player, "There was an error determining your frame. Exiting export mode", true); - players.remove(player); - return; - } - - // Check offset of control blocks - Block signBlock = sPlayer.blocks.poll(); - Block buttonBlock = sPlayer.blocks.poll(); - - // Check offset of exit block - Block exitBlock = sPlayer.blocks.poll(); - - // Determine frame width/height - int frameWidth = 1; - int frameHeight = 1; - while (topleft.getRelative(modX * frameWidth, 0, modZ * frameWidth).getType() == Material.BEDROCK) { - frameWidth++; - } - while (topleft.getRelative(0, -frameHeight, 0).getType() == Material.BEDROCK) { - frameHeight++; - } - frameWidth = frameWidth - 2; - frameHeight = frameHeight - 2; - Block startBlock = topleft.getRelative(modX, -1, modZ); - - if (!checkOffset(signBlock.getLocation(), startBlock.getLocation(), modX, modZ, frameWidth, frameHeight)) { - sendMessage(player, "Your sign block is outside of your stargate. Exiting", true); - return; - } - if (!checkOffset(buttonBlock.getLocation(), startBlock.getLocation(), modX, modZ, frameWidth, frameHeight)) { - sendMessage(player, "Your button block is outside of your stargate. Exiting", true); - return; - } - if (!checkOffset(exitBlock.getLocation(), startBlock.getLocation(), modX, modZ, frameWidth, frameHeight)) { - sendMessage(player, "Your exit block is outside of your stargate. Exiting", true); - return; - } - - Gate gate = storeGate(player, startBlock, signBlock, buttonBlock, exitBlock, modX, modZ, frameWidth, frameHeight); - if (gate != null) { - Gate.registerGate(gate); - sendMessage(player, "Your gate layout has been exported and loaded", false); - } - } - - public Gate storeGate(Player player, Block startBlock, Block signBlock, Block buttonBlock, Block exitBlock, int modX, int modZ, int width, int height) { - SGCPlayer sPlayer = players.get(player); - // Store the gate layout - HashMap typeLookup = new HashMap(); - - Character[][] layout = new Character[height][width]; - HashMap types = new HashMap(); - HashMap metadata = new HashMap(); - - // Validate gate before saving - boolean exitFound = false; - int controlsFound = 0; - - // Init types map - Character nextChar = 'A'; - types.put('.', Gate.ENTRANCE); - types.put('*', Gate.EXIT); - types.put(' ', Gate.ANYTHING); - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - Block fBlock = startBlock.getRelative(modX * x, -y, modZ * x); - int type = fBlock.getTypeId(); - int data = fBlock.getData(); - int lookup = type + (data << 16); - // Anything - if (type == Material.AIR.getId()) { - layout[y][x] = ' '; - continue; - } - // Entrance - if (type == Material.BEDROCK.getId()) { - if (fBlock.equals(exitBlock)) { - exitFound = true; - layout[y][x] = '*'; - continue; - } - layout[y][x] = '.'; - continue; - } - if (fBlock.equals(signBlock) || fBlock.equals(buttonBlock)) { - controlsFound++; - layout[y][x] = '-'; - Integer cType = types.get('-'); - if (cType != null && cType != type) { - sendMessage(player, "Both your control blocks must be on the same block type. Exiting", true); - return null; - } - types.put('-', type); - continue; - } - // Store block/metadata for gate - if (!typeLookup.containsKey(lookup)) { - typeLookup.put(lookup, nextChar); - types.put(nextChar, type); - if (data != 0) - metadata.put(nextChar, data); - nextChar++; - } - layout[y][x] = typeLookup.get(lookup); - } - } - - if (!exitFound) { - sendMessage(player, "Your exit was not in an entrance block. Exiting", true); - return null; - } - if (controlsFound != 2) { - sendMessage(player, "One of your control blocks was missing. Exiting", true); - return null; - } - - Gate gate = new Gate(sPlayer.args[1] + ".gate", layout, types, metadata); - gate.setPortalBlockOpen(Material.PORTAL.getId()); - gate.setPortalBlockClosed(Material.AIR.getId()); - gate.save(Stargate.getGateFolder()); - return gate; - } - - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - if (!(sender instanceof Player)) { - sender.sendMessage("[SGC] This command can only be used ingame"); - return true; - } - Player player = (Player)sender; - // SGC import/export - if (command.getName().equalsIgnoreCase("sgc") && args.length > 0) { - // Import - if (args[0].equalsIgnoreCase("import")) { - if (!player.hasPermission("stargate.command.import")) { - StargateCommand.sendMessage(player, "Permission Denied", true); - return true; - } - if (args.length < 2) { - StargateCommand.sendMessage(player, "You did not specify a gate to import", true); - return true; - } - if (Gate.getGateByName(args[1] + ".gate") == null) { - StargateCommand.sendMessage(player, "The gate you specified does not exist", true); - return true; - } - - StargateCommand.sendMessage(player, "Please select two blocks to define gate location/direction", false); - StargateCommand.sendMessage(player, "Do this by right-clicking two blocks next to each other", false); - players.put(player, new SGCPlayer(player, Action.IMPORT, args)); - // Export - } else if (args[0].equalsIgnoreCase("export")) { - if (!player.hasPermission("stargate.command.export")) { - StargateCommand.sendMessage(player, "Permission Denied", true); - return true; - } - if (args.length < 2) { - sendMessage(player, "You must provide a gate name", true); - return true; - } - boolean force = false; - if (args.length > 2 && args[2].equalsIgnoreCase("force")) force = true; - if (Gate.getGateByName(args[1] + ".gate") != null && !force) { - sendMessage(player, "A gate by that name exists. Use force to overwrite", true); - return true; - } - StargateCommand.sendMessage(player, "Please select where you would like the sign placed", false); - StargateCommand.sendMessage(player, "Do this by right-clicking the block", false); - players.put(player, new SGCPlayer(player, Action.EXPORT, args)); - // Cancel - } else if (args[0].equalsIgnoreCase("cancel")) { - players.remove(player); - StargateCommand.sendMessage(player, "Command cancelled", false); - } - return true; - } - return false; - } - - public static void sendMessage(CommandSender sender, String message, boolean error) { - if (error) { - message = ChatColor.RED + "[SGC] " + ChatColor.WHITE + message; - } else { - message = ChatColor.BLUE + "[SGC] " + ChatColor.WHITE + message; - } - sender.sendMessage(message); - } - - private class BlockChange { - public Blox block; - public Integer newType; - public Integer newData; - } - - public enum Action { - IMPORT, - EXPORT - } -} +package net.TheDgtl.StargateCommand; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.logging.Logger; + +import net.TheDgtl.Stargate.Blox; +import net.TheDgtl.Stargate.Gate; +import net.TheDgtl.Stargate.Portal; +import net.TheDgtl.Stargate.Stargate; + +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Server; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; + +public class StargateCommand extends JavaPlugin { + private Logger log; + private Server server; + private PluginManager pm; + + private Stargate sg = null; + + public HashMap players = new HashMap(); + + public void onEnable() { + this.server = getServer(); + this.pm = server.getPluginManager(); + this.log = server.getLogger(); + + sg = (Stargate)pm.getPlugin("Stargate"); + + if (sg == null) { + log.severe("[SGC] Error, Stargate not found. Disabling"); + pm.disablePlugin(this); + return; + } + + pm.registerEvents(new SGCListener(this), this); + } + + public void onDisable() { + + } + + public void importGate(Player player, Gate gate, Block baseBlock, int modX, int modZ, boolean force) { + if (gate == null) { + StargateCommand.sendMessage(player, "The gate specified does not exist", true); + return; + } + + Blox topLeft = new Blox(baseBlock.getLocation().add(0, gate.getLayout().length, 0)); + + if (!drawGate(topLeft, gate, modX, modZ, force)) { + StargateCommand.sendMessage(player, "Gate interfered with existing terrain. Import cancelled. User force to ignore", true); + return; + } + sendMessage(player, "Your gate has been imported successfully", false); + } + + public boolean drawGate(Blox topleft, Gate gate, int modX, int modZ, boolean force) { + Character[][] layout = gate.getLayout(); + HashMap types = gate.getTypes(); + HashMap metadata = gate.getMetaData(); + int closedType = gate.getPortalBlockClosed(); + + // Queue used incase we need to undo + ArrayList blockQueue = new ArrayList(); + + for (int y = 0; y < layout.length; y++) { + for (int x = 0; x < layout[y].length; x++) { + int id = types.get(layout[y][x]); + Integer mData = metadata.get(layout[y][x]); + + if (id == Gate.ANYTHING) { + continue; + } + + if (id == Gate.ENTRANCE || id == Gate.EXIT) { + id = closedType; + } + + Blox block = topleft.modRelative(x, y, 0, modX, 1, modZ); + if (block.getType() != Material.AIR.getId() && !force) { + return false; + } + + BlockChange bc = new BlockChange(); + bc.block = block; + bc.newType = id; + bc.newData = mData; + blockQueue.add(bc); + } + } + + for(BlockChange bc : blockQueue) { + bc.block.setType(bc.newType); + if (bc.newData != null) + bc.block.setData(bc.newData); + } + return true; + } + + private boolean checkOffset(Location a, Location b, int modX, int modZ, int width, int height) { + int offX = Math.abs(a.getBlockX() - b.getBlockX()); + int offY = Math.abs(a.getBlockY() - b.getBlockY()); + int offZ = Math.abs(a.getBlockZ() - b.getBlockZ()); + if (modX == 0 && (offX != 0 || offZ > width)) return false; + if (modZ == 0 && (offZ != 0 || offX > width)) return false; + if (offY > height) return false; + return true; + } + + public void exportGate(Player player, Block topleft) { + SGCPlayer sPlayer = players.get(player); + // Determine facing + int tmp = 0; + int modX = 0; + int modZ = 0; + if (topleft.getRelative(BlockFace.EAST).getType() == Material.BEDROCK) { + modZ = -1; + tmp++; + } + if (topleft.getRelative(BlockFace.WEST).getType() == Material.BEDROCK) { + modZ = 1; + tmp++; + } + if (topleft.getRelative(BlockFace.NORTH).getType() == Material.BEDROCK) { + modX = -1; + tmp++; + } + if (topleft.getRelative(BlockFace.SOUTH).getType() == Material.BEDROCK) { + modX = 1; + tmp++; + } + if (tmp != 1 || topleft.getRelative(BlockFace.DOWN).getType() != Material.BEDROCK) { + StargateCommand.sendMessage(player, "There was an error determining your frame. Exiting export mode", true); + players.remove(player); + return; + } + + // Check offset of control blocks + Block signBlock = sPlayer.blocks.poll(); + Block buttonBlock = sPlayer.blocks.poll(); + + // Check offset of exit block + Block exitBlock = sPlayer.blocks.poll(); + + // Determine frame width/height + int frameWidth = 1; + int frameHeight = 1; + while (topleft.getRelative(modX * frameWidth, 0, modZ * frameWidth).getType() == Material.BEDROCK) { + frameWidth++; + } + while (topleft.getRelative(0, -frameHeight, 0).getType() == Material.BEDROCK) { + frameHeight++; + } + frameWidth = frameWidth - 2; + frameHeight = frameHeight - 2; + Block startBlock = topleft.getRelative(modX, -1, modZ); + + if (!checkOffset(signBlock.getLocation(), startBlock.getLocation(), modX, modZ, frameWidth, frameHeight)) { + sendMessage(player, "Your sign block is outside of your stargate. Exiting", true); + return; + } + if (!checkOffset(buttonBlock.getLocation(), startBlock.getLocation(), modX, modZ, frameWidth, frameHeight)) { + sendMessage(player, "Your button block is outside of your stargate. Exiting", true); + return; + } + if (!checkOffset(exitBlock.getLocation(), startBlock.getLocation(), modX, modZ, frameWidth, frameHeight)) { + sendMessage(player, "Your exit block is outside of your stargate. Exiting", true); + return; + } + + Gate gate = storeGate(player, startBlock, signBlock, buttonBlock, exitBlock, modX, modZ, frameWidth, frameHeight); + if (gate != null) { + Gate.registerGate(gate); + sendMessage(player, "Your gate layout has been exported and loaded", false); + } + } + + public Gate storeGate(Player player, Block startBlock, Block signBlock, Block buttonBlock, Block exitBlock, int modX, int modZ, int width, int height) { + SGCPlayer sPlayer = players.get(player); + // Store the gate layout + HashMap typeLookup = new HashMap(); + + Character[][] layout = new Character[height][width]; + HashMap types = new HashMap(); + HashMap metadata = new HashMap(); + + // Validate gate before saving + boolean exitFound = false; + int controlsFound = 0; + + // Init types map + Character nextChar = 'A'; + types.put('.', Gate.ENTRANCE); + types.put('*', Gate.EXIT); + types.put(' ', Gate.ANYTHING); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + Block fBlock = startBlock.getRelative(modX * x, -y, modZ * x); + int type = fBlock.getTypeId(); + int data = fBlock.getData(); + int lookup = type + (data << 16); + // Anything + if (type == Material.AIR.getId()) { + layout[y][x] = ' '; + continue; + } + // Entrance + if (type == Material.BEDROCK.getId()) { + if (fBlock.equals(exitBlock)) { + exitFound = true; + layout[y][x] = '*'; + continue; + } + layout[y][x] = '.'; + continue; + } + if (fBlock.equals(signBlock) || fBlock.equals(buttonBlock)) { + controlsFound++; + layout[y][x] = '-'; + Integer cType = types.get('-'); + if (cType != null && cType != type) { + sendMessage(player, "Both your control blocks must be on the same block type. Exiting", true); + return null; + } + types.put('-', type); + continue; + } + // Store block/metadata for gate + if (!typeLookup.containsKey(lookup)) { + typeLookup.put(lookup, nextChar); + types.put(nextChar, type); + if (data != 0) + metadata.put(nextChar, data); + nextChar++; + } + layout[y][x] = typeLookup.get(lookup); + } + } + + if (!exitFound) { + sendMessage(player, "Your exit was not in an entrance block. Exiting", true); + return null; + } + if (controlsFound != 2) { + sendMessage(player, "One of your control blocks was missing. Exiting", true); + return null; + } + + Gate gate = new Gate(sPlayer.args[1] + ".gate", layout, types, metadata); + gate.setPortalBlockOpen(Material.PORTAL.getId()); + gate.setPortalBlockClosed(Material.AIR.getId()); + gate.save(Stargate.getGateFolder()); + return gate; + } + + public void dialGate(Player player, String dest, String source, String network) { + Portal sourcePortal = Portal.getByName(source, network); + Portal destPortal = Portal.getByName(dest, network); + if (sourcePortal == null || destPortal == null) { + sendMessage(player, "The specified Stargate connection does not exist", true); + return; + } + if (sourcePortal.getWorld() != player.getWorld() && destPortal.getWorld() != player.getWorld()) { + sendMessage(player, "Neither of the specified gates are on your world", true); + return; + } + if (!Stargate.canAccessNetwork(player, network)) { + sendMessage(player, "You do not have access to that gate network", true); + return; + } + sourcePortal.setDestination(destPortal); + if (!sourcePortal.open(player, false)) { + sendMessage(player, "There was an error opening the gate", true); + return; + } + sendMessage(player, "The gate has been connected and opened", false); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("[SGC] This command can only be used ingame"); + return true; + } + Player player = (Player)sender; + // SGC import/export + if (command.getName().equalsIgnoreCase("sgc")) { + if (args.length == 0) return false; + // Import + if (args[0].equalsIgnoreCase("import")) { + if (!player.hasPermission("stargate.command.import")) { + StargateCommand.sendMessage(player, "Permission Denied", true); + return true; + } + if (args.length < 2) { + sendMessage(player, "Usage: /sgc import [force]", false); + sendMessage(player, "Use force to ignore terrain intersection", false); + sendMessage(player, "Example: /sgc import super force", false); + return true; + } + if (Gate.getGateByName(args[1] + ".gate") == null) { + StargateCommand.sendMessage(player, "The gate you specified does not exist", true); + return true; + } + + StargateCommand.sendMessage(player, "Please select two blocks to define gate location/direction", false); + StargateCommand.sendMessage(player, "Do this by right-clicking two blocks next to each other", false); + players.put(player, new SGCPlayer(player, Action.IMPORT, args)); + // Export + } else if (args[0].equalsIgnoreCase("export")) { + if (!player.hasPermission("stargate.command.export")) { + StargateCommand.sendMessage(player, "Permission Denied", true); + return true; + } + if (args.length < 2) { + StargateCommand.sendMessage(player, "Usage: /sgc export [force]", false); + StargateCommand.sendMessage(player, "Use force to overwrite existing .gate files", false); + sendMessage(player, "Example: /sgc export super force", false); + return true; + } + boolean force = false; + if (args.length > 2 && args[2].equalsIgnoreCase("force")) force = true; + if (Gate.getGateByName(args[1] + ".gate") != null && !force) { + sendMessage(player, "A gate by that name exists. Use force to overwrite", true); + return true; + } + StargateCommand.sendMessage(player, "Please select where you would like the sign placed", false); + StargateCommand.sendMessage(player, "Do this by right-clicking the block", false); + players.put(player, new SGCPlayer(player, Action.EXPORT, args)); + // Cancel + } else if (args[0].equalsIgnoreCase("cancel")) { + players.remove(player); + StargateCommand.sendMessage(player, "Command cancelled", false); + } + return true; + } else if (command.getName().equalsIgnoreCase("dial")) { + if (args.length < 1 || args.length > 2) return false; + String dest = null; + String source = null; + String network = null; + dest = args[0]; + if (args.length > 1) { + if (args.length < 2) { + sendMessage(player, "You must provide a network to direct dial a gate", true); + return true; + } + source = args[1]; + network = args[2]; + dialGate(player, dest, source, network); + } else { + players.put(player, new SGCPlayer(player, Action.DIAL, args)); + sendMessage(player, "The next Stargate you activate will have " + dest + " set as the destination if available", false); + } + return true; + } + return false; + } + + public static void sendMessage(CommandSender sender, String message, boolean error) { + if (error) { + message = ChatColor.RED + "[SGC] " + ChatColor.WHITE + message; + } else { + message = ChatColor.BLUE + "[SGC] " + ChatColor.WHITE + message; + } + sender.sendMessage(message); + } + + private class BlockChange { + public Blox block; + public Integer newType; + public Integer newData; + } + + public enum Action { + IMPORT, + EXPORT, + DIAL + } +} diff --git a/src/plugin.yml b/src/plugin.yml index 5b533ba..f351d64 100644 --- a/src/plugin.yml +++ b/src/plugin.yml @@ -1,18 +1,27 @@ -name: StargateCommand -main: net.TheDgtl.StargateCommand.StargateCommand -version: 0.0.1 -description: Command addon for the Stargate plugin for Bukkit -author: Drakia -depend: [Stargate] -website: http://www.thedgtl.net -commands: - sgc: - description: Used to reload the plugin. Console use only. - usage: / reload - Used to reload the plugin. Console use only. -permissions: - stargate.command.import: - description: Allow the user of /sgc import - default: op - stargate.command.export: - description: Allow the user of /sgc export - default: op \ No newline at end of file +name: StargateCommand +main: net.TheDgtl.StargateCommand.StargateCommand +version: 0.0.1 +description: Command addon for the Stargate plugin for Bukkit +author: Drakia +depend: [Stargate] +website: http://www.thedgtl.net +commands: + sgc: + description: StargateCommand import/export commands. + usage: | + / [force] + Type: "/ import" for help with import + Type: "/ export" for help with export + Type: "/ cancel" to cancel any pending SGC action + dial: + description: Dial a stargate + usage: / [source] [network] +permissions: + stargate.command.import: + description: Allow the use of /sgc import + default: op + stargate.command.export: + description: Allow the use of /sgc export + default: op + stargate.command.dial: + description: Allow the use of /dial \ No newline at end of file