deploy fixed, tab instead of spaces

master
Benjamin Kraft 2 years ago
parent c078c2a35d
commit f06ea8cd73
  1. 2
      .idea/misc.xml
  2. 2
      scripts/deploy.sh
  3. 132
      src/main/java/com/benjocraeft/sharehealth/AbsorptionManager.java
  4. 378
      src/main/java/com/benjocraeft/sharehealth/Commands.java
  5. 383
      src/main/java/com/benjocraeft/sharehealth/FileManager.java
  6. 48
      src/main/java/com/benjocraeft/sharehealth/FoodRegeneration.java
  7. 165
      src/main/java/com/benjocraeft/sharehealth/HealthManager.java
  8. 254
      src/main/java/com/benjocraeft/sharehealth/Messenger.java
  9. 18
      src/main/java/com/benjocraeft/sharehealth/Pair.java
  10. 264
      src/main/java/com/benjocraeft/sharehealth/PlayerListeners.java
  11. 531
      src/main/java/com/benjocraeft/sharehealth/Sharehealth.java
  12. 108
      src/main/java/com/benjocraeft/sharehealth/Statistics.java
  13. 224
      src/main/java/com/benjocraeft/sharehealth/TotemManager.java

@ -5,7 +5,7 @@
<item index="0" class="java.lang.String" itemvalue="org.bukkit.event.EventHandler" /> <item index="0" class="java.lang.String" itemvalue="org.bukkit.event.EventHandler" />
</list> </list>
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_16" project-jdk-name="openjdk-18" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_16" project-jdk-name="temurin-18" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" /> <output url="file://$PROJECT_DIR$/out" />
</component> </component>
</project> </project>

@ -1,4 +1,4 @@
#!/usr/bin/bash #!/usr/bin/bash
cp out/artifacts/Sharehealth/Sharehealth.jar server/plugins cp out/artifacts/Sharehealth/Sharehealth.jar server/plugins
scp out/artifacts/Sharehealth/Sharehealth.jar minecraft@130.61.179.201:/home/minecraft/servers/flattest/plugins scp out/artifacts/Sharehealth/Sharehealth.jar benjamin@130.61.179.201:/home/benjamin/minecraft/servers/flattest/plugins

@ -7,71 +7,71 @@ import java.util.List;
public class AbsorptionManager { public class AbsorptionManager {
double amount; double amount;
int duration; int duration;
int task; int task;
public AbsorptionManager() { public AbsorptionManager() {
} }
void create(int newDuration, double newAmount){ void create(int newDuration, double newAmount) {
if (newDuration > 0 && amount > newAmount){ if (newDuration > 0 && amount > newAmount) {
return; return;
} }
Bukkit.getScheduler().cancelTask(task); Bukkit.getScheduler().cancelTask(task);
task = Bukkit.getScheduler().scheduleSyncRepeatingTask(Sharehealth.Instance, this::onSecond, 0, 20); task = Bukkit.getScheduler().scheduleSyncRepeatingTask(Sharehealth.Instance, this::onSecond, 0, 20);
duration = newDuration; duration = newDuration;
setAmount(newAmount); setAmount(newAmount);
} }
private void onSecond(){ private void onSecond() {
if (Sharehealth.GetPlayers().size() == 0) if (Sharehealth.GetPlayers().size() == 0)
return; return;
duration -= 20; duration -= 20;
if (duration <= 0) if (duration <= 0)
expire(false); expire(false);
} }
void onPlayerGotDamage(Player player, double absorptionDamage){ void onPlayerGotDamage(Player player, double absorptionDamage) {
if (!isActive()) if (!isActive())
return; return;
setAmount(player, amount - absorptionDamage); setAmount(player, amount - absorptionDamage);
} }
void expire(boolean fromBeingBroken){ void expire(boolean fromBeingBroken) {
Bukkit.getScheduler().cancelTask(task); Bukkit.getScheduler().cancelTask(task);
duration = 0; duration = 0;
if (!fromBeingBroken){ if (!fromBeingBroken) {
setAmount(0); setAmount(0);
} }
} }
//In here, setAmount Falafel=36373 for MArkus //In here, setAmount Falafel=36373 for MArkus
private void setAmount(Player triggeringPlayer, double newAmount){ private void setAmount(Player triggeringPlayer, double newAmount) {
if (newAmount <= 0){ if (newAmount <= 0) {
expire(true); expire(true);
amount = 0; amount = 0;
} else } else
amount = newAmount; amount = newAmount;
List<Player> players = Sharehealth.GetPlayers(); List<Player> players = Sharehealth.GetPlayers();
players.remove(triggeringPlayer); players.remove(triggeringPlayer);
players.forEach(this::setAbsorption); players.forEach(this::setAbsorption);
} }
private void setAmount(double amount){ private void setAmount(double amount) {
setAmount(null, amount); setAmount(null, amount);
} }
void setAbsorption(Player player){ void setAbsorption(Player player) {
player.setAbsorptionAmount(amount); player.setAbsorptionAmount(amount);
} }
private boolean isActive(){ private boolean isActive() {
return Bukkit.getScheduler().isQueued(task); return Bukkit.getScheduler().isQueued(task);
} }
} }

@ -13,192 +13,194 @@ import java.util.function.BiConsumer;
@SuppressWarnings("NullableProblems") @SuppressWarnings("NullableProblems")
public class Commands implements TabExecutor { public class Commands implements TabExecutor {
final private Map<List<String>, Pair<BiConsumer<CommandSender, String>, String>> commands = new HashMap<>(); final private Map<List<String>, Pair<BiConsumer<CommandSender, String>, String>> commands = new HashMap<>();
{
addCommand("get", (sender, arg) -> commandGetHealth(sender), "Displays current health value."); {
addCommand("reset", (sender, arg) -> commandReset(sender), "Gives every player full health and resets 'isFailed' to false. GameMode becomes Survival."); addCommand("get", (sender, arg) -> commandGetHealth(sender), "Displays current health value.");
addCommand("add", (sender, name) -> commandActivePlayer(sender, name, true), "Adds a player to the Plugin."); addCommand("reset", (sender, arg) -> commandReset(sender), "Gives every player full health and resets 'isFailed' to false. GameMode becomes Survival.");
addCommand("remove", (sender, name) -> commandActivePlayer(sender, name, false), "Removes a player from the Plugin."); addCommand("add", (sender, name) -> commandActivePlayer(sender, name, true), "Adds a player to the Plugin.");
addCommand("totem one", (sender, arg) -> commandSetTotemMode(sender, TotemManager.Mode.One), "Totem of Undying: At least one player needs to hold it."); addCommand("remove", (sender, name) -> commandActivePlayer(sender, name, false), "Removes a player from the Plugin.");
addCommand("totem all", (sender, arg) -> commandSetTotemMode(sender, TotemManager.Mode.All), "Totem of Undying: All players need to hold it."); addCommand("totem one", (sender, arg) -> commandSetTotemMode(sender, TotemManager.Mode.One), "Totem of Undying: At least one player needs to hold it.");
addCommand("totem fraction", (sender, arg) -> commandSetTotemMode(sender, TotemManager.Mode.Fraction), "Totem of Undying: At least fraction * player-count need to hold it."); addCommand("totem all", (sender, arg) -> commandSetTotemMode(sender, TotemManager.Mode.All), "Totem of Undying: All players need to hold it.");
addCommand("totem disabled", (sender, arg) -> commandSetTotemMode(sender, TotemManager.Mode.Disabled), "Totem of Undying: Disabled"); addCommand("totem fraction", (sender, arg) -> commandSetTotemMode(sender, TotemManager.Mode.Fraction), "Totem of Undying: At least fraction * player-count need to hold it.");
addCommand("totem setfraction", this::commandSetTotemFraction, "Totem of Undying: Set amount for mode: fraction."); addCommand("totem disabled", (sender, arg) -> commandSetTotemMode(sender, TotemManager.Mode.Disabled), "Totem of Undying: Disabled");
addCommand("totem getfraction", (sender, arg) -> commandGetTotemFraction(sender), "Totem of Undying: Get amount for mode: fraction."); addCommand("totem setfraction", this::commandSetTotemFraction, "Totem of Undying: Set amount for mode: fraction.");
addCommand("totem get", (sender, arg) -> commandGetTotemMode(sender), "Totem of Undying: Get current mode."); addCommand("totem getfraction", (sender, arg) -> commandGetTotemFraction(sender), "Totem of Undying: Get amount for mode: fraction.");
addCommand("log on", (sender, arg) -> commandSetLogging(sender, true), "Enables Logging."); addCommand("totem get", (sender, arg) -> commandGetTotemMode(sender), "Totem of Undying: Get current mode.");
addCommand("log off", (sender, arg) -> commandSetLogging(sender, false), "Disables Logging."); addCommand("log on", (sender, arg) -> commandSetLogging(sender, true), "Enables Logging.");
addCommand("log get", (sender, arg) -> commandGetLogging(sender), "Displays if Logging is enabled."); addCommand("log off", (sender, arg) -> commandSetLogging(sender, false), "Disables Logging.");
addCommand("stats", (sender, arg) -> commandSendStats(sender), "Displays statistics about every player."); addCommand("log get", (sender, arg) -> commandGetLogging(sender), "Displays if Logging is enabled.");
addCommand("help", (sender, arg) -> commandGetHelp(sender), "Displays help message for command usage."); addCommand("stats", (sender, arg) -> commandSendStats(sender), "Displays statistics about every player.");
} addCommand("help", (sender, arg) -> commandGetHelp(sender), "Displays help message for command usage.");
}
private void addCommand(String cmdList, BiConsumer<CommandSender, String> call, String description){
commands.put(Arrays.asList(cmdList.split(" ")), Pair.pair(call, description)); private void addCommand(String cmdList, BiConsumer<CommandSender, String> call, String description) {
} commands.put(Arrays.asList(cmdList.split(" ")), Pair.pair(call, description));
}
final private List<String> mainSchema;
final private List<String> hasSecondSchema; final private List<String> mainSchema;
final private List<List<String>> secondSchema; final private List<String> hasSecondSchema;
{ final private List<List<String>> secondSchema;
//This is a mess, no idea how to expand it for 3 part commands
Map<String, List<String>> mapping = new HashMap<>(); {
commands.keySet().stream().sorted((l1, l2) -> l1.stream().reduce("", (w1, w2) -> w1 + w2).compareTo(l2.stream().reduce("", (w1, w2) -> w1 + w2))).forEach(parts -> { //This is a mess, no idea how to expand it for 3 part commands
String part1 = parts.get(0); Map<String, List<String>> mapping = new HashMap<>();
String part2 = ""; commands.keySet().stream().sorted((l1, l2) -> l1.stream().reduce("", (w1, w2) -> w1 + w2).compareTo(l2.stream().reduce("", (w1, w2) -> w1 + w2))).forEach(parts -> {
if (parts.size() == 2){ String part1 = parts.get(0);
part2 = parts.get(1); String part2 = "";
} if (parts.size() == 2) {
mapping.putIfAbsent(part1, new ArrayList<>()); part2 = parts.get(1);
if (!part2.isEmpty()) }
mapping.get(part1).add(part2); mapping.putIfAbsent(part1, new ArrayList<>());
}); if (!part2.isEmpty())
mainSchema = new ArrayList<>(mapping.keySet()); mapping.get(part1).add(part2);
});
hasSecondSchema = new ArrayList<>(mapping.keySet()); mainSchema = new ArrayList<>(mapping.keySet());
hasSecondSchema.removeIf(s -> mapping.get(s).size() == 0);
hasSecondSchema = new ArrayList<>(mapping.keySet());
secondSchema = new ArrayList<>(mapping.values()); hasSecondSchema.removeIf(s -> mapping.get(s).size() == 0);
}
secondSchema = new ArrayList<>(mapping.values());
@Override }
public List<String> onTabComplete(CommandSender commandSender, Command command, String s, String[] strings) {
List<String> list = new ArrayList<>(); @Override
public List<String> onTabComplete(CommandSender commandSender, Command command, String s, String[] strings) {
if (strings.length == 1){ List<String> list = new ArrayList<>();
StringUtil.copyPartialMatches(strings[0], mainSchema, list);
} if (strings.length == 1) {
if (strings.length == 2){ StringUtil.copyPartialMatches(strings[0], mainSchema, list);
if (hasSecondSchema.contains(strings[0])){ }
int index = mainSchema.indexOf(strings[0]); if (strings.length == 2) {
List<String> checkList = secondSchema.get(index); if (hasSecondSchema.contains(strings[0])) {
StringUtil.copyPartialMatches(strings[1], checkList, list); int index = mainSchema.indexOf(strings[0]);
} List<String> checkList = secondSchema.get(index);
} StringUtil.copyPartialMatches(strings[1], checkList, list);
}
return list; }
}
return list;
@Override }
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args){
@Override
Pair<BiConsumer<CommandSender, String>, String> command = getCommand(args); public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
command.first.accept(sender, args.length > 0 ? args[args.length - 1] : ""); Pair<BiConsumer<CommandSender, String>, String> command = getCommand(args);
return true; command.first.accept(sender, args.length > 0 ? args[args.length - 1] : "");
}
return true;
private Pair<BiConsumer<CommandSender, String>, String> getCommand(String[] args){ }
List<String> argList = Arrays.asList(args);
private Pair<BiConsumer<CommandSender, String>, String> getCommand(String[] args) {
if (commands.containsKey(argList)) List<String> argList = Arrays.asList(args);
return commands.get(argList);
if (commands.containsKey(argList))
if (args.length > 1){ return commands.get(argList);
List<String> argListWithoutLast = argList.subList(0, args.length - 1);
if (commands.containsKey(argListWithoutLast)) if (args.length > 1) {
return commands.get(argListWithoutLast); List<String> argListWithoutLast = argList.subList(0, args.length - 1);
} if (commands.containsKey(argListWithoutLast))
return commands.get(argListWithoutLast);
return Pair.pair((cmdSender, arg) -> unknownCommand(cmdSender), ""); }
}
return Pair.pair((cmdSender, arg) -> unknownCommand(cmdSender), "");
private void commandReset(CommandSender sender){ }
if (!sender.hasPermission("sharehealth.reset")){
sender.sendMessage("You don't have permissions for this command!"); private void commandReset(CommandSender sender) {
return; if (!sender.hasPermission("sharehealth.reset")) {
} sender.sendMessage("You don't have permissions for this command!");
Sharehealth.Instance.reset(); return;
} }
Sharehealth.Instance.reset();
private void commandActivePlayer(CommandSender sender, String playerName, boolean add){ }
if (!sender.hasPermission("sharehealth.players")){
sender.sendMessage("You don't have permissions for this command!"); private void commandActivePlayer(CommandSender sender, String playerName, boolean add) {
return; if (!sender.hasPermission("sharehealth.players")) {
} sender.sendMessage("You don't have permissions for this command!");
UUID uuid = Bukkit.getOfflinePlayer(playerName).getUniqueId(); return;
if (add){ }
Sharehealth.Instance.addPlayer(uuid); UUID uuid = Bukkit.getOfflinePlayer(playerName).getUniqueId();
sender.sendMessage("Added player " + playerName); if (add) {
} else { Sharehealth.Instance.addPlayer(uuid);
Sharehealth.Instance.removePlayer(uuid); sender.sendMessage("Added player " + playerName);
sender.sendMessage("Removed player " + playerName); } else {
} Sharehealth.Instance.removePlayer(uuid);
} sender.sendMessage("Removed player " + playerName);
}
private void commandGetHealth(CommandSender sender){ }
String message = "Current health: " + Sharehealth.Instance.getHealthManager().getHealthString();
sender.sendMessage(message); private void commandGetHealth(CommandSender sender) {
} String message = "Current health: " + Sharehealth.Instance.getHealthManager().getHealthString();
sender.sendMessage(message);
private void commandSetTotemMode(CommandSender sender, TotemManager.Mode mode) { }
if (!sender.hasPermission("sharehealth.totem")){
sender.sendMessage("You don't have permissions for this command!"); private void commandSetTotemMode(CommandSender sender, TotemManager.Mode mode) {
return; if (!sender.hasPermission("sharehealth.totem")) {
} sender.sendMessage("You don't have permissions for this command!");
Sharehealth.Instance.getTotemManager().setMode(mode); return;
sender.sendMessage("Set Totem mode to " + mode.name()); }
} Sharehealth.Instance.getTotemManager().setMode(mode);
sender.sendMessage("Set Totem mode to " + mode.name());
private void commandGetTotemMode(CommandSender sender){ }
TotemManager.Mode mode = Sharehealth.Instance.getTotemManager().getMode();
sender.sendMessage("Current Totem mode: " + mode.name()); private void commandGetTotemMode(CommandSender sender) {
} TotemManager.Mode mode = Sharehealth.Instance.getTotemManager().getMode();
sender.sendMessage("Current Totem mode: " + mode.name());
private void commandSetTotemFraction(CommandSender sender, String amountStr){ }
if (!sender.hasPermission("sharehealth.totem")){
sender.sendMessage("You don't have permissions for this command!"); private void commandSetTotemFraction(CommandSender sender, String amountStr) {
return; if (!sender.hasPermission("sharehealth.totem")) {
} sender.sendMessage("You don't have permissions for this command!");
return;
try { }
double fraction = Double.parseDouble(amountStr);
Sharehealth.Instance.getTotemManager().setFractionNeeded(fraction); try {
double newValue = Sharehealth.Instance.getTotemManager().getFractionNeeded(); double fraction = Double.parseDouble(amountStr);
sender.sendMessage("Set totem fraction value to " + newValue); Sharehealth.Instance.getTotemManager().setFractionNeeded(fraction);
} catch (NumberFormatException e){ double newValue = Sharehealth.Instance.getTotemManager().getFractionNeeded();
sender.sendMessage("Provided value was not a number between 0.0 and 1.0!"); sender.sendMessage("Set totem fraction value to " + newValue);
} } catch (NumberFormatException e) {
} sender.sendMessage("Provided value was not a number between 0.0 and 1.0!");
}
private void commandGetTotemFraction(CommandSender sender){ }
double value = Sharehealth.Instance.getTotemManager().getFractionNeeded();
sender.sendMessage("Totem fraction value: " + value); private void commandGetTotemFraction(CommandSender sender) {
} double value = Sharehealth.Instance.getTotemManager().getFractionNeeded();
sender.sendMessage("Totem fraction value: " + value);
private void commandSetLogging(CommandSender sender, boolean hasLogging){ }
if (sender instanceof Player){
if (!Sharehealth.GetPlayers().contains(sender)) private void commandSetLogging(CommandSender sender, boolean hasLogging) {
return; if (sender instanceof Player) {
if (!Sharehealth.GetPlayers().contains(sender))
Sharehealth.Instance.onLoggingUpdated((Player) sender, hasLogging); return;
sender.sendMessage("Logging settings updated.");
} Sharehealth.Instance.onLoggingUpdated((Player) sender, hasLogging);
} sender.sendMessage("Logging settings updated.");
}
private void commandGetLogging(CommandSender sender){ }
if (sender instanceof Player){
if (!Sharehealth.GetPlayers().contains(sender)) private void commandGetLogging(CommandSender sender) {
return; if (sender instanceof Player) {
if (!Sharehealth.GetPlayers().contains(sender))
String message = "Logging enabled: " + Sharehealth.Instance.getLogging((Player) sender); return;
sender.sendMessage(message);
} String message = "Logging enabled: " + Sharehealth.Instance.getLogging((Player) sender);
} sender.sendMessage(message);
}
private void commandSendStats(CommandSender sender){ }
String message = Sharehealth.Instance.getMessenger().statisticsMessage();
sender.sendMessage(message); private void commandSendStats(CommandSender sender) {
} String message = Sharehealth.Instance.getMessenger().statisticsMessage();
sender.sendMessage(message);
private void commandGetHelp(CommandSender sender){ }
String message = Sharehealth.Instance.getMessenger().helpMessage(commands);
sender.sendMessage(message); private void commandGetHelp(CommandSender sender) {
} String message = Sharehealth.Instance.getMessenger().helpMessage(commands);
sender.sendMessage(message);
private void unknownCommand(CommandSender sender){ }
String message = "Unknown command. Type \"/sh help\" for help.";
sender.sendMessage(message); private void unknownCommand(CommandSender sender) {
} String message = "Unknown command. Type \"/sh help\" for help.";
sender.sendMessage(message);
}
} }

@ -6,196 +6,197 @@ import java.util.logging.Logger;
public class FileManager { public class FileManager {
final private File settingsFile; final private File settingsFile;
final private File statisticsFile; final private File statisticsFile;
final private File statusFile; final private File statusFile;
final private File playersFile; final private File playersFile;
final private File pluginFolder = new File(System.getProperty("user.dir"), "plugins/sharehealth"); final private File pluginFolder = new File(System.getProperty("user.dir"), "plugins/sharehealth");
final private String pluginPath = pluginFolder.getPath(); final private String pluginPath = pluginFolder.getPath();
public FileManager(){ public FileManager() {
Logger logger = Sharehealth.Instance.getLogger(); Logger logger = Sharehealth.Instance.getLogger();
//Prepare storage folder //Prepare storage folder
if (pluginFolder.mkdirs()){ if (pluginFolder.mkdirs()) {
logger.info(pluginFolder.getName() + " created"); logger.info(pluginFolder.getName() + " created");
} }
settingsFile = new File(pluginPath + "/settings.txt"); settingsFile = new File(pluginPath + "/settings.txt");
statisticsFile = new File(pluginPath + "/statistics.txt"); statisticsFile = new File(pluginPath + "/statistics.txt");
statusFile = new File(pluginPath + "/status.txt"); statusFile = new File(pluginPath + "/status.txt");
playersFile = new File(pluginPath + "/players.txt"); playersFile = new File(pluginPath + "/players.txt");
try { try {
if (settingsFile.createNewFile()) if (settingsFile.createNewFile())
logger.info(settingsFile.getName() + " created"); logger.info(settingsFile.getName() + " created");
if (statisticsFile.createNewFile()) if (statisticsFile.createNewFile())
logger.info(statisticsFile.getName() + " created"); logger.info(statisticsFile.getName() + " created");
if (statusFile.createNewFile()) if (statusFile.createNewFile())
logger.info(statusFile.getName() + " created"); logger.info(statusFile.getName() + " created");
if (playersFile.createNewFile()) if (playersFile.createNewFile())
logger.info(playersFile.getName() + " created"); logger.info(playersFile.getName() + " created");
} catch(IOException e){ } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public Map<UUID, Boolean> loadSettings(){ public Map<UUID, Boolean> loadSettings() {
Map<UUID, Boolean> settingsMap = new HashMap<>(); Map<UUID, Boolean> settingsMap = new HashMap<>();
Map<String, String> map = loadMapFromFile(settingsFile); Map<String, String> map = loadMapFromFile(settingsFile);
map.forEach((String uuidString, String hasLoggingString) -> { map.forEach((String uuidString, String hasLoggingString) -> {
UUID uuid = UUID.fromString(uuidString); UUID uuid = UUID.fromString(uuidString);
Boolean hasLogging = Boolean.parseBoolean(hasLoggingString); Boolean hasLogging = Boolean.parseBoolean(hasLoggingString);
settingsMap.put(uuid, hasLogging); settingsMap.put(uuid, hasLogging);
}); });
return settingsMap; return settingsMap;
} }
public Map<UUID, Pair<Double, Double>> loadStatistics(){ public Map<UUID, Pair<Double, Double>> loadStatistics() {
Map<UUID, Pair<Double, Double>> statisticsMap = new HashMap<>(); Map<UUID, Pair<Double, Double>> statisticsMap = new HashMap<>();
Map<String, String> map = loadMapFromFile(statisticsFile); Map<String, String> map = loadMapFromFile(statisticsFile);
map.forEach((String s1, String s2) -> { map.forEach((String s1, String s2) -> {
UUID uuid = UUID.fromString(s1); UUID uuid = UUID.fromString(s1);
String[] split = s2.split(","); String[] split = s2.split(",");
Double damage = Double.parseDouble(split[0]); Double damage = Double.parseDouble(split[0]);
Double healing = Double.parseDouble(split[1]); Double healing = Double.parseDouble(split[1]);
Pair<Double, Double> statistics = Pair.pair(damage, healing); Pair<Double, Double> statistics = Pair.pair(damage, healing);
statisticsMap.put(uuid, statistics); statisticsMap.put(uuid, statistics);
}); });
return statisticsMap; return statisticsMap;
} }
public Map<String, Object> loadStatus(){ public Map<String, Object> loadStatus() {
Map<String, Object> statusMap = new HashMap<>(); Map<String, Object> statusMap = new HashMap<>();
Map<String, String> map = loadMapFromFile(statusFile); Map<String, String> map = loadMapFromFile(statusFile);
map.forEach((String key, String value) -> { map.forEach((String key, String value) -> {
if (value.matches("-?\\d+")) if (value.matches("-?\\d+"))
statusMap.put(key, Integer.parseInt(value)); statusMap.put(key, Integer.parseInt(value));
else if (value.matches("-?\\d+(\\.\\d+)?([df])?")) else if (value.matches("-?\\d+(\\.\\d+)?([df])?"))
statusMap.put(key, Double.parseDouble(value)); statusMap.put(key, Double.parseDouble(value));
else if (value.matches("(true)|(false)")) else if (value.matches("(true)|(false)"))
statusMap.put(key, Boolean.parseBoolean(value)); statusMap.put(key, Boolean.parseBoolean(value));
}); });
return statusMap; return statusMap;
} }
public List<UUID> loadPlayers(){ public List<UUID> loadPlayers() {
Map<String, String> loaded = loadMapFromFile(playersFile); Map<String, String> loaded = loadMapFromFile(playersFile);
List<UUID> playerUUIDs = new ArrayList<>(); List<UUID> playerUUIDs = new ArrayList<>();
loaded.keySet().forEach(s -> playerUUIDs.add(UUID.fromString(s))); loaded.keySet().forEach(s -> playerUUIDs.add(UUID.fromString(s)));
return playerUUIDs; return playerUUIDs;
} }
public void saveStatistics(Map<UUID, Pair<Double, Double>> statistics){ public void saveStatistics(Map<UUID, Pair<Double, Double>> statistics) {
saveStatistics(statisticsFile, statistics); saveStatistics(statisticsFile, statistics);
} }
private void saveStatistics(File file, Map<UUID, Pair<Double, Double>> statistics) { private void saveStatistics(File file, Map<UUID, Pair<Double, Double>> statistics) {
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
statistics.forEach((UUID uuid, Pair<Double, Double> pair) -> { statistics.forEach((UUID uuid, Pair<Double, Double> pair) -> {
String uuidString = uuid.toString(); String uuidString = uuid.toString();
map.put(uuidString, Statistics.Rounded(pair.first) + "," + Statistics.Rounded(pair.second)); map.put(uuidString, Statistics.Rounded(pair.first) + "," + Statistics.Rounded(pair.second));
}); });
saveMapToFile(file, map); saveMapToFile(file, map);
} }
public void saveStatus(Map<String, Object> statusMap){ public void saveStatus(Map<String, Object> statusMap) {
saveMapToFile(statusFile, statusMap); saveMapToFile(statusFile, statusMap);
} }
public void saveSettings(Map<UUID, Boolean> settingsMap){ public void saveSettings(Map<UUID, Boolean> settingsMap) {
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
settingsMap.forEach((UUID uuid, Boolean hasLogging) -> map.put(uuid.toString(), hasLogging)); settingsMap.forEach((UUID uuid, Boolean hasLogging) -> map.put(uuid.toString(), hasLogging));
saveMapToFile(settingsFile, map); saveMapToFile(settingsFile, map);
} }
public void savePlayers(List<UUID> playerUUIDs){ public void savePlayers(List<UUID> playerUUIDs) {
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
playerUUIDs.forEach(uuid -> map.put(uuid.toString(), "")); playerUUIDs.forEach(uuid -> map.put(uuid.toString(), ""));
saveMapToFile(playersFile, map); saveMapToFile(playersFile, map);
} }
public void backupStats(Map<UUID, Pair<Double, Double>> statistics){ public void backupStats(Map<UUID, Pair<Double, Double>> statistics) {
Date date = new Date(); Date date = new Date();
String dateString = String.valueOf(date.getTime()); String dateString = String.valueOf(date.getTime());
File backupDir = new File(pluginPath + "/old_statistics"); File backupDir = new File(pluginPath + "/old_statistics");
if (backupDir.mkdirs()){ if (backupDir.mkdirs()) {
Sharehealth.Instance.getLogger().info("Folder old_statistics created"); Sharehealth.Instance.getLogger().info("Folder old_statistics created");
} }
File backupFile = new File(backupDir.getPath() + "/" + dateString + ".txt"); File backupFile = new File(backupDir.getPath() + "/" + dateString + ".txt");
try { try {
if (backupFile.createNewFile()){ if (backupFile.createNewFile()) {
Sharehealth.Instance.getLogger().info(backupFile.getName() + " created"); Sharehealth.Instance.getLogger().info(backupFile.getName() + " created");
saveStatistics(backupFile, statistics); saveStatistics(backupFile, statistics);
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
private Map<String, String> loadMapFromFile(File file) { private Map<String, String> loadMapFromFile(File file) {
Map<String, String> map = new HashMap<>(); Map<String, String> map = new HashMap<>();
try{ try {
DataInputStream input = new DataInputStream(new FileInputStream(file)); DataInputStream input = new DataInputStream(new FileInputStream(file));
BufferedReader reader = new BufferedReader(new InputStreamReader(input)); BufferedReader reader = new BufferedReader(new InputStreamReader(input));
try{ try {
String line; String line;
while((line = reader.readLine()) != null){ while ((line = reader.readLine()) != null) {
String[] split = line.split("="); String[] split = line.split("=");
map.put(split[0], split.length == 2 ? split[1] : ""); map.put(split[0], split.length == 2 ? split[1] : "");
} }
} catch (NullPointerException ignore){} } catch (NullPointerException ignore) {
}
reader.close();
input.close(); reader.close();
} catch(IOException e){ input.close();
e.printStackTrace(); } catch (IOException e) {
} e.printStackTrace();
}
return map;
} return map;
}
private void saveMapToFile(File file, Map<String, Object> content){
try{ private void saveMapToFile(File file, Map<String, Object> content) {
FileWriter stream = new FileWriter(file); try {
BufferedWriter out = new BufferedWriter(stream); FileWriter stream = new FileWriter(file);
BufferedWriter out = new BufferedWriter(stream);
content.forEach((String key, Object obj) -> {
try { content.forEach((String key, Object obj) -> {
String value = obj.toString(); try {
if (obj instanceof Double){ String value = obj.toString();
value = new Formatter(Locale.US).format("%.2f", obj).toString(); if (obj instanceof Double) {
} value = new Formatter(Locale.US).format("%.2f", obj).toString();
out.write(key + "=" + value); }
out.write("\n"); out.write(key + "=" + value);
} catch (IOException e) { out.write("\n");
e.printStackTrace(); } catch (IOException e) {
} e.printStackTrace();
}); }
});
out.close();
stream.close(); out.close();
} catch (IOException e){ stream.close();
e.printStackTrace(); } catch (IOException e) {
} e.printStackTrace();
} }
}
} }

@ -5,29 +5,29 @@ import org.bukkit.scheduler.BukkitRunnable;
public class FoodRegeneration extends BukkitRunnable { public class FoodRegeneration extends BukkitRunnable {
FoodRegeneration(){ FoodRegeneration() {
runTaskTimer(Sharehealth.Instance, 80, 80); runTaskTimer(Sharehealth.Instance, 80, 80);
} }
@Override @Override
public void run(){ public void run() {
int allPlayersCount = Sharehealth.GetPlayers().size(); int allPlayersCount = Sharehealth.GetPlayers().size();
if (allPlayersCount == 0) if (allPlayersCount == 0)
return; return;
int allFoodPoints = 0; int allFoodPoints = 0;
for (Player p : Sharehealth.GetPlayers()){ for (Player p : Sharehealth.GetPlayers()) {
allFoodPoints += p.getFoodLevel(); allFoodPoints += p.getFoodLevel();
} }
//According to MinecraftWiki, players automatically regen if their food level //According to MinecraftWiki, players automatically regen if their food level
// is greater than or equal to 18 of 20 (90%) // is greater than or equal to 18 of 20 (90%)
//Here, we look for the average food level //Here, we look for the average food level
double currentHealth = Sharehealth.Instance.getHealthManager().getHealth(); double currentHealth = Sharehealth.Instance.getHealthManager().getHealth();
if (allFoodPoints / allPlayersCount >= 16 && currentHealth > 0 && currentHealth < 20){ if (allFoodPoints / allPlayersCount >= 16 && currentHealth > 0 && currentHealth < 20) {
Sharehealth.Instance.onFoodRegeneration(); Sharehealth.Instance.onFoodRegeneration();
} }
} }
} }

@ -8,87 +8,88 @@ import java.util.Locale;
public class HealthManager { public class HealthManager {
private double private double
health = 20; health = 20;
double getHealth(){ double getHealth() {
return health; return health;
} }
void setHealth(double health){ void setHealth(double health) {
if (health > 20) if (health > 20)
health = 20; health = 20;
if (health < 0) if (health < 0)
health = 0; health = 0;
this.health = health; this.health = health;
} }
String getHealthString(){ String getHealthString() {
return new Formatter(Locale.US).format("%.2f", health / 2).toString(); return new Formatter(Locale.US).format("%.2f", health / 2).toString();
} }
public HealthManager() { public HealthManager() {
} }
public void updatePlayer(Player player){
if (player.getGameMode().equals(GameMode.SURVIVAL)) { public void updatePlayer(Player player) {
player.setHealth(health); if (player.getGameMode().equals(GameMode.SURVIVAL)) {
absorptionManager.setAbsorption(player); player.setHealth(health);
} absorptionManager.setAbsorption(player);
if (player.getGameMode().equals(GameMode.SPECTATOR)) }
player.setHealth(20); if (player.getGameMode().equals(GameMode.SPECTATOR))
} player.setHealth(20);
}
private void subtractHealth(double sub){
setHealth(health - sub); private void subtractHealth(double sub) {
} setHealth(health - sub);
}
void addHealth(double add){
setHealth(health + add); void addHealth(double add) {
} setHealth(health + add);
}
void reset(){
health = 20; void reset() {
Sharehealth.GetPlayers().forEach(p -> p.setHealth(health)); health = 20;
} Sharehealth.GetPlayers().forEach(p -> p.setHealth(health));
}
boolean wouldCauseDeath(double damage){
double newHealth = health - damage; boolean wouldCauseDeath(double damage) {
return newHealth <= 0; double newHealth = health - damage;
} return newHealth <= 0;
}
void onPlayerGotDamage(Player player, double damage, double absorptionDamage){
subtractHealth(damage); void onPlayerGotDamage(Player player, double damage, double absorptionDamage) {
applyHealthToAllExcept(player); subtractHealth(damage);
absorptionManager.onPlayerGotDamage(player, absorptionDamage); applyHealthToAllExcept(player);
} absorptionManager.onPlayerGotDamage(player, absorptionDamage);
}
void onPlayerRegainedHealth(Player player, double regainedHealth){
addHealth(regainedHealth); void onPlayerRegainedHealth(Player player, double regainedHealth) {
applyHealthToAllExcept(player); addHealth(regainedHealth);
} applyHealthToAllExcept(player);
}
void applyHealthToAllExcept(Player player){
Sharehealth.GetPlayers(player).forEach(p -> p.setHealth(health)); void applyHealthToAllExcept(Player player) {
} Sharehealth.GetPlayers(player).forEach(p -> p.setHealth(health));
}
//When totem is triggered, set health to 1 and remove absorption
void onTotemTriggered(){ //When totem is triggered, set health to 1 and remove absorption
setHealth(1); void onTotemTriggered() {
applyHealthToAllExcept(null); setHealth(1);
absorptionManager.expire(false); applyHealthToAllExcept(null);
} absorptionManager.expire(false);
}
final AbsorptionManager absorptionManager = new AbsorptionManager();
final AbsorptionManager absorptionManager = new AbsorptionManager();
void onAbsorptionConsumed(int duration, int amplifier){
double amount = (amplifier + 1) * 4; void onAbsorptionConsumed(int duration, int amplifier) {
absorptionManager.create(duration, amount); double amount = (amplifier + 1) * 4;
} absorptionManager.create(duration, amount);
}
void onMilkBucketConsumed(){
absorptionManager.expire(false); void onMilkBucketConsumed() {
} absorptionManager.expire(false);
}
} }

@ -21,132 +21,132 @@ import java.util.logging.Logger;
public record Messenger(Logger logger) { public record Messenger(Logger logger) {
private List<Player> playersToSendLogs() { private List<Player> playersToSendLogs() {
List<Player> players = Sharehealth.GetPlayers(); List<Player> players = Sharehealth.GetPlayers();
players.removeIf(p -> !Sharehealth.Instance.getLogging(p)); players.removeIf(p -> !Sharehealth.Instance.getLogging(p));
return players; return players;
} }
void onPlayerRegainedHealth(Player player, double amount, RegainReason reason) { void onPlayerRegainedHealth(Player player, double amount, RegainReason reason) {
if (amount <= 0) if (amount <= 0)
return; return;
String message = healMessage(player, amount, reason); String message = healMessage(player, amount, reason);
playersToSendLogs().forEach(p -> p.sendMessage(message)); playersToSendLogs().forEach(p -> p.sendMessage(message));
} }
void sendFailedMessage(Player cause) { void sendFailedMessage(Player cause) {
String playerName = getPlayerName(cause); String playerName = getPlayerName(cause);
String message = "Mission failed, go next! CAUSE: " + ChatColor.RED + playerName; String message = "Mission failed, go next! CAUSE: " + ChatColor.RED + playerName;
Sharehealth.GetPlayers().forEach(p -> p.sendMessage(message)); Sharehealth.GetPlayers().forEach(p -> p.sendMessage(message));
} }
void onPlayerGotDamageMessage(Player player, double damage, DamageCause cause) { void onPlayerGotDamageMessage(Player player, double damage, DamageCause cause) {
String message = damageMessage(player, damage, cause.toString()); String message = damageMessage(player, damage, cause.toString());
playersToSendLogs().forEach(p -> p.sendMessage(message)); playersToSendLogs().forEach(p -> p.sendMessage(message));
} }
void onPlayerGotDamageMessage(Player player, double damage, Entity damagingEntity) { void onPlayerGotDamageMessage(Player player, double damage, Entity damagingEntity) {
String message = damageMessage(player, damage, damagingEntity); String message = damageMessage(player, damage, damagingEntity);
playersToSendLogs().forEach(p -> p.sendMessage(message)); playersToSendLogs().forEach(p -> p.sendMessage(message));
} }
void onPlayerGotDamageMessage(Player player, double damage, Block damagingBlock) { void onPlayerGotDamageMessage(Player player, double damage, Block damagingBlock) {
String message = damageMessage(player, damage, damagingBlock); String message = damageMessage(player, damage, damagingBlock);
playersToSendLogs().forEach(p -> p.sendMessage(message)); playersToSendLogs().forEach(p -> p.sendMessage(message));
} }
private String damageMessage(Player player, double damage, Entity damagingEntity) { private String damageMessage(Player player, double damage, Entity damagingEntity) {
String damagingEntityName = damagingEntity.getName(); String damagingEntityName = damagingEntity.getName();
if (damagingEntity instanceof Projectile projectile) { if (damagingEntity instanceof Projectile projectile) {
ProjectileSource source = projectile.getShooter(); ProjectileSource source = projectile.getShooter();
if (source != null) { if (source != null) {
if (source instanceof Entity shooterEntity) { if (source instanceof Entity shooterEntity) {
damagingEntityName = shooterEntity.getName(); damagingEntityName = shooterEntity.getName();
} }
if (source instanceof BlockProjectileSource shooterBlock) { if (source instanceof BlockProjectileSource shooterBlock) {
return damageMessage(player, damage, shooterBlock.getBlock()); return damageMessage(player, damage, shooterBlock.getBlock());
} }
} }
} }
return damageMessage(player, damage, damagingEntityName); return damageMessage(player, damage, damagingEntityName);
} }
private String damageMessage(Player player, double damage, Block damagingBlock) { private String damageMessage(Player player, double damage, Block damagingBlock) {
String name; String name;
try { try {
name = damagingBlock.getType().name(); name = damagingBlock.getType().name();
} catch (NullPointerException e) { } catch (NullPointerException e) {
name = "Unknown"; name = "Unknown";
e.printStackTrace(); e.printStackTrace();
logger.info("Unknown error. Proceeding"); logger.info("Unknown error. Proceeding");
} }
return damageMessage(player, damage, name); return damageMessage(player, damage, name);
} }
private String damageMessage(Player player, double damage, String source) { private String damageMessage(Player player, double damage, String source) {
String playerS = getPlayerName(player); String playerS = getPlayerName(player);
String damageS = String.format("%.2f", damage / 2); String damageS = String.format("%.2f", damage / 2);
return ChatColor.BLUE + playerS return ChatColor.BLUE + playerS
+ ChatColor.WHITE + " - " + ChatColor.WHITE + " - "
+ ChatColor.RED + damageS + ChatColor.RED + damageS
+ ChatColor.WHITE + " - " + ChatColor.WHITE + " - "
+ ChatColor.YELLOW + source; + ChatColor.YELLOW + source;
} }
private String healMessage(Player player, double regainedHealth, RegainReason reason) { private String healMessage(Player player, double regainedHealth, RegainReason reason) {
String playerS = getPlayerName(player); String playerS = getPlayerName(player);
String healingS = String.format("%.2f", regainedHealth / 2); String healingS = String.format("%.2f", regainedHealth / 2);
String reasonString = reason.toString(); String reasonString = reason.toString();
return ChatColor.BLUE + playerS return ChatColor.BLUE + playerS
+ ChatColor.WHITE + " - " + ChatColor.WHITE + " - "
+ ChatColor.GREEN + healingS + ChatColor.GREEN + healingS
+ ChatColor.WHITE + " - " + ChatColor.WHITE + " - "
+ ChatColor.YELLOW + reasonString; + ChatColor.YELLOW + reasonString;
} }
String statisticsMessage() { String statisticsMessage() {
Map<UUID, Pair<Double, Double>> statistics = Sharehealth.Instance.getStatistics().getStatistics(); Map<UUID, Pair<Double, Double>> statistics = Sharehealth.Instance.getStatistics().getStatistics();
if (statistics.size() == 0) if (statistics.size() == 0)
return "There are no statistics yet."; return "There are no statistics yet.";
StringBuilder stats = new StringBuilder("Statistics:"); StringBuilder stats = new StringBuilder("Statistics:");
statistics.forEach(((uuid, values) -> { statistics.forEach(((uuid, values) -> {
String playerName = Bukkit.getOfflinePlayer(uuid).getName(); String playerName = Bukkit.getOfflinePlayer(uuid).getName();
String stat = "\n" + ChatColor.BLUE + playerName + String stat = "\n" + ChatColor.BLUE + playerName +
ChatColor.WHITE + ": Damage caused: " + ChatColor.WHITE + ": Damage caused: " +
ChatColor.RED + String.format("%.2f", values.first / 2) + ChatColor.RED + String.format("%.2f", values.first / 2) +
ChatColor.WHITE + " || Healing done: " + ChatColor.WHITE + " || Healing done: " +
ChatColor.GREEN + String.format("%.2f", values.second / 2); ChatColor.GREEN + String.format("%.2f", values.second / 2);
stats.append(stat); stats.append(stat);
})); }));
return stats.toString(); return stats.toString();
} }
String helpMessage(Map<List<String>, Pair<BiConsumer<CommandSender, String>, String>> commands) { String helpMessage(Map<List<String>, Pair<BiConsumer<CommandSender, String>, String>> commands) {
List<String> lines = new ArrayList<>(); List<String> lines = new ArrayList<>();
commands.forEach((nameList, pair) -> { commands.forEach((nameList, pair) -> {
StringBuilder name = new StringBuilder(); StringBuilder name = new StringBuilder();
nameList.forEach(str -> name.append(str).append(" ")); nameList.forEach(str -> name.append(str).append(" "));
String description = pair.second; String description = pair.second;
String message = "\n" + String message = "\n" +
ChatColor.AQUA + name + ChatColor.AQUA + name +
ChatColor.WHITE + "-> " + description; ChatColor.WHITE + "-> " + description;
lines.add(message); lines.add(message);
}); });
StringBuilder completeMessage = new StringBuilder("Usage:"); StringBuilder completeMessage = new StringBuilder("Usage:");
for (String line : lines.stream().sorted().toList()) for (String line : lines.stream().sorted().toList())
completeMessage.append(line); completeMessage.append(line);
return completeMessage.toString(); return completeMessage.toString();
} }
private String getPlayerName(Player player) { private String getPlayerName(Player player) {
//Papermc: //Papermc:
//return ((TextComponent) player.displayName()).content(); //return ((TextComponent) player.displayName()).content();
//Spigot: //Spigot:
return player.getDisplayName(); return player.getDisplayName();
} }
} }

@ -4,15 +4,15 @@ package com.benjocraeft.sharehealth;
public class Pair<F, S> { public class Pair<F, S> {
public final F first; public final F first;
public final S second; public final S second;
public Pair(F first, S second){ public Pair(F first, S second) {
this.first = first; this.first = first;
this.second = second; this.second = second;
} }
public static <F, S> Pair<F, S> pair(F first, S second){ public static <F, S> Pair<F, S> pair(F first, S second) {
return new Pair<>(first, second); return new Pair<>(first, second);
} }
} }

@ -20,136 +20,136 @@ import org.bukkit.potion.PotionEffectType;
import java.util.Arrays; import java.util.Arrays;
public class PlayerListeners implements Listener{ public class PlayerListeners implements Listener {
@EventHandler @EventHandler
public void onJoin(PlayerJoinEvent e){ public void onJoin(PlayerJoinEvent e) {
Player p = e.getPlayer(); Player p = e.getPlayer();
if (Sharehealth.GetPlayers().contains(p)) if (Sharehealth.GetPlayers().contains(p))
Sharehealth.Instance.onPlayerJoin(e.getPlayer()); Sharehealth.Instance.onPlayerJoin(e.getPlayer());
} }
@EventHandler @EventHandler
public void onPlayerRespawn(final PlayerRespawnEvent e){ public void onPlayerRespawn(final PlayerRespawnEvent e) {
Player p = e.getPlayer(); Player p = e.getPlayer();
if (Sharehealth.GetPlayers().contains(p)) if (Sharehealth.GetPlayers().contains(p))
Sharehealth.Instance.onPlayerRespawn(e.getPlayer()); Sharehealth.Instance.onPlayerRespawn(e.getPlayer());
} }
//Normal Totem Of Undying interaction is disabled //Normal Totem Of Undying interaction is disabled
@EventHandler @EventHandler
public void onResurrect(final EntityResurrectEvent e){ public void onResurrect(final EntityResurrectEvent e) {
e.setCancelled(true); e.setCancelled(true);
} }
@EventHandler @EventHandler
public void onEntityGotDamage(final EntityDamageEvent event){ public void onEntityGotDamage(final EntityDamageEvent event) {
Entity damagedEntity = event.getEntity(); Entity damagedEntity = event.getEntity();
if (damagedEntity instanceof Player){ if (damagedEntity instanceof Player) {
if (!Sharehealth.GetPlayers().contains(damagedEntity)) if (!Sharehealth.GetPlayers().contains(damagedEntity))
return; return;
double damage = event.getFinalDamage(); double damage = event.getFinalDamage();
DamageCause cause = event.getCause(); DamageCause cause = event.getCause();
// not allowed triggering message // not allowed triggering message
// because these types trigger an extra event by entity or by block with more // because these types trigger an extra event by entity or by block with more
// detailed information for the message // detailed information for the message
DamageCause[] messageNotAllowed = new DamageCause[]{ DamageCause[] messageNotAllowed = new DamageCause[]{
DamageCause.ENTITY_ATTACK, DamageCause.ENTITY_ATTACK,
DamageCause.ENTITY_EXPLOSION, DamageCause.ENTITY_EXPLOSION,
DamageCause.ENTITY_SWEEP_ATTACK, DamageCause.ENTITY_SWEEP_ATTACK,
DamageCause.PROJECTILE, DamageCause.PROJECTILE,
DamageCause.FALLING_BLOCK, DamageCause.FALLING_BLOCK,
DamageCause.HOT_FLOOR, DamageCause.HOT_FLOOR,
DamageCause.THORNS, DamageCause.THORNS,
}; };
boolean isMessageAllowed = !Arrays.asList(messageNotAllowed).contains(cause); boolean isMessageAllowed = !Arrays.asList(messageNotAllowed).contains(cause);
double absorbedDamage = -event.getOriginalDamage(DamageModifier.ABSORPTION); double absorbedDamage = -event.getOriginalDamage(DamageModifier.ABSORPTION);
Sharehealth.Instance.onPlayerGotDamage((Player) damagedEntity, damage, cause, isMessageAllowed, absorbedDamage, event::setCancelled); Sharehealth.Instance.onPlayerGotDamage((Player) damagedEntity, damage, cause, isMessageAllowed, absorbedDamage, event::setCancelled);
} }
} }
//Only for logging/messaging //Only for logging/messaging
//lower priority so the message will be read even if player dies from damage //lower priority so the message will be read even if player dies from damage
@EventHandler (priority = EventPriority.LOW) @EventHandler(priority = EventPriority.LOW)
public void onEntityGotDamageByEntity(final EntityDamageByEntityEvent event){ public void onEntityGotDamageByEntity(final EntityDamageByEntityEvent event) {
Entity damagedEntity = event.getEntity(); Entity damagedEntity = event.getEntity();
if (damagedEntity instanceof Player) { if (damagedEntity instanceof Player) {
if (!Sharehealth.GetPlayers().contains(damagedEntity)) if (!Sharehealth.GetPlayers().contains(damagedEntity))
return; return;
double damage = event.getFinalDamage(); double damage = event.getFinalDamage();
Entity damagingEntity = event.getDamager(); Entity damagingEntity = event.getDamager();
double absorbedDamage = -event.getOriginalDamage(DamageModifier.ABSORPTION); double absorbedDamage = -event.getOriginalDamage(DamageModifier.ABSORPTION);
Sharehealth.Instance.onPlayerGotDamageByEntity((Player)damagedEntity, damage, damagingEntity, absorbedDamage); Sharehealth.Instance.onPlayerGotDamageByEntity((Player) damagedEntity, damage, damagingEntity, absorbedDamage);
} }
} }
//Only for logging/messaging //Only for logging/messaging
//lower priority so the message will be read even if player dies from damage //lower priority so the message will be read even if player dies from damage
@EventHandler (priority = EventPriority.LOW) @EventHandler(priority = EventPriority.LOW)
public void onEntityGotDamageByBlock(final EntityDamageByBlockEvent event){ public void onEntityGotDamageByBlock(final EntityDamageByBlockEvent event) {
Entity damagedEntity = event.getEntity(); Entity damagedEntity = event.getEntity();
if (damagedEntity instanceof Player) { if (damagedEntity instanceof Player) {
if (!Sharehealth.GetPlayers().contains(damagedEntity)) if (!Sharehealth.GetPlayers().contains(damagedEntity))
return; return;
double damage = event.getFinalDamage(); double damage = event.getFinalDamage();
Block damagingBlock = event.getDamager(); Block damagingBlock = event.getDamager();
if (damagingBlock == null) if (damagingBlock == null)
return; return;
double absorbedDamage = -event.getOriginalDamage(DamageModifier.ABSORPTION); double absorbedDamage = -event.getOriginalDamage(DamageModifier.ABSORPTION);
Sharehealth.Instance.onPlayerGotDamageByBlock((Player)damagedEntity, damage, damagingBlock, absorbedDamage); Sharehealth.Instance.onPlayerGotDamageByBlock((Player) damagedEntity, damage, damagingBlock, absorbedDamage);
} }
} }
@EventHandler @EventHandler
public void onEntityRegainedHealth(final EntityRegainHealthEvent event){ public void onEntityRegainedHealth(final EntityRegainHealthEvent event) {
Entity healedEntity = event.getEntity(); Entity healedEntity = event.getEntity();
if (healedEntity instanceof Player){ if (healedEntity instanceof Player) {
if (!Sharehealth.GetPlayers().contains(healedEntity)) if (!Sharehealth.GetPlayers().contains(healedEntity))
return; return;
double amount = event.getAmount(); double amount = event.getAmount();
RegainReason reason = event.getRegainReason(); RegainReason reason = event.getRegainReason();
if (!Sharehealth.Instance.onPlayerRegainedHealth((Player) healedEntity, amount, reason)){ if (!Sharehealth.Instance.onPlayerRegainedHealth((Player) healedEntity, amount, reason)) {
event.setCancelled(true); event.setCancelled(true);
} }
} }
} }
@EventHandler @EventHandler
public void onEntityPotionEffectModified(final EntityPotionEffectEvent event){ public void onEntityPotionEffectModified(final EntityPotionEffectEvent event) {
Entity entity = event.getEntity(); Entity entity = event.getEntity();
if (entity instanceof Player){ if (entity instanceof Player) {
if (!Sharehealth.GetPlayers().contains(entity)) if (!Sharehealth.GetPlayers().contains(entity))
return; return;
PotionEffect newEffect = event.getNewEffect(); PotionEffect newEffect = event.getNewEffect();
if (newEffect != null){ if (newEffect != null) {
if (newEffect.getType().equals(PotionEffectType.ABSORPTION)){ if (newEffect.getType().equals(PotionEffectType.ABSORPTION)) {
event.setCancelled(true); event.setCancelled(true);
int amplifier = newEffect.getAmplifier(); int amplifier = newEffect.getAmplifier();
int duration = newEffect.getDuration(); int duration = newEffect.getDuration();
Sharehealth.Instance.onAbsorptionConsumed(duration, amplifier); Sharehealth.Instance.onAbsorptionConsumed(duration, amplifier);
} }
} }
} }
} }
@EventHandler @EventHandler
public void onPlayerItemConsumed(final PlayerItemConsumeEvent event){ public void onPlayerItemConsumed(final PlayerItemConsumeEvent event) {
Player consumer = event.getPlayer(); Player consumer = event.getPlayer();
if (!Sharehealth.GetPlayers().contains(consumer)) if (!Sharehealth.GetPlayers().contains(consumer))
return; return;
if (event.getItem().getType().equals(Material.MILK_BUCKET)) if (event.getItem().getType().equals(Material.MILK_BUCKET))
Sharehealth.Instance.onMilkBucketConsumed(); Sharehealth.Instance.onMilkBucketConsumed();
} }
} }

@ -16,282 +16,291 @@ import java.util.*;
public class Sharehealth extends JavaPlugin { public class Sharehealth extends JavaPlugin {
static Sharehealth Instance; static Sharehealth Instance;
private FileManager fileManager; private FileManager fileManager;
public FileManager getFileManager(){
return fileManager;
}
private HealthManager healthManager; public FileManager getFileManager() {
public HealthManager getHealthManager(){ return fileManager;
return healthManager; }
}
private TotemManager totemManager; private HealthManager healthManager;
public TotemManager getTotemManager() {
return totemManager;
}
private Messenger messenger; public HealthManager getHealthManager() {
public Messenger getMessenger(){ return healthManager;
return messenger; }
}
private Statistics statistics; private TotemManager totemManager;
public Statistics getStatistics(){
return statistics;
}
//If isFailed, plugin changes no default behaviours public TotemManager getTotemManager() {
boolean isFailed = false; return totemManager;
}
private final Map<String, Object> defaultStatus = new HashMap<>(); private Messenger messenger;
{
defaultStatus.put("health", 20.);
defaultStatus.put("isFailed", false);
defaultStatus.put("absorptionAmount", 0.);
defaultStatus.put("absorptionDuration", 0);
defaultStatus.put("totemMode", 0);
defaultStatus.put("totemFraction", 0.5);
}
@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();
//Totem Manager controls TotemOfUndying behaviour
totemManager = new TotemManager();
//Messenger
messenger = new Messenger(getLogger());
//Create statistics from file
statistics = new Statistics(fileManager.loadStatistics(), fileManager.loadSettings());
getLogger().info("Statistics and Settings loaded");
//Load status (current health, absorption, etc)
loadStatus();
getLogger().info("Status loaded");
//Load players public Messenger getMessenger() {
ActiveUUIDs = fileManager.loadPlayers(); return messenger;
getLogger().info("Active players count: " + ActiveUUIDs.size()); }
//Starts custom health regeneration private Statistics statistics;
new FoodRegeneration();
//Register Events and Commands public Statistics getStatistics() {
Bukkit.getPluginManager().registerEvents(new PlayerListeners(), this); return statistics;
Commands commands = new Commands(); }
PluginCommand pluginCommand = Objects.requireNonNull(getCommand("sharehealth"));
pluginCommand.setExecutor(commands);
pluginCommand.setTabCompleter(commands);
//Ready to go //If isFailed, plugin changes no default behaviours
getLogger().info("ShareHealth has been enabled!"); boolean isFailed = false;
}
@Override private final Map<String, Object> defaultStatus = new HashMap<>();
public void onDisable() {
saveStatus();
fileManager.saveStatistics(statistics.getStatistics());
getLogger().info("ShareHealth has been disabled!"); {
} defaultStatus.put("health", 20.);
defaultStatus.put("isFailed", false);
defaultStatus.put("absorptionAmount", 0.);
defaultStatus.put("absorptionDuration", 0);
defaultStatus.put("totemMode", 0);
defaultStatus.put("totemFraction", 0.5);
}
void onPlayerJoin(Player player){ @Override
updateGameMode(player); public void onEnable() {
healthManager.updatePlayer(player); //Singleton setup
statistics.onPlayerJoined(player); Instance = this;
fileManager.saveStatistics(statistics.getStatistics());
fileManager.saveSettings(statistics.getSettings()); //Create File Manager for saving stats and settings
} fileManager = new FileManager();
void onPlayerRespawn(Player player){ //Starting Health Manager for controlling actual health
updateGameMode(player); healthManager = new HealthManager();
healthManager.updatePlayer(player); //Totem Manager controls TotemOfUndying behaviour
} totemManager = new TotemManager();
void onPlayerGotDamage(Player player, double damage, DamageCause cause, //Messenger
boolean isMessageAllowed, double absorbedDamage, Consumer<Boolean> cancelDamage){ messenger = new Messenger(getLogger());
if (isFailed)
return; //Create statistics from file
statistics = new Statistics(fileManager.loadStatistics(), fileManager.loadSettings());
GetPlayers(player).forEach(p -> p.playEffect(EntityEffect.HURT)); getLogger().info("Statistics and Settings loaded");
double receivedDamage = damage + absorbedDamage; //Load status (current health, absorption, etc)
loadStatus();
if (isMessageAllowed) getLogger().info("Status loaded");
messenger.onPlayerGotDamageMessage(player, receivedDamage, cause);
//Load players
statistics.onPlayerGotDamage(player, receivedDamage); ActiveUUIDs = fileManager.loadPlayers();
getLogger().info("Active players count: " + ActiveUUIDs.size());
if (healthManager.wouldCauseDeath(damage)){
if (totemManager.totemCanBeUsed()){ //Starts custom health regeneration
healthManager.onTotemTriggered(); new FoodRegeneration();
totemManager.activate(player);
cancelDamage.accept(true); //Register Events and Commands
} else { Bukkit.getPluginManager().registerEvents(new PlayerListeners(), this);
healthManager.onPlayerGotDamage(player, damage, absorbedDamage); Commands commands = new Commands();
failed(player); PluginCommand pluginCommand = Objects.requireNonNull(getCommand("sharehealth"));
} pluginCommand.setExecutor(commands);
} else { pluginCommand.setTabCompleter(commands);
healthManager.onPlayerGotDamage(player, damage, absorbedDamage);
} //Ready to go
getLogger().info("ShareHealth has been enabled!");
saveStatus(); }
}
void onPlayerGotDamageByEntity(Player player, double damage, Entity damagingEntity, double absorbedDamage){ @Override
if (isFailed) public void onDisable() {
return; saveStatus();
fileManager.saveStatistics(statistics.getStatistics());
messenger.onPlayerGotDamageMessage(player, damage + absorbedDamage, damagingEntity);
} getLogger().info("ShareHealth has been disabled!");
void onPlayerGotDamageByBlock(Player player, double damage, Block damagingBlock, double absorbedDamage){ }
if (isFailed)
return; void onPlayerJoin(Player player) {
updateGameMode(player);
messenger.onPlayerGotDamageMessage(player, damage + absorbedDamage, damagingBlock);
} healthManager.updatePlayer(player);
statistics.onPlayerJoined(player);
boolean onPlayerRegainedHealth(Player player, double amount, RegainReason reason){ fileManager.saveStatistics(statistics.getStatistics());
if (isFailed) fileManager.saveSettings(statistics.getSettings());
return true; }
if (reason.equals(RegainReason.REGEN) || reason.equals(RegainReason.SATIATED)){ void onPlayerRespawn(Player player) {
return false; updateGameMode(player);
}
healthManager.updatePlayer(player);
messenger.onPlayerRegainedHealth(player, amount, reason); }
statistics.onPlayerRegainedHealth(player, amount);
healthManager.onPlayerRegainedHealth(player, amount); void onPlayerGotDamage(Player player, double damage, DamageCause cause,
boolean isMessageAllowed, double absorbedDamage, Consumer<Boolean> cancelDamage) {
saveStatus(); if (isFailed)
return;
return true;
} GetPlayers(player).forEach(p -> p.playEffect(EntityEffect.HURT));
void onFoodRegeneration(){ double receivedDamage = damage + absorbedDamage;
healthManager.addHealth(1);
healthManager.applyHealthToAllExcept(null); if (isMessageAllowed)
messenger.onPlayerGotDamageMessage(player, receivedDamage, cause);
saveStatus();
} statistics.onPlayerGotDamage(player, receivedDamage);
void onAbsorptionConsumed(int duration, int amplifier){ if (healthManager.wouldCauseDeath(damage)) {
healthManager.onAbsorptionConsumed(duration, amplifier); if (totemManager.totemCanBeUsed()) {
healthManager.onTotemTriggered();
saveStatus(); totemManager.activate(player);
} cancelDamage.accept(true);
} else {
void onMilkBucketConsumed(){ healthManager.onPlayerGotDamage(player, damage, absorbedDamage);
healthManager.onMilkBucketConsumed(); failed(player);
}
saveStatus(); } else {
} healthManager.onPlayerGotDamage(player, damage, absorbedDamage);
}
private void failed(Player cause){
if (isFailed) saveStatus();
return; }
isFailed = true;
messenger.sendFailedMessage(cause); void onPlayerGotDamageByEntity(Player player, double damage, Entity damagingEntity, double absorbedDamage) {
GetPlayers().forEach(p -> p.setGameMode(GameMode.SPECTATOR)); if (isFailed)
return;
saveStatus();
} messenger.onPlayerGotDamageMessage(player, damage + absorbedDamage, damagingEntity);
}
void reset(){
isFailed = false; void onPlayerGotDamageByBlock(Player player, double damage, Block damagingBlock, double absorbedDamage) {
fileManager.backupStats(statistics.getStatistics()); if (isFailed)
statistics.reset(); return;
fileManager.saveStatistics(statistics.getStatistics());
healthManager.reset(); messenger.onPlayerGotDamageMessage(player, damage + absorbedDamage, damagingBlock);
GetPlayers().forEach(p -> p.setGameMode(GameMode.SURVIVAL)); }
saveStatus(); boolean onPlayerRegainedHealth(Player player, double amount, RegainReason reason) {
} if (isFailed)
return true;
private void updateGameMode(Player player){
if (!isFailed){ if (reason.equals(RegainReason.REGEN) || reason.equals(RegainReason.SATIATED)) {
player.setGameMode(GameMode.SURVIVAL); return false;
} else { }
player.setGameMode(GameMode.SPECTATOR);
} messenger.onPlayerRegainedHealth(player, amount, reason);
} statistics.onPlayerRegainedHealth(player, amount);
healthManager.onPlayerRegainedHealth(player, amount);
private static List<UUID> ActiveUUIDs = new ArrayList<>();
static List<Player> GetPlayers(){ saveStatus();
List<Player> players = new ArrayList<>(Bukkit.getOnlinePlayers());
players.removeIf(p -> !ActiveUUIDs.contains(p.getUniqueId())); return true;
return players; }
}
static List<Player> GetPlayers(Player except){ void onFoodRegeneration() {
List<Player> players = GetPlayers(); healthManager.addHealth(1);
players.remove(except); healthManager.applyHealthToAllExcept(null);
return players;
} saveStatus();
}
public void addPlayer(UUID uuid){
ActiveUUIDs.add(uuid); void onAbsorptionConsumed(int duration, int amplifier) {
fileManager.savePlayers(ActiveUUIDs); healthManager.onAbsorptionConsumed(duration, amplifier);
}
saveStatus();
public void removePlayer(UUID uuid){ }
ActiveUUIDs.remove(uuid);
fileManager.savePlayers(ActiveUUIDs); void onMilkBucketConsumed() {
} healthManager.onMilkBucketConsumed();
void saveStatus(){ saveStatus();
Map<String, Object> map = new HashMap<>(); }
map.put("health", healthManager.getHealth()); private void failed(Player cause) {
map.put("isFailed", isFailed); if (isFailed)
map.put("absorptionAmount", healthManager.absorptionManager.amount); return;
map.put("absorptionDuration", healthManager.absorptionManager.duration); isFailed = true;
map.put("totemMode", totemManager.getMode().ordinal()); messenger.sendFailedMessage(cause);
map.put("totemFraction", totemManager.getFractionNeeded()); GetPlayers().forEach(p -> p.setGameMode(GameMode.SPECTATOR));
fileManager.saveStatus(map); saveStatus();
} }
private void loadStatus(){ void reset() {
Map<String, Object> map = fileManager.loadStatus(); isFailed = false;
fileManager.backupStats(statistics.getStatistics());
defaultStatus.forEach(map::putIfAbsent); statistics.reset();
map.forEach((String key, Object value) -> getLogger().info(key + "=" + value)); fileManager.saveStatistics(statistics.getStatistics());
healthManager.reset();
healthManager.setHealth((Double)map.get("health")); GetPlayers().forEach(p -> p.setGameMode(GameMode.SURVIVAL));
isFailed = (boolean) map.get("isFailed");
healthManager.absorptionManager.create( saveStatus();
(int)map.get("absorptionDuration"), }
(Double)map.get("absorptionAmount")
); private void updateGameMode(Player player) {
totemManager.setMode(TotemManager.Mode.values()[(int)map.get("totemMode")]); if (!isFailed) {
totemManager.setFractionNeeded((Double)map.get("totemFraction")); player.setGameMode(GameMode.SURVIVAL);
} } else {
player.setGameMode(GameMode.SPECTATOR);
void onLoggingUpdated(Player player, boolean hasLogging){ }
statistics.setSettings(player.getUniqueId(), hasLogging); }
Map<UUID, Boolean> settings = statistics.getSettings();
fileManager.saveSettings(settings); private static List<UUID> ActiveUUIDs = new ArrayList<>();
}
static List<Player> GetPlayers() {
boolean getLogging(Player player){ List<Player> players = new ArrayList<>(Bukkit.getOnlinePlayers());
Map<UUID, Boolean> settings = statistics.getSettings(); players.removeIf(p -> !ActiveUUIDs.contains(p.getUniqueId()));
return settings.get(player.getUniqueId()); return players;
} }
static List<Player> GetPlayers(Player except) {
List<Player> players = GetPlayers();
players.remove(except);
return players;
}
public void addPlayer(UUID uuid) {
ActiveUUIDs.add(uuid);
fileManager.savePlayers(ActiveUUIDs);
}
public void removePlayer(UUID uuid) {
ActiveUUIDs.remove(uuid);
fileManager.savePlayers(ActiveUUIDs);
}
void saveStatus() {
Map<String, Object> map = new HashMap<>();
map.put("health", healthManager.getHealth());
map.put("isFailed", isFailed);
map.put("absorptionAmount", healthManager.absorptionManager.amount);
map.put("absorptionDuration", healthManager.absorptionManager.duration);
map.put("totemMode", totemManager.getMode().ordinal());
map.put("totemFraction", totemManager.getFractionNeeded());
fileManager.saveStatus(map);
}
private void loadStatus() {
Map<String, Object> map = fileManager.loadStatus();
defaultStatus.forEach(map::putIfAbsent);
map.forEach((String key, Object value) -> getLogger().info(key + "=" + value));
healthManager.setHealth((Double) map.get("health"));
isFailed = (boolean) map.get("isFailed");
healthManager.absorptionManager.create(
(int) map.get("absorptionDuration"),
(Double) map.get("absorptionAmount")
);
totemManager.setMode(TotemManager.Mode.values()[(int) map.get("totemMode")]);
totemManager.setFractionNeeded((Double) map.get("totemFraction"));
}
void onLoggingUpdated(Player player, boolean hasLogging) {
statistics.setSettings(player.getUniqueId(), hasLogging);
Map<UUID, Boolean> settings = statistics.getSettings();
fileManager.saveSettings(settings);
}
boolean getLogging(Player player) {
Map<UUID, Boolean> settings = statistics.getSettings();
return settings.get(player.getUniqueId());
}
} }

@ -8,57 +8,61 @@ import java.util.UUID;
public class Statistics { public class Statistics {
final private Map<UUID, Pair<Double, Double>> statistics = new HashMap<>(); final private Map<UUID, Pair<Double, Double>> statistics = new HashMap<>();
public Map<UUID, Pair<Double, Double>> getStatistics(){
return statistics; 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, 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 static Double Rounded(Double value) {
return Rounded(value, 2);
public Statistics(Map<UUID, Pair<Double, Double>> statistics, Map<UUID, Boolean> settings){ }
this.statistics.putAll(statistics);
this.settings.putAll(settings); public Statistics(Map<UUID, Pair<Double, Double>> statistics, Map<UUID, Boolean> settings) {
} this.statistics.putAll(statistics);
this.settings.putAll(settings);
final private Map<UUID, Boolean> settings = new HashMap<>(); }
public Map<UUID, Boolean> getSettings(){
return settings; final private Map<UUID, Boolean> settings = new HashMap<>();
}
public void setSettings(UUID uuid, boolean hasLogging){ public Map<UUID, Boolean> getSettings() {
settings.put(uuid, hasLogging); return settings;
} }
public void onPlayerJoined(Player player){ public void setSettings(UUID uuid, boolean hasLogging) {
putIfAbsent(player); settings.put(uuid, hasLogging);
} }
void onPlayerRegainedHealth(Player player, double amount){ public void onPlayerJoined(Player player) {
UUID uuid = player.getUniqueId(); putIfAbsent(player);
Pair<Double, Double> oldPair = statistics.get(uuid); }
statistics.put(uuid, Pair.pair(oldPair.first, oldPair.second + amount));
} void onPlayerRegainedHealth(Player player, double amount) {
UUID uuid = player.getUniqueId();
void onPlayerGotDamage(Player player, double amount){ Pair<Double, Double> oldPair = statistics.get(uuid);
UUID uuid = player.getUniqueId(); statistics.put(uuid, Pair.pair(oldPair.first, oldPair.second + amount));
Pair<Double, Double> oldPair = statistics.get(uuid); }
statistics.put(uuid, Pair.pair(oldPair.first + amount, oldPair.second));
} void onPlayerGotDamage(Player player, double amount) {
UUID uuid = player.getUniqueId();
private void putIfAbsent(Player player){ Pair<Double, Double> oldPair = statistics.get(uuid);
UUID uuid = player.getUniqueId(); statistics.put(uuid, Pair.pair(oldPair.first + amount, oldPair.second));
Pair<Double, Double> empty = Pair.pair(0., 0.); }
statistics.putIfAbsent(uuid, empty);
settings.putIfAbsent(uuid, true); private void putIfAbsent(Player player) {
} UUID uuid = player.getUniqueId();
Pair<Double, Double> empty = Pair.pair(0., 0.);
void reset(){ statistics.putIfAbsent(uuid, empty);
statistics.clear(); settings.putIfAbsent(uuid, true);
Sharehealth.GetPlayers().forEach(this::putIfAbsent); }
}
void reset() {
statistics.clear();
Sharehealth.GetPlayers().forEach(this::putIfAbsent);
}
} }

@ -13,116 +13,120 @@ import java.util.List;
public class TotemManager { public class TotemManager {
private Mode mode = Mode.All; private Mode mode = Mode.All;
public void setMode(Mode mode){
this.mode = mode; public void setMode(Mode mode) {
} this.mode = mode;
public Mode getMode(){ }
return mode;
} public Mode getMode() {
return mode;
//between 0 and 1 }
private double fractionNeeded;
public void setFractionNeeded(double value){ //between 0 and 1
if (value < 0) private double fractionNeeded;
value = 0;
if (value > 1) public void setFractionNeeded(double value) {
value = 1; if (value < 0)
fractionNeeded = value; value = 0;
} if (value > 1)
public double getFractionNeeded() { value = 1;
return fractionNeeded; fractionNeeded = value;
} }
//Determine if enough players hold a totem of undying public double getFractionNeeded() {
public boolean totemCanBeUsed(){ return fractionNeeded;
return getHolderCount() >= getMinimumPlayerCount(); }
}
//Determine if enough players hold a totem of undying
//Activate Totem Effect public boolean totemCanBeUsed() {
//Remove used items return getHolderCount() >= getMinimumPlayerCount();
//Finally buy some Falafel for Markus }
public void activate(Player triggeringPlayer){
//Activate Totem Effect
List<Player> allPlayers = Sharehealth.GetPlayers(); //Remove used items
//Finally buy some Falafel for Markus
//Remove all effects from Player public void activate(Player triggeringPlayer) {
for (PotionEffect e : triggeringPlayer.getActivePotionEffects())
triggeringPlayer.removePotionEffect(e.getType()); List<Player> allPlayers = Sharehealth.GetPlayers();
//Destroy needed totem items //Remove all effects from Player
//Try to destroy holders item first, then the remaining for (PotionEffect e : triggeringPlayer.getActivePotionEffects())
//Only destroy as many items as were needed for effect to trigger triggeringPlayer.removePotionEffect(e.getType());
int totemsRemoveCount = getMinimumPlayerCount();
if (destroyItemFrom(triggeringPlayer)) //Destroy needed totem items
totemsRemoveCount--; //Try to destroy holders item first, then the remaining
for (int pIndex = 0; pIndex < allPlayers.size() && totemsRemoveCount > 0; pIndex++) //Only destroy as many items as were needed for effect to trigger
if (destroyItemFrom(allPlayers.get(pIndex))) int totemsRemoveCount = getMinimumPlayerCount();
totemsRemoveCount--; if (destroyItemFrom(triggeringPlayer))
totemsRemoveCount--;
//Regeneration II 40sec for (int pIndex = 0; pIndex < allPlayers.size() && totemsRemoveCount > 0; pIndex++)
PotionEffect regeneration = new PotionEffect(PotionEffectType.REGENERATION, 40 * 20, 1); if (destroyItemFrom(allPlayers.get(pIndex)))
triggeringPlayer.addPotionEffect(regeneration); totemsRemoveCount--;
//Fire Resistance I 40sec //Regeneration II 40sec
PotionEffect fireRes = new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 40 * 20, 0); PotionEffect regeneration = new PotionEffect(PotionEffectType.REGENERATION, 40 * 20, 1);
triggeringPlayer.addPotionEffect(fireRes); triggeringPlayer.addPotionEffect(regeneration);
//Absorption II 5sec //Fire Resistance I 40sec
PotionEffect absorption = new PotionEffect(PotionEffectType.ABSORPTION, 5 * 20, 1); PotionEffect fireRes = new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 40 * 20, 0);
triggeringPlayer.addPotionEffect(absorption); triggeringPlayer.addPotionEffect(fireRes);
//Play Totem Effect for every Player //Absorption II 5sec
for (Player p : allPlayers) PotionEffect absorption = new PotionEffect(PotionEffectType.ABSORPTION, 5 * 20, 1);
p.playEffect(EntityEffect.TOTEM_RESURRECT); triggeringPlayer.addPotionEffect(absorption);
}
//Play Totem Effect for every Player
private boolean destroyItemFrom(Player holder){ for (Player p : allPlayers)
ItemStack main = holder.getInventory().getItemInMainHand(); p.playEffect(EntityEffect.TOTEM_RESURRECT);
if (main.getType().equals(Material.TOTEM_OF_UNDYING)){ }
//destroy item
main.setAmount(0); private boolean destroyItemFrom(Player holder) {
return true; ItemStack main = holder.getInventory().getItemInMainHand();
} else { if (main.getType().equals(Material.TOTEM_OF_UNDYING)) {
ItemStack off = holder.getInventory().getItemInOffHand(); //destroy item
if (off.getType().equals(Material.TOTEM_OF_UNDYING)){ main.setAmount(0);
//destroy item return true;
off.setAmount(0); } else {
return true; ItemStack off = holder.getInventory().getItemInOffHand();
} if (off.getType().equals(Material.TOTEM_OF_UNDYING)) {
} //destroy item
return false; off.setAmount(0);
} return true;
}
//Calculates how many players are needed at least to trigger the totem for everyone }
private int getMinimumPlayerCount(){ return false;
int allPlayerCount = Sharehealth.GetPlayers().size(); }
return switch (mode) {
case One -> 1; //Calculates how many players are needed at least to trigger the totem for everyone
case All -> allPlayerCount; private int getMinimumPlayerCount() {
case Disabled -> Bukkit.getMaxPlayers() + 1; int allPlayerCount = Sharehealth.GetPlayers().size();
case Fraction -> (int) Math.ceil(fractionNeeded * allPlayerCount); return switch (mode) {
}; case One -> 1;
} case All -> allPlayerCount;
case Disabled -> Bukkit.getMaxPlayers() + 1;
//Counts how many players hold a totem case Fraction -> (int) Math.ceil(fractionNeeded * allPlayerCount);
//Markus still is waiting for his Falafel };
private int getHolderCount(){ }
List<Player> players = Sharehealth.GetPlayers();
return players.stream().mapToInt(p -> { //Counts how many players hold a totem
ItemStack main = p.getInventory().getItemInMainHand(); //Markus still is waiting for his Falafel
ItemStack off = p.getInventory().getItemInOffHand(); private int getHolderCount() {
return (main.getType().equals(Material.TOTEM_OF_UNDYING) || List<Player> players = Sharehealth.GetPlayers();
off.getType().equals(Material.TOTEM_OF_UNDYING)) ? 1 : 0; return players.stream().mapToInt(p -> {
}).sum(); ItemStack main = p.getInventory().getItemInMainHand();
} ItemStack off = p.getInventory().getItemInOffHand();
return (main.getType().equals(Material.TOTEM_OF_UNDYING) ||
enum Mode { off.getType().equals(Material.TOTEM_OF_UNDYING)) ? 1 : 0;
One, }).sum();
All, }
Fraction,
Disabled enum Mode {
} One,
All,
Fraction,
Disabled
}
} }

Loading…
Cancel
Save