143 lines
4.4 KiB
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; }
|
|
}
|
|
}
|