001    package org.bukkit.command.defaults;
002    
003    import org.bukkit.Bukkit;
004    import org.bukkit.ChatColor;
005    import org.bukkit.Location;
006    import org.bukkit.command.CommandSender;
007    import org.bukkit.entity.Player;
008    
009    public class PlaySoundCommand extends VanillaCommand {
010        public PlaySoundCommand() {
011            super("playsound");
012            this.description = "Plays a sound to a given player";
013            this.usageMessage = "/playsound <sound> <player> [x] [y] [z] [volume] [pitch] [minimumVolume]";
014            this.setPermission("bukkit.command.playsound");
015        }
016    
017        @Override
018        public boolean execute(CommandSender sender, String currentAlias, String[] args) {
019            if (!testPermission(sender)) {
020                return true;
021            }
022    
023            if (args.length < 2) {
024                sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
025                return false;
026            }
027            final String soundArg = args[0];
028            final String playerArg = args[1];
029    
030            final Player player = Bukkit.getPlayerExact(playerArg);
031            if (player == null) {
032                sender.sendMessage(ChatColor.RED + "Can't find player " + playerArg);
033                return false;
034            }
035    
036            final Location location = player.getLocation();
037    
038            double x = Math.floor(location.getX());
039            double y = Math.floor(location.getY() + 0.5D);
040            double z = Math.floor(location.getZ());
041            double volume = 1.0D;
042            double pitch = 1.0D;
043            double minimumVolume = 0.0D;
044    
045            switch (args.length) {
046            default:
047            case 8:
048                minimumVolume = getDouble(sender, args[7], 0.0D, 1.0D);
049            case 7:
050                pitch = getDouble(sender, args[6], 0.0D, 2.0D);
051            case 6:
052                volume = getDouble(sender, args[5], 0.0D, Float.MAX_VALUE);
053            case 5:
054                z = getRelativeDouble(z, sender, args[4]);
055            case 4:
056                y = getRelativeDouble(y, sender, args[3]);
057            case 3:
058                x = getRelativeDouble(x, sender, args[2]);
059            case 2:
060                // Noop
061            }
062    
063            final double fixedVolume = volume > 1.0D ? volume * 16.0D : 16.0D;
064            final Location soundLocation = new Location(player.getWorld(), x, y, z);
065            if (location.distanceSquared(soundLocation) > fixedVolume * fixedVolume) {
066                if (minimumVolume <= 0.0D) {
067                    sender.sendMessage(ChatColor.RED + playerArg + " is too far away to hear the sound");
068                    return false;
069                }
070    
071                final double deltaX = x - location.getX();
072                final double deltaY = y - location.getY();
073                final double deltaZ = z - location.getZ();
074                final double delta = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) / 2.0D;
075    
076                if (delta > 0.0D) {
077                    location.add(deltaX / delta, deltaY / delta, deltaZ / delta);
078                }
079    
080                player.playSound(location, soundArg, (float) minimumVolume, (float) pitch);
081            } else {
082                player.playSound(soundLocation, soundArg, (float) volume, (float) pitch);
083            }
084            sender.sendMessage(String.format("Played '%s' to %s", soundArg, playerArg));
085            return true;
086        }
087    }