package dev.loki.survivor; import dev.loki.mdbd; import dev.loki.player.PlayerState; import org.bukkit.entity.Player; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; public class SurvivorMovement { private final SurvivorController controller; private boolean isSprinting; private boolean isExhausted; private int exhaustionTicks; private int exhaustionCooldownTicks; private boolean isCrawling; private static final float WALK_SPEED = 0.2f; private static final float SPRINT_SPEED = 0.3f; private static final float CRAWL_SPEED = 0.06f; private static final int EXHAUSTION_DURATION = 60; private static final int EXHAUSTION_COOLDOWN = 100; public SurvivorMovement(SurvivorController controller) { this.controller = controller; this.isSprinting = false; this.isExhausted = false; this.isCrawling = false; } public void onSprintStart() { if (isExhausted || controller.isDowned()) return; isSprinting = true; } public void onSprintEnd() { if (!isSprinting) return; isSprinting = false; if (!isExhausted && !controller.isDowned()) { isExhausted = true; exhaustionTicks = EXHAUSTION_DURATION; } } public void tick() { if (isExhausted) { if (exhaustionTicks > 0) { exhaustionTicks--; } else { exhaustionCooldownTicks = EXHAUSTION_COOLDOWN; isExhausted = false; } } else if (exhaustionCooldownTicks > 0) { exhaustionCooldownTicks--; } updateCrawlState(); applyEffects(); } private void updateCrawlState() { Player player = controller.getPlayer(); if (player == null) return; boolean shouldCrawl = controller.isDowned(); if (shouldCrawl != isCrawling) { isCrawling = shouldCrawl; if (isCrawling) { player.setSneaking(true); } else { player.setSneaking(false); } } } private void applyEffects() { Player player = controller.getPlayer(); if (player == null) return; if (isCrawling) { player.addPotionEffect(new PotionEffect(PotionEffectType.SLOWNESS, 5, 2, false, false)); } } public float getCurrentSpeed() { if (controller.isDowned()) { return CRAWL_SPEED; } if (isExhausted) { return WALK_SPEED; } if (isSprinting) { return SPRINT_SPEED; } return WALK_SPEED; } public void onStateChange(PlayerState newState) { if (newState == PlayerState.DOWNED) { isSprinting = false; } } public boolean isSprinting() { return isSprinting; } public boolean isExhausted() { return isExhausted; } public boolean canSprint() { return !isExhausted && exhaustionCooldownTicks <= 0 && !controller.isDowned(); } public double getExhaustionPercent() { if (isExhausted) { return (double) exhaustionTicks / EXHAUSTION_DURATION; } return 0; } }