commit
627b793257
13 changed files with 974 additions and 0 deletions
@ -0,0 +1,113 @@ |
||||
# User-specific stuff |
||||
.idea/ |
||||
|
||||
*.iml |
||||
*.ipr |
||||
*.iws |
||||
|
||||
# IntelliJ |
||||
out/ |
||||
|
||||
# Compiled class file |
||||
*.class |
||||
|
||||
# Log file |
||||
*.log |
||||
|
||||
# BlueJ files |
||||
*.ctxt |
||||
|
||||
# Package Files # |
||||
*.jar |
||||
*.war |
||||
*.nar |
||||
*.ear |
||||
*.zip |
||||
*.tar.gz |
||||
*.rar |
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml |
||||
hs_err_pid* |
||||
|
||||
*~ |
||||
|
||||
# temporary files which can be created if a process still has a handle open of a deleted file |
||||
.fuse_hidden* |
||||
|
||||
# KDE directory preferences |
||||
.directory |
||||
|
||||
# Linux trash folder which might appear on any partition or disk |
||||
.Trash-* |
||||
|
||||
# .nfs files are created when an open file is removed but is still being accessed |
||||
.nfs* |
||||
|
||||
# General |
||||
.DS_Store |
||||
.AppleDouble |
||||
.LSOverride |
||||
|
||||
# Icon must end with two \r |
||||
Icon |
||||
|
||||
# Thumbnails |
||||
._* |
||||
|
||||
# Files that might appear in the root of a volume |
||||
.DocumentRevisions-V100 |
||||
.fseventsd |
||||
.Spotlight-V100 |
||||
.TemporaryItems |
||||
.Trashes |
||||
.VolumeIcon.icns |
||||
.com.apple.timemachine.donotpresent |
||||
|
||||
# Directories potentially created on remote AFP share |
||||
.AppleDB |
||||
.AppleDesktop |
||||
Network Trash Folder |
||||
Temporary Items |
||||
.apdisk |
||||
|
||||
# Windows thumbnail cache files |
||||
Thumbs.db |
||||
Thumbs.db:encryptable |
||||
ehthumbs.db |
||||
ehthumbs_vista.db |
||||
|
||||
# Dump file |
||||
*.stackdump |
||||
|
||||
# Folder config file |
||||
[Dd]esktop.ini |
||||
|
||||
# Recycle Bin used on file shares |
||||
$RECYCLE.BIN/ |
||||
|
||||
# Windows Installer files |
||||
*.cab |
||||
*.msi |
||||
*.msix |
||||
*.msm |
||||
*.msp |
||||
|
||||
# Windows shortcuts |
||||
*.lnk |
||||
|
||||
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 |
||||
.flattened-pom.xml |
||||
|
||||
# Common working directory |
||||
run/ |
@ -0,0 +1 @@ |
||||
xcopy IntelliJ_IDEA\Sharehealth\target\Sharehealth.jar Minecraft_Servers\Server_1.16.4\plugins\ /Y |
@ -0,0 +1 @@ |
||||
cp IntelliJ_IDEA/Sharehealth_1.16.4/target/sharehealth-1.0-SNAPSHOT.jar Minecraft_Servers/Server_1.16.4/plugins/ |
@ -0,0 +1,13 @@ |
||||
name: Sharehealth |
||||
version: 1.0 |
||||
main: com.benjocraeft.sharehealth.Sharehealth |
||||
api-version: 1.16 |
||||
authors: [ BenjoCraeft ] |
||||
description: This plugin makes all players on the server share their health, if one dies, everybody dies. |
||||
website: https://mc.benjocraeft.com |
||||
|
||||
commands: |
||||
sharehealth: |
||||
usage: /<command> |
||||
aliases: [sh] |
||||
description: Defined by ShareHealth plugin |
@ -0,0 +1,133 @@ |
||||
package com.benjocraeft.sharehealth; |
||||
|
||||
import org.bukkit.command.CommandExecutor; |
||||
import org.apache.commons.lang.math.NumberUtils; |
||||
import org.bukkit.Bukkit; |
||||
import org.bukkit.ChatColor; |
||||
import org.bukkit.command.Command; |
||||
import org.bukkit.command.CommandSender; |
||||
import org.bukkit.entity.Player; |
||||
|
||||
public class Commands implements CommandExecutor { |
||||
|
||||
@Override |
||||
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args){ |
||||
|
||||
if (args.length != 0){ |
||||
if (args[0].equalsIgnoreCase("reset")){ |
||||
commandSetHealth(20, true); |
||||
} |
||||
else if (args[0].equalsIgnoreCase("set")){ |
||||
if (args.length > 1){ |
||||
if (NumberUtils.isNumber(args[1])){ |
||||
double num = NumberUtils.createDouble(args[1]); |
||||
commandSetHealth(num); |
||||
} else if (args[1].equalsIgnoreCase("max")){ |
||||
if (args.length > 2){ |
||||
if (NumberUtils.isNumber(args[2])){ |
||||
double num = NumberUtils.createDouble(args[2]); |
||||
commandSetMaxHealth(num); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
else if (args[0].equalsIgnoreCase("get")){ |
||||
if (args.length > 1){ |
||||
if (args[1].equalsIgnoreCase("max")){ |
||||
if (args.length > 2){ |
||||
if (args[2].equalsIgnoreCase("raw")){ |
||||
commandGetMaxHealth(sender, true); |
||||
} |
||||
} else { |
||||
commandGetMaxHealth(sender, false); |
||||
} |
||||
} |
||||
} else { |
||||
commandGetHealth(sender); |
||||
} |
||||
|
||||
} |
||||
else if (args[0].equalsIgnoreCase("log")){ |
||||
if (args.length > 1){ |
||||
if (args[1].equalsIgnoreCase("off")){ |
||||
commandSetLogging(false); |
||||
} |
||||
if (args[1].equalsIgnoreCase("on")){ |
||||
commandSetLogging(true); |
||||
} |
||||
} |
||||
} |
||||
else if(args[0].equalsIgnoreCase("stats")){ |
||||
commandSendStats(); |
||||
} |
||||
else if (args[0].equalsIgnoreCase("help")){ |
||||
commandGetHelp(sender); |
||||
} else { |
||||
unknownCommand(sender); |
||||
} |
||||
} else { |
||||
commandGetHelp(sender); |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
private void commandSetMaxHealth(double health){ |
||||
|
||||
} |
||||
|
||||
private void commandSetHealth(double health, boolean reset){ |
||||
Sharehealth.Instance.getHealthManager().setHealth(health); |
||||
if (reset){ |
||||
Sharehealth.Instance.reset(); |
||||
} |
||||
} |
||||
|
||||
private void commandSetHealth(double health){ |
||||
commandSetHealth(health, false); |
||||
} |
||||
|
||||
private void commandGetHealth(CommandSender sender){ |
||||
sender.sendMessage("Current health: " + Sharehealth.Instance.getHealthManager().getHealthString()); |
||||
} |
||||
|
||||
private void commandGetMaxHealth(CommandSender sender, boolean raw){ |
||||
|
||||
} |
||||
|
||||
private void commandSetLogging(boolean log){ |
||||
Sharehealth.Instance.getMessenger().setLogging(log); |
||||
} |
||||
|
||||
private void commandSendStats(){ |
||||
StringBuilder stats = new StringBuilder("Statistics:\n"); |
||||
Sharehealth.Instance.getStatistics().getStatistics().forEach(((uuid, values) -> { |
||||
Player player = Bukkit.getPlayer(uuid); |
||||
if (player != null){ |
||||
String playerName = player.getDisplayName(); |
||||
String stat = ChatColor.AQUA + playerName + ChatColor.WHITE + |
||||
": Damage caused: " + ChatColor.RED + String.format("%.2f", values.first) + ChatColor.WHITE + |
||||
" Healing done: " + ChatColor.GREEN + String.format("%.2f", values.second) + "\n"; |
||||
stats.append(stat); |
||||
} |
||||
})); |
||||
Bukkit.getOnlinePlayers().forEach((Player p) -> p.sendMessage(stats.toString())); |
||||
} |
||||
|
||||
private void commandGetHelp(CommandSender sender){ |
||||
String help = "Usage:\n" + |
||||
"get -> returns current globally shared health\n" + |
||||
"set [number] -> sets new globally shared health\n" + |
||||
"reset -> heals every player and resets 'isFailed' to false\n" + |
||||
"log [on/off] -> activates/deactivates player log messages about damage and healings" + |
||||
"stats -> sends everyone statistics for every player"; |
||||
sender.sendMessage(help); |
||||
} |
||||
|
||||
private void unknownCommand(CommandSender sender){ |
||||
String msg = "Unknown command, use help."; |
||||
sender.sendMessage(msg); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,137 @@ |
||||
package com.benjocraeft.sharehealth; |
||||
|
||||
import java.io.*; |
||||
import java.util.*; |
||||
|
||||
public class FileManager { |
||||
|
||||
final private File settingsFile; |
||||
final private File statisticsFile; |
||||
final private File statusFile; |
||||
|
||||
|
||||
public FileManager(){ |
||||
File pluginFolder = new File(System.getProperty("user.dir"), "plugins/sharehealth"); |
||||
String pluginPath = pluginFolder.getPath(); |
||||
|
||||
//Prepare storage folder
|
||||
if (pluginFolder.mkdirs()){ |
||||
//TODO Log
|
||||
} |
||||
|
||||
settingsFile = new File(pluginPath + "/settings.txt"); |
||||
statisticsFile = new File(pluginPath + "/statistics.txt"); |
||||
statusFile = new File(pluginPath + "/status.txt"); |
||||
try { |
||||
if (settingsFile.createNewFile()){ |
||||
//TODO Log
|
||||
} |
||||
if (statisticsFile.createNewFile()){ |
||||
//TODO Log
|
||||
} |
||||
if (statusFile.createNewFile()){ |
||||
//TODO Log
|
||||
} |
||||
} catch(IOException e){ |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
|
||||
public Map<String, String> loadSettings(){ |
||||
return loadFromFile(settingsFile); |
||||
} |
||||
public Map<UUID, Pair<Double, Double>> loadStatistics(){ |
||||
Map<String, String> map = loadFromFile(statisticsFile); |
||||
|
||||
Map<UUID, Pair<Double, Double>> statisticsMap = new HashMap<>(); |
||||
map.forEach((String s1, String s2) -> { |
||||
UUID uuid = UUID.fromString(s1); |
||||
|
||||
String[] split = s2.split(","); |
||||
Double damage = Double.parseDouble(split[0]); |
||||
Double healing = Double.parseDouble(split[1]); |
||||
Pair<Double, Double> statistics = Pair.pair(damage, healing); |
||||
|
||||
statisticsMap.put(uuid, statistics); |
||||
}); |
||||
|
||||
return statisticsMap; |
||||
} |
||||
public Map<String, Object> loadStatus(){ |
||||
Map<String, String> map = loadFromFile(statusFile); |
||||
Map<String, Object> statusMap = new HashMap<>(); |
||||
|
||||
map.putIfAbsent("health", "20"); |
||||
map.putIfAbsent("isFailed", "false"); |
||||
|
||||
statusMap.put("health", Double.parseDouble(map.get("health"))); |
||||
statusMap.put("isFailed", Boolean.parseBoolean(map.get("isFailed"))); |
||||
|
||||
return statusMap; |
||||
} |
||||
|
||||
public void saveStatistics(Map<UUID, Pair<Double, Double>> statistics){ |
||||
Map<String, Object> map = new HashMap<>(); |
||||
|
||||
statistics.forEach((UUID uuid, Pair<Double, Double> pair) -> { |
||||
String uuidString = uuid.toString(); |
||||
map.put(uuidString, Statistics.Rounded(pair.first) + "," + Statistics.Rounded(pair.second)); |
||||
}); |
||||
|
||||
saveToFile(statisticsFile, map); |
||||
} |
||||
|
||||
public void saveStatus(Map<String, Object> statusMap){ |
||||
saveToFile(statusFile, statusMap); |
||||
} |
||||
|
||||
private Map<String, String> loadFromFile(File file) { |
||||
Map<String, String> map = new HashMap<>(); |
||||
|
||||
try{ |
||||
DataInputStream input = new DataInputStream(new FileInputStream(file)); |
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(input)); |
||||
|
||||
try{ |
||||
String line; |
||||
while((line = reader.readLine()) != null){ |
||||
String[] split = line.split("="); |
||||
map.put(split[0], split[1]); |
||||
} |
||||
} catch (NullPointerException ignore){} |
||||
|
||||
reader.close(); |
||||
input.close(); |
||||
} catch(IOException e){ |
||||
e.printStackTrace(); |
||||
} |
||||
|
||||
return map; |
||||
} |
||||
|
||||
private void saveToFile(File file, Map<String, Object> content){ |
||||
try{ |
||||
FileWriter stream = new FileWriter(file); |
||||
BufferedWriter out = new BufferedWriter(stream); |
||||
|
||||
content.forEach((String key, Object obj) -> { |
||||
try { |
||||
String value = obj.toString(); |
||||
if (obj instanceof Double){ |
||||
value = new Formatter(Locale.US).format("%.2f", obj).toString(); |
||||
} |
||||
out.write(key + "=" + value); |
||||
out.write("\n"); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
}); |
||||
|
||||
out.close(); |
||||
stream.close(); |
||||
} catch (IOException e){ |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,74 @@ |
||||
package com.benjocraeft.sharehealth; |
||||
|
||||
import org.bukkit.Bukkit; |
||||
import org.bukkit.GameMode; |
||||
import org.bukkit.entity.Player; |
||||
|
||||
import java.util.Formatter; |
||||
import java.util.Locale; |
||||
|
||||
public class HealthManager { |
||||
|
||||
private double health = 20; |
||||
|
||||
double getHealth(){ |
||||
return health; |
||||
} |
||||
|
||||
void setHealth(double health){ |
||||
if (health > 20) |
||||
health = 20; |
||||
if (health < 0) |
||||
health = 0; |
||||
this.health = health; |
||||
} |
||||
|
||||
String getHealthString(){ |
||||
return new Formatter(Locale.US).format("%.2f", health).toString(); |
||||
} |
||||
|
||||
|
||||
public HealthManager() { |
||||
|
||||
} |
||||
public void updatePlayer(Player player){ |
||||
if (player.getGameMode().equals(GameMode.SURVIVAL)) |
||||
player.setHealth(health); |
||||
if (player.getGameMode().equals(GameMode.SPECTATOR)) |
||||
player.setHealth(20); |
||||
} |
||||
|
||||
private void subtractHealth(double sub){ |
||||
setHealth(health - sub); |
||||
} |
||||
|
||||
void addHealth(double add){ |
||||
setHealth(health + add); |
||||
} |
||||
|
||||
void reset(){ |
||||
health = 20; |
||||
Bukkit.getOnlinePlayers().forEach(p -> p.setHealth(health)); |
||||
} |
||||
|
||||
boolean onPlayerGotDamage(Player player, double damage){ |
||||
subtractHealth(damage); |
||||
setHealthByPlayer(player); |
||||
|
||||
return health > 0; |
||||
} |
||||
|
||||
void onPlayerRegainedHealth(Player player, double regainedHealth){ |
||||
addHealth(regainedHealth); |
||||
setHealthByPlayer(player); |
||||
} |
||||
|
||||
void setHealthByPlayer(Player player){ |
||||
for (Player p : Sharehealth.GetAlivePlayers()){ |
||||
if (p.equals(player)) |
||||
continue; |
||||
p.setHealth(health); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,40 @@ |
||||
package com.benjocraeft.sharehealth; |
||||
|
||||
import org.bukkit.attribute.Attribute; |
||||
import org.bukkit.entity.Player; |
||||
import org.bukkit.scheduler.BukkitRunnable; |
||||
|
||||
import java.util.Objects; |
||||
|
||||
public class HealthRegenTask extends BukkitRunnable { |
||||
|
||||
final private HealthManager healthManager; |
||||
|
||||
|
||||
HealthRegenTask(HealthManager healthManager){ |
||||
this.healthManager = healthManager; |
||||
runTaskTimer(Sharehealth.Instance, 80, 80); |
||||
} |
||||
|
||||
@Override |
||||
public void run(){ |
||||
int allPlayersCount = Sharehealth.GetAlivePlayers().size(); |
||||
if (allPlayersCount == 0) |
||||
return; |
||||
|
||||
int allFoodPoints = 0; |
||||
for (Player p : Sharehealth.GetAlivePlayers()){ |
||||
allFoodPoints += p.getFoodLevel(); |
||||
} |
||||
|
||||
//According to MinecraftWiki, players automatically regen if their food level
|
||||
// is greater than or equal to 18 of 20 (90%)
|
||||
//Here, we look for the average food level
|
||||
if (allFoodPoints / allPlayersCount >= 18 && this.healthManager.getHealth() != 0){ |
||||
this.healthManager.addHealth(1); |
||||
this.healthManager.setHealthByPlayer(null); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,110 @@ |
||||
package com.benjocraeft.sharehealth; |
||||
|
||||
import org.bukkit.Bukkit; |
||||
import org.bukkit.ChatColor; |
||||
import org.bukkit.GameMode; |
||||
import org.bukkit.block.Block; |
||||
import org.bukkit.entity.Entity; |
||||
import org.bukkit.entity.Player; |
||||
import org.bukkit.entity.Projectile; |
||||
import org.bukkit.event.entity.EntityDamageEvent; |
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause; |
||||
import org.bukkit.event.entity.EntityRegainHealthEvent; |
||||
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; |
||||
|
||||
import java.util.Objects; |
||||
import java.util.logging.Logger; |
||||
|
||||
public class Messenger { |
||||
|
||||
private boolean logging = true; |
||||
void setLogging(boolean logging){ |
||||
this.logging = logging; |
||||
} |
||||
|
||||
private Logger logger; |
||||
|
||||
Messenger(Logger logger){ |
||||
this.logger = logger; |
||||
} |
||||
|
||||
void onPlayerRegainedHealth(Player player, double amount, RegainReason reason){ |
||||
if (!logging || amount <= 0) |
||||
return; |
||||
String message = healMessage(player, amount, reason); |
||||
Bukkit.getOnlinePlayers().forEach(p -> p.sendMessage(message)); |
||||
} |
||||
|
||||
void sendFailedMessage(Player cause){ |
||||
Bukkit.getOnlinePlayers().forEach(p -> { |
||||
String message = "Mission failed, go next! CAUSE: " + ChatColor.RED + cause.getDisplayName(); |
||||
p.sendMessage(message); |
||||
}); |
||||
} |
||||
|
||||
void onPlayerGotDamageMessage(Player player, double damage, DamageCause cause){ |
||||
if (!logging) |
||||
return; |
||||
String message = damageMessage(player, damage, cause); |
||||
Bukkit.getOnlinePlayers().forEach(p -> p.sendMessage(message)); |
||||
} |
||||
|
||||
void onPlayerGotDamageMessage(Player player, double damage, Entity damager){ |
||||
if (!logging) |
||||
return; |
||||
String message = damageMessage(player, damage, damager); |
||||
Bukkit.getOnlinePlayers().forEach(p -> p.sendMessage(message)); |
||||
} |
||||
|
||||
void onPlayerGotDamageMessage(Player player, double damage, Block damager){ |
||||
if (!logging) |
||||
return; |
||||
String message = damageMessage(player, damage, damager); |
||||
Bukkit.getOnlinePlayers().forEach(p -> p.sendMessage(message)); |
||||
} |
||||
|
||||
private String damageMessage(Player player, double damage){ |
||||
String playerS = player.getDisplayName(); |
||||
String damageS = String.format("%.2f", damage / 2); |
||||
return ChatColor.AQUA + playerS |
||||
+ ChatColor.WHITE + " shared " |
||||
+ ChatColor.RED + damageS |
||||
+ ChatColor.WHITE + " hearts damage!"; |
||||
} |
||||
|
||||
private String damageMessage(Player player, double damage, DamageCause cause){ |
||||
return damageMessage(player, damage) + ChatColor.YELLOW + " Cause: " + cause; |
||||
} |
||||
|
||||
private String damageMessage(Player player, double damage, Entity damager){ |
||||
String name = damager.getName(); |
||||
if (damager instanceof Projectile){ |
||||
name = Objects.requireNonNull(((Projectile) damager).getShooter()).toString(); |
||||
} |
||||
return damageMessage(player, damage) + ChatColor.YELLOW + " Attacker: " + name; |
||||
} |
||||
|
||||
private String damageMessage(Player player, double damage, Block damager){ |
||||
String name; |
||||
try{ |
||||
name = damager.getType().name(); |
||||
} catch(NullPointerException e){ |
||||
name = "Unknown"; |
||||
e.printStackTrace(); |
||||
logger.info("Unknown error. Proceeding"); |
||||
} |
||||
return damageMessage(player, damage) + ChatColor.YELLOW + " Block: " + name; |
||||
} |
||||
|
||||
private String healMessage(Player player, double regainedHealth, RegainReason reason){ |
||||
String playerS = player.getDisplayName(); |
||||
String healingS = Double.toString(regainedHealth / 2); |
||||
String causeS = reason.toString(); |
||||
return ChatColor.AQUA + playerS |
||||
+ ChatColor.WHITE + " shared " |
||||
+ ChatColor.GREEN + healingS |
||||
+ ChatColor.WHITE + " hearts healing!" |
||||
+ ChatColor.YELLOW + " Cause: " + causeS; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,18 @@ |
||||
package com.benjocraeft.sharehealth; |
||||
|
||||
|
||||
public class Pair<F, S> { |
||||
|
||||
|
||||
public F first; |
||||
public S second; |
||||
|
||||
public Pair(F first, S second){ |
||||
this.first = first; |
||||
this.second = second; |
||||
} |
||||
|
||||
public static <F, S> Pair<F, S> pair(F first, S second){ |
||||
return new Pair<>(first, second); |
||||
} |
||||
} |
@ -0,0 +1,104 @@ |
||||
package com.benjocraeft.sharehealth; |
||||
|
||||
import org.bukkit.block.Block; |
||||
import org.bukkit.entity.Entity; |
||||
import org.bukkit.entity.Player; |
||||
import org.bukkit.event.EventHandler; |
||||
import org.bukkit.event.Listener; |
||||
import org.bukkit.event.entity.*; |
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause; |
||||
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; |
||||
import org.bukkit.event.player.PlayerJoinEvent; |
||||
import org.bukkit.event.player.PlayerRespawnEvent; |
||||
import org.bukkit.potion.PotionEffect; |
||||
import org.bukkit.potion.PotionEffectType; |
||||
|
||||
|
||||
public class PlayerListeners implements Listener{ |
||||
|
||||
@EventHandler |
||||
public void onJoin(PlayerJoinEvent e){ |
||||
Sharehealth.Instance.onPlayerJoin(e.getPlayer()); |
||||
} |
||||
|
||||
@EventHandler |
||||
public void onPlayerRespawn(final PlayerRespawnEvent event){ |
||||
Sharehealth.Instance.onPlayerRespawn(event.getPlayer()); |
||||
} |
||||
|
||||
@EventHandler |
||||
public void onEntityGotDamage(final EntityDamageEvent event){ |
||||
Entity entity = event.getEntity(); |
||||
double damage = event.getFinalDamage(); |
||||
DamageCause cause = event.getCause(); |
||||
|
||||
DamageCause[] notAllowed = new DamageCause[]{ |
||||
DamageCause.ENTITY_ATTACK, |
||||
DamageCause.ENTITY_EXPLOSION, |
||||
DamageCause.PROJECTILE, |
||||
DamageCause.CONTACT |
||||
}; |
||||
|
||||
if (entity instanceof Player){ |
||||
boolean allowed = true; |
||||
for (DamageCause damageCause : notAllowed) { |
||||
if (cause.equals(damageCause)){ |
||||
allowed = false; |
||||
break; |
||||
} |
||||
} |
||||
Sharehealth.Instance.onPlayerGotDamage((Player) entity, damage, cause, allowed); |
||||
} |
||||
} |
||||
|
||||
@EventHandler |
||||
public void onEntityGotDamageByEntity(final EntityDamageByEntityEvent event){ |
||||
Entity entity = event.getEntity(); |
||||
double damage = event.getFinalDamage(); |
||||
Entity cause = event.getDamager(); |
||||
|
||||
if (entity instanceof Player) { |
||||
Sharehealth.Instance.onPlayerGotDamageByEntity((Player)entity, damage, cause); |
||||
} |
||||
} |
||||
|
||||
@EventHandler |
||||
public void onEntityGotDamageByBlock(final EntityDamageByBlockEvent event){ |
||||
Entity entity = event.getEntity(); |
||||
double damage = event.getFinalDamage(); |
||||
Block cause = event.getDamager(); |
||||
|
||||
if (entity instanceof Player) { |
||||
Sharehealth.Instance.onPlayerGotDamageByBlock((Player)entity, damage, cause); |
||||
} |
||||
} |
||||
|
||||
@EventHandler |
||||
public void onEntityRegainedHealth(final EntityRegainHealthEvent event){ |
||||
Entity entity = event.getEntity(); |
||||
double amount = event.getAmount(); |
||||
RegainReason reason = event.getRegainReason(); |
||||
|
||||
if (entity instanceof Player){ |
||||
Player player = (Player) entity; |
||||
if (!Sharehealth.Instance.onPlayerRegainedHealth(player, amount, reason)){ |
||||
event.setCancelled(true); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@EventHandler |
||||
public void onEntityPotionEffectModified(final EntityPotionEffectEvent event){ |
||||
Entity entity = event.getEntity(); |
||||
if (entity instanceof Player){ |
||||
PotionEffect newEffect = event.getNewEffect(); |
||||
if (newEffect != null){ |
||||
if (newEffect.getType().equals(PotionEffectType.ABSORPTION)){ |
||||
event.setCancelled(true); |
||||
int level = newEffect.getAmplifier(); |
||||
Sharehealth.Instance.onAbsorptionPrevented(level); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,184 @@ |
||||
package com.benjocraeft.sharehealth; |
||||
|
||||
import org.bukkit.*; |
||||
import org.bukkit.block.Block; |
||||
import org.bukkit.entity.*; |
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause; |
||||
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; |
||||
import org.bukkit.plugin.java.JavaPlugin; |
||||
|
||||
import java.util.*; |
||||
|
||||
public class Sharehealth extends JavaPlugin { |
||||
|
||||
static Sharehealth Instance; |
||||
|
||||
private FileManager fileManager; |
||||
public FileManager getFileManager(){ |
||||
return fileManager; |
||||
} |
||||
|
||||
private HealthManager healthManager; |
||||
public HealthManager getHealthManager(){ |
||||
return healthManager; |
||||
} |
||||
|
||||
private Messenger messenger; |
||||
public Messenger getMessenger(){ |
||||
return messenger; |
||||
} |
||||
|
||||
private Statistics statistics; |
||||
public Statistics getStatistics(){ |
||||
return statistics; |
||||
} |
||||
|
||||
boolean isFailed = false; |
||||
|
||||
@Override |
||||
public void onEnable(){ |
||||
|
||||
//Singleton setup
|
||||
Instance = this; |
||||
|
||||
//Create File Manager for saving stats and settings
|
||||
fileManager = new FileManager(); |
||||
|
||||
//Starting Health Manager for controlling actual health
|
||||
healthManager = new HealthManager(); |
||||
|
||||
//Messenger
|
||||
messenger = new Messenger(getLogger()); |
||||
|
||||
//Create statistics from file
|
||||
statistics = new Statistics(fileManager.loadStatistics()); |
||||
|
||||
loadStatus(); |
||||
|
||||
//Starts custom health regeneration
|
||||
new HealthRegenTask(healthManager); |
||||
|
||||
//Register Events and Commands
|
||||
Bukkit.getPluginManager().registerEvents(new PlayerListeners(), this); |
||||
Objects.requireNonNull(getCommand("sharehealth")).setExecutor(new Commands()); |
||||
|
||||
//Ready to go
|
||||
getLogger().info("ShareHealth has been enabled!"); |
||||
} |
||||
|
||||
@Override |
||||
public void onDisable() { |
||||
getLogger().info("ShareHealth has been disabled!"); |
||||
} |
||||
|
||||
void onPlayerJoin(Player player){ |
||||
updateGameMode(player); |
||||
|
||||
healthManager.updatePlayer(player); |
||||
statistics.onPlayerJoined(player); |
||||
fileManager.saveStatistics(statistics.getStatistics()); |
||||
} |
||||
|
||||
void onPlayerRespawn(Player player){ |
||||
updateGameMode(player); |
||||
|
||||
healthManager.updatePlayer(player); |
||||
} |
||||
|
||||
void onPlayerGotDamage(Player player, double damage, DamageCause cause, boolean allowed){ |
||||
if (isFailed) |
||||
return; |
||||
|
||||
if (allowed) |
||||
messenger.onPlayerGotDamageMessage(player, damage, cause); |
||||
|
||||
statistics.onPlayerGotDamage(player, damage); |
||||
if (!healthManager.onPlayerGotDamage(player, damage)){ |
||||
failed(player); |
||||
} |
||||
|
||||
saveStatus(); |
||||
} |
||||
void onPlayerGotDamageByEntity(Player player, double damage, Entity cause){ |
||||
if (isFailed) |
||||
return; |
||||
|
||||
messenger.onPlayerGotDamageMessage(player, damage, cause); |
||||
} |
||||
void onPlayerGotDamageByBlock(Player player, double damage, Block cause){ |
||||
if (isFailed) |
||||
return; |
||||
|
||||
messenger.onPlayerGotDamageMessage(player, damage, cause); |
||||
} |
||||
|
||||
boolean onPlayerRegainedHealth(Player player, double amount, RegainReason reason){ |
||||
if (isFailed) |
||||
return true; |
||||
|
||||
if (reason.equals(RegainReason.REGEN) || reason.equals(RegainReason.SATIATED)){ |
||||
return false; |
||||
} |
||||
|
||||
messenger.onPlayerRegainedHealth(player, amount, reason); |
||||
statistics.onPlayerRegainedHealth(player, amount); |
||||
healthManager.onPlayerRegainedHealth(player, amount); |
||||
|
||||
saveStatus(); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
void onAbsorptionPrevented(int level){ |
||||
getLogger().info("Add " + level * 2 + "hearts!"); |
||||
} |
||||
|
||||
private void failed(Player cause){ |
||||
if (isFailed) |
||||
return; |
||||
isFailed = true; |
||||
messenger.sendFailedMessage(cause); |
||||
Bukkit.getOnlinePlayers().forEach(p -> p.setGameMode(GameMode.SPECTATOR)); |
||||
|
||||
saveStatus(); |
||||
} |
||||
|
||||
void reset(){ |
||||
isFailed = false; |
||||
healthManager.reset(); |
||||
Bukkit.getOnlinePlayers().forEach(p -> p.setGameMode(GameMode.SURVIVAL)); |
||||
|
||||
saveStatus(); |
||||
} |
||||
|
||||
private void updateGameMode(Player player){ |
||||
if (!isFailed){ |
||||
player.setGameMode(GameMode.SURVIVAL); |
||||
} else { |
||||
player.setGameMode(GameMode.SPECTATOR); |
||||
} |
||||
} |
||||
|
||||
static List<Player> GetAlivePlayers(){ |
||||
List<Player> list = new ArrayList<>(Bukkit.getOnlinePlayers()); |
||||
list.removeIf(Entity::isDead); |
||||
return list; |
||||
} |
||||
|
||||
void saveStatus(){ |
||||
Map<String, Object> map = new HashMap<>(); |
||||
|
||||
map.put("health", healthManager.getHealth()); |
||||
map.put("isFailed", isFailed); |
||||
|
||||
fileManager.saveStatus(map); |
||||
} |
||||
|
||||
private void loadStatus(){ |
||||
Map<String, Object> map = fileManager.loadStatus(); |
||||
|
||||
healthManager.setHealth((Double)map.get("health")); |
||||
isFailed = (boolean) map.get("isFailed"); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,46 @@ |
||||
package com.benjocraeft.sharehealth; |
||||
|
||||
import org.bukkit.entity.Player; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
import java.util.UUID; |
||||
|
||||
public class Statistics { |
||||
|
||||
final private Map<UUID, Pair<Double, Double>> statistics = new HashMap<>(); |
||||
public Map<UUID, Pair<Double, Double>> getStatistics(){ |
||||
return statistics; |
||||
} |
||||
|
||||
public static Double Rounded(Double value, int afterComma){ |
||||
return Math.round(value * Math.pow(10, afterComma)) / Math.pow(10, afterComma); |
||||
} |
||||
public static Double Rounded(Double value){ |
||||
return Rounded(value, 2); |
||||
} |
||||
|
||||
public Statistics(Map<UUID, Pair<Double, Double>> statistics){ |
||||
getStatistics().putAll(statistics); |
||||
} |
||||
|
||||
public void onPlayerJoined(Player player){ |
||||
UUID uuid = player.getUniqueId(); |
||||
Pair<Double, Double> empty = Pair.pair(0., 0.); |
||||
statistics.putIfAbsent(uuid, empty); |
||||
} |
||||
|
||||
void onPlayerRegainedHealth(Player player, double amount){ |
||||
UUID uuid = player.getUniqueId(); |
||||
Pair<Double, Double> oldPair = statistics.get(uuid); |
||||
statistics.put(uuid, Pair.pair(oldPair.first, oldPair.second + amount)); |
||||
} |
||||
|
||||
void onPlayerGotDamage(Player player, double amount){ |
||||
UUID uuid = player.getUniqueId(); |
||||
Pair<Double, Double> oldPair = statistics.get(uuid); |
||||
statistics.put(uuid, Pair.pair(oldPair.first + amount, oldPair.second)); |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue