Skip to content

Instantly share code, notes, and snippets.

@NeatMonster
Last active November 5, 2017 21:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NeatMonster/6414575 to your computer and use it in GitHub Desktop.
Save NeatMonster/6414575 to your computer and use it in GitHub Desktop.
package fr.neatmonster.lasergun;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.SerializableAs;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitRunnable;
import com.comphenix.protocol.Packets;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import com.google.common.primitives.Ints;
public class LaserGun extends JavaPlugin implements Listener {
@SerializableAs("PotionEffect")
public static class IPotionEffect extends PotionEffect implements ConfigurationSerializable {
public IPotionEffect(final Map<String, Object> map) {
super(PotionEffectType.getByName((String) map.get("type")), (int) map.get("duration"), (int) map
.get("amplifier"), (boolean) map.get("ambient"));
}
public IPotionEffect(final PotionEffect effect) {
super(effect.getType(), effect.getDuration(), effect.getAmplifier(), effect.isAmbient());
}
@Override
public Map<String, Object> serialize() {
final Map<String, Object> map = new HashMap<String, Object>();
map.put("type", getType().getName());
map.put("duration", getDuration());
map.put("amplifier", getAmplifier());
map.put("ambient", isAmbient());
return map;
}
}
private class LaserBeam extends BukkitRunnable {
private final List<Integer> entitiesIds = new ArrayList<Integer>();
public LaserBeam(final Location location) {
int vehicle = add(location);
for (int i = 0; i < 9; i++) {
final int passenger = add(location);
mount(passenger, vehicle);
vehicle = passenger;
}
for (final Entity entity : location.getWorld().getEntities())
if (entity instanceof LivingEntity)
for (final Entry<Integer, IPotionEffect> entry : effects.entrySet())
if (entity.getLocation().distance(location) < entry.getKey())
((LivingEntity) entity).addPotionEffect(entry.getValue());
}
private int add(final Location location) {
final int entityId = currentId--;
final PacketContainer packet = new PacketContainer(Packets.Server.MOB_SPAWN);
packet.getIntegers().write(0, entityId).write(1, (int) EntityType.CREEPER.getTypeId())
.write(2, (int) (location.getX() * 32)).write(3, (int) (location.getY() * 32))
.write(4, (int) (location.getZ() * 32));
final WrappedDataWatcher watcher = new WrappedDataWatcher();
watcher.setObject(0, Byte.valueOf((byte) 32));
watcher.setObject(17, Byte.valueOf((byte) 1));
packet.getDataWatcherModifier().write(0, watcher);
send(packet);
entitiesIds.add(entityId);
return entityId;
}
private void mount(final int passenger, final int vehicle) {
final PacketContainer packet = new PacketContainer(Packets.Server.ATTACH_ENTITY);
packet.getIntegers().write(0, 0).write(1, passenger).write(2, vehicle);
send(packet);
}
@Override
public void run() {
final PacketContainer packet = new PacketContainer(Packets.Server.DESTROY_ENTITY);
packet.getIntegerArrays().write(0, Ints.toArray(entitiesIds));
send(packet);
entitiesIds.clear();
}
public void send(final PacketContainer packet) {
for (final Player player : Bukkit.getOnlinePlayers())
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
} catch (final InvocationTargetException e) {
e.printStackTrace();
}
}
}
private static final ItemStack DEFAULT_AMMUNITION = new ItemStack(Material.NETHER_STAR, 0);
private static final Map<Integer, PotionEffect> DEFAULT_EFFECTS = new HashMap<Integer, PotionEffect>();
private static final ItemStack DEFAULT_LASERGUN = new ItemStack(Material.MELON_STEM);
static {
DEFAULT_EFFECTS.put(1, new IPotionEffect(new PotionEffect(PotionEffectType.HARM, 1, 1)));
final ItemMeta itemMeta = DEFAULT_LASERGUN.getItemMeta();
itemMeta.setDisplayName(ChatColor.BLUE + "LaserGun");
itemMeta.setLore(Arrays.asList(new String[] { ChatColor.LIGHT_PURPLE + "*pew*" + ChatColor.GRAY
+ " Use right click to fire! " + ChatColor.LIGHT_PURPLE + "*pew*" }));
DEFAULT_LASERGUN.setItemMeta(itemMeta);
}
private ItemStack ammunition = null;
private int currentId = Integer.MAX_VALUE;
private final Map<Integer, IPotionEffect> effects = new HashMap<Integer, IPotionEffect>();
private ItemStack laserGun = null;
@Override
public boolean onCommand(final CommandSender sender, final Command command, final String label, final String[] args) {
if (command.getName().equalsIgnoreCase("laserbeam")) {
if (sender.hasPermission("lasergun.trigger"))
try {
final Location location = sender instanceof Player ? ((Player) sender).getLocation()
: ((BlockCommandSender) sender).getBlock().getLocation().add(0.5D, 1D, 0.5D);
for (int i = 0; i < 3; i++) {
final int coordinate = Integer.parseInt(args[i].substring(args[i].startsWith("~") ? 1 : 0));
if (args[i].startsWith("~"))
location.add(i == 0 ? coordinate : 0D, i == 1 ? coordinate : 0D, i == 2 ? coordinate : 0D);
else if (i == 0)
location.setX(coordinate);
else if (i == 1)
location.setY(coordinate);
else if (i == 2)
location.setZ(coordinate);
}
Bukkit.getScheduler().scheduleSyncDelayedTask(this, new LaserBeam(location), 20L);
} catch (final Exception e) {
final Player player = Bukkit.getPlayer(args[0]);
if (player != null)
Bukkit.getScheduler().scheduleSyncDelayedTask(this, new LaserBeam(player.getLocation()), 20L);
else
sender.sendMessage(ChatColor.YELLOW
+ "Usage: /laserbeam <player|[~]x [~]y [~]z> - trigger a LaserBeam");
}
else
sender.sendMessage(ChatColor.RED + "You're not allowed to trigger a LaserBeam!");
return true;
} else if (command.getName().equalsIgnoreCase("lasergun")) {
if (sender instanceof Player) {
final Player player = (Player) sender;
if (player.hasPermission("lasergun.get")) {
if (args.length == 0) {
player.getInventory().addItem(laserGun);
player.sendMessage(ChatColor.GREEN + "Here is your LaserGun, please be careful.");
} else
player.sendMessage(ChatColor.YELLOW + "Usage: /lg - get a a LaserGun");
} else
player.sendMessage(ChatColor.RED + "You're not allowed to get a LaserGun!");
} else
sender.sendMessage("Only a player can carry a LaserGun!");
return true;
}
return false;
}
@Override
public void onEnable() {
getConfig().set("ammunition", ammunition = getConfig().getItemStack("ammunition", DEFAULT_AMMUNITION));
effects.clear();
if (!getConfig().contains("effects"))
getConfig().createSection("effects", DEFAULT_EFFECTS);
for (final Entry<String, Object> entry : getConfig().getConfigurationSection("effects").getValues(false).entrySet())
effects.put(Integer.parseInt(entry.getKey()), (IPotionEffect) entry.getValue());
getConfig().set("lasergun", laserGun = getConfig().getItemStack("lasergun", DEFAULT_LASERGUN));
saveConfig();
getServer().getPluginManager().registerEvents(this, this);
}
@EventHandler
@SuppressWarnings("deprecation")
public void onPlayerInteract(final PlayerInteractEvent event) {
final Player player = event.getPlayer();
if (player.getItemInHand().equals(laserGun)) {
if (player.hasPermission("lasergun.use")) {
if (player.getInventory().containsAtLeast(ammunition, ammunition.getAmount() > 0 ? 1 : 0)) {
player.getInventory().removeItem(ammunition);
player.updateInventory();
Location location = null;
if (event.getAction() == Action.RIGHT_CLICK_AIR)
location = player.getTargetBlock(null, 200).getLocation().add(0.5D, 1D, 0.5D);
else if (event.getAction() == Action.RIGHT_CLICK_BLOCK)
location = event.getClickedBlock().getLocation().add(0.5D, 1D, 0.5D);
if (location != null) {
Bukkit.getScheduler().scheduleSyncDelayedTask(this, new LaserBeam(location), 20L);
player.getWorld().playSound(player.getLocation(), Sound.SHOOT_ARROW, 1.0f, 1.0f);
}
} else
player.getWorld().playSound(player.getLocation(), Sound.ITEM_BREAK, 1.0f, 1.0f);
} else
player.sendMessage(ChatColor.RED + "You're not allowed to use a LaserGun!");
event.setCancelled(true);
}
}
}
name: LaserGun
version: 1.0.1
author: NeatMonster
main: fr.neatmonster.lasergun.LaserGun
depend: [ProtocolLib]
commands:
laserbeam:
aliases: [lb]
lasergun:
aliases: [lg]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment