package net.minecraft.command.commands; import java.util.ArrayList; import java.util.Collections; import java.util.List; import net.minecraft.block.Block; import net.minecraft.command.CommandException; import net.minecraft.command.CommandUtilities; import net.minecraft.command.ICommandSender; import net.minecraft.command.NumberInvalidException; 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.Shift; import net.minecraft.item.Item; import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.Vec3; import net.minecraft.world.World; import net.minecraft.world.WorldServer; public abstract class CommandParticle extends CommandArg<Integer> { public static final CommandConstructable constructable = new CommandConstructable() { @Override public CommandArg<Integer> construct(final CParserData data) throws SyntaxErrorException { if (data.path.isEmpty()) return new Primitive(data); return "iconcrack".equals(data.path.get(0)) ? new ItemParticle(data) : new BlockParticle(data); } }; private final CommandArg<Shift> origin; private final CommandArg<Double> dx_r, dy_g, dz_b, vel_bright; private final CommandArg<Integer> count; private final CommandArg<String> mode; private final CommandArg<List<ICommandSender>> targets; private CommandParticle(final CParserData data, final int startIndex) { this.origin = data.get(TypeIDs.Shift, startIndex); this.dx_r = data.get(TypeIDs.Double); this.dy_g = data.get(TypeIDs.Double); this.dz_b = data.get(TypeIDs.Double); this.vel_bright = data.get(TypeIDs.Double); this.count = data.get(TypeIDs.Integer); this.mode = data.get(TypeIDs.String); this.targets = data.get(TypeIDs.ICmdSenderList); } protected Integer procCommand(final ICommandSender sender, final String particleID, final EnumParticleTypes particle, final int[] paramArray) throws CommandException, NumberInvalidException { final Shift shift = this.origin.eval(sender); final double dx_r = this.dx_r.eval(sender); final double dy_g = this.dy_g.eval(sender); final double dz_b = this.dz_b.eval(sender); final double vel_bright = this.vel_bright.eval(sender); final int count = this.count == null ? 0 : this.count.eval(sender); final boolean force = this.mode != null && "force".equalsIgnoreCase(this.mode.eval(sender)); final List<ICommandSender> targets = this.targets == null ? Collections.singletonList(sender) : this.targets.eval(sender); CommandUtilities.checkInt(count, 0); final World world = sender.getEntityWorld(); if (world instanceof WorldServer) { final WorldServer worldServer = (WorldServer) world; for (final ICommandSender target : targets) { final Vec3 targetPos = shift.addBase(target.getPositionVector()); worldServer.func_180505_a(particle, force, targetPos.xCoord, targetPos.yCoord, targetPos.zCoord, count, dx_r, dy_g, dz_b, vel_bright, paramArray); } CommandUtilities.notifyOperators(sender, "commands.particle.success", particleID, Math.max(count, 1) * targets.size()); return targets.size(); } return 0; } private static class Primitive extends CommandParticle { private final CommandArg<String> particleType; private Primitive(final CParserData data) { super(data, 1); this.particleType = data.get(TypeIDs.String, 0); } @Override public Integer eval(final ICommandSender sender) throws CommandException { final String particleID = this.particleType.eval(sender); EnumParticleTypes particle; List<Integer> params = null; String particleID_ = particleID; while ((particle = EnumParticleTypes.getByName(particleID_)) == null) { final int index = particleID_.lastIndexOf('_', particleID_.length() - 2) + 1; if (index == 0) throw new CommandException("commands.particle.notFound", particleID); if (params == null) params = new ArrayList<>(); try { params.add(Integer.parseInt(particleID_.substring(index, particleID_.length() - (params.isEmpty() ? 0 : 1)))); } catch (final NumberFormatException ex) { throw new CommandException("commands.particle.notFound", particleID); } particleID_ = particleID_.substring(0, index); } final int paramCount = params == null ? 0 : params.size(); if (particle.func_179345_d() != paramCount) throw new CommandException("commands.particle.notFound", particleID); final int[] paramArray = new int[paramCount]; for (int i = 0; i < paramCount; ++i) paramArray[i] = params.get(paramCount - i - 1); return this.procCommand(sender, particleID, particle, paramArray); } } private static abstract class Parametrized extends CommandParticle { protected String particleID; private Parametrized(final CParserData data) { super(data, 2); this.particleID = data.path.get(0); } @Override public Integer eval(final ICommandSender sender) throws CommandException { final EnumParticleTypes particle = EnumParticleTypes.getByName(this.particleID + "_"); if (particle == null) throw new CommandException("commands.particle.notFound", this.particleID); final int[] params = this.getParams(sender); return this.procCommand(sender, this.getParticleID(params), particle, params); } protected abstract int[] getParams(ICommandSender sender) throws CommandException; protected abstract String getParticleID(int[] params) throws CommandException; } private static class BlockParticle extends Parametrized { private final CommandArg<Block> blockID; private final CommandArg<Integer> meta; private BlockParticle(final CParserData data) { super(data); this.blockID = data.get(TypeIDs.BlockID, 0); this.meta = data.get(TypeIDs.Integer); } @Override protected int[] getParams(final ICommandSender sender) throws CommandException { return new int[] { Block.blockRegistry.getIDForObject(this.blockID.eval(sender)) + 4096 * this.meta.eval(sender) }; } @Override protected String getParticleID(final int[] params) throws CommandException { return this.particleID + "_" + params[0]; } } private static class ItemParticle extends Parametrized { private final CommandArg<Item> itemID; private final CommandArg<Integer> meta; private ItemParticle(final CParserData data) { super(data); this.itemID = data.get(TypeIDs.ItemID, 0); this.meta = data.get(TypeIDs.Integer); } @Override protected int[] getParams(final ICommandSender sender) throws CommandException { return new int[] { Item.itemRegistry.getIDForObject(this.itemID.eval(sender)), this.meta.eval(sender) }; } @Override protected String getParticleID(final int[] params) throws CommandException { return this.particleID + "_" + params[0] + "_" + params[1]; } } }