Stage 12: Data storage system

This commit is contained in:
loki5512344 2026-05-31 20:47:02 +02:00
parent 82ed455cd2
commit 4fd7955d56
62 changed files with 5613 additions and 0 deletions

View file

@ -0,0 +1,156 @@
package dev.loki.survivor;
import dev.loki.player.PlayerState;
import dev.loki.player.Survivor;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.UUID;
public class SurvivorHealing {
private final SurvivorController controller;
private Player healingTarget;
private int healingTicks;
private int totalHealingTicks;
private boolean isSelfHeal;
private static final int SELF_HEAL_TICKS = 600;
private static final int OTHER_HEAL_TICKS = 320;
private static final double HEAL_RANGE = 3.0;
public SurvivorHealing(SurvivorController controller) {
this.controller = controller;
}
public void startHealing(Player target) {
if (isHealing()) return;
if (controller.isDowned()) return;
Player healer = controller.getPlayer();
if (healer == null) return;
UUID targetUuid = target.getUniqueId();
Survivor targetSurvivor = getSurvivorFromPlayer(target);
if (targetSurvivor == null) return;
PlayerState targetState = targetSurvivor.getState();
if (targetState != PlayerState.INJURED && targetState != PlayerState.DOWNED) return;
boolean selfHeal = healer.getUniqueId().equals(targetUuid);
if (selfHeal && targetState == PlayerState.DOWNED) return;
this.healingTarget = target;
this.isSelfHeal = selfHeal;
this.totalHealingTicks = selfHeal ? SELF_HEAL_TICKS : OTHER_HEAL_TICKS;
this.healingTicks = totalHealingTicks;
sendProgressMessage();
}
public void tick() {
if (!isHealing()) return;
Player healer = controller.getPlayer();
if (healer == null || healingTarget == null) {
cancelHealing();
return;
}
if (!healingTarget.isOnline()) {
cancelHealing();
return;
}
Survivor targetSurvivor = getSurvivorFromPlayer(healingTarget);
if (targetSurvivor == null) {
cancelHealing();
return;
}
PlayerState targetState = targetSurvivor.getState();
if (targetState != PlayerState.INJURED && targetState != PlayerState.DOWNED) {
completeHealing(targetSurvivor);
return;
}
if (!isSelfHeal && healer.getLocation().distance(healingTarget.getLocation()) > HEAL_RANGE) {
cancelHealing();
return;
}
healingTicks--;
sendProgressMessage();
if (healingTicks <= 0) {
completeHealing(targetSurvivor);
}
}
private void completeHealing(Survivor target) {
PlayerState currentState = target.getState();
PlayerState newState = (currentState == PlayerState.DOWNED) ? PlayerState.INJURED : PlayerState.HEALTHY;
target.setState(newState);
Player targetPlayer = healingTarget;
if (targetPlayer != null && targetPlayer.isOnline()) {
String message = newState == PlayerState.HEALTHY ? "<green>Вы полностью вылечились!"
: "<yellow>Вы встали на ноги!";
targetPlayer.sendMessage(MiniMessage.miniMessage().deserialize(message));
}
cancelHealing();
}
public void cancelHealing() {
if (healingTarget != null && healingTarget.isOnline() && isHealing()) {
healingTarget.sendActionBar(Component.empty());
}
healingTarget = null;
healingTicks = 0;
}
private void sendProgressMessage() {
if (healingTarget == null) return;
double progress = 1.0 - ((double) healingTicks / totalHealingTicks);
String bar = renderProgressBar(progress);
Component message = MiniMessage.miniMessage().deserialize(
isSelfHeal ? "<gray>Лечение себя: " + bar
: "<gray>Лечение союзника: " + bar
);
healingTarget.sendActionBar(message);
}
private String renderProgressBar(double progress) {
int filled = (int) (10 * progress);
int empty = 10 - filled;
StringBuilder bar = new StringBuilder("<green>");
bar.append("█".repeat(filled));
bar.append("<gray>");
bar.append("░".repeat(empty));
bar.append(" <white>").append((int)(progress * 100)).append("%");
return bar.toString();
}
private Survivor getSurvivorFromPlayer(Player player) {
if (controller.getPlayer() != null && controller.getPlayer().equals(player)) {
return controller.getSurvivor();
}
return null;
}
public boolean isHealing() {
return healingTicks > 0;
}
public Player getHealingTarget() {
return healingTarget;
}
public double getProgress() {
if (!isHealing()) return 0;
return 1.0 - ((double) healingTicks / totalHealingTicks);
}
}