1
0
mirror of https://github.com/chylex/Bukkit-Plugins.git synced 2025-04-07 00:15:49 +02:00

Add Ultra-DeathSwap

This commit is contained in:
chylex 2020-05-09 02:47:59 +02:00
parent b542475182
commit a5fd09295a
11 changed files with 766 additions and 0 deletions

7
DeathSwap/config.yml Normal file
View File

@ -0,0 +1,7 @@
game:
minSwapTime: 25
maxSwapTime: 90
resistanceDuration: 6
spawnDistance: 1000
allowDrops: true
startKit: ""

11
DeathSwap/plugin.yml Normal file
View File

@ -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

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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");
}
}
}

View File

@ -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);
}
}
}

View File

@ -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()) + "!");
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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-DeathSwap | [CurseForge](https://www.curseforge.com/minecraft/bukkit-plugins/ultra-deathswap) | Made for 1.15.2, needs API updates. | Reformatted & updated `plugin.yml`. |