diff --git a/DeathSwap/config.yml b/DeathSwap/config.yml new file mode 100644 index 0000000..0023eba --- /dev/null +++ b/DeathSwap/config.yml @@ -0,0 +1,7 @@ +game: + minSwapTime: 25 + maxSwapTime: 90 + resistanceDuration: 6 + spawnDistance: 1000 + allowDrops: true + startKit: "" \ No newline at end of file diff --git a/DeathSwap/plugin.yml b/DeathSwap/plugin.yml new file mode 100644 index 0000000..40d2a56 --- /dev/null +++ b/DeathSwap/plugin.yml @@ -0,0 +1,11 @@ +name: DeathSwap +main: cz.fo2.chylex.deathswap.DeathSwap +version: 1.1 beta +author: chylex +website: https://chylex.com +load: POSTWORLD +commands: + deathswap: + aliases: [ds,swap] + description: DeathSwap commands + usage: /deathswap diff --git a/DeathSwap/src/cz/fo2/chylex/deathswap/CommandOverride.java b/DeathSwap/src/cz/fo2/chylex/deathswap/CommandOverride.java new file mode 100644 index 0000000..7e848b8 --- /dev/null +++ b/DeathSwap/src/cz/fo2/chylex/deathswap/CommandOverride.java @@ -0,0 +1,25 @@ +package cz.fo2.chylex.deathswap; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +public class CommandOverride{ + public static boolean listCommand(DeathSwap plugin, CommandSender s){ + if (plugin.swapper.isPlaying()){ + StringBuilder alive = new StringBuilder(), dead = new StringBuilder(); + for(String str : plugin.swapper.getPlayers()){ + alive.append(str).append(", "); + } + for(String str : plugin.spectating.getSpectators()){ + dead.append(str).append(", "); + } + if (alive.length() > 0){ + s.sendMessage(ChatColor.GREEN + "[Alive] " + ChatColor.RESET + alive.substring(0, alive.length() - 2)); + } + if (dead.length() > 0){ + s.sendMessage(ChatColor.GREEN + "[Spectating] " + ChatColor.RESET + dead.substring(0, dead.length() - 2)); + } + return true; + } + return false; + } +} diff --git a/DeathSwap/src/cz/fo2/chylex/deathswap/Config.java b/DeathSwap/src/cz/fo2/chylex/deathswap/Config.java new file mode 100644 index 0000000..d7c41ca --- /dev/null +++ b/DeathSwap/src/cz/fo2/chylex/deathswap/Config.java @@ -0,0 +1,30 @@ +package cz.fo2.chylex.deathswap; +import org.bukkit.ChatColor; +import org.bukkit.configuration.file.FileConfiguration; + +public class Config{ + private DeathSwap plugin; + public int min_swap_time, max_swap_time, resistance_duration, spawn_distance; + public boolean allow_drops; + public String spawn_items; + + public Config(DeathSwap plugin){ + this.plugin = plugin; + plugin.saveDefaultConfig(); + } + + public Config load(){ + FileConfiguration conf = plugin.getConfig(); + min_swap_time = conf.getInt("game.minSwapTime", 25); + max_swap_time = conf.getInt("game.maxSwapTime", 90); + resistance_duration = conf.getInt("game.resistanceDuration", 6); + spawn_distance = conf.getInt("game.spawnDistance", 1000); + allow_drops = conf.getBoolean("game.allowDrops", true); + spawn_items = conf.getString("game.startKit", ""); + return this; + } + + public static String hl(String msg){ + return new StringBuilder().append(ChatColor.RED).append(msg).append(ChatColor.RESET).toString(); + } +} diff --git a/DeathSwap/src/cz/fo2/chylex/deathswap/DeathSwap.java b/DeathSwap/src/cz/fo2/chylex/deathswap/DeathSwap.java new file mode 100644 index 0000000..8cea870 --- /dev/null +++ b/DeathSwap/src/cz/fo2/chylex/deathswap/DeathSwap.java @@ -0,0 +1,76 @@ +package cz.fo2.chylex.deathswap; +import java.util.Arrays; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; +import org.bukkit.plugin.java.JavaPlugin; + +public class DeathSwap extends JavaPlugin implements Listener{ + public Config config; + public Swapper swapper; + public Spectating spectating; + + @Override + public void onEnable(){ + config = new Config(this).load(); + swapper = new Swapper(this); + spectating = new Spectating(this); + new EventListener(this); + } + + @Override + public void onDisable(){ + } + + @Override + public boolean onCommand(CommandSender s, Command cmd, String alias, String[] args){ + if (s instanceof Player && ((Player)s).isOp() == false){ + s.sendMessage("You don't have permissions!"); + return true; + } + if (args.length == 0){ + s.sendMessage(ChatColor.GREEN + "[DeathSwap commands]"); + String a = "/" + alias + " "; + s.sendMessage(a + "start - start the game"); + s.sendMessage(a + "resume - resume after server crash"); + s.sendMessage(a + "reload - reload configuration file"); + } + else if (args[0].equals("start")){ + if (swapper.isPlaying()){ + s.sendMessage("There's already a game running!"); + } + else if (getServer().getOnlinePlayers().length < 2){ + s.sendMessage("Not enough players to start the game!"); + } + else{ + getServer().getWorlds().get(0).setTime(0L); + getServer().broadcastMessage("Let the game begin!"); + PlayerDistribution.distributeOnGrid(Arrays.asList(getServer().getOnlinePlayers()), getServer().getWorlds().get(0), config.spawn_distance); + swapper.start(); + } + } + else if (args[0].equals("resume")){ + if (swapper.isPlaying()){ + s.sendMessage("There's already a game running!"); + } + else if (getServer().getOnlinePlayers().length < 2){ + s.sendMessage("Not enough players to start the game!"); + } + else{ + getServer().broadcastMessage("Let the game continue!"); + swapper.start(false); + } + } + else if (args[0].equals("reload")){ + reloadConfig(); + config.load(); + s.sendMessage("Configuration file was reloaded!"); + } + else{ + return false; + } + return true; + } +} diff --git a/DeathSwap/src/cz/fo2/chylex/deathswap/EventListener.java b/DeathSwap/src/cz/fo2/chylex/deathswap/EventListener.java new file mode 100644 index 0000000..bbf4c0c --- /dev/null +++ b/DeathSwap/src/cz/fo2/chylex/deathswap/EventListener.java @@ -0,0 +1,81 @@ +package cz.fo2.chylex.deathswap; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.event.server.ServerCommandEvent; +import cz.fo2.chylex.util.BukkitUtil; + +public class EventListener implements Listener{ + private DeathSwap plugin; + + public EventListener(DeathSwap plugin){ + this.plugin = plugin; + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @EventHandler + public void onPlayerLogin(PlayerJoinEvent e){ + if (!plugin.swapper.canPlayerJoin(e.getPlayer().getName())){ + plugin.spectating.addSpectator(e.getPlayer()); + } + else if (plugin.swapper.isPlaying()){ + plugin.swapper.onPlayerJoin(e.getPlayer().getName()); + } + } + + @EventHandler + public void onPlayerRespawn(PlayerRespawnEvent e){ + if (plugin.swapper.isPlaying()){ + plugin.spectating.addSpectator(e.getPlayer()); + } + } + + @EventHandler + public void onPlayerDisconnect(PlayerQuitEvent e){ + if (plugin.swapper.canPlayerJoin(e.getPlayer().getName()) && plugin.swapper.isPlaying()){ + plugin.swapper.onPlayerDisconnect(e.getPlayer().getName()); + } + } + + @EventHandler + public void onPlayerDeath(PlayerDeathEvent e){ + if (plugin.swapper.isPlaying()){ + plugin.swapper.onPlayerDeath(e.getEntity().getName()); + if (!plugin.swapper.isPlaying() || !plugin.config.allow_drops){ + e.setDroppedExp(0); + e.getDrops().clear(); + } + } + } + + @EventHandler + public void onEntityDamage(EntityDamageEvent e){ // I HATE SPAWN SUFFOCATION!!!!! + if (e.getCause() == DamageCause.SUFFOCATION && e instanceof Player && plugin.swapper.canPlayerJoin(((Player)e.getEntity()).getName()) && plugin.swapper.isPlaying() && plugin.swapper.spawnProtection){ + Location loc = e.getEntity().getLocation().clone(); + BukkitUtil.getHighestBlockYAt(loc); + e.getEntity().teleport(loc); + } + } + + @EventHandler + public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent e){ + if (e.getMessage().startsWith("/list")){ + e.setCancelled(CommandOverride.listCommand(plugin, e.getPlayer())); + } + } + + @EventHandler + public void onServerCommand(ServerCommandEvent e){ + if (e.getCommand().startsWith("list")){ + e.setCommand(CommandOverride.listCommand(plugin, e.getSender()) ? "" : "list"); + } + } +} diff --git a/DeathSwap/src/cz/fo2/chylex/deathswap/PlayerDistribution.java b/DeathSwap/src/cz/fo2/chylex/deathswap/PlayerDistribution.java new file mode 100644 index 0000000..3c2d0e3 --- /dev/null +++ b/DeathSwap/src/cz/fo2/chylex/deathswap/PlayerDistribution.java @@ -0,0 +1,38 @@ +package cz.fo2.chylex.deathswap; +import cz.fo2.chylex.util.BukkitUtil; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +public class PlayerDistribution{ + public static void distributeOnGrid(Collection<Player> players, World world, int distance){ + int gridSize = 1, gridPls = players.size() - 9; + while(gridPls > 0){ + gridPls -= (++gridSize) * 8; + } + List<Vector> locs = new ArrayList<Vector>(); + for(int a = -gridSize; a <= gridSize; a++){ + for(int b = -gridSize; b <= gridSize; b++){ + locs.add(new Vector(a * distance, 0, b * distance)); + } + } + Collections.shuffle(locs); + + for(Player p : players){ + Location l = locs.get(0).toLocation(world); + Chunk c = world.getChunkAt(l); + if (!c.isLoaded()){ + c.load(true); + } + BukkitUtil.getHighestBlockYAt(l); + p.teleport(l); + locs.remove(0); + } + } +} diff --git a/DeathSwap/src/cz/fo2/chylex/deathswap/Spectating.java b/DeathSwap/src/cz/fo2/chylex/deathswap/Spectating.java new file mode 100644 index 0000000..fdf7dfe --- /dev/null +++ b/DeathSwap/src/cz/fo2/chylex/deathswap/Spectating.java @@ -0,0 +1,211 @@ +package cz.fo2.chylex.deathswap; +import org.bukkit.GameMode; +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.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.event.entity.FoodLevelChangeEvent; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.metadata.FixedMetadataValue; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +public class Spectating implements Listener{ + private DeathSwap plugin; + private Map<String, Integer> spectators = new ConcurrentHashMap<String, Integer>(); + + public Spectating(DeathSwap plugin){ + this.plugin = plugin; + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + public Set<String> getSpectators(){ + return Collections.unmodifiableSet(spectators.keySet()); + } + + public void addSpectator(Player p){ + final String name = p.getName(); + spectators.put(name, -1); + p.setMetadata("DeathSwap_Spec", new FixedMetadataValue(plugin, true)); + + plugin.getServer().getScheduler().runTaskLater(plugin, new Runnable(){ + @Override + public void run(){ + Player p = plugin.getServer().getPlayerExact(name); + if (p == null){ + return; + } + p.setAllowFlight(true); + p.setFlying(true); + } + }, 5L); + + p.setGameMode(GameMode.ADVENTURE); + for(Player pl : plugin.getServer().getOnlinePlayers()){ + pl.hidePlayer(p); + } + + p.sendMessage("You're spectating. You can only chat with other spectators. Click to teleport between players."); + } + + public void removeSpectator(Player p){ + spectators.remove(p.getName()); + p.removeMetadata("DeathSwap_Spec", plugin); + + p.setAllowFlight(false); + p.setFlying(false); + p.setGameMode(GameMode.SURVIVAL); + for(Player pl : plugin.getServer().getOnlinePlayers()){ + pl.showPlayer(p); + } + } + + public boolean isSpectator(Player p){ + return p.hasMetadata("DeathSwap_Spec"); + } + + public boolean isSpectator(String s){ + return spectators.containsKey(s); + } + + @EventHandler + public void onPlayerLogin(PlayerJoinEvent e){ + for(String s : spectators.keySet()){ + Player p = plugin.getServer().getPlayerExact(s); + if (p != null){ + e.getPlayer().hidePlayer(p); + } + } + } + + @EventHandler + public void onPlayerDisconnect(PlayerQuitEvent e){ + removeSpectator(e.getPlayer()); + } + + @EventHandler + public void onAsyncPlayerChat(AsyncPlayerChatEvent e){ + if (!isSpectator(e.getPlayer())){ + return; + } + for(Iterator<Player> iter = e.getRecipients().iterator(); iter.hasNext(); ){ + if (!isSpectator(iter.next())){ + iter.remove(); + } + } + e.setFormat("[Spectating] " + e.getFormat()); + } + + @EventHandler + public void onBlockBreak(BlockBreakEvent e){ + if (isSpectator(e.getPlayer())){ + e.setCancelled(true); + } + } + + @EventHandler + public void onBlockPlace(BlockPlaceEvent e){ + if (isSpectator(e.getPlayer())){ + e.setCancelled(true); + e.getPlayer().getInventory().clear(); + } + } + + @EventHandler + public void onPlayerPickupItem(PlayerPickupItemEvent e){ + if (isSpectator(e.getPlayer())){ + e.setCancelled(true); + } + } + + @EventHandler + public void onPlayerDropItem(PlayerDropItemEvent e){ + if (isSpectator(e.getPlayer())){ + e.setCancelled(true); + e.getPlayer().getInventory().clear(); + } + } + + @EventHandler + public void onEntityDamage(EntityDamageEvent e){ + if (e.getEntity() instanceof Player && isSpectator((Player)e.getEntity())){ + e.setCancelled(true); + } + } + + @EventHandler + public void onEntityDamageByEntity(EntityDamageByEntityEvent e){ + if (e.getDamager() instanceof Player && isSpectator((Player)e.getDamager())){ + e.setCancelled(true); + } + } + + @EventHandler + public void onFoodLevelChange(FoodLevelChangeEvent e){ + if (isSpectator((Player)e.getEntity())){ + e.setFoodLevel(20); + } + } + + @EventHandler + public void onEntityTarget(EntityTargetEvent e){ + if (e.getTarget() instanceof Player && isSpectator((Player)e.getTarget())){ + e.setCancelled(true); + } + } + + @EventHandler + public void onPlayerInteract(PlayerInteractEvent e){ + if (isSpectator(e.getPlayer())){ + e.setCancelled(true); + int add = (e.getAction() == Action.LEFT_CLICK_AIR || e.getAction() == Action.LEFT_CLICK_BLOCK) ? 1 : (e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK) ? -1 : 0; + if (add == 0){ + return; + } + + List<Player> list = new ArrayList<Player>(); + for(String player : plugin.swapper.getPlayers()){ + Player p = plugin.getServer().getPlayerExact(player); + if (p != null){ + list.add(p); + } + } + int size = list.size(); + if (size == 0){ + return; + } + + Integer cur = spectators.get(e.getPlayer().getName()); + if (cur == null){ + cur = -1; + } + if (add == 1){ + cur = cur + 1 < size ? cur + 1 : 0; + } + else if (add == -1){ + cur = cur - 1 >= 0 ? cur - 1 : size - 1; + } + cur = Math.max(0, Math.min(size - 1, cur)); + spectators.put(e.getPlayer().getName(), cur); + + Player target = list.get(cur); + e.getPlayer().teleport(target); + e.getPlayer().sendMessage("You were teleported to " + Config.hl(target.getName()) + "!"); + } + } +} diff --git a/DeathSwap/src/cz/fo2/chylex/deathswap/Swapper.java b/DeathSwap/src/cz/fo2/chylex/deathswap/Swapper.java new file mode 100644 index 0000000..0a736fd --- /dev/null +++ b/DeathSwap/src/cz/fo2/chylex/deathswap/Swapper.java @@ -0,0 +1,234 @@ +package cz.fo2.chylex.deathswap; +import cz.fo2.chylex.util.BukkitUtil; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; + +public class Swapper{ + private DeathSwap plugin; + private Set<String> players; + private Map<String, Byte> disconnected; + private Random rand; + private int taskId = -1; + private int time; + private PotionEffect resistanceEffect; + public boolean spawnProtection; + + public Swapper(DeathSwap plugin){ + this.plugin = plugin; + players = new HashSet<String>(); + disconnected = new HashMap<String, Byte>(); + rand = new Random(); + spawnProtection = false; + } + + public Set<String> getPlayers(){ + return Collections.unmodifiableSet(players); + } + + public void start(){ + start(true); + } + + public void start(boolean resetPlayers){ + if (isPlaying()){ + return; + } + renewTimer(); + time += 8; // cooldown + resistanceEffect = new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 20 * plugin.config.resistance_duration, 5, true); + + spawnProtection = true; + plugin.getServer().getScheduler().runTaskLater(plugin, new Runnable(){ + @Override + public void run(){ + spawnProtection = false; + } + }, 120L); + + players.clear(); + disconnected.clear(); + List<ItemStack> startItems = new ArrayList<ItemStack>(); + for(String ar : plugin.config.spawn_items.split(",")){ + try{ + String[] data = ar.split(":"); + String[] star = data[0].split("\\*"); + int id = Integer.parseInt(star.length > 1 ? star[1] : star[0]); + int am = star.length > 1 ? Integer.parseInt(star[0]) : 1; + int dur = data.length > 1 ? Integer.parseInt(data[1]) : 0; + startItems.add(new ItemStack(id, am, (short)dur)); + }catch(NumberFormatException e){ + } + } + ItemStack[] startItemsArray = startItems.toArray(new ItemStack[startItems.size()]); + + PotionEffect startResistance = new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 200, 5, true); + for(Player p : plugin.getServer().getOnlinePlayers()){ + players.add(p.getName()); + if (resetPlayers){ + BukkitUtil.resetPlayer(p); + p.addPotionEffect(startResistance); + p.getInventory().addItem(startItemsArray); + } + } + + taskId = plugin.getServer().getScheduler().runTaskTimer(plugin, new Runnable(){ + @Override + public void run(){ + if (disconnected.size() > 0){ + for(String s : new HashSet<String>(disconnected.keySet())){ + byte b = (byte)(disconnected.get(s) + 1); + if (b >= 60){ + plugin.getServer().broadcastMessage(Config.hl(s) + " was disqualified"); + onPlayerDeath(s); + } + else{ + disconnected.put(s, b); + } + } + } + + if (--time <= 0){ + swap(); + renewTimer(); + } + } + }, 20L, 20L).getTaskId(); + } + + public boolean isPlaying(){ + return taskId != -1; + } + + public boolean canPlayerJoin(String player){ + return !isPlaying() || players.contains(player); + } + + public void onPlayerJoin(String player){ + if (!isPlaying()){ + return; + } + disconnected.remove(player); + } + + public void onPlayerDisconnect(String player){ + if (!isPlaying()){ + return; + } + disconnected.put(player, (byte)0); + } + + public void onPlayerDeath(String player){ + if (!isPlaying()){ + return; + } + players.remove(player); + updateGameState(); + } + + public void updateGameState(){ + int sz = players.size(); + if (sz == 0){ + plugin.getServer().broadcastMessage("Well, there are no players in the game, this shouldn't have happened... Awkward."); + end(); + } + else if (sz == 1){ + for(String s : plugin.spectating.getSpectators()){ + Player p = plugin.getServer().getPlayerExact(s); + if (p != null){ + plugin.spectating.removeSpectator(p); + } + } + String name = players.iterator().next(); + plugin.getServer().broadcastMessage(Config.hl(name) + " is the winner!"); + Location spawn = plugin.getServer().getWorlds().get(0).getSpawnLocation().clone(); + spawn.setY(spawn.getWorld().getHighestBlockYAt(spawn.getBlockX(), spawn.getBlockZ())); + for(Player p : plugin.getServer().getOnlinePlayers()){ + p.teleport(spawn); + if (p.getName().equals(name)){ + BukkitUtil.resetPlayer(p); + } + } + end(); + } + } + + public void end(){ + plugin.getServer().getScheduler().cancelTask(taskId); + players.clear(); + disconnected.clear(); + taskId = -1; + spawnProtection = false; + } + + private void swap(){ + List<Player> pls = new ArrayList<Player>(); + for(String s : players){ + Player p = plugin.getServer().getPlayerExact(s); + if (p != null){ + pls.add(p); + } + } + int size = pls.size(); + if (size < 2){ + return; + } + else if (size == 2){ + Player p1 = pls.get(0), p2 = pls.get(1); + Location l1 = p1.getLocation().clone(), l2 = p2.getLocation().clone(); + preTeleport(p1); + preTeleport(p2); + p1.teleport(l2); + p2.teleport(l1); + postTeleport(p1); + postTeleport(p2); + p1.sendMessage("You were swapped with " + Config.hl(p2.getName()) + "!"); + p2.sendMessage("You were swapped with " + Config.hl(p1.getName()) + "!"); + } + else{ + Collections.shuffle(pls, rand); + Player[] arrPlr = pls.toArray(new Player[size]); + Location[] arrLoc = new Location[size]; + for(int i = 0; i < size; i++){ + arrLoc[i] = arrPlr[i].getLocation().clone(); + } + for(int i = 0; i < size; i++){ + Player next = arrPlr[i + 1 == size ? 0 : i + 1], prev = arrPlr[i == 0 ? size - 1 : i - 1]; + arrPlr[i].sendMessage("You're now at " + Config.hl(next.getName()) + "'s location, and " + Config.hl(prev.getName()) + " is on yours!"); + preTeleport(arrPlr[i]); + arrPlr[i].teleport(arrLoc[i + 1 == size ? 0 : i + 1]); + postTeleport(arrPlr[i]); + } + } + for(String s : plugin.spectating.getSpectators()){ + Player p = plugin.getServer().getPlayerExact(s); + if (p != null){ + p.sendMessage("Players were swapped!"); + } + } + } + + private void preTeleport(Player p){ + if (p.isInsideVehicle()){ + p.leaveVehicle(); + } + } + + private void postTeleport(Player p){ + p.addPotionEffect(resistanceEffect); + } + + private void renewTimer(){ + time = rand.nextInt(Math.max(1, plugin.config.max_swap_time - plugin.config.min_swap_time)) + plugin.config.min_swap_time; + } +} diff --git a/DeathSwap/src/cz/fo2/chylex/util/BukkitUtil.java b/DeathSwap/src/cz/fo2/chylex/util/BukkitUtil.java new file mode 100644 index 0000000..0355d8f --- /dev/null +++ b/DeathSwap/src/cz/fo2/chylex/util/BukkitUtil.java @@ -0,0 +1,49 @@ +package cz.fo2.chylex.util; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.potion.PotionEffect; +import java.util.Arrays; + +public class BukkitUtil{ + public static ItemStack setNameAndLore(ItemStack is, String name, String... lore){ + ItemMeta meta = is.getItemMeta(); + if (name != null){ + meta.setDisplayName(ChatColor.RESET + name); + } + if (lore != null && lore.length > 0 && !lore[0].isEmpty()){ + meta.setLore(Arrays.asList(lore)); + } + is.setItemMeta(meta); + return is; + } + + public static void resetPlayer(Player p){ + p.setFallDistance(0f); + p.setFireTicks(0); + p.setFoodLevel(20); + p.setGameMode(GameMode.SURVIVAL); + p.setHealth(20); + for(PotionEffect eff : p.getActivePotionEffects()){ + p.removePotionEffect(eff.getType()); + } + PlayerInventory inv = p.getInventory(); + inv.clear(); + inv.setHelmet(null); + inv.setChestplate(null); + inv.setLeggings(null); + inv.setBoots(null); + } + + public static void getHighestBlockYAt(Location loc){ + loc.setY(128); + while(loc.getBlock().getTypeId() == 0){ + loc.setY(loc.getY() - 1); + } + loc.setY(loc.getY() + 2D); + } +} diff --git a/README.md b/README.md index e2f9edd..c42bf9f 100644 --- a/README.md +++ b/README.md @@ -1 +1,5 @@ My old Bukkit plugins that probably don't work anymore. They have been open-sourced so feel free to update and re-release them as long as you follow the license. + +| Plugin | Link | State | Changes | +| ------ | ---- | ----- | ------- | +| Ultra-Death Swap | [CurseForge](https://www.curseforge.com/minecraft/bukkit-plugins/ultra-deathswap) | Made for 1.15.2, needs API updates. | Reformatted & updated `plugin.yml`. |