Files
SurvivalMechanics/src/main/java/me/viper/survivalmechanics/mechanics/StaminaManager.java
2026-01-28 22:06:29 +01:00

204 lines
10 KiB
Java

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;
// Low hunger or thirst reduces stamina regeneration
if (hunger < criticalThreshold || thirst < criticalThreshold) {
regen *= hungerThirstPenalty;
}
// Low fatigue reduces stamina regeneration
if (fatigue < criticalThreshold) {
regen *= fatiguePenalty;
}
stamina = Math.min(maxStamina, stamina + (int) regen);
staminaLevels.put(playerId, stamina);
// Warning when stamina is too low to sprint
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); // Every 60 seconds
}
@EventHandler
public void onPlayerToggleSprint(PlayerToggleSprintEvent event) {
Player player = event.getPlayer();
UUID playerId = player.getUniqueId();
int stamina = staminaLevels.getOrDefault(playerId, maxStamina);
if (event.isSprinting()) {
// Prevent sprinting if stamina is too low
if (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 {
// Drain stamina when sprinting
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);
// Jumping drains stamina
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);
}
// Climbing at high altitudes drains stamina faster
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) {
// When player attacks (is the damager)
if (event.getDamager() instanceof Player) {
Player player = (Player) event.getDamager();
UUID playerId = player.getUniqueId();
int stamina = staminaLevels.getOrDefault(playerId, maxStamina);
// Combat drains stamina
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);
}
}