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,168 @@
package dev.loki.ui;
import dev.loki.mdbd;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.title.Title;
import org.bukkit.entity.Player;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.function.Consumer;
public class TitleUI {
private final mdbd plugin;
private final Map<UUID, SkillCheckState> activeSkillChecks;
public TitleUI(mdbd plugin) {
this.plugin = plugin;
this.activeSkillChecks = new HashMap<>();
}
public void showGameStart(Player player, boolean isKiller) {
Title.Times times = Title.Times.times(
Duration.ofMillis(500),
Duration.ofSeconds(3),
Duration.ofMillis(500)
);
Component title;
Component subtitle;
if (isKiller) {
title = Component.text("KILLER")
.color(NamedTextColor.DARK_RED)
.decoration(TextDecoration.BOLD, true);
subtitle = Component.text("Sacrifice them all")
.color(NamedTextColor.RED);
} else {
title = Component.text("SURVIVOR")
.color(NamedTextColor.DARK_GREEN)
.decoration(TextDecoration.BOLD, true);
subtitle = Component.text("Repair generators and escape")
.color(NamedTextColor.GREEN);
}
player.showTitle(Title.title(title, subtitle, times));
}
public void showVictory(Player player, boolean escaped) {
Title.Times times = Title.Times.times(
Duration.ofMillis(500),
Duration.ofSeconds(5),
Duration.ofSeconds(1)
);
Component title = escaped
? Component.text("ESCAPED!")
.color(NamedTextColor.GREEN)
.decoration(TextDecoration.BOLD, true)
: Component.text("VICTORY!")
.color(NamedTextColor.DARK_RED)
.decoration(TextDecoration.BOLD, true);
Component subtitle = escaped
? Component.text("You survived the night")
.color(NamedTextColor.DARK_GREEN)
: Component.text("All survivors sacrificed")
.color(NamedTextColor.RED);
player.showTitle(Title.title(title, subtitle, times));
}
public void showDefeat(Player player) {
Title.Times times = Title.Times.times(
Duration.ofMillis(500),
Duration.ofSeconds(5),
Duration.ofSeconds(1)
);
Component title = Component.text("DEFEAT")
.color(NamedTextColor.DARK_RED)
.decoration(TextDecoration.BOLD, true);
Component subtitle = Component.text("The Entity claims all")
.color(NamedTextColor.RED);
player.showTitle(Title.title(title, subtitle, times));
}
public void showSkillCheck(Player player, int windowTicks, Consumer<Boolean> callback) {
UUID uuid = player.getUniqueId();
if (activeSkillChecks.containsKey(uuid)) {
callback.accept(false);
return;
}
int startTick = plugin.getServer().getCurrentTick();
int successStart = startTick + (windowTicks / 2);
int successEnd = successStart + (windowTicks / 2);
SkillCheckState state = new SkillCheckState(startTick, successStart, successEnd, callback);
activeSkillChecks.put(uuid, state);
plugin.getServer().getScheduler().runTaskTimer(plugin, task -> {
int currentTick = plugin.getServer().getCurrentTick();
SkillCheckState checkState = activeSkillChecks.get(uuid);
if (checkState == null || player.isSneaking()) {
task.cancel();
boolean success = checkState != null && currentTick >= checkState.successStart
&& currentTick <= checkState.successEnd;
activeSkillChecks.remove(uuid);
callback.accept(success);
return;
}
if (currentTick > checkState.successEnd + 5) {
task.cancel();
activeSkillChecks.remove(uuid);
callback.accept(false);
return;
}
renderSkillCheck(player, checkState, currentTick);
}, 1L, 1L);
}
private void renderSkillCheck(Player player, SkillCheckState state, int currentTick) {
double progress = (currentTick - state.startTick) / 40.0;
int position = (int) (progress * 20) % 21;
StringBuilder visual = new StringBuilder();
int successStartPos = (int) ((state.successStart - state.startTick) / 40.0 * 20);
int successEndPos = (int) ((state.successEnd - state.startTick) / 40.0 * 20);
for (int i = 0; i <= 20; i++) {
if (i == position) {
visual.append("◆");
} else if (i >= successStartPos && i <= successEndPos) {
visual.append("░");
} else {
visual.append("─");
}
}
Component title = Component.text(visual.toString())
.color(NamedTextColor.WHITE);
Component subtitle = Component.text("CROUCH when in the zone!")
.color(NamedTextColor.YELLOW);
Title.Times times = Title.Times.times(Duration.ZERO, Duration.ofMillis(100), Duration.ZERO);
player.showTitle(Title.title(title, subtitle, times));
}
public void clearSkillChecks() {
for (SkillCheckState state : activeSkillChecks.values()) {
state.callback().accept(false);
}
activeSkillChecks.clear();
}
private record SkillCheckState(int startTick, int successStart, int successEnd, Consumer<Boolean> callback) {}
}