Ready. Set. Go!
This commit is contained in:
commit
8e38aac816
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
target/
|
||||||
|
pom.xml.tag
|
||||||
|
pom.xml.releaseBackup
|
||||||
|
pom.xml.versionsBackup
|
||||||
|
pom.xml.next
|
||||||
|
release.properties
|
||||||
|
dependency-reduced-pom.xml
|
||||||
|
buildNumber.properties
|
||||||
|
.mvn/timing.properties
|
||||||
|
.mvn/wrapper/maven-wrapper.jar
|
||||||
|
.project
|
||||||
|
.classpath
|
9
LICENSE
Normal file
9
LICENSE
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
Copyright (c) 2023, apio
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
23
README.md
Normal file
23
README.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# death-swap
|
||||||
|
|
||||||
|
DeathSwap plugin for 1.19 Minecraft Java servers (Spigot/Paper)
|
||||||
|
|
||||||
|
## WARNING
|
||||||
|
|
||||||
|
This plugin is not configurable and makes several assumptions (as it was coded for a specific use case). These assumptions are:
|
||||||
|
|
||||||
|
- That the server the plugin is running on serves as a lobby for the game, and nothing else. This is because when starting a DeathSwap game all players on the server are automatically added to the game. This plugin is intended for multi-world networks (using BungeeCord for example) where one server would be the DeathSwap server and other servers would have other minigames/worlds/etc.
|
||||||
|
|
||||||
|
- That the default gamemode on said lobby is Adventure Mode. The plugin puts all players in Adventure Mode when returning them to the lobby.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Build the plugin with Maven or download a .jar from the Releases section, and copy it to your server's plugins/ folder. Then, to start a game (2+ players required) run the command `/dswap overworld` (or `/dswap nether` to play in the Nether). This can be automated further using clickable signs/NPCs.
|
||||||
|
|
||||||
|
Every 30 seconds - 2:30 minutes, a swap will occur. There is a small chance that a swap will be canceled (around 1/6). A timer is displayed above the hotbar showing how much time has passed since the last swap.
|
||||||
|
|
||||||
|
Whenever a player dies/leaves the game, they will be transported back to the lobby. When only one player is remaining, that player will win and the game will end.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Free and open-source software under the [BSD-2-Clause](LICENSE) license.
|
40
pom.xml
Normal file
40
pom.xml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>eu.cloudapio.deathswap</groupId>
|
||||||
|
<artifactId>deathswap</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<name>deathswap</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>spigot-repo</id>
|
||||||
|
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spigotmc</groupId>
|
||||||
|
<artifactId>spigot-api</artifactId>
|
||||||
|
<version>1.19.4-R0.1-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>${project.basedir}/src/main/resources</directory>
|
||||||
|
<includes>
|
||||||
|
<include>plugin.yml</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</build>
|
||||||
|
</project>
|
33
src/main/java/eu/cloudapio/deathswap/DeathSwap.java
Normal file
33
src/main/java/eu/cloudapio/deathswap/DeathSwap.java
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package eu.cloudapio.deathswap;
|
||||||
|
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
public class DeathSwap extends JavaPlugin {
|
||||||
|
public static DeathSwapGame game;
|
||||||
|
|
||||||
|
public static JavaPlugin plugin;
|
||||||
|
|
||||||
|
public static SwapNotifier notifier;
|
||||||
|
public static SwapRunner runner;
|
||||||
|
public static SwapTimeNotifier timeNotifier;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
plugin = (JavaPlugin)this;
|
||||||
|
|
||||||
|
game = new DeathSwapGame();
|
||||||
|
|
||||||
|
notifier = new SwapNotifier();
|
||||||
|
timeNotifier = new SwapTimeNotifier();
|
||||||
|
runner = new SwapRunner();
|
||||||
|
|
||||||
|
this.getCommand("dswap").setExecutor(new DeathSwapCommand());
|
||||||
|
|
||||||
|
getServer().getPluginManager().registerEvents(new EventListener(), (Plugin)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
}
|
||||||
|
}
|
30
src/main/java/eu/cloudapio/deathswap/DeathSwapCommand.java
Normal file
30
src/main/java/eu/cloudapio/deathswap/DeathSwapCommand.java
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package eu.cloudapio.deathswap;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.command.*;
|
||||||
|
import org.bukkit.entity.*;
|
||||||
|
|
||||||
|
public class DeathSwapCommand implements CommandExecutor {
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||||
|
if(args.length != 1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sender instanceof Player) {
|
||||||
|
Player player = (Player) sender;
|
||||||
|
|
||||||
|
int status = DeathSwap.game.start(args[0].equals("nether"));
|
||||||
|
if(status == -1)
|
||||||
|
{
|
||||||
|
player.sendMessage(ChatColor.RED + "Not enough players to start a game.");
|
||||||
|
} else if(status == -2)
|
||||||
|
{
|
||||||
|
player.sendMessage(ChatColor.RED + "A DeathSwap game is already in progress!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
314
src/main/java/eu/cloudapio/deathswap/DeathSwapGame.java
Normal file
314
src/main/java/eu/cloudapio/deathswap/DeathSwapGame.java
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
package eu.cloudapio.deathswap;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Difficulty;
|
||||||
|
import org.bukkit.GameMode;
|
||||||
|
import org.bukkit.GameRule;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.WorldCreator;
|
||||||
|
import org.bukkit.World.Environment;
|
||||||
|
import org.bukkit.advancement.Advancement;
|
||||||
|
import org.bukkit.advancement.AdvancementProgress;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
public class DeathSwapGame {
|
||||||
|
ArrayList<Player> players;
|
||||||
|
WorldCreator wc;
|
||||||
|
World world;
|
||||||
|
Random randomizer;
|
||||||
|
String worldName;
|
||||||
|
|
||||||
|
boolean isPlayingGame = false;
|
||||||
|
|
||||||
|
int minDeathSwapPlayers = 2;
|
||||||
|
int minSwapTime = 30;
|
||||||
|
int maxSwapTime = 150;
|
||||||
|
double swapCancelProbability = 0.15;
|
||||||
|
|
||||||
|
long lastSwapTime;
|
||||||
|
|
||||||
|
public DeathSwapGame()
|
||||||
|
{
|
||||||
|
randomizer = new Random(System.currentTimeMillis());
|
||||||
|
players = new ArrayList<Player>();
|
||||||
|
worldName = "death-swap";
|
||||||
|
wc = new WorldCreator(worldName);
|
||||||
|
|
||||||
|
getMainWorld().setPVP(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private World getMainWorld()
|
||||||
|
{
|
||||||
|
return Bukkit.getServer().getWorlds().get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isUnspawnableNetherLocation(World world, Location loc)
|
||||||
|
{
|
||||||
|
if(world.getBlockAt(loc).getType() == Material.AIR) return true;
|
||||||
|
if(world.getBlockAt(loc).getType() == Material.BEDROCK) return true;
|
||||||
|
|
||||||
|
if(world.getBlockAt(loc.add(0, 1, 0)).getType() != Material.AIR) return true;
|
||||||
|
if(world.getBlockAt(loc.add(0, 2, 0)).getType() != Material.AIR) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Selects a spawn location not in the air, not in water and not on top of bedrock (nether roof).
|
||||||
|
private Location randomSpawnLocation(World world, boolean isNether)
|
||||||
|
{
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
int x = randomizer.nextInt(-1000000, 1000000);
|
||||||
|
int z = randomizer.nextInt(-1000000, 1000000);
|
||||||
|
|
||||||
|
if(Math.abs(x) < 500) continue;
|
||||||
|
if(Math.abs(z) < 500) continue;
|
||||||
|
|
||||||
|
int y = 0;
|
||||||
|
|
||||||
|
if(isNether) {
|
||||||
|
y = 95;
|
||||||
|
while(isUnspawnableNetherLocation(world, new Location(world, x, y, z)))
|
||||||
|
{
|
||||||
|
y--;
|
||||||
|
if(y == 0) break;
|
||||||
|
}
|
||||||
|
if(y == 0) continue;
|
||||||
|
}
|
||||||
|
else y = world.getHighestBlockYAt(x, z);
|
||||||
|
|
||||||
|
if(world.getBlockAt(x, y, z).getType() == Material.WATER) continue;
|
||||||
|
if(world.getBlockAt(x, y, z).getType() == Material.LAVA) continue;
|
||||||
|
|
||||||
|
return new Location(world, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void revokeAdvancements(Player p)
|
||||||
|
{
|
||||||
|
Iterator<Advancement> iterator = Bukkit.getServer().advancementIterator();
|
||||||
|
while (iterator.hasNext())
|
||||||
|
{
|
||||||
|
AdvancementProgress progress = p.getAdvancementProgress(iterator.next());
|
||||||
|
for (String criteria : progress.getAwardedCriteria())
|
||||||
|
progress.revokeCriteria(criteria);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetPlayer(Player p)
|
||||||
|
{
|
||||||
|
p.getInventory().clear();
|
||||||
|
p.setHealth(20);
|
||||||
|
p.setFoodLevel(20);
|
||||||
|
p.setFireTicks(0);
|
||||||
|
p.setTotalExperience(0);
|
||||||
|
p.setFreezeTicks(0);
|
||||||
|
p.setFallDistance(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int start(boolean isNether)
|
||||||
|
{
|
||||||
|
if(Bukkit.getServer().getOnlinePlayers().size() < minDeathSwapPlayers)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isPlayingGame)
|
||||||
|
{
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
players = new ArrayList<Player>(Bukkit.getServer().getOnlinePlayers());
|
||||||
|
|
||||||
|
Bukkit.broadcastMessage(ChatColor.YELLOW + "Starting DeathSwap game...");
|
||||||
|
|
||||||
|
isPlayingGame = true;
|
||||||
|
|
||||||
|
Bukkit.getServer().unloadWorld(world, false);
|
||||||
|
|
||||||
|
deleteWorld(worldName);
|
||||||
|
|
||||||
|
wc.copy(Bukkit.getServer().getWorlds().get(0));
|
||||||
|
wc.seed(randomizer.nextLong());
|
||||||
|
if(isNether)
|
||||||
|
{
|
||||||
|
wc.environment(Environment.NETHER);
|
||||||
|
}
|
||||||
|
world = wc.createWorld();
|
||||||
|
world.setKeepSpawnInMemory(false);
|
||||||
|
world.setDifficulty(Difficulty.NORMAL);
|
||||||
|
world.setPVP(false);
|
||||||
|
world.setGameRule(GameRule.DO_IMMEDIATE_RESPAWN, true);
|
||||||
|
|
||||||
|
ArrayList<Location> spawnLocations = new ArrayList<Location>(players.size());
|
||||||
|
for(int i = 0; i < players.size(); i++)
|
||||||
|
{
|
||||||
|
spawnLocations.add(randomSpawnLocation(world, isNether));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < players.size(); i++)
|
||||||
|
{
|
||||||
|
Player p = players.get(i);
|
||||||
|
revokeAdvancements(p);
|
||||||
|
resetPlayer(p);
|
||||||
|
p.setGameMode(GameMode.SURVIVAL);
|
||||||
|
p.teleport(spawnLocations.get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
int swapTime = getSwapTime();
|
||||||
|
int tickTime = swapTime * 20;
|
||||||
|
Bukkit.getLogger().log(Level.INFO, String.format("Next swap in %d seconds", swapTime));
|
||||||
|
Bukkit.getServer().getScheduler().runTaskLater(DeathSwap.plugin, DeathSwap.notifier, tickTime - 60);
|
||||||
|
Bukkit.getServer().getScheduler().runTaskLater(DeathSwap.plugin, DeathSwap.runner, tickTime);
|
||||||
|
Bukkit.getServer().getScheduler().runTaskLater(DeathSwap.plugin, DeathSwap.timeNotifier, 20);
|
||||||
|
|
||||||
|
lastSwapTime = world.getFullTime();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void teleportToWorldSpawn(Player p)
|
||||||
|
{
|
||||||
|
Location worldSpawn = getMainWorld().getSpawnLocation();
|
||||||
|
|
||||||
|
p.setGameMode(GameMode.ADVENTURE);
|
||||||
|
resetPlayer(p);
|
||||||
|
p.teleport(worldSpawn);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasPlayer(Player player)
|
||||||
|
{
|
||||||
|
for(Player p : players)
|
||||||
|
{
|
||||||
|
if(p.getUniqueId().equals(player.getUniqueId()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkGameEnd()
|
||||||
|
{
|
||||||
|
if(players.size() < minDeathSwapPlayers)
|
||||||
|
{
|
||||||
|
if(players.size() == 0)
|
||||||
|
{
|
||||||
|
Bukkit.broadcastMessage(ChatColor.translateAlternateColorCodes('&', "&eNo one won &f(&cis this a bug?&f)"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Player winner = players.get(0);
|
||||||
|
Bukkit.broadcastMessage(ChatColor.translateAlternateColorCodes('&',
|
||||||
|
String.format("&3%s &6won the game!", winner.getName())));
|
||||||
|
}
|
||||||
|
|
||||||
|
Bukkit.getScheduler().cancelTasks(DeathSwap.plugin);
|
||||||
|
|
||||||
|
isPlayingGame = false;
|
||||||
|
|
||||||
|
for(Player p : players)
|
||||||
|
{
|
||||||
|
teleportToWorldSpawn(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void playerDied(Player player)
|
||||||
|
{
|
||||||
|
if(!isPlayingGame) return;
|
||||||
|
|
||||||
|
if(hasPlayer(player))
|
||||||
|
{
|
||||||
|
players.remove(player);
|
||||||
|
player.setGameMode(GameMode.ADVENTURE);
|
||||||
|
|
||||||
|
Bukkit.broadcastMessage(ChatColor.translateAlternateColorCodes('&',
|
||||||
|
String.format("&3%s &chas died. &9%d players &fremaining!", player.getName(), players.size())));
|
||||||
|
|
||||||
|
checkGameEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void playerLeft(Player player)
|
||||||
|
{
|
||||||
|
if(!isPlayingGame) return;
|
||||||
|
|
||||||
|
if(hasPlayer(player))
|
||||||
|
{
|
||||||
|
players.remove(player);
|
||||||
|
player.setGameMode(GameMode.ADVENTURE);
|
||||||
|
teleportToWorldSpawn(player);
|
||||||
|
|
||||||
|
Bukkit.broadcastMessage(ChatColor.translateAlternateColorCodes('&',
|
||||||
|
String.format("&3%s &cleft. &9%d players &fremaining!", player.getName(), players.size())));
|
||||||
|
|
||||||
|
checkGameEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteWorld(String worldName)
|
||||||
|
{
|
||||||
|
File container = Bukkit.getServer().getWorldContainer();
|
||||||
|
|
||||||
|
for(File f : container.listFiles())
|
||||||
|
{
|
||||||
|
if(f.getName().equals(worldName))
|
||||||
|
{
|
||||||
|
deleteFolder(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteFolder(File folder)
|
||||||
|
{
|
||||||
|
if(folder.isDirectory())
|
||||||
|
{
|
||||||
|
for(File f : folder.listFiles())
|
||||||
|
{
|
||||||
|
deleteFolder(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
folder.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void swap()
|
||||||
|
{
|
||||||
|
lastSwapTime = world.getFullTime();
|
||||||
|
|
||||||
|
if(randomizer.nextDouble() < swapCancelProbability) {
|
||||||
|
Bukkit.broadcastMessage(ChatColor.GOLD + "Swap cancelled!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<Location> locations = new ArrayList<Location>(players.size() + 1);
|
||||||
|
for(Player p : players)
|
||||||
|
{
|
||||||
|
locations.add(p.getLocation());
|
||||||
|
}
|
||||||
|
locations.add(locations.get(0));
|
||||||
|
|
||||||
|
for(int i = 0; i < players.size(); i++)
|
||||||
|
{
|
||||||
|
players.get(i).teleport(locations.get(i+1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSwapTime()
|
||||||
|
{
|
||||||
|
return randomizer.nextInt(minSwapTime, maxSwapTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTicksSinceLastSwap()
|
||||||
|
{
|
||||||
|
return world.getFullTime() - lastSwapTime;
|
||||||
|
}
|
||||||
|
}
|
22
src/main/java/eu/cloudapio/deathswap/EventListener.java
Normal file
22
src/main/java/eu/cloudapio/deathswap/EventListener.java
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package eu.cloudapio.deathswap;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
|
||||||
|
public class EventListener implements Listener {
|
||||||
|
@EventHandler public void onPlayerDeath(PlayerDeathEvent event)
|
||||||
|
{
|
||||||
|
if(event.getEntity() instanceof Player)
|
||||||
|
{
|
||||||
|
DeathSwap.game.playerDied((Player)event.getEntity());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler public void onPlayerLeave(PlayerQuitEvent event)
|
||||||
|
{
|
||||||
|
DeathSwap.game.playerLeft((Player)event.getPlayer());
|
||||||
|
}
|
||||||
|
}
|
15
src/main/java/eu/cloudapio/deathswap/SwapNotifier.java
Normal file
15
src/main/java/eu/cloudapio/deathswap/SwapNotifier.java
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package eu.cloudapio.deathswap;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
|
||||||
|
public class SwapNotifier implements Runnable {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if(DeathSwap.game.isPlayingGame){
|
||||||
|
Bukkit.broadcastMessage(ChatColor.GOLD + "Swapping in 3 seconds.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
21
src/main/java/eu/cloudapio/deathswap/SwapRunner.java
Normal file
21
src/main/java/eu/cloudapio/deathswap/SwapRunner.java
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package eu.cloudapio.deathswap;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
|
public class SwapRunner implements Runnable {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if(DeathSwap.game.isPlayingGame){
|
||||||
|
DeathSwap.game.swap();
|
||||||
|
|
||||||
|
int swapTime = DeathSwap.game.getSwapTime();
|
||||||
|
int tickTime = swapTime * 20;
|
||||||
|
Bukkit.getLogger().log(Level.INFO, String.format("Next swap in %d seconds", swapTime));
|
||||||
|
Bukkit.getServer().getScheduler().runTaskLater(DeathSwap.plugin, DeathSwap.notifier, tickTime - 60);
|
||||||
|
Bukkit.getServer().getScheduler().runTaskLater(DeathSwap.plugin, DeathSwap.runner, tickTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
31
src/main/java/eu/cloudapio/deathswap/SwapTimeNotifier.java
Normal file
31
src/main/java/eu/cloudapio/deathswap/SwapTimeNotifier.java
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package eu.cloudapio.deathswap;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import net.md_5.bungee.api.ChatMessageType;
|
||||||
|
import net.md_5.bungee.api.chat.TextComponent;
|
||||||
|
|
||||||
|
public class SwapTimeNotifier implements Runnable {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
if(DeathSwap.game.isPlayingGame) {
|
||||||
|
long secondsSinceLastSwap = DeathSwap.game.getTicksSinceLastSwap() / 20;
|
||||||
|
boolean safe = secondsSinceLastSwap < DeathSwap.game.minSwapTime;
|
||||||
|
|
||||||
|
TextComponent tc = new TextComponent(String.format("[%s] Time since last swap: %d s", safe ? "safe" : "unsafe", secondsSinceLastSwap));
|
||||||
|
tc.setColor(safe ? ChatColor.GREEN : ChatColor.RED);
|
||||||
|
|
||||||
|
for(Player p : DeathSwap.game.players)
|
||||||
|
{
|
||||||
|
p.spigot().sendMessage(ChatMessageType.ACTION_BAR, tc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bukkit.getServer().getScheduler().runTaskLater(DeathSwap.plugin, DeathSwap.timeNotifier, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
9
src/main/resources/plugin.yml
Normal file
9
src/main/resources/plugin.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
main: eu.cloudapio.deathswap.DeathSwap
|
||||||
|
name: death-swap
|
||||||
|
version: 0.1
|
||||||
|
api-version: 1.19
|
||||||
|
commands:
|
||||||
|
dswap:
|
||||||
|
description: Death Swap
|
||||||
|
usage: /<command> [overworld|nether]
|
||||||
|
permission: deathswap.dswap
|
Loading…
Reference in New Issue
Block a user