package com.tiedup.remake.cells; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import net.minecraft.core.BlockPos; import org.jetbrains.annotations.Nullable; /** * Server-side manager tracking which players are in selection mode * (Set Spawn, Set Delivery, Set Disguise) after clicking a Cell Core menu button. * * Static map pattern matching ForcedSeatingHandler. */ public class CellSelectionManager { private static final long TIMEOUT_MS = 30 * 1000L; private static final double MAX_DISTANCE_SQ = 10.0 * 10.0; private static final ConcurrentHashMap selections = new ConcurrentHashMap<>(); public static class SelectionContext { public final SelectionMode mode; public final BlockPos corePos; public final UUID cellId; public final long startTimeMs; public final BlockPos playerStartPos; public SelectionContext( SelectionMode mode, BlockPos corePos, UUID cellId, BlockPos playerStartPos ) { this.mode = mode; this.corePos = corePos; this.cellId = cellId; this.startTimeMs = System.currentTimeMillis(); this.playerStartPos = playerStartPos; } } public static void startSelection( UUID playerId, SelectionMode mode, BlockPos corePos, UUID cellId, BlockPos playerPos ) { selections.put( playerId, new SelectionContext(mode, corePos, cellId, playerPos) ); } @Nullable public static SelectionContext getSelection(UUID playerId) { return selections.get(playerId); } public static void clearSelection(UUID playerId) { selections.remove(playerId); } public static boolean isInSelectionMode(UUID playerId) { return selections.containsKey(playerId); } /** * Check if selection should be cancelled due to timeout or distance. */ public static boolean shouldCancel(UUID playerId, BlockPos currentPos) { SelectionContext ctx = selections.get(playerId); if (ctx == null) return false; // Timeout check if (System.currentTimeMillis() - ctx.startTimeMs > TIMEOUT_MS) { return true; } // Distance check (from core, not player start) if (ctx.corePos.distSqr(currentPos) > MAX_DISTANCE_SQ) { return true; } return false; } /** * Called on player disconnect to prevent memory leaks. */ public static void cleanup(UUID playerId) { selections.remove(playerId); } }