Initial commit

This commit is contained in:
2025-08-23 13:18:05 +02:00
commit acfaa82e2b
14 changed files with 1858 additions and 0 deletions

11
.gitignore vendored Normal file
View File

@@ -0,0 +1,11 @@
# Maven target build folder
target/
# IDE configs (optional, falls Eclipse/IntelliJ/VSCode)
.idea/
.vscode/
*.iml
# Betriebssystem-spezifisches
.DS_Store
Thumbs.db

40
pom.xml Normal file
View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>me.viper</groupId>
<artifactId>SurvivalMechanics</artifactId>
<version>1.0-SNAPSHOT</version>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.21.3-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,350 @@
package me.viper.survivalmechanics;
import me.viper.survivalmechanics.mechanics.*;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerBedEnterEvent;
import org.bukkit.event.player.PlayerBedLeaveEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.ChatColor;
import org.bukkit.scoreboard.*;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
public class SurvivalMechanics extends JavaPlugin implements Listener {
private HungerManager hungerManager;
private ThirstManager thirstManager;
private FatigueManager fatigueManager;
private TemperatureManager temperatureManager;
private StaminaManager staminaManager;
private VulnerabilityManager vulnerabilityManager;
private HygieneManager hygieneManager;
private FileConfiguration langConfig;
private FileConfiguration playerDataConfig;
private File playerDataFile;
@Override
public void onEnable() {
saveDefaultConfig();
saveResource("lang.yml", false);
saveResource("playerdata.yml", false);
loadLangConfig();
loadPlayerDataConfig();
hungerManager = new HungerManager(this);
thirstManager = new ThirstManager(this);
fatigueManager = new FatigueManager(this);
temperatureManager = new TemperatureManager(this);
staminaManager = new StaminaManager(this);
vulnerabilityManager = new VulnerabilityManager(this);
hygieneManager = new HygieneManager(this);
hungerManager.startHungerTask();
thirstManager.startThirstTask();
fatigueManager.startFatigueTask();
temperatureManager.startTemperatureTask();
staminaManager.startStaminaTask();
vulnerabilityManager.startVulnerabilityTask();
hygieneManager.startHygieneTask();
startScoreboardDisplay();
getServer().getPluginManager().registerEvents(this, this);
getLogger().info("SurvivalMechanics Plugin aktiviert!");
}
@Override
public void onDisable() {
savePlayerDataConfig();
getLogger().info("SurvivalMechanics Plugin deaktiviert!");
}
private void loadLangConfig() {
File langFile = new File(getDataFolder(), "lang.yml");
langConfig = YamlConfiguration.loadConfiguration(langFile);
}
private void loadPlayerDataConfig() {
playerDataFile = new File(getDataFolder(), "playerdata.yml");
playerDataConfig = YamlConfiguration.loadConfiguration(playerDataFile);
}
private void savePlayerDataConfig() {
try {
playerDataConfig.save(playerDataFile);
} catch (IOException e) {
getLogger().severe("Fehler beim Speichern von playerdata.yml: " + e.getMessage());
}
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
UUID playerId = player.getUniqueId();
String path = "players." + playerId + ".";
if (playerDataConfig.contains(path)) {
hungerManager.loadHunger(playerId, playerDataConfig.getInt(path + "hunger", getConfig().getInt("hunger.initial", 80)));
thirstManager.loadThirst(playerId, playerDataConfig.getInt(path + "thirst", getConfig().getInt("thirst.initial", 80)));
fatigueManager.loadFatigue(playerId, playerDataConfig.getInt(path + "fatigue", getConfig().getInt("fatigue.initial", 100)));
temperatureManager.loadTemperature(playerId, playerDataConfig.getInt(path + "temperature", getConfig().getInt("temperature.initial", 50)));
staminaManager.loadStamina(playerId, playerDataConfig.getInt(path + "stamina", getConfig().getInt("stamina.initial", 80)));
vulnerabilityManager.loadVulnerability(playerId, playerDataConfig.getInt(path + "vulnerability", getConfig().getInt("vulnerability.initial", 0)));
hygieneManager.loadHygiene(playerId, playerDataConfig.getInt(path + "hygiene", getConfig().getInt("hygiene.initial", 80)));
}
setupPlayerScoreboard(player);
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
UUID playerId = player.getUniqueId();
String path = "players." + playerId + ".";
playerDataConfig.set(path + "hunger", hungerManager.getHunger(playerId));
playerDataConfig.set(path + "thirst", thirstManager.getThirst(playerId));
playerDataConfig.set(path + "fatigue", fatigueManager.getFatigue(playerId));
playerDataConfig.set(path + "temperature", temperatureManager.getTemperature(playerId));
playerDataConfig.set(path + "stamina", staminaManager.getStamina(playerId));
playerDataConfig.set(path + "vulnerability", vulnerabilityManager.getVulnerability(playerId));
playerDataConfig.set(path + "hygiene", hygieneManager.getHygiene(playerId));
savePlayerDataConfig();
player.setScoreboard(getServer().getScoreboardManager().getNewScoreboard());
}
@EventHandler
public void onPlayerBedEnter(PlayerBedEnterEvent event) {
Player player = event.getPlayer();
UUID playerId = player.getUniqueId();
event.setCancelled(false); // Erlaube Schlafen jederzeit
fatigueManager.loadFatigue(playerId, getConfig().getInt("fatigue.max", 100));
staminaManager.loadStamina(playerId, getConfig().getInt("stamina.max", 100));
int hunger = hungerManager.getHunger(playerId);
int thirst = thirstManager.getThirst(playerId);
int hungerReduction = getConfig().getInt("hunger.sleep-reduction", 50);
int thirstReduction = getConfig().getInt("thirst.sleep-reduction", 50);
hungerManager.loadHunger(playerId, Math.max(0, hunger - hungerReduction));
thirstManager.loadThirst(playerId, Math.max(0, thirst - thirstReduction));
if (canSendMessage(playerId, "fatigue")) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("fatigue.rested", "§aDu erwachst erfrischt und voller Energie!")));
player.getWorld().playSound(player.getLocation(), "entity.player.levelup", 1.0f, 1.0f);
setLastMessageTime(playerId, "fatigue");
}
}
@EventHandler
public void onPlayerBedLeave(PlayerBedLeaveEvent event) {
Player player = event.getPlayer();
player.getWorld().setTime(0); // Setze Tageszeit auf Morgen
}
@EventHandler
public void onPlayerDeath(PlayerDeathEvent event) {
Player player = event.getEntity();
UUID playerId = player.getUniqueId();
String deathCause = null;
if (hungerManager.getHunger(playerId) == 0 && getConfig().getBoolean("hunger.death-enabled", true)) {
deathCause = langConfig.getString("hunger.death", "§4Du bist verhungert!");
} else if (thirstManager.getThirst(playerId) == 0 && getConfig().getBoolean("thirst.death-enabled", true)) {
deathCause = langConfig.getString("thirst.death", "§4Du bist verdurstet!");
} else if (fatigueManager.getFatigue(playerId) == 0 && getConfig().getBoolean("fatigue.death-enabled", true)) {
deathCause = langConfig.getString("fatigue.death", "§4Du bist vor Erschöpfung zusammengebrochen!");
} else if (temperatureManager.getTemperature(playerId) == 0 && getConfig().getBoolean("temperature.death-enabled", true)) {
String biome = player.getWorld().getBiome(player.getLocation()).getKey().getKey().toUpperCase();
boolean isRaining = player.getWorld().hasStorm() && player.getLocation().getBlock().getLightFromSky() == 15;
deathCause = langConfig.getString(isRaining ? "temperature.death-rain" : (getConfig().getStringList("temperature.cold-biomes").contains(biome) ? "temperature.death-cold" : "temperature.death-hot"), "§4Deine Körpertemperatur hat dich umgebracht!");
} else if (hygieneManager.getHygiene(playerId) == 0 && getConfig().getBoolean("hygiene.death-enabled", true)) {
deathCause = langConfig.getString("hygiene.death", "§4Eine Infektion hat dich dahingerafft!");
}
if (deathCause != null) {
event.setDeathMessage(ChatColor.translateAlternateColorCodes('&', deathCause));
player.getWorld().playSound(player.getLocation(), "entity.player.death", 1.0f, 1.0f);
}
}
private void startScoreboardDisplay() {
new BukkitRunnable() {
@Override
public void run() {
for (Player player : getServer().getOnlinePlayers()) {
updatePlayerScoreboard(player);
}
}
}.runTaskTimer(this, 0L, getConfig().getLong("display.update-interval", 100)); // Alle 5 Sekunden
}
private void setupPlayerScoreboard(Player player) {
ScoreboardManager manager = getServer().getScoreboardManager();
Scoreboard scoreboard = manager.getNewScoreboard();
Objective objective = scoreboard.registerNewObjective("survival", "dummy", ChatColor.translateAlternateColorCodes('&', langConfig.getString("scoreboard.title", "&6Survival")));
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
player.setScoreboard(scoreboard);
}
private void updatePlayerScoreboard(Player player) {
UUID playerId = player.getUniqueId();
Scoreboard scoreboard = player.getScoreboard();
Objective objective = scoreboard.getObjective("survival");
if (objective == null) {
setupPlayerScoreboard(player);
scoreboard = player.getScoreboard();
objective = scoreboard.getObjective("survival");
}
// Reset previous scores
for (String entry : scoreboard.getEntries()) {
scoreboard.resetScores(entry);
}
// Get player stats
int hunger = hungerManager.getHunger(playerId);
int thirst = thirstManager.getThirst(playerId);
int fatigue = fatigueManager.getFatigue(playerId);
int temperature = temperatureManager.getTemperature(playerId);
int stamina = staminaManager.getStamina(playerId);
int vulnerability = vulnerabilityManager.getVulnerability(playerId);
int hygiene = hygieneManager.getHygiene(playerId);
int barLength = getConfig().getInt("display.bar-length", 5);
String barFilled = getConfig().getString("display.bar-filled", "");
String barEmpty = getConfig().getString("display.bar-empty", "");
String hungerColor = getConfig().getString("display.hunger-color", "§6");
String thirstColor = getConfig().getString("display.thirst-color", "§b");
String fatigueColor = getConfig().getString("display.fatigue-color", "§7");
String temperatureColor = getConfig().getString("display.temperature-color", "§c");
String staminaColor = getConfig().getString("display.stamina-color", "§a");
String vulnerabilityColor = getConfig().getString("display.vulnerability-color", "§4");
String hygieneColor = getConfig().getString("display.hygiene-color", "§9");
int mildThreshold = getConfig().getInt("display.mild-threshold", 60);
int criticalThreshold = getConfig().getInt("vulnerability.critical-threshold", 80); // Use vulnerability-specific threshold
// Get status based on thresholds
String hungerStatus = getStatus("hunger", hunger, mildThreshold, getConfig().getInt("hunger.critical-threshold", 20));
String thirstStatus = getStatus("thirst", thirst, mildThreshold, getConfig().getInt("thirst.critical-threshold", 20));
String fatigueStatus = getStatus("fatigue", fatigue, mildThreshold, getConfig().getInt("fatigue.critical-threshold", 20));
String temperatureStatus = getTemperatureStatus(temperature, mildThreshold, getConfig().getInt("temperature.critical-threshold", 20));
String staminaStatus = getStatus("stamina", stamina, mildThreshold, getConfig().getInt("stamina.critical-threshold", 20));
String vulnerabilityStatus = getVulnerabilityStatus(vulnerability, mildThreshold, criticalThreshold);
String hygieneStatus = getStatus("hygiene", hygiene, mildThreshold, getConfig().getInt("hygiene.critical-threshold", 20));
// Set scores
String[] entries = new String[] {
"§r", // Leerzeile
hungerColor + langConfig.getString("scoreboard.hunger", "HP") + ": " + getProgressBar(hunger, 100, barLength, barFilled, barEmpty) + " " + hungerStatus,
thirstColor + langConfig.getString("scoreboard.thirst", "TH") + ": " + getProgressBar(thirst, 100, barLength, barFilled, barEmpty) + " " + thirstStatus,
"§r ", // Leerzeile
fatigueColor + langConfig.getString("scoreboard.fatigue", "FT") + ": " + getProgressBar(fatigue, 100, barLength, barFilled, barEmpty) + " " + fatigueStatus,
temperatureColor + langConfig.getString("scoreboard.temperature", "TP") + ": " + getProgressBar(temperature, 100, barLength, barFilled, barEmpty) + " " + temperatureStatus,
"§r ", // Leerzeile
staminaColor + langConfig.getString("scoreboard.stamina", "ST") + ": " + getProgressBar(stamina, 100, barLength, barFilled, barEmpty) + " " + staminaStatus,
vulnerabilityColor + langConfig.getString("scoreboard.vulnerability", "VL") + ": " + getProgressBar(vulnerability, 100, barLength, barFilled, barEmpty) + " " + vulnerabilityStatus,
hygieneColor + langConfig.getString("scoreboard.hygiene", "HY") + ": " + getProgressBar(hygiene, 100, barLength, barFilled, barEmpty) + " " + hygieneStatus
};
for (int i = 0; i < entries.length; i++) {
String entry = ChatColor.translateAlternateColorCodes('&', entries[i]);
if (entry.length() > 40) {
entry = entry.substring(0, 40); // Scoreboard-Zeilen sind auf 40 Zeichen begrenzt
}
Score score = objective.getScore(entry);
score.setScore(entries.length - i); // Höhere Werte oben
}
}
private String getProgressBar(int current, int max, int totalBars, String filled, String empty) {
int filledBars = (int) ((double) current / max * totalBars);
int emptyBars = totalBars - filledBars;
StringBuilder bar = new StringBuilder();
for (int i = 0; i < filledBars; i++) {
bar.append(filled);
}
for (int i = 0; i < emptyBars; i++) {
bar.append(empty);
}
return bar.toString();
}
private String getStatus(String mechanic, int value, int mildThreshold, int criticalThreshold) {
String statusKey;
if (value >= mildThreshold) {
statusKey = mechanic + ".status.full";
} else if (value > criticalThreshold) {
statusKey = mechanic + ".status.mild";
} else if (value > 0) {
statusKey = mechanic + ".status." + (mechanic.equals("hygiene") ? "dirty" : "tired");
} else {
statusKey = mechanic + ".status." + (mechanic.equals("hunger") ? "starving" : mechanic.equals("thirst") ? "dehydrated" : mechanic.equals("fatigue") ? "exhausted" : mechanic.equals("stamina") ? "exhausted" : "critical");
}
return ChatColor.translateAlternateColorCodes('&', langConfig.getString(statusKey, ""));
}
private String getTemperatureStatus(int value, int mildThreshold, int criticalThreshold) {
String statusKey;
if (value >= 40 && value <= 60) {
statusKey = "temperature.status.full";
} else if (value > 60) {
statusKey = value >= criticalThreshold + 60 ? "temperature.status.critical" : "temperature.status.hot";
} else {
statusKey = value <= criticalThreshold ? "temperature.status.critical" : "temperature.status.cold";
}
return ChatColor.translateAlternateColorCodes('&', langConfig.getString(statusKey, ""));
}
private String getVulnerabilityStatus(int value, int mildThreshold, int criticalThreshold) {
String statusKey;
if (value >= criticalThreshold) {
statusKey = "vulnerability.status.critical";
} else if (value > mildThreshold) {
statusKey = "vulnerability.status.injured";
} else if (value > getConfig().getInt("display.critical-threshold", 20)) {
statusKey = "vulnerability.status.mild";
} else {
statusKey = "vulnerability.status.full";
}
return ChatColor.translateAlternateColorCodes('&', langConfig.getString(statusKey, ""));
}
public boolean canSendMessage(UUID playerId, String mechanic) {
long currentTime = System.currentTimeMillis();
long lastTime = langConfig.getLong("last-message." + mechanic + "." + playerId, 0L);
return (currentTime - lastTime) / 1000 >= getConfig().getInt(mechanic + ".message-cooldown", 60);
}
public void setLastMessageTime(UUID playerId, String mechanic) {
langConfig.set("last-message." + mechanic + "." + playerId, System.currentTimeMillis());
try {
langConfig.save(new File(getDataFolder(), "lang.yml"));
} catch (IOException e) {
getLogger().severe("Fehler beim Speichern von lang.yml: " + e.getMessage());
}
}
public HungerManager getHungerManager() {
return hungerManager;
}
public ThirstManager getThirstManager() {
return thirstManager;
}
public FatigueManager getFatigueManager() {
return fatigueManager;
}
public TemperatureManager getTemperatureManager() {
return temperatureManager;
}
public StaminaManager getStaminaManager() {
return staminaManager;
}
public VulnerabilityManager getVulnerabilityManager() {
return vulnerabilityManager;
}
public HygieneManager getHygieneManager() {
return hygieneManager;
}
public FileConfiguration getLangConfig() {
return langConfig;
}
}

View File

@@ -0,0 +1,147 @@
package me.viper.survivalmechanics.mechanics;
import me.viper.survivalmechanics.SurvivalMechanics;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.ChatColor;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class FatigueManager implements Listener {
private final JavaPlugin plugin;
private final Map<UUID, Integer> fatigueLevels = new HashMap<>();
private final Map<UUID, BukkitTask> deathTimers = new HashMap<>();
private final int maxFatigue;
private final double decreaseRate;
private final double activityMultiplier;
private final double nightMultiplier;
private final double climbingMultiplier;
private final int climbingHeightThreshold;
private final double climbingHeightScaling;
private final int slownessDuration;
private final int slownessAmplifier;
private final int blurDuration;
private final int blurAmplifier;
private final double staminaPenalty;
private final int criticalThreshold;
private final boolean deathEnabled;
private final int deathDelay;
private final int messageCooldown;
private final boolean criticalMessageOnly;
public FatigueManager(JavaPlugin plugin) {
this.plugin = plugin;
this.maxFatigue = plugin.getConfig().getInt("fatigue.max", 100);
this.decreaseRate = plugin.getConfig().getDouble("fatigue.decrease-rate", 0.5);
this.activityMultiplier = plugin.getConfig().getDouble("fatigue.activity-multiplier", 2);
this.nightMultiplier = plugin.getConfig().getDouble("fatigue.night-multiplier", 2);
this.climbingMultiplier = plugin.getConfig().getDouble("fatigue.climbing-multiplier", 2);
this.climbingHeightThreshold = plugin.getConfig().getInt("fatigue.climbing-height-threshold", 100);
this.climbingHeightScaling = plugin.getConfig().getDouble("fatigue.climbing-height-scaling", 0.01);
this.slownessDuration = plugin.getConfig().getInt("fatigue.slowness-duration", 200);
this.slownessAmplifier = plugin.getConfig().getInt("fatigue.slowness-amplifier", 1);
this.blurDuration = plugin.getConfig().getInt("fatigue.blur-duration", 100);
this.blurAmplifier = plugin.getConfig().getInt("fatigue.blur-amplifier", 1);
this.staminaPenalty = plugin.getConfig().getDouble("fatigue.stamina-penalty", 1.5);
this.criticalThreshold = plugin.getConfig().getInt("fatigue.critical-threshold", 20);
this.deathEnabled = plugin.getConfig().getBoolean("fatigue.death-enabled", true);
this.deathDelay = plugin.getConfig().getInt("fatigue.death-delay", 60);
this.messageCooldown = plugin.getConfig().getInt("fatigue.message-cooldown", 60);
this.criticalMessageOnly = plugin.getConfig().getBoolean("fatigue.critical-message-only", true);
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
public void startFatigueTask() {
new BukkitRunnable() {
@Override
public void run() {
for (Player player : plugin.getServer().getOnlinePlayers()) {
UUID playerId = player.getUniqueId();
int fatigue = fatigueLevels.getOrDefault(playerId, maxFatigue);
double decrease = decreaseRate;
long time = player.getWorld().getTime();
boolean isNight = time >= 12000 && time < 24000;
if (isNight) {
decrease *= nightMultiplier;
}
if (player.isSprinting() || player.isSwimming()) {
decrease *= activityMultiplier;
}
fatigue = Math.max(0, fatigue - (int) decrease);
fatigueLevels.put(playerId, fatigue);
if (fatigue <= criticalThreshold && fatigue > 0) {
player.addPotionEffect(new PotionEffect(PotionEffectType.SLOWNESS, slownessDuration, slownessAmplifier));
player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, blurDuration, blurAmplifier));
if (canSendMessage(playerId)) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("fatigue.critical", "§7Du kannst dich kaum wach halten!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
} else if (fatigue == 0 && deathEnabled && !deathTimers.containsKey(playerId)) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("fatigue.warning", "§4Deine Erschöpfung wird dich umbringen!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
deathTimers.put(playerId, new BukkitRunnable() {
@Override
public void run() {
if (fatigueLevels.getOrDefault(playerId, maxFatigue) == 0) {
player.setHealth(0);
}
deathTimers.remove(playerId);
}
}.runTaskLater(plugin, 20L * deathDelay));
} else if (fatigue >= maxFatigue && canSendMessage(playerId) && !criticalMessageOnly) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("fatigue.rested", "§aDu erwachst erholt und voller Kraft!")));
player.getWorld().playSound(player.getLocation(), "entity.player.levelup", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
}
}
}.runTaskTimer(plugin, 0L, 20L * 60); // Alle 60 Sekunden
}
@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
Player player = event.getPlayer();
UUID playerId = player.getUniqueId();
int fatigue = fatigueLevels.getOrDefault(playerId, maxFatigue);
if (player.isClimbing() && player.getLocation().getY() > climbingHeightThreshold) {
double heightFactor = 1 + ((player.getLocation().getY() - climbingHeightThreshold) * climbingHeightScaling);
fatigue = Math.max(0, fatigue - (int) (decreaseRate * climbingMultiplier * heightFactor));
fatigueLevels.put(playerId, fatigue);
if (fatigue <= criticalThreshold && fatigue > 0 && canSendMessage(playerId)) {
player.addPotionEffect(new PotionEffect(PotionEffectType.SLOWNESS, slownessDuration, slownessAmplifier));
player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, blurDuration, blurAmplifier));
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("fatigue.critical", "§7Du kannst dich kaum wach halten!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
}
((SurvivalMechanics) plugin).getStaminaManager().applyFatiguePenalty(playerId, staminaPenalty);
}
private boolean canSendMessage(UUID playerId) {
return ((SurvivalMechanics) plugin).canSendMessage(playerId, "fatigue");
}
private void setLastMessageTime(UUID playerId) {
((SurvivalMechanics) plugin).setLastMessageTime(playerId, "fatigue");
}
public int getFatigue(UUID playerId) {
return fatigueLevels.getOrDefault(playerId, maxFatigue);
}
public void loadFatigue(UUID playerId, int fatigue) {
fatigueLevels.put(playerId, fatigue);
}
}

View File

@@ -0,0 +1,185 @@
package me.viper.survivalmechanics.mechanics;
import me.viper.survivalmechanics.SurvivalMechanics;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerToggleSprintEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.Material;
import org.bukkit.ChatColor;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.List;
public class HungerManager implements Listener {
private final JavaPlugin plugin;
private final Map<UUID, Integer> hungerLevels = new HashMap<>();
private final Map<UUID, BukkitTask> deathTimers = new HashMap<>();
private final int maxHunger;
private final double decreaseRate;
private final double sprintMultiplier;
private final double combatMultiplier;
private final double nightMultiplier;
private final int sleepReduction;
private final double damage;
private final int criticalThreshold;
private final boolean deathEnabled;
private final int deathDelay;
private final List<String> foodItems;
private final int foodRecoveryRate;
private final boolean particleEffect;
private final int messageCooldown;
private final boolean criticalMessageOnly;
public HungerManager(JavaPlugin plugin) {
this.plugin = plugin;
this.maxHunger = plugin.getConfig().getInt("hunger.max", 100);
this.decreaseRate = plugin.getConfig().getDouble("hunger.decrease-rate", 0.5);
this.sprintMultiplier = plugin.getConfig().getDouble("hunger.sprint-multiplier", 2);
this.combatMultiplier = plugin.getConfig().getDouble("hunger.combat-multiplier", 3);
this.nightMultiplier = plugin.getConfig().getDouble("hunger.night-multiplier", 1.5);
this.sleepReduction = plugin.getConfig().getInt("hunger.sleep-reduction", 50);
this.damage = plugin.getConfig().getDouble("hunger.damage", 0.5);
this.criticalThreshold = plugin.getConfig().getInt("hunger.critical-threshold", 20);
this.deathEnabled = plugin.getConfig().getBoolean("hunger.death-enabled", true);
this.deathDelay = plugin.getConfig().getInt("hunger.death-delay", 60);
this.foodItems = plugin.getConfig().getStringList("hunger.food-items");
this.foodRecoveryRate = plugin.getConfig().getInt("hunger.food-recovery-rate", 20);
this.particleEffect = plugin.getConfig().getBoolean("hunger.particle-effect", true);
this.messageCooldown = plugin.getConfig().getInt("hunger.message-cooldown", 60);
this.criticalMessageOnly = plugin.getConfig().getBoolean("hunger.critical-message-only", true);
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
public void startHungerTask() {
new BukkitRunnable() {
@Override
public void run() {
for (Player player : plugin.getServer().getOnlinePlayers()) {
UUID playerId = player.getUniqueId();
int hunger = hungerLevels.getOrDefault(playerId, maxHunger);
double decrease = decreaseRate;
long time = player.getWorld().getTime();
boolean isNight = time >= 12000 && time < 24000;
if (isNight) {
decrease *= nightMultiplier;
}
hunger = Math.max(0, hunger - (int) decrease);
hungerLevels.put(playerId, hunger);
if (hunger <= criticalThreshold && hunger > 0) {
player.damage(damage);
if (canSendMessage(playerId)) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("hunger.critical", "§4Dein Körper schwächt durch Hunger!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
} else if (hunger == 0 && deathEnabled && !deathTimers.containsKey(playerId)) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("hunger.warning", "§4Du bist dem Verhungern nahe!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
deathTimers.put(playerId, new BukkitRunnable() {
@Override
public void run() {
if (hungerLevels.getOrDefault(playerId, maxHunger) == 0) {
player.setHealth(0);
}
deathTimers.remove(playerId);
}
}.runTaskLater(plugin, 20L * deathDelay));
} else if (hunger >= maxHunger && canSendMessage(playerId) && !criticalMessageOnly) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("hunger.fed", "§aDu fühlst dich satt und gestärkt!")));
player.getWorld().playSound(player.getLocation(), "entity.player.levelup", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
}
}
}.runTaskTimer(plugin, 0L, 20L * 60); // Alle 60 Sekunden
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
UUID playerId = player.getUniqueId();
if (event.hasItem() && foodItems.contains(event.getItem().getType().toString())) {
int hunger = hungerLevels.getOrDefault(playerId, maxHunger);
hunger = Math.min(maxHunger, hunger + foodRecoveryRate);
hungerLevels.put(playerId, hunger);
event.getItem().setAmount(event.getItem().getAmount() - 1);
if (particleEffect) {
player.getWorld().spawnParticle(org.bukkit.Particle.HEART, player.getLocation().add(0, 1, 0), 5);
}
if (canSendMessage(playerId) && !criticalMessageOnly) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("hunger.fed", "§aDu fühlst dich satt und gestärkt!")));
player.getWorld().playSound(player.getLocation(), "entity.player.levelup", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
if (deathTimers.containsKey(playerId)) {
deathTimers.get(playerId).cancel();
deathTimers.remove(playerId);
}
}
}
@EventHandler
public void onPlayerToggleSprint(PlayerToggleSprintEvent event) {
if (event.isSprinting()) {
Player player = event.getPlayer();
UUID playerId = player.getUniqueId();
int hunger = hungerLevels.getOrDefault(playerId, maxHunger);
hunger = Math.max(0, hunger - (int) (decreaseRate * sprintMultiplier));
hungerLevels.put(playerId, hunger);
if (hunger <= criticalThreshold && hunger > 0 && canSendMessage(playerId)) {
player.damage(damage);
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("hunger.critical", "§4Dein Körper schwächt durch Hunger!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
}
}
@EventHandler
public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
if (event.getEntity() instanceof Player) {
Player player = (Player) event.getEntity();
UUID playerId = player.getUniqueId();
int hunger = hungerLevels.getOrDefault(playerId, maxHunger);
hunger = Math.max(0, hunger - (int) (decreaseRate * combatMultiplier));
hungerLevels.put(playerId, hunger);
if (hunger <= criticalThreshold && hunger > 0 && canSendMessage(playerId)) {
player.damage(damage);
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("hunger.critical", "§4Dein Körper schwächt durch Hunger!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
}
}
private boolean canSendMessage(UUID playerId) {
return ((SurvivalMechanics) plugin).canSendMessage(playerId, "hunger");
}
private void setLastMessageTime(UUID playerId) {
((SurvivalMechanics) plugin).setLastMessageTime(playerId, "hunger");
}
public int getHunger(UUID playerId) {
return hungerLevels.getOrDefault(playerId, maxHunger);
}
public void loadHunger(UUID playerId, int hunger) {
hungerLevels.put(playerId, hunger);
}
public List<String> getFoodItems() {
return foodItems;
}
}

View File

@@ -0,0 +1,179 @@
package me.viper.survivalmechanics.mechanics;
import me.viper.survivalmechanics.SurvivalMechanics;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.Material;
import org.bukkit.ChatColor;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.List;
public class HygieneManager implements Listener {
private final JavaPlugin plugin;
private final Map<UUID, Integer> hygieneLevels = new HashMap<>();
private final Map<UUID, BukkitTask> deathTimers = new HashMap<>();
private final int maxHygiene;
private final double decreaseRate;
private final List<String> dirtyBiomes;
private final double diggingMultiplier;
private final double climbingMultiplier;
private final int climbingHeightThreshold;
private final double climbingHeightScaling;
private final double vulnerabilityExhaustionMultiplier;
private final double recoveryRate;
private final double waterRecoveryRate;
private final int weaknessDuration;
private final int weaknessAmplifier;
private final int criticalThreshold;
private final boolean deathEnabled;
private final int deathDelay;
private final int messageCooldown;
private final boolean criticalMessageOnly;
public HygieneManager(JavaPlugin plugin) {
this.plugin = plugin;
this.maxHygiene = plugin.getConfig().getInt("hygiene.max", 100);
this.decreaseRate = plugin.getConfig().getDouble("hygiene.decrease-rate", 0.5);
this.dirtyBiomes = plugin.getConfig().getStringList("hygiene.dirty-biomes");
this.diggingMultiplier = plugin.getConfig().getDouble("hygiene.digging-multiplier", 3);
this.climbingMultiplier = plugin.getConfig().getDouble("hygiene.climbing-multiplier", 2);
this.climbingHeightThreshold = plugin.getConfig().getInt("hygiene.climbing-height-threshold", 100);
this.climbingHeightScaling = plugin.getConfig().getDouble("hygiene.climbing-height-scaling", 0.01);
this.vulnerabilityExhaustionMultiplier = plugin.getConfig().getDouble("hygiene.vulnerability-exhaustion-multiplier", 2);
this.recoveryRate = plugin.getConfig().getDouble("hygiene.recovery-rate", 1);
this.waterRecoveryRate = plugin.getConfig().getDouble("hygiene.water-recovery-rate", 5);
this.weaknessDuration = plugin.getConfig().getInt("hygiene.weakness-duration", 200);
this.weaknessAmplifier = plugin.getConfig().getInt("hygiene.weakness-amplifier", 1);
this.criticalThreshold = plugin.getConfig().getInt("hygiene.critical-threshold", 20);
this.deathEnabled = plugin.getConfig().getBoolean("hygiene.death-enabled", true);
this.deathDelay = plugin.getConfig().getInt("hygiene.death-delay", 60);
this.messageCooldown = plugin.getConfig().getInt("hygiene.message-cooldown", 60);
this.criticalMessageOnly = plugin.getConfig().getBoolean("hygiene.critical-message-only", true);
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
public void startHygieneTask() {
new BukkitRunnable() {
@Override
public void run() {
for (Player player : plugin.getServer().getOnlinePlayers()) {
UUID playerId = player.getUniqueId();
int hygiene = hygieneLevels.getOrDefault(playerId, maxHygiene);
int vulnerability = ((SurvivalMechanics) plugin).getVulnerabilityManager().getVulnerability(playerId);
String biome = player.getWorld().getBiome(player.getLocation()).getKey().getKey().toUpperCase();
double decrease = decreaseRate;
if (dirtyBiomes.contains(biome)) {
decrease *= 2;
}
if (vulnerability > plugin.getConfig().getInt("vulnerability.critical-threshold", 80)) {
decrease *= vulnerabilityExhaustionMultiplier;
}
hygiene = Math.max(0, hygiene - (int) decrease);
hygieneLevels.put(playerId, hygiene);
if (hygiene <= criticalThreshold && hygiene > 0) {
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS, weaknessDuration, weaknessAmplifier));
if (canSendMessage(playerId)) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("hygiene.critical", "§4Schmutz und Gestank machen dich krank!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
} else if (hygiene == 0 && deathEnabled && !deathTimers.containsKey(playerId)) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("hygiene.warning", "§4Eine Infektion droht dich zu töten!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
deathTimers.put(playerId, new BukkitRunnable() {
@Override
public void run() {
if (hygieneLevels.getOrDefault(playerId, maxHygiene) == 0) {
player.setHealth(0);
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("hygiene.death", "§4Eine Infektion hat dein Leben beendet!")));
}
deathTimers.remove(playerId);
}
}.runTaskLater(plugin, 20L * deathDelay));
} else if (hygiene >= maxHygiene && canSendMessage(playerId) && !criticalMessageOnly) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("hygiene.clean", "§aDu fühlst dich sauber und wohl!")));
player.getWorld().playSound(player.getLocation(), "entity.player.levelup", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
}
}
}.runTaskTimer(plugin, 0L, 20L * 60); // Alle 60 Sekunden
}
@EventHandler
public void onBlockBreak(BlockBreakEvent event) {
Player player = event.getPlayer();
UUID playerId = player.getUniqueId();
Material blockType = event.getBlock().getType();
if (blockType == Material.DIRT || blockType == Material.GRASS_BLOCK) {
int hygiene = hygieneLevels.getOrDefault(playerId, maxHygiene);
hygiene = Math.max(0, hygiene - (int) (decreaseRate * diggingMultiplier));
hygieneLevels.put(playerId, hygiene);
if (hygiene <= criticalThreshold && hygiene > 0 && canSendMessage(playerId)) {
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS, weaknessDuration, weaknessAmplifier));
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("hygiene.critical", "§4Schmutz und Gestank machen dich krank!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
}
}
@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
Player player = event.getPlayer();
UUID playerId = player.getUniqueId();
int hygiene = hygieneLevels.getOrDefault(playerId, maxHygiene);
if (player.getLocation().getBlock().isLiquid()) {
hygiene = Math.min(maxHygiene, hygiene + (int) waterRecoveryRate);
hygieneLevels.put(playerId, hygiene);
if (hygiene >= maxHygiene && canSendMessage(playerId) && !criticalMessageOnly) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("hygiene.clean", "§aDu fühlst dich sauber und wohl!")));
player.getWorld().playSound(player.getLocation(), "entity.player.levelup", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
if (deathTimers.containsKey(playerId)) {
deathTimers.get(playerId).cancel();
deathTimers.remove(playerId);
}
} else if (player.isClimbing() && player.getLocation().getY() > climbingHeightThreshold) {
double heightFactor = 1 + ((player.getLocation().getY() - climbingHeightThreshold) * climbingHeightScaling);
hygiene = Math.max(0, hygiene - (int) (decreaseRate * climbingMultiplier * heightFactor));
hygieneLevels.put(playerId, hygiene);
if (hygiene <= criticalThreshold && hygiene > 0 && canSendMessage(playerId)) {
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS, weaknessDuration, weaknessAmplifier));
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("hygiene.critical", "§4Schmutz und Gestank machen dich krank!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
}
}
private boolean canSendMessage(UUID playerId) {
return ((SurvivalMechanics) plugin).canSendMessage(playerId, "hygiene");
}
private void setLastMessageTime(UUID playerId) {
((SurvivalMechanics) plugin).setLastMessageTime(playerId, "hygiene");
}
public int getHygiene(UUID playerId) {
return hygieneLevels.getOrDefault(playerId, maxHygiene);
}
public void loadHygiene(UUID playerId, int hygiene) {
hygieneLevels.put(playerId, hygiene);
}
}

View File

@@ -0,0 +1,182 @@
package me.viper.survivalmechanics.mechanics;
import me.viper.survivalmechanics.SurvivalMechanics;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerToggleSprintEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.ChatColor;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class StaminaManager implements Listener {
private final JavaPlugin plugin;
private final Map<UUID, Integer> staminaLevels = new HashMap<>();
private final int maxStamina;
private final double decreaseRate;
private final double sprintMultiplier;
private final double jumpMultiplier;
private final double combatMultiplier;
private final double climbingMultiplier;
private final int climbingHeightThreshold;
private final double climbingHeightScaling;
private final double regenRate;
private final double hungerThirstPenalty;
private final double fatiguePenalty;
private final double vulnerabilityStaminaPenalty;
private final double staminaVulnerabilityIncrease;
private final int criticalThreshold;
private final int minToSprint;
private final int messageCooldown;
private final boolean criticalMessageOnly;
public StaminaManager(JavaPlugin plugin) {
this.plugin = plugin;
this.maxStamina = plugin.getConfig().getInt("stamina.max", 100);
this.decreaseRate = plugin.getConfig().getDouble("stamina.decrease-rate", 1);
this.sprintMultiplier = plugin.getConfig().getDouble("stamina.sprint-multiplier", 3);
this.jumpMultiplier = plugin.getConfig().getDouble("stamina.jump-multiplier", 2);
this.combatMultiplier = plugin.getConfig().getDouble("stamina.combat-multiplier", 4);
this.climbingMultiplier = plugin.getConfig().getDouble("stamina.climbing-multiplier", 2);
this.climbingHeightThreshold = plugin.getConfig().getInt("stamina.climbing-height-threshold", 100);
this.climbingHeightScaling = plugin.getConfig().getDouble("stamina.climbing-height-scaling", 0.01);
this.regenRate = plugin.getConfig().getDouble("stamina.regen-rate", 2);
this.hungerThirstPenalty = plugin.getConfig().getDouble("stamina.hunger-thirst-penalty", 0.5);
this.fatiguePenalty = plugin.getConfig().getDouble("stamina.fatigue-penalty", 0.5);
this.vulnerabilityStaminaPenalty = plugin.getConfig().getDouble("stamina.vulnerability-stamina-penalty", 0.7);
this.staminaVulnerabilityIncrease = plugin.getConfig().getDouble("stamina.stamina-vulnerability-increase", 2);
this.criticalThreshold = plugin.getConfig().getInt("stamina.critical-threshold", 20);
this.minToSprint = plugin.getConfig().getInt("stamina.min-to-sprint", 20);
this.messageCooldown = plugin.getConfig().getInt("stamina.message-cooldown", 60);
this.criticalMessageOnly = plugin.getConfig().getBoolean("stamina.critical-message-only", true);
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
public void startStaminaTask() {
new BukkitRunnable() {
@Override
public void run() {
for (Player player : plugin.getServer().getOnlinePlayers()) {
UUID playerId = player.getUniqueId();
int stamina = staminaLevels.getOrDefault(playerId, maxStamina);
int hunger = ((SurvivalMechanics) plugin).getHungerManager().getHunger(playerId);
int thirst = ((SurvivalMechanics) plugin).getThirstManager().getThirst(playerId);
int fatigue = ((SurvivalMechanics) plugin).getFatigueManager().getFatigue(playerId);
double regen = regenRate;
if (hunger < criticalThreshold || thirst < criticalThreshold) {
regen *= hungerThirstPenalty;
}
if (fatigue < criticalThreshold) {
regen *= fatiguePenalty;
}
stamina = Math.min(maxStamina, stamina + (int) regen);
staminaLevels.put(playerId, stamina);
if (stamina <= criticalThreshold && canSendMessage(playerId)) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("stamina.critical-sprint", "§4Du bist zu schwach, um zu sprinten!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
}
}
}.runTaskTimer(plugin, 0L, 20L * 60); // Alle 60 Sekunden
}
@EventHandler
public void onPlayerToggleSprint(PlayerToggleSprintEvent event) {
Player player = event.getPlayer();
UUID playerId = player.getUniqueId();
int stamina = staminaLevels.getOrDefault(playerId, maxStamina);
if (event.isSprinting() && stamina < minToSprint) {
event.setCancelled(true);
if (canSendMessage(playerId)) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("stamina.critical-sprint", "§4Du bist zu schwach, um zu sprinten!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
} else if (event.isSprinting()) {
stamina = Math.max(0, stamina - (int) (decreaseRate * sprintMultiplier));
staminaLevels.put(playerId, stamina);
applyVulnerabilityIncrease(playerId);
}
}
@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
Player player = event.getPlayer();
UUID playerId = player.getUniqueId();
int stamina = staminaLevels.getOrDefault(playerId, maxStamina);
if (player.getVelocity().getY() > 0 && !player.isOnGround()) {
stamina = Math.max(0, stamina - (int) (decreaseRate * jumpMultiplier));
staminaLevels.put(playerId, stamina);
if (stamina <= criticalThreshold && canSendMessage(playerId)) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("stamina.critical-jump", "§4Du bist zu schwach, um zu springen!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
applyVulnerabilityIncrease(playerId);
} else if (player.isClimbing() && player.getLocation().getY() > climbingHeightThreshold) {
double heightFactor = 1 + ((player.getLocation().getY() - climbingHeightThreshold) * climbingHeightScaling);
stamina = Math.max(0, stamina - (int) (decreaseRate * climbingMultiplier * heightFactor));
staminaLevels.put(playerId, stamina);
if (stamina <= criticalThreshold && canSendMessage(playerId)) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("climbing.critical", "§4Das Klettern zehrt an deinen Kräften!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
applyVulnerabilityIncrease(playerId);
}
}
@EventHandler
public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
if (event.getEntity() instanceof Player) {
Player player = (Player) event.getEntity();
UUID playerId = player.getUniqueId();
int stamina = staminaLevels.getOrDefault(playerId, maxStamina);
stamina = Math.max(0, stamina - (int) (decreaseRate * combatMultiplier));
staminaLevels.put(playerId, stamina);
if (stamina <= criticalThreshold && canSendMessage(playerId)) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("stamina.critical-combat", "§4Du bist zu schwach, um zu kämpfen!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
applyVulnerabilityIncrease(playerId);
}
}
public void applyFatiguePenalty(UUID playerId, double penalty) {
int stamina = staminaLevels.getOrDefault(playerId, maxStamina);
stamina = Math.max(0, stamina - (int) (decreaseRate * penalty));
staminaLevels.put(playerId, stamina);
}
private void applyVulnerabilityIncrease(UUID playerId) {
int stamina = staminaLevels.getOrDefault(playerId, maxStamina);
if (stamina <= criticalThreshold) {
((SurvivalMechanics) plugin).getVulnerabilityManager().increaseVulnerability(playerId, (int) staminaVulnerabilityIncrease);
}
}
private boolean canSendMessage(UUID playerId) {
return ((SurvivalMechanics) plugin).canSendMessage(playerId, "stamina");
}
private void setLastMessageTime(UUID playerId) {
((SurvivalMechanics) plugin).setLastMessageTime(playerId, "stamina");
}
public int getStamina(UUID playerId) {
return staminaLevels.getOrDefault(playerId, maxStamina);
}
public void loadStamina(UUID playerId, int stamina) {
staminaLevels.put(playerId, stamina);
}
}

View File

@@ -0,0 +1,196 @@
package me.viper.survivalmechanics.mechanics;
import me.viper.survivalmechanics.SurvivalMechanics;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.ChatColor;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.List;
public class TemperatureManager implements Listener {
private final JavaPlugin plugin;
private final Map<UUID, Integer> temperatureLevels = new HashMap<>();
private final Map<UUID, BukkitTask> deathTimers = new HashMap<>();
private final int maxTemperature;
private final double decreaseRate;
private final List<String> coldBiomes;
private final List<String> hotBiomes;
private final double coldDamage;
private final double hotDamage;
private final int warmthRadius;
private final double rainCoolRate;
private final double rainMultiplier;
private final double nightColdMultiplier;
private final int criticalThreshold;
private final boolean deathEnabled;
private final int deathDelay;
private final int messageCooldown;
private final boolean criticalMessageOnly;
public TemperatureManager(JavaPlugin plugin) {
this.plugin = plugin;
this.maxTemperature = plugin.getConfig().getInt("temperature.max", 100);
this.decreaseRate = plugin.getConfig().getDouble("temperature.decrease-rate", 1);
this.coldBiomes = plugin.getConfig().getStringList("temperature.cold-biomes");
this.hotBiomes = plugin.getConfig().getStringList("temperature.hot-biomes");
this.coldDamage = plugin.getConfig().getDouble("temperature.cold-damage", 0.5);
this.hotDamage = plugin.getConfig().getDouble("temperature.hot-damage", 0.5);
this.warmthRadius = plugin.getConfig().getInt("temperature.warmth-radius", 5);
this.rainCoolRate = plugin.getConfig().getDouble("temperature.rain-cool-rate", 2);
this.rainMultiplier = plugin.getConfig().getDouble("temperature.rain-multiplier", 1.5);
this.nightColdMultiplier = plugin.getConfig().getDouble("temperature.night-cold-multiplier", 1.5);
this.criticalThreshold = plugin.getConfig().getInt("temperature.critical-threshold", 20);
this.deathEnabled = plugin.getConfig().getBoolean("temperature.death-enabled", true);
this.deathDelay = plugin.getConfig().getInt("temperature.death-delay", 60);
this.messageCooldown = plugin.getConfig().getInt("temperature.message-cooldown", 60);
this.criticalMessageOnly = plugin.getConfig().getBoolean("temperature.critical-message-only", true);
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
public void startTemperatureTask() {
new BukkitRunnable() {
@Override
public void run() {
for (Player player : plugin.getServer().getOnlinePlayers()) {
UUID playerId = player.getUniqueId();
int temperature = temperatureLevels.getOrDefault(playerId, maxTemperature);
int hygiene = ((SurvivalMechanics) plugin).getHygieneManager().getHygiene(playerId);
double decrease = decreaseRate;
String biome = player.getWorld().getBiome(player.getLocation()).getKey().getKey().toUpperCase();
long time = player.getWorld().getTime();
boolean isNight = time >= 12000 && time < 24000;
boolean isRaining = player.getWorld().hasStorm() && player.getLocation().getBlock().getLightFromSky() == 15;
if (hotBiomes.contains(biome)) {
temperature = Math.min(maxTemperature, temperature + (int) decrease);
if (temperature <= criticalThreshold && temperature > 0) {
player.damage(hotDamage);
if (canSendMessage(playerId)) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("temperature.critical-hot", "§4Die Hitze überwältigt dich!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
} else if (temperature == 0 && deathEnabled && !deathTimers.containsKey(playerId)) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("temperature.warning-hot", "§4Die Hitze wird dich bald töten!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
deathTimers.put(playerId, new BukkitRunnable() {
@Override
public void run() {
if (temperatureLevels.getOrDefault(playerId, maxTemperature) == 0) {
player.setHealth(0);
}
deathTimers.remove(playerId);
}
}.runTaskLater(plugin, 20L * deathDelay));
}
} else if (coldBiomes.contains(biome)) {
decrease *= isNight ? nightColdMultiplier : 1;
temperature = Math.max(0, temperature - (int) decrease);
if (temperature <= criticalThreshold && temperature > 0) {
player.damage(coldDamage);
if (canSendMessage(playerId)) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("temperature.critical-cold", "§4Du zitterst unkontrollierbar!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
} else if (temperature == 0 && deathEnabled && !deathTimers.containsKey(playerId)) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("temperature.warning-cold", "§4Die Kälte wird dich bald töten!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
deathTimers.put(playerId, new BukkitRunnable() {
@Override
public void run() {
if (temperatureLevels.getOrDefault(playerId, maxTemperature) == 0) {
player.setHealth(0);
}
deathTimers.remove(playerId);
}
}.runTaskLater(plugin, 20L * deathDelay));
}
} else if (isRaining) {
decrease *= rainMultiplier;
temperature = Math.max(0, temperature - (int) (decrease + rainCoolRate));
if (temperature <= criticalThreshold && temperature > 0) {
player.damage(coldDamage);
if (canSendMessage(playerId)) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("temperature.rain", "§4Der Regen lässt dich erfrieren!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
} else if (temperature == 0 && deathEnabled && !deathTimers.containsKey(playerId)) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("temperature.warning-rain", "§4Der Regen wird dich unterkühlen!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
deathTimers.put(playerId, new BukkitRunnable() {
@Override
public void run() {
if (temperatureLevels.getOrDefault(playerId, maxTemperature) == 0) {
player.setHealth(0);
}
deathTimers.remove(playerId);
}
}.runTaskLater(plugin, 20L * deathDelay));
}
} else {
int recovery = hygiene < ((SurvivalMechanics) plugin).getConfig().getInt("hygiene.critical-threshold", 20) ? 1 : 2;
if (temperature > maxTemperature / 2) {
temperature = Math.max(maxTemperature / 2, temperature - recovery);
} else if (temperature < maxTemperature / 2) {
temperature = Math.min(maxTemperature / 2, temperature + recovery);
}
}
temperatureLevels.put(playerId, temperature);
if (temperature >= maxTemperature && canSendMessage(playerId) && !criticalMessageOnly) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("temperature.comfortable", "§aDeine Körpertemperatur fühlt sich gut an!")));
player.getWorld().playSound(player.getLocation(), "entity.player.levelup", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
}
}
}.runTaskTimer(plugin, 0L, 20L * 60); // Alle 60 Sekunden
}
@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
Player player = event.getPlayer();
UUID playerId = player.getUniqueId();
int temperature = temperatureLevels.getOrDefault(playerId, maxTemperature);
boolean isRaining = player.getWorld().hasStorm() && player.getLocation().getBlock().getLightFromSky() == 15;
if (isRaining) {
temperature = Math.max(0, temperature - (int) (decreaseRate * rainMultiplier + rainCoolRate));
temperatureLevels.put(playerId, temperature);
if (temperature <= criticalThreshold && temperature > 0 && canSendMessage(playerId)) {
player.damage(coldDamage);
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("temperature.rain", "§4Der Regen lässt dich erfrieren!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
}
}
private boolean canSendMessage(UUID playerId) {
return ((SurvivalMechanics) plugin).canSendMessage(playerId, "temperature");
}
private void setLastMessageTime(UUID playerId) {
((SurvivalMechanics) plugin).setLastMessageTime(playerId, "temperature");
}
public int getTemperature(UUID playerId) {
return temperatureLevels.getOrDefault(playerId, maxTemperature);
}
public void loadTemperature(UUID playerId, int temperature) {
temperatureLevels.put(playerId, temperature);
}
}

View File

@@ -0,0 +1,141 @@
package me.viper.survivalmechanics.mechanics;
import me.viper.survivalmechanics.SurvivalMechanics;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.Material;
import org.bukkit.ChatColor;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.List;
public class ThirstManager implements Listener {
private final JavaPlugin plugin;
private final Map<UUID, Integer> thirstLevels = new HashMap<>();
private final Map<UUID, BukkitTask> deathTimers = new HashMap<>();
private final int maxThirst;
private final double decreaseRate;
private final List<String> hotBiomes;
private final double hotBiomeMultiplier;
private final int rainRegenRate;
private final int waterRegenRate;
private final int sleepReduction;
private final double damage;
private final int criticalThreshold;
private final boolean deathEnabled;
private final int deathDelay;
private final int messageCooldown;
private final boolean criticalMessageOnly;
public ThirstManager(JavaPlugin plugin) {
this.plugin = plugin;
this.maxThirst = plugin.getConfig().getInt("thirst.max", 100);
this.decreaseRate = plugin.getConfig().getDouble("thirst.decrease-rate", 1);
this.hotBiomes = plugin.getConfig().getStringList("thirst.hot-biomes");
this.hotBiomeMultiplier = plugin.getConfig().getDouble("thirst.hot-biome-multiplier", 2);
this.rainRegenRate = plugin.getConfig().getInt("thirst.rain-regen-rate", 1);
this.waterRegenRate = plugin.getConfig().getInt("thirst.water-regen-rate", 5);
this.sleepReduction = plugin.getConfig().getInt("thirst.sleep-reduction", 50);
this.damage = plugin.getConfig().getDouble("thirst.damage", 0.5);
this.criticalThreshold = plugin.getConfig().getInt("thirst.critical-threshold", 20);
this.deathEnabled = plugin.getConfig().getBoolean("thirst.death-enabled", true);
this.deathDelay = plugin.getConfig().getInt("thirst.death-delay", 60);
this.messageCooldown = plugin.getConfig().getInt("thirst.message-cooldown", 60);
this.criticalMessageOnly = plugin.getConfig().getBoolean("thirst.critical-message-only", true);
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
public void startThirstTask() {
new BukkitRunnable() {
@Override
public void run() {
for (Player player : plugin.getServer().getOnlinePlayers()) {
UUID playerId = player.getUniqueId();
int thirst = thirstLevels.getOrDefault(playerId, maxThirst);
double decrease = decreaseRate;
String biome = player.getWorld().getBiome(player.getLocation()).getKey().getKey().toUpperCase();
boolean isRaining = player.getWorld().hasStorm() && player.getLocation().getBlock().getLightFromSky() == 15;
if (hotBiomes.contains(biome)) {
decrease *= hotBiomeMultiplier;
}
if (isRaining) {
thirst = Math.min(maxThirst, thirst + rainRegenRate);
} else {
thirst = Math.max(0, thirst - (int) decrease);
}
thirstLevels.put(playerId, thirst);
if (thirst <= criticalThreshold && thirst > 0) {
player.damage(damage);
if (canSendMessage(playerId)) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("thirst.critical", "§4Deine Kehle brennt vor Durst!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
} else if (thirst == 0 && deathEnabled && !deathTimers.containsKey(playerId)) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("thirst.warning", "§4Dehydration droht dich zu töten!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
deathTimers.put(playerId, new BukkitRunnable() {
@Override
public void run() {
if (thirstLevels.getOrDefault(playerId, maxThirst) == 0) {
player.setHealth(0);
}
deathTimers.remove(playerId);
}
}.runTaskLater(plugin, 20L * deathDelay));
} else if (thirst >= maxThirst && canSendMessage(playerId) && !criticalMessageOnly) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("thirst.hydrated", "§aDu fühlst dich erfrischt!")));
player.getWorld().playSound(player.getLocation(), "entity.player.levelup", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
}
}
}.runTaskTimer(plugin, 0L, 20L * 60); // Alle 60 Sekunden
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
UUID playerId = player.getUniqueId();
if (event.hasItem() && event.getItem().getType() == Material.POTION) {
int thirst = thirstLevels.getOrDefault(playerId, maxThirst);
thirst = Math.min(maxThirst, thirst + waterRegenRate);
thirstLevels.put(playerId, thirst);
event.getItem().setAmount(event.getItem().getAmount() - 1);
if (canSendMessage(playerId) && !criticalMessageOnly) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("thirst.hydrated", "§aDu fühlst dich erfrischt!")));
player.getWorld().playSound(player.getLocation(), "entity.player.levelup", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
if (deathTimers.containsKey(playerId)) {
deathTimers.get(playerId).cancel();
deathTimers.remove(playerId);
}
}
}
private boolean canSendMessage(UUID playerId) {
return ((SurvivalMechanics) plugin).canSendMessage(playerId, "thirst");
}
private void setLastMessageTime(UUID playerId) {
((SurvivalMechanics) plugin).setLastMessageTime(playerId, "thirst");
}
public int getThirst(UUID playerId) {
return thirstLevels.getOrDefault(playerId, maxThirst);
}
public void loadThirst(UUID playerId, int thirst) {
thirstLevels.put(playerId, thirst);
}
}

View File

@@ -0,0 +1,151 @@
package me.viper.survivalmechanics.mechanics;
import me.viper.survivalmechanics.SurvivalMechanics;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.ChatColor;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.List;
public class VulnerabilityManager implements Listener {
private final JavaPlugin plugin;
private final Map<UUID, Integer> vulnerabilityLevels = new HashMap<>();
private final int maxVulnerability;
private final double increaseRate;
private final double criticalHitMultiplier;
private final double heavyArmorMultiplier;
private final double hungerExhaustionMultiplier;
private final double recoveryRate;
private final double foodRecoveryRate;
private final int weaknessDuration;
private final int weaknessAmplifier;
private final int criticalThreshold;
private final int messageCooldown;
private final boolean criticalMessageOnly;
public VulnerabilityManager(JavaPlugin plugin) {
this.plugin = plugin;
this.maxVulnerability = plugin.getConfig().getInt("vulnerability.max", 100);
this.increaseRate = plugin.getConfig().getDouble("vulnerability.increase-rate", 5);
this.criticalHitMultiplier = plugin.getConfig().getDouble("vulnerability.critical-hit-multiplier", 2);
this.heavyArmorMultiplier = plugin.getConfig().getDouble("vulnerability.heavy-armor-multiplier", 2);
this.hungerExhaustionMultiplier = plugin.getConfig().getDouble("vulnerability.hunger-exhaustion-multiplier", 2);
this.recoveryRate = plugin.getConfig().getDouble("vulnerability.recovery-rate", 2);
this.foodRecoveryRate = plugin.getConfig().getDouble("vulnerability.food-recovery-rate", 3);
this.weaknessDuration = plugin.getConfig().getInt("vulnerability.weakness-duration", 200);
this.weaknessAmplifier = plugin.getConfig().getInt("vulnerability.weakness-amplifier", 1);
this.criticalThreshold = plugin.getConfig().getInt("vulnerability.critical-threshold", 80);
this.messageCooldown = plugin.getConfig().getInt("vulnerability.message-cooldown", 60);
this.criticalMessageOnly = plugin.getConfig().getBoolean("vulnerability.critical-message-only", true);
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
public void startVulnerabilityTask() {
new BukkitRunnable() {
@Override
public void run() {
for (Player player : plugin.getServer().getOnlinePlayers()) {
UUID playerId = player.getUniqueId();
int vulnerability = vulnerabilityLevels.getOrDefault(playerId, 0);
int hunger = ((SurvivalMechanics) plugin).getHungerManager().getHunger(playerId);
int thirst = ((SurvivalMechanics) plugin).getThirstManager().getThirst(playerId);
double recovery = recoveryRate;
if (hunger < ((SurvivalMechanics) plugin).getConfig().getInt("hunger.critical-threshold", 20) ||
thirst < ((SurvivalMechanics) plugin).getConfig().getInt("thirst.critical-threshold", 20)) {
vulnerability = Math.min(maxVulnerability, vulnerability + (int) (increaseRate * hungerExhaustionMultiplier));
} else {
vulnerability = Math.max(0, vulnerability - (int) recovery);
}
vulnerabilityLevels.put(playerId, vulnerability);
if (vulnerability >= criticalThreshold && canSendMessage(playerId)) {
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS, weaknessDuration, weaknessAmplifier));
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("vulnerability.critical", "§4Deine Verletzungen machen dich schwach!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
setLastMessageTime(playerId);
} else if (vulnerability == 0 && canSendMessage(playerId) && !criticalMessageOnly) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("vulnerability.healed", "§aDu bist wieder vollständig geheilt!")));
player.getWorld().playSound(player.getLocation(), "entity.player.levelup", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
}
}
}.runTaskTimer(plugin, 0L, 20L * 60); // Alle 60 Sekunden
}
@EventHandler
public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
if (event.getEntity() instanceof Player) {
Player player = (Player) event.getEntity();
UUID playerId = player.getUniqueId();
int vulnerability = vulnerabilityLevels.getOrDefault(playerId, 0);
vulnerability = Math.min(maxVulnerability, vulnerability + (int) increaseRate);
vulnerabilityLevels.put(playerId, vulnerability);
if (vulnerability >= criticalThreshold) {
event.setDamage(event.getDamage() * criticalHitMultiplier);
}
for (ItemStack armor : player.getInventory().getArmorContents()) {
if (armor != null && (armor.getType().toString().contains("DIAMOND") || armor.getType().toString().contains("NETHERITE"))) {
vulnerability = Math.min(maxVulnerability, vulnerability + (int) (increaseRate * heavyArmorMultiplier));
vulnerabilityLevels.put(playerId, vulnerability);
}
}
if (vulnerability >= criticalThreshold && canSendMessage(playerId)) {
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS, weaknessDuration, weaknessAmplifier));
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("vulnerability.critical", "§4Deine Verletzungen machen dich schwach!")));
player.getWorld().playSound(player.getLocation(), "entity.player.hurt", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
}
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
UUID playerId = player.getUniqueId();
if (event.hasItem() && ((SurvivalMechanics) plugin).getHungerManager().getFoodItems().contains(event.getItem().getType().toString())) {
int vulnerability = vulnerabilityLevels.getOrDefault(playerId, 0);
vulnerability = Math.max(0, vulnerability - (int) foodRecoveryRate);
vulnerabilityLevels.put(playerId, vulnerability);
if (vulnerability == 0 && canSendMessage(playerId) && !criticalMessageOnly) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', ((SurvivalMechanics) plugin).getLangConfig().getString("vulnerability.healed", "§aDu bist wieder vollständig geheilt!")));
player.getWorld().playSound(player.getLocation(), "entity.player.levelup", 1.0f, 1.0f);
setLastMessageTime(playerId);
}
}
}
public void increaseVulnerability(UUID playerId, int amount) {
int vulnerability = vulnerabilityLevels.getOrDefault(playerId, 0);
vulnerability = Math.min(maxVulnerability, vulnerability + amount);
vulnerabilityLevels.put(playerId, vulnerability);
}
private boolean canSendMessage(UUID playerId) {
return ((SurvivalMechanics) plugin).canSendMessage(playerId, "vulnerability");
}
private void setLastMessageTime(UUID playerId) {
((SurvivalMechanics) plugin).setLastMessageTime(playerId, "vulnerability");
}
public int getVulnerability(UUID playerId) {
return vulnerabilityLevels.getOrDefault(playerId, 0);
}
public void loadVulnerability(UUID playerId, int vulnerability) {
vulnerabilityLevels.put(playerId, vulnerability);
}
}

View File

@@ -0,0 +1,174 @@
# Konfiguration für Hunger
hunger:
max: 100 # Maximaler Hungerwert (0-100). Bestimmt die Obergrenze für den Hunger.
initial: 80 # Startwert für Hunger beim Betreten des Servers (0-100). 100 = Satt, 0 = Verhungert.
decrease-rate: 0.5 # Wie viel Hunger pro Intervall abnimmt (z. B. 0.5 pro 20 Sekunden). Höhere Werte = schnellerer Hungerabbau.
decrement-interval: 20 # Intervall in Sekunden, in dem Hunger, Durst, etc. aktualisiert werden (z. B. 20 = alle 20 Sekunden).
sprint-multiplier: 1.5 # Multiplikator für Hungerabbau beim Sprinten (z. B. 1.5 = 50% schnellerer Abbau). Werte > 1 erhöhen den Verbrauch.
combat-multiplier: 2 # Multiplikator für Hungerabbau im Kampf (z. B. 2 = doppelter Abbau). Werte > 1 erhöhen den Verbrauch.
night-multiplier: 1.2 # Multiplikator für Hungerabbau nachts (z. B. 1.2 = 20% schnellerer Abbau). Werte > 1 erhöhen den Verbrauch.
sleep-reduction: 40 # Wie viel Hunger durch Schlafen regeneriert wird (z. B. 40 = +40 Hunger). Werte 0-100.
damage: 0.5 # Schaden pro Sekunde, wenn Hunger = 0 (z. B. 0.5 = halbes Herz pro Sekunde). Werte > 0 aktivieren Schaden.
critical-threshold: 20 # Schwellenwert für kritischen Hunger (z. B. 20 = bei ≤20 wird "Verhungert" angezeigt und Effekte starten).
death-enabled: true # Ob Spieler bei Hunger = 0 nach Verzögerung sterben (true/false).
death-delay: 60 # Verzögerung in Sekunden, bevor Spieler bei Hunger = 0 stirbt (z. B. 60 = 1 Minute).
food-items: # Liste der Nahrungsmittel, die Hunger regenerieren.
- BREAD # Brot
- APPLE # Apfel
- COOKED_BEEF # Gekochtes Rindfleisch
- COOKED_CHICKEN # Gekochtes Hühnchen
food-recovery-rate: 34 # Wie viel Hunger ein Nahrungsmittel regeneriert (z. B. 34 = +34 Hunger pro Item, 3 Brote/Fleisch füllen von 0 auf 100). Werte 0-100.
particle-effect: true # Ob Partikeleffekte bei kritischem Hunger angezeigt werden (true/false).
message-cooldown: 60 # Abklingzeit in Sekunden für Hungermeldungen (z. B. 60 = Meldung alle 60 Sekunden).
critical-message-only: true # Ob nur kritische Meldungen (bei ≤20) gesendet werden (true = nur kritische, false = auch andere).
# Konfiguration für Durst
thirst:
max: 100 # Maximaler Durstwert (0-100). Bestimmt die Obergrenze für Durst.
initial: 80 # Startwert für Durst beim Betreten des Servers (0-100). 100 = Erfrischt, 0 = Dehydriert.
decrease-rate: 0.8 # Wie viel Durst pro Intervall abnimmt (z. B. 0.8 pro 20 Sekunden). Höhere Werte = schnellerer Durstabbau.
decrement-interval: 20 # Intervall in Sekunden, in dem Durst aktualisiert wird (z. B. 20 = alle 20 Sekunden).
hot-biomes: # Biome, in denen Durst schneller abnimmt (heiße Biome).
- DESERT # Wüste
- SAVANNA # Savanne
- BADLANDS # Tafelberge
hot-biome-multiplier: 1.5 # Multiplikator für Durstabbau in heißen Biomen (z. B. 1.5 = 50% schneller). Werte > 1 erhöhen den Verbrauch.
rain-regen-rate: 2 # Wie viel Durst im Regen regeneriert wird pro Intervall (z. B. 2 = +2 Durst). Werte 0-100.
water-regen-rate: 50 # Wie viel Durst durch Trinken von Wasser regeneriert wird (z. B. 50 = +50 Durst, 2 Wasser füllen von 0 auf 100). Werte 0-100.
sleep-reduction: 40 # Wie viel Durst durch Schlafen regeneriert wird (z. B. 40 = +40 Durst). Werte 0-100.
damage: 0.5 # Schaden pro Sekunde, wenn Durst = 0 (z. B. 0.5 = halbes Herz pro Sekunde). Werte > 0 aktivieren Schaden.
critical-threshold: 20 # Schwellenwert für kritischen Durst (z. B. 20 = bei ≤20 wird "Dehydriert" angezeigt und Effekte starten).
death-enabled: true # Ob Spieler bei Durst = 0 nach Verzögerung sterben (true/false).
death-delay: 60 # Verzögerung in Sekunden, bevor Spieler bei Durst = 0 stirbt (z. B. 60 = 1 Minute).
message-cooldown: 60 # Abklingzeit in Sekunden für Durstmeldungen (z. B. 60 = Meldung alle 60 Sekunden).
critical-message-only: true # Ob nur kritische Meldungen (bei ≤20) gesendet werden (true = nur kritische, false = auch andere).
# Konfiguration für Müdigkeit
fatigue:
max: 100 # Maximaler Müdigkeitswert (0-100). Bestimmt die Obergrenze für Müdigkeit.
initial: 100 # Startwert für Müdigkeit beim Betreten des Servers (0-100). 100 = Erholt, 0 = Erschöpft.
decrease-rate: 1.0 # Wie viel Müdigkeit pro Intervall abnimmt (z. B. 1.0 pro 30 Sekunden). Höhere Werte = schnellerer Abbau.
decrement-interval: 40 # Intervall in Sekunden, in dem Müdigkeit aktualisiert wird (z. B. 30 = alle 30 Sekunden).
activity-multiplier: 1.0 # Multiplikator für Müdigkeitsabbau bei Aktivitäten wie Sprinten/Schwimmen (z. B. 1.5 = 50% schneller). Werte > 1 erhöhen den Verbrauch.
night-multiplier: 2.0 # Multiplikator für Müdigkeitsabbau nachts (z. B. 2.0 = 2x schneller). Werte > 1 erhöhen den Verbrauch.
climbing-multiplier: 1.5 # Multiplikator für Müdigkeitsabbau beim Klettern (z. B. 1.5 = 50% schneller). Werte > 1 erhöhen den Verbrauch.
climbing-height-threshold: 100 # Höhe (Y-Koordinate), ab der Klettern Müdigkeit beeinflusst (z. B. 100 = ab Y=100).
climbing-height-scaling: 0.01 # Skalierungsfaktor für Müdigkeitsabbau basierend auf Kletterhöhe (z. B. 0.01 = 1% mehr pro Block über Schwelle).
slowness-duration: 200 # Dauer des Langsamkeitseffekts bei kritischer Müdigkeit in Ticks (z. B. 200 = 10 Sekunden). 20 Ticks = 1 Sekunde.
slowness-amplifier: 1 # Stärke des Langsamkeitseffekts (z. B. 1 = Langsamkeit I). Werte 0-255.
blur-duration: 100 # Dauer des Blindheitseffekts bei kritischer Müdigkeit in Ticks (z. B. 100 = 5 Sekunden). 20 Ticks = 1 Sekunde.
blur-amplifier: 1 # Stärke des Blindheitseffekts (z. B. 1 = Blindheit I). Werte 0-255.
stamina-penalty: 1.0 # Multiplikator für Ausdauerabbau bei kritischer Müdigkeit (z. B. 1.0 = kein zusätzlicher Abbau). Werte < 1 verringern, > 1 erhöhen.
critical-threshold: 20 # Schwellenwert für kritische Müdigkeit (z. B. 20 = bei ≤20 werden Effekte und Meldungen ausgelöst).
death-enabled: true # Ob Spieler bei Müdigkeit = 0 nach Verzögerung sterben (true/false).
death-delay: 60 # Verzögerung in Sekunden, bevor Spieler bei Müdigkeit = 0 stirbt (z. B. 60 = 1 Minute).
message-cooldown: 60 # Abklingzeit in Sekunden für Müdigkeitsmeldungen (z. B. 60 = Meldung alle 60 Sekunden).
critical-message-only: true # Ob nur kritische Meldungen (bei ≤20) gesendet werden (true = nur kritische, false = auch andere).
# Konfiguration für Temperatur
temperature:
max: 50 # Maximaler Temperaturwert (0-100). 50 = Angenehm, 0 = Unterkühlt, 100 = Überhitzt.
initial: 50 # Startwert für Temperatur beim Betreten des Servers (0-100). 50 = Angenehm.
decrease-rate: 0.6 # Wie viel Temperatur in kalten Biomen pro Intervall abnimmt (z. B. 0.6 pro 20 Sekunden). Höhere Werte = schnellerer Abfall.
increase-rate: 0.6 # Wie viel Temperatur in heißen Biomen pro Intervall steigt (z. B. 0.6 pro 20 Sekunden). Höhere Werte = schnellerer Anstieg.
decrement-interval: 20 # Intervall in Sekunden, in dem Temperatur aktualisiert wird (z. B. 20 = alle 20 Sekunden).
cold-biomes: # Biome, in denen Temperatur abnimmt (kalte Biome).
- SNOWY_TAIGA # Verschneite Taiga
- SNOWY_TUNDRA # Verschneite Tundra
- ICE_SPIKES # Eisspitzen
hot-biomes: # Biome, in denen Temperatur steigt (heiße Biome).
- DESERT # Wüste
- SAVANNA # Savanne
- BADLANDS # Tafelberge
cold-damage: 0.5 # Schaden pro Sekunde bei kritischer Unterkühlung (z. B. 0.5 = halbes Herz pro Sekunde). Werte > 0 aktivieren Schaden.
hot-damage: 0.5 # Schaden pro Sekunde bei kritischer Überhitzung (z. B. 0.5 = halbes Herz pro Sekunde). Werte > 0 aktivieren Schaden.
warmth-radius: 5 # Radius in Blöcken, in dem Wärmequellen (z. B. Lagerfeuer) die Temperatur erhöhen (z. B. 5 = 5 Blöcke).
rain-cool-rate: 1 # Wie viel Temperatur im Regen pro Intervall abnimmt (z. B. 1 = -1 Temperatur). Werte > 0 kühlen ab.
rain-multiplier: 1.2 # Multiplikator für Temperaturabbau im Regen (z. B. 1.2 = 20% schneller). Werte > 1 erhöhen den Abfall.
night-cold-multiplier: 1.2 # Multiplikator für Temperaturabbau nachts in kalten Biomen (z. B. 1.2 = 20% schneller). Werte > 1 erhöhen den Abfall.
critical-threshold: 20 # Schwellenwert für kritische Temperatur (z. B. 20 = bei ≤20 oder ≥80 werden Effekte und Meldungen ausgelöst).
death-enabled: true # Ob Spieler bei kritischer Temperatur nach Verzögerung sterben (true/false).
death-delay: 60 # Verzögerung in Sekunden, bevor Spieler bei kritischer Temperatur stirbt (z. B. 60 = 1 Minute).
message-cooldown: 60 # Abklingzeit in Sekunden für Temperaturmeldungen (z. B. 60 = Meldung alle 60 Sekunden).
critical-message-only: true # Ob nur kritische Meldungen (bei ≤20 oder ≥80) gesendet werden (true = nur kritische, false = auch andere).
# Konfiguration für Ausdauer
stamina:
max: 100 # Maximaler Ausdauerwert (0-100). Bestimmt die Obergrenze für Ausdauer.
initial: 100 # Startwert für Ausdauer beim Betreten des Servers (0-100). 100 = Energiegeladen, 0 = Ausgelaugt.
decrease-rate: 0.5 # Wie viel Ausdauer pro Intervall abnimmt (z. B. 1.0 pro 20 Sekunden). Höhere Werte = schnellerer Abbau.
decrement-interval: 20 # Intervall in Sekunden, in dem Ausdauer aktualisiert wird (z. B. 20 = alle 20 Sekunden).
sprint-multiplier: 0.5 # Multiplikator für Ausdauerabbau beim Sprinten (z. B. 5 = 3x schneller). Werte > 1 erhöhen den Verbrauch.
jump-multiplier: 1.0 # Multiplikator für Ausdauerabbau beim Springen (z. B. 1.5 = 50% schneller). Werte > 1 erhöhen den Verbrauch.
combat-multiplier: 2 # Multiplikator für Ausdauerabbau im Kampf (z. B. 2 = 2x schneller). Werte > 1 erhöhen den Verbrauch.
climbing-multiplier: 1.5 # Multiplikator für Ausdauerabbau beim Klettern (z. B. 1.5 = 50% schneller). Werte > 1 erhöhen den Verbrauch.
climbing-height-threshold: 100 # Höhe (Y-Koordinate), ab der Klettern Ausdauer beeinflusst (z. B. 100 = ab Y=100).
climbing-height-scaling: 0.01 # Skalierungsfaktor für Ausdauerabbau basierend auf Kletterhöhe (z. B. 0.01 = 1% mehr pro Block über Schwelle).
regen-rate: 3 # Wie viel Ausdauer pro Intervall regeneriert wird, wenn der Spieler ruht (z. B. 3 = +3 Ausdauer). Werte 0-100.
hunger-thirst-penalty: 0.5 # Multiplikator für Ausdauerabbau bei kritischem Hunger/Durst (z. B. 0.5 = 50% langsamer). Werte < 1 verringern, > 1 erhöhen.
fatigue-penalty: 0.5 # Multiplikator für Ausdauerabbau bei kritischer Müdigkeit (z. B. 0.5 = 50% langsamer). Werte < 1 verringern, > 1 erhöhen.
vulnerability-stamina-penalty: 0.7 # Multiplikator für Ausdauerabbau bei kritischer Verletzlichkeit (z. B. 0.7 = 30% langsamer). Werte < 1 verringern, > 1 erhöhen.
stamina-vulnerability-increase: 2 # Wie viel Verletzlichkeit durch niedrige Ausdauer steigt (z. B. 2 = +2 Verletzlichkeit). Werte 0-100.
critical-threshold: 20 # Schwellenwert für kritische Ausdauer (z. B. 20 = bei ≤20 werden Effekte und Meldungen ausgelöst).
min-to-sprint: 20 # Mindest-Ausdauerwert, um sprinten zu können (z. B. 20 = Sprinten bei ≤20 nicht möglich).
message-cooldown: 60 # Abklingzeit in Sekunden für Ausdauermeldungen (z. B. 60 = Meldung alle 60 Sekunden).
critical-message-only: true # Ob nur kritische Meldungen (bei ≤20) gesendet werden (true = nur kritische, false = auch andere).
# Konfiguration für Verletztbarkeit
vulnerability:
max: 100 # Maximale Verletzlichkeit (0-100). 0 = Gesund, 100 = Schwer verletzt.
initial: 0 # Startwert für Verletzlichkeit beim Betreten des Servers (0-100). 0 = Gesund, 100 = Schwer verletzt.
increase-rate: 3 # Wie viel Verletzlichkeit pro Intervall steigt (z. B. 3 pro 20 Sekunden bei Schaden). Höhere Werte = schnellerer Anstieg.
decrement-interval: 20 # Intervall in Sekunden, in dem Verletzlichkeit aktualisiert wird (z. B. 20 = alle 20 Sekunden).
critical-hit-multiplier: 1.5 # Multiplikator für Verletzlichkeitsanstieg bei kritischen Treffern (z. B. 1.5 = 50% mehr). Werte > 1 erhöhen den Anstieg.
heavy-armor-multiplier: 1.5 # Multiplikator für Verletzlichkeitsanstieg bei schwerer Rüstung (z. B. 1.5 = 50% mehr). Werte > 1 erhöhen den Anstieg.
hunger-exhaustion-multiplier: 1.5 # Multiplikator für Verletzlichkeitsanstieg bei kritischem Hunger/Müdigkeit (z. B. 1.5 = 50% mehr). Werte > 1 erhöhen den Anstieg.
recovery-rate: 3 # Wie viel Verletzlichkeit pro Intervall sinkt, wenn der Spieler ruht (z. B. 3 = -3 Verletzlichkeit). Werte 0-100.
food-recovery-rate: 34 # Wie viel Verletzlichkeit durch Essen sinkt (z. B. 34 = -34 Verletzlichkeit pro Nahrung, 3 Brote/Fleisch setzen von 100 auf 0). Werte 0-100.
weakness-duration: 200 # Dauer des Schwächeeffekts bei kritischer Verletzlichkeit in Ticks (z. B. 200 = 10 Sekunden). 20 Ticks = 1 Sekunde.
weakness-amplifier: 1 # Stärke des Schwächeeffekts (z. B. 1 = Schwäche I). Werte 0-255.
critical-threshold: 80 # Schwellenwert für kritische Verletzlichkeit (z. B. 80 = bei ≥80 wird "Schwer verletzt" angezeigt und Effekte starten).
message-cooldown: 60 # Abklingzeit in Sekunden für Verletzlichkeitsmeldungen (z. B. 60 = Meldung alle 60 Sekunden).
critical-message-only: true # Ob nur kritische Meldungen (bei ≥80) gesendet werden (true = nur kritische, false = auch andere).
# Konfiguration für Hygiene
hygiene:
max: 100 # Maximaler Hygienewert (0-100). Bestimmt die Obergrenze für Hygiene.
initial: 80 # Startwert für Hygiene beim Betreten des Servers (0-100). 100 = Sauber, 0 = Verwahrlost.
decrease-rate: 0.5 # Wie viel Hygiene pro Intervall abnimmt (z. B. 0.5 pro 20 Sekunden). Höhere Werte = schnellerer Abbau.
decrement-interval: 20 # Intervall in Sekunden, in dem Hygiene aktualisiert wird (z. B. 20 = alle 20 Sekunden).
dirty-biomes: # Biome, in denen Hygiene schneller abnimmt (schmutzige Biome).
- SWAMP # Sumpf
- MUDDY_SWAMP # Schlammiger Sumpf
digging-multiplier: 2 # Multiplikator für Hygieneabbau beim Graben (z. B. 2 = doppelt so schnell). Werte > 1 erhöhen den Verbrauch.
climbing-multiplier: 1.5 # Multiplikator für Hygieneabbau beim Klettern (z. B. 1.5 = 50% schneller). Werte > 1 erhöhen den Verbrauch.
climbing-height-threshold: 100 # Höhe (Y-Koordinate), ab der Klettern Hygiene beeinflusst (z. B. 100 = ab Y=100).
climbing-height-scaling: 0.01 # Skalierungsfaktor für Hygieneabbau basierend auf Kletterhöhe (z. B. 0.01 = 1% mehr pro Block über Schwelle).
vulnerability-exhaustion-multiplier: 2 # Multiplikator für Verletzlichkeitsanstieg bei kritischer Hygiene (z. B. 2 = doppelt so viel). Werte > 1 erhöhen den Anstieg.
recovery-rate: 2 # Wie viel Hygiene pro Intervall regeneriert wird, wenn der Spieler ruht (z. B. 2 = +2 Hygiene). Werte 0-100.
water-recovery-rate: 6 # Wie viel Hygiene durch Wasser (z. B. Schwimmen) regeneriert wird (z. B. 6 = +6 Hygiene). Werte 0-100.
weakness-duration: 200 # Dauer des Schwächeeffekts bei kritischer Hygiene in Ticks (z. B. 200 = 10 Sekunden). 20 Ticks = 1 Sekunde.
weakness-amplifier: 1 # Stärke des Schwächeeffekts (z. B. 1 = Schwäche I). Werte 0-255.
critical-threshold: 20 # Schwellenwert für kritische Hygiene (z. B. 20 = bei ≤20 wird "Verwahrlost" angezeigt und Effekte starten).
death-enabled: true # Ob Spieler bei kritischer Hygiene nach Verzögerung sterben (true/false).
death-delay: 60 # Verzögerung in Sekunden, bevor Spieler bei kritischer Hygiene stirbt (z. B. 60 = 1 Minute).
message-cooldown: 60 # Abklingzeit in Sekunden für Hygienemeldungen (z. B. 60 = Meldung alle 60 Sekunden).
critical-message-only: true # Ob nur kritische Meldungen (bei ≤20) gesendet werden (true = nur kritische, false = auch andere).
# Konfiguration für die ActionBar-Anzeige
display:
bar-length: 5 # Länge der Balken im Scoreboard (z. B. 5 = █████ bei vollem Wert). Werte 1-10, kürzere Balken = weniger gequetscht.
bar-filled: "█" # Zeichen für gefüllte Balken im Scoreboard (z. B. █). Beliebiges Zeichen möglich.
bar-empty: "▒" # Zeichen für leere Balken im Scoreboard (z. B. ▒). Beliebiges Zeichen möglich.
update-interval: 100 # Intervall in Ticks, in dem das Scoreboard aktualisiert wird (z. B. 100 = 5 Sekunden). 20 Ticks = 1 Sekunde.
critical-display-threshold: 60 # Schwellenwert für Statusanzeige im Scoreboard (z. B. 60 = Status wie "Mild" ab ≤60). Werte 0-100.
rotation-interval: 80 # Intervall in Ticks, in dem die ActionBar rotiert (z. B. 80 = 4 Sekunden). 20 Ticks = 1 Sekunde.
hunger-color: "§6" # Farbcode für Hunger im Scoreboard (z. B. §6 = Gold). Minecraft-Farbcodes (§0-§f).
thirst-color: "§b" # Farbcode für Durst im Scoreboard (z. B. §b = Hellblau). Minecraft-Farbcodes (§0-§f).
fatigue-color: "§7" # Farbcode für Müdigkeit im Scoreboard (z. B. §7 = Grau). Minecraft-Farbcodes (§0-§f).
temperature-color: "§c" # Farbcode für Temperatur im Scoreboard (z. B. §c = Rot). Minecraft-Farbcodes (§0-§f).
stamina-color: "§a" # Farbcode für Ausdauer im Scoreboard (z. B. §a = Grün). Minecraft-Farbcodes (§0-§f).
vulnerability-color: "§4" # Farbcode für Verletzlichkeit im Scoreboard (z. B. §4 = Dunkelrot). Minecraft-Farbcodes (§0-§f).
hygiene-color: "§9" # Farbcode für Hygiene im Scoreboard (z. B. §9 = Dunkelblau). Minecraft-Farbcodes (§0-§f).
mild-threshold: 60 # Schwellenwert für "Mild"-Status im Scoreboard (z. B. 60 = "Mild" bei ≤60 für Hunger, Durst, etc.). Werte 0-100.
critical-threshold: 20 # Schwellenwert für kritischen Status im Scoreboard (z. B. 20 = "Verhungert" bei ≤20 für Hunger). Werte 0-100.

View File

@@ -0,0 +1,95 @@
scoreboard:
title: "&6Survival"
hunger: "HP"
thirst: "TH"
fatigue: "FT"
temperature: "TP"
stamina: "ST"
vulnerability: "VL"
hygiene: "HY"
hunger:
critical: "&4Dein Körper schwächt durch Hunger!"
warning: "&4Du bist dem Verhungern nahe!"
fed: "&aDu fühlst dich satt und gestärkt!"
death: "&4Dein Körper gibt dem Hunger nach!"
status:
full: "&aSatt"
mild: "&eHungrig"
hungry: "&cSehr hungrig"
starving: "&4Verhungert"
thirst:
critical: "&4Deine Kehle brennt vor Durst!"
warning: "&4Dehydration droht dich zu töten!"
hydrated: "&aDu fühlst dich erfrischt!"
death: "&4Dein Körper verdurstet elendig!"
status:
full: "&aErfrischt"
mild: "&eDurstig"
thirsty: "&cSehr durstig"
dehydrated: "&4Dehydriert"
fatigue:
critical: "&7Du kannst dich kaum wach halten!"
warning: "&4Deine Erschöpfung wird dich umbringen!"
rested: "&aDu erwachst erholt und voller Kraft!"
death: "&4Dein Körper bricht vor Erschöpfung zusammen!"
status:
full: "&aErholt"
mild: "&eMüde"
tired: "&cSehr müde"
exhausted: "&4Erschöpft"
temperature:
critical-cold: "&4Du zitterst unkontrollierbar!"
critical-hot: "&4Die Hitze überwältigt dich!"
rain: "&4Der Regen lässt dich erfrieren!"
warning-cold: "&4Die Kälte wird dich bald töten!"
warning-hot: "&4Die Hitze wird dich bald töten!"
warning-rain: "&4Der Regen wird dich unterkühlen!"
comfortable: "&aDeine Körpertemperatur fühlt sich gut an!"
death-cold: "&4Dein Körper gibt der Kälte nach!"
death-hot: "&4Die Hitze raubt dir das Leben!"
death-rain: "&4Der Regen hat dich unterkühlt!"
status:
full: "&aAngenehm"
mild: "&eUnwohl"
extreme: "&cKalt/Hot"
critical: "&4Unterkühlt/Überhitzt"
stamina:
critical-sprint: "&4Du bist zu schwach, um zu sprinten!"
critical-jump: "&4Du bist zu schwach, um zu springen!"
critical-combat: "&4Du bist zu schwach, um zu kämpfen!"
full: "&aDu sprühst vor Energie!"
vulnerability: "&4Deine Schwäche macht dich anfälliger!"
status:
full: "&aEnergiegeladen"
mild: "&eErmüdet"
tired: "&cSehr erschöpft"
exhausted: "&4Völlig erschöpft"
vulnerability:
critical: "&4Deine Verletzungen machen dich schwach!"
healed: "&aDu bist wieder vollständig geheilt!"
food-heal: "&eNahrung lindert deine Wunden!"
status:
full: "&aGesund"
mild: "&eVerletzt"
injured: "&cSchwer verletzt"
critical: "&4Kritisch"
hygiene:
critical: "&4Schmutz und Gestank machen dich krank!"
warning: "&4Eine Infektion droht dich zu töten!"
clean: "&aDu fühlst dich sauber und wohl!"
death: "&4Eine Infektion hat dein Leben beendet!"
status:
full: "&aSauber"
mild: "&eSchmutzig"
dirty: "&cSehr schmutzig"
filthy: "&4Verseucht"
climbing:
critical: "&4Das Klettern zehrt an deinen Kräften!"

View File

@@ -0,0 +1,2 @@
# Wird dynamisch generiert
players: {}

View File

@@ -0,0 +1,5 @@
name: SurvivalMechanics
main: me.viper.survivalmechanics.SurvivalMechanics
version: 1.0-SNAPSHOT
api-version: 1.21
author: M_Viper