Stage 12: Data storage system
This commit is contained in:
parent
82ed455cd2
commit
4fd7955d56
62 changed files with 5613 additions and 0 deletions
77
src/main/java/dev/loki/survivor/SurvivorController.java
Normal file
77
src/main/java/dev/loki/survivor/SurvivorController.java
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
package dev.loki.survivor;
|
||||
|
||||
import dev.loki.player.PlayerState;
|
||||
import dev.loki.player.Survivor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class SurvivorController {
|
||||
private final Survivor survivor;
|
||||
private final SurvivorMovement movement;
|
||||
private final SurvivorHealing healing;
|
||||
|
||||
public SurvivorController(Survivor survivor) {
|
||||
this.survivor = survivor;
|
||||
this.movement = new SurvivorMovement(this);
|
||||
this.healing = new SurvivorHealing(this);
|
||||
}
|
||||
|
||||
public void onSprintStart() {
|
||||
movement.onSprintStart();
|
||||
}
|
||||
|
||||
public void onSprintEnd() {
|
||||
movement.onSprintEnd();
|
||||
}
|
||||
|
||||
public void onHealAttempt(Player target) {
|
||||
healing.startHealing(target);
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
movement.tick();
|
||||
healing.tick();
|
||||
updateSpeed();
|
||||
}
|
||||
|
||||
private void updateSpeed() {
|
||||
Player player = survivor.getPlayer();
|
||||
if (player == null) return;
|
||||
|
||||
float speed = movement.getCurrentSpeed();
|
||||
player.setWalkSpeed(speed);
|
||||
}
|
||||
|
||||
public void onStateChange(PlayerState newState) {
|
||||
movement.onStateChange(newState);
|
||||
}
|
||||
|
||||
public UUID getUuid() {
|
||||
return survivor.getUuid();
|
||||
}
|
||||
|
||||
public Survivor getSurvivor() {
|
||||
return survivor;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return survivor.getPlayer();
|
||||
}
|
||||
|
||||
public PlayerState getState() {
|
||||
return survivor.getState();
|
||||
}
|
||||
|
||||
public boolean isDowned() {
|
||||
return survivor.getState() == PlayerState.DOWNED;
|
||||
}
|
||||
|
||||
public boolean isInjured() {
|
||||
return survivor.getState() == PlayerState.INJURED;
|
||||
}
|
||||
|
||||
public boolean isHealthy() {
|
||||
return survivor.getState() == PlayerState.HEALTHY;
|
||||
}
|
||||
}
|
||||
156
src/main/java/dev/loki/survivor/SurvivorHealing.java
Normal file
156
src/main/java/dev/loki/survivor/SurvivorHealing.java
Normal 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);
|
||||
}
|
||||
}
|
||||
121
src/main/java/dev/loki/survivor/SurvivorMovement.java
Normal file
121
src/main/java/dev/loki/survivor/SurvivorMovement.java
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue