mdbd/src/main/java/dev/loki/hook/HookRescue.java

143 lines
4.4 KiB
Java

package dev.loki.hook;
import dev.loki.mdbd;
import dev.loki.player.PlayerState;
import dev.loki.player.Survivor;
import dev.loki.ui.ActionBar;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class HookRescue {
private final mdbd plugin;
private final ActionBar actionBar;
private final Map<UUID, RescueSession> activeRescues;
private static final int RESCUE_DURATION_TICKS = 40;
private static final double RESCUE_RANGE = 3.0;
public HookRescue(mdbd plugin, ActionBar actionBar) {
this.plugin = plugin;
this.actionBar = actionBar;
this.activeRescues = new HashMap<>();
}
public boolean startRescue(Survivor rescuer, Hook hook) {
UUID uuid = rescuer.getUuid();
if (activeRescues.containsKey(uuid)) return false;
if (!hook.isOccupied() || hook.getHookedSurvivor() == null) return false;
Location hookLoc = hook.getLocation();
Player player = rescuer.getPlayer();
if (player == null || player.getLocation().distance(hookLoc) > RESCUE_RANGE) {
return false;
}
RescueSession session = new RescueSession(rescuer, hook, RESCUE_DURATION_TICKS);
activeRescues.put(uuid, session);
BukkitTask task = plugin.getServer().getScheduler().runTaskTimer(
plugin,
() -> tickRescue(uuid),
1L, 1L
);
session.setTask(task);
return true;
}
private void tickRescue(UUID uuid) {
RescueSession session = activeRescues.get(uuid);
if (session == null) return;
Survivor rescuer = session.getRescuer();
Hook hook = session.getHook();
Player player = rescuer.getPlayer();
if (player == null || !player.isOnline()) {
cancelRescue(uuid);
return;
}
if (player.getLocation().distance(hook.getLocation()) > RESCUE_RANGE) {
cancelRescue(uuid);
actionBar.sendMessage(player, "<red>Rescue cancelled - too far!");
return;
}
session.incrementProgress();
double percent = session.getProgressPercent();
actionBar.showProgress(player, "Rescuing...", percent);
if (session.isComplete()) {
completeRescue(session);
activeRescues.remove(uuid);
}
}
private void completeRescue(RescueSession session) {
Survivor rescuer = session.getRescuer();
Hook hook = session.getHook();
Survivor victim = hook.getHookedSurvivor();
hook.unhookSurvivor();
if (victim != null) {
victim.setState(PlayerState.INJURED);
Player victimPlayer = victim.getPlayer();
if (victimPlayer != null) {
victimPlayer.teleport(hook.getLocation().clone().add(1, 0, 0));
}
}
Player rescuerPlayer = rescuer.getPlayer();
if (rescuerPlayer != null) {
actionBar.sendMessage(rescuerPlayer, "<green>Rescue complete!");
}
}
public void cancelRescue(UUID uuid) {
RescueSession session = activeRescues.remove(uuid);
if (session != null) {
session.cancel();
}
}
public boolean isRescuing(UUID uuid) {
return activeRescues.containsKey(uuid);
}
public void clear() {
for (RescueSession session : activeRescues.values()) {
session.cancel();
}
activeRescues.clear();
}
private static class RescueSession {
private final Survivor rescuer;
private final Hook hook;
private final int durationTicks;
private int progressTicks;
private BukkitTask task;
RescueSession(Survivor rescuer, Hook hook, int durationTicks) {
this.rescuer = rescuer;
this.hook = hook;
this.durationTicks = durationTicks;
this.progressTicks = 0;
}
void incrementProgress() { progressTicks++; }
boolean isComplete() { return progressTicks >= durationTicks; }
double getProgressPercent() { return (double) progressTicks / durationTicks * 100; }
void setTask(BukkitTask task) { this.task = task; }
void cancel() { if (task != null) task.cancel(); }
Survivor getRescuer() { return rescuer; }
Hook getHook() { return hook; }
}
}