package com.sijobe.spc.command; import com.sijobe.spc.core.IPlayerMP; import com.sijobe.spc.validation.Parameter; import com.sijobe.spc.validation.ParameterInteger; import com.sijobe.spc.validation.ParameterString; import com.sijobe.spc.validation.Parameters; import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandSender; import com.sijobe.spc.wrapper.Coordinate; import com.sijobe.spc.wrapper.Item; import com.sijobe.spc.wrapper.Player; import java.util.HashMap; import java.util.List; import net.minecraft.src.MathHelper; /** * Creates a path with the specified size. * * @author q3hardcore * @version 1.4 */ @Command ( name = "path", description = "Creates a path", version = "1.4" ) public class Path extends StandardCommand implements IPlayerMP { /** * The parameters of the command */ private static final Parameters PARAMETERS = new Parameters ( new Parameter[] { new ParameterString("[BLOCK]",true), new ParameterInteger("[RADIUS]",true) } ); /** * A hashmap containing path settings for each player */ private static HashMap<String, int[]> playerConfig = new HashMap<String, int[]>(); /** * Name of the current world */ private static String worldName = ""; /** * @see com.sijobe.spc.wrapper.CommandBase#execute(com.sijobe.spc.wrapper.CommandSender, java.util.List) */ @Override public void execute(CommandSender sender, List<?> params) throws CommandException { Player player = getSenderAsPlayer(sender); String playerName = player.getPlayerName(); checkWorld(player); if (params.size() >= 1) { String args[] = ((String)params.get(0)).split("(\\^|:)"); int block = -1; int size = 3; int meta = 0; try { block = Integer.parseInt(args[0]); } catch (NumberFormatException e) { block = -1; } if (block == -1) { block = Item.getItemId((args[0]).replace('_', ' ')); } if (args[0].equalsIgnoreCase("air")) { block = 0; } if (!player.getWorld().isValidBlockType(block) && block != 0) { // isValidBlockType should be static throw new CommandException("Unknown block: " + args[0]); } if(args.length > 1) { try { meta = Integer.parseInt(args[1]); } catch (NumberFormatException e) { sender.sendMessageToPlayer("Invalid metadata value specified, using default."); meta = 0; } if(meta < 0 || meta > 15) { sender.sendMessageToPlayer("Using default metadata value."); meta = 0; } } if (params.size() > 1) { size = (Integer)params.get(1); if(size < 1) { throw new CommandException("Size must be at least 1."); } if(size > 50) { sender.sendMessageToPlayer("Clamping path size."); size = 50; } } if(playerConfig.containsKey(playerName)) { int[] plrData = playerConfig.get(playerName); if(plrData[0] == block && plrData[1] == meta && plrData[2] == size) { throw new CommandException("Already making specified type of path!"); } } sender.sendMessageToPlayer("Path mode enabled."); playerConfig.put(playerName, new int[]{block, meta, size, -1, -1, -1}); } else if(playerConfig.containsKey(playerName) && playerConfig.get(playerName)[0] > -1) { sender.sendMessageToPlayer("Path mode disabled."); playerConfig.get(playerName)[0] = -1; } else { throw new CommandException("Must specify block."); } } private void checkWorld(Player player) { String currentWorldName = player.getWorld().getName(); if(!worldName.equals(currentWorldName)) { System.out.println("SPC: Clearing path settings."); playerConfig.clear(); worldName = currentWorldName; } } /** * @see com.sijobe.spc.wrapper.CommandBase#getParameters() */ @Override public Parameters getParameters() { return PARAMETERS; } /** * @see com.sijobe.spc.core.IHook#init(java.lang.Object[]) */ @Override public void init(Object... params) { } /** * @see com.sijobe.spc.core.IPlayerMP#onTick(com.sijobe.spc.wrapper.Player) */ @Override public void onTick(Player player) { checkWorld(player); String playerName = player.getPlayerName(); if (playerConfig.containsKey(playerName)) { int[] plrData = playerConfig.get(playerName); makePath(player, plrData); } else { return; } } /** * Check if block is valid, if so makes path * * @param player - The player that is making a path * @param data - Path data for player */ private void makePath(Player player, int[] data) { if (data[0] >= 0) { // block Coordinate position = player.getPosition(); int x = MathHelper.floor_double(position.getX()); int y = MathHelper.floor_double(position.getY()); // used to take away 1 int z = MathHelper.floor_double(position.getZ()); if (x != data[3] || y != data[4] || z != data[5]) { // prevx, prevy, prevz int start = data[2] * -1 + 1; // size for (int i = start; i < data[2]; i++) { for (int j = -1; j < data[2]; j++) { for (int k = start; k < data[2]; k++) { if (j == -1) { this.setBlock(player, x + i, y + j, z + k, data[0], data[1]); } else { this.setBlock(player, x + i, y + j, z + k, 0, 0); } } } } data[3] = x; data[4] = y; data[5] = z; } } } /** * Sets block at specified position to specified type * This function should be re-written to be parsed a World object * Additionally, SPC's World class needs setBlockWithNotify added * * @param player - The player whose world we are setting a block in * @param i - The X position of the block * @param j - The Y position of the block * @param k - The Z position of the block * @param type - The type (ID) of the block */ private void setBlock(Player player, int i, int j, int k, int type, int meta) { //player.getWorld().getMinecraftWorld().func_94575_c(i, j, k, type); player.getWorld().setBlockDataWithMeta(new Coordinate(i, j, k), type, meta); } }