package net.minecraft.command.commands; import java.util.List; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.command.CommandException; import net.minecraft.command.CommandHandler; import net.minecraft.command.CommandResultStats; import net.minecraft.command.CommandUtilities; import net.minecraft.command.ICommandSender; import net.minecraft.command.SyntaxErrorException; import net.minecraft.command.arg.CommandArg; import net.minecraft.command.collections.TypeIDs; import net.minecraft.command.construction.CommandConstructable; import net.minecraft.command.construction.CommandDescriptorDefault.CParserData; import net.minecraft.command.type.custom.coordinate.TypeCoordinates; import net.minecraft.command.type.custom.coordinate.TypeCoordinates.Shift; import net.minecraft.entity.Entity; import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.server.MinecraftServer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockPos; import net.minecraft.util.IChatComponent; import net.minecraft.util.Vec3; import net.minecraft.world.World; public class CommandExecuteAt extends CommandArg<Integer> { public static final CommandConstructable constructable = new CommandConstructable() { @Override public CommandExecuteAt construct(final CParserData data) throws SyntaxErrorException { return new CommandExecuteAt( data.get(TypeIDs.ICmdSenderList), data.get(TypeIDs.Shift), data.get(TypeIDs.Integer)); } }; public static final CommandConstructable constructableDetect = new CommandConstructable() { @Override public Detect construct(final CParserData data) throws SyntaxErrorException { return new CommandExecuteAt.Detect( data.get(TypeIDs.ICmdSenderList), data.get(TypeIDs.Shift), data.get(TypeIDs.Shift), data.get(TypeIDs.BlockID), data.get(TypeIDs.Integer), data.get(TypeIDs.NBTCompound), data.get(TypeIDs.Integer)); } }; private final CommandArg<List<ICommandSender>> targets; private final CommandArg<Shift> position; private final CommandArg<Integer> command; public CommandExecuteAt(final CommandArg<List<ICommandSender>> targets, final CommandArg<Shift> position, final CommandArg<Integer> command) { this.targets = targets; this.position = position == null ? TypeCoordinates.trivialShift : position; this.command = command; } @Override public Integer eval(final ICommandSender sender) throws CommandException { final List<ICommandSender> targets = this.targets.eval(sender); final Shift shift = this.position.eval(sender); this.evalArgs(sender); this.checkArgs(); int successCount = 0; for (final ICommandSender target : targets) { final Vec3 targetPos = target.getPositionVector(); final ICommandSender wrapped = this.wrapTarget(target, sender, shift.addBase(targetPos)); if (this.check(sender, wrapped)) successCount += CommandHandler.executeCommand(wrapped, this.command); // Can also be changed to '+1 if successfull' } if (successCount < 1) throw new CommandException("commands.execute.allInvocationsFailed", ""); // The command string is dead... (for the moment) sender.func_174794_a(CommandResultStats.Type.AFFECTED_ENTITIES, targets.size()); return successCount; } private ICommandSender wrapTarget(final ICommandSender target, final ICommandSender sender, final Vec3 pos) { return new ICommandSender() { @Override public String getName() { return target.getName(); } @Override public IChatComponent getDisplayName() { return target.getDisplayName(); } @Override public void addChatMessage(final IChatComponent message) { sender.addChatMessage(message); } @Override public boolean canCommandSenderUseCommand(final int permissionLevel, final String command) { return sender.canCommandSenderUseCommand(permissionLevel, command); } BlockPos blockPos = new BlockPos(pos); @Override public BlockPos getPosition() { return new BlockPos(this.blockPos); } @Override public Vec3 getPositionVector() { return pos; } @Override public World getEntityWorld() { return target.getEntityWorld(); } @Override public Entity getCommandSenderEntity() { return target instanceof Entity ? (Entity) target : null; } @Override public boolean sendCommandFeedback() { final MinecraftServer server = MinecraftServer.getServer(); return server == null || server.worldServers[0].getGameRules().getGameRuleBooleanValue("commandBlockOutput"); } @Override public void func_174794_a(final CommandResultStats.Type stat, final int value) { target.func_174794_a(stat, value); } }; } @SuppressWarnings("unused") protected boolean check(final ICommandSender sender, final ICommandSender target) { return true; } @SuppressWarnings("unused") protected void evalArgs(final ICommandSender sender) throws CommandException { } protected void checkArgs() throws CommandException { } private static class Detect extends CommandExecuteAt { private final CommandArg<Shift> blockPosition; private final CommandArg<Block> blockID; private final CommandArg<Integer> metadata; private final CommandArg<NBTTagCompound> nbt; private Shift eBlockPosition; private Block eBlockID; private int eMetadata; private NBTTagCompound eNBT; public Detect(final CommandArg<List<ICommandSender>> targets, final CommandArg<Shift> position, final CommandArg<Shift> blockPosition, final CommandArg<Block> blockID, final CommandArg<Integer> metadata, final CommandArg<NBTTagCompound> nbt, final CommandArg<Integer> command) { super(targets, position, command); this.blockPosition = blockPosition; this.blockID = blockID; this.metadata = metadata; this.nbt = nbt; } @Override protected boolean check(final ICommandSender sender, final ICommandSender target) { final World world = target.getEntityWorld(); BlockPos blockPos = null; try { blockPos = new BlockPos(this.eBlockPosition.addBase(target.getPositionVector())); } catch (final CommandException e) { CommandUtilities.errorMessage(sender, "commands.execute.failed", "detect", target.getName()); } final IBlockState blockState = world.getBlockState(blockPos); boolean valid = blockState.getBlock() == Detect.this.eBlockID; if (valid && Detect.this.metadata != null) valid = blockState.getBlock().getMetaFromState(blockState) == Detect.this.eMetadata; if (valid && Detect.this.eNBT != null) { final TileEntity te = world.getTileEntity(blockPos); if (te != null) { final NBTTagCompound tag = new NBTTagCompound(); te.writeToNBT(tag); valid = NBTBase.compareTags(Detect.this.eNBT, tag, true); } else valid = false; } if (!valid) CommandUtilities.errorMessage(sender, "commands.execute.failed", "detect", target.getName()); return valid; } @Override protected void evalArgs(final ICommandSender sender) throws CommandException { this.eBlockPosition = this.blockPosition.eval(sender); this.eBlockID = this.blockID.eval(sender); if (this.metadata != null) this.eMetadata = this.metadata.eval(sender); this.eNBT = CommandArg.eval(this.nbt, sender); } @Override protected void checkArgs() throws CommandException { if (this.metadata != null) CommandUtilities.checkInt(this.eMetadata, 0, 15); } } }