Remove build artifacts, dev tool configs, unused dependencies, and third-party source dumps. Add proper README, update .gitignore, clean up Makefile.
187 lines
5.6 KiB
Java
187 lines
5.6 KiB
Java
package com.tiedup.remake.minigame;
|
|
|
|
import com.tiedup.remake.core.TiedUpMod;
|
|
import java.util.Map;
|
|
import java.util.UUID;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
import net.minecraft.server.level.ServerPlayer;
|
|
import net.minecraft.sounds.SoundEvents;
|
|
import net.minecraft.sounds.SoundSource;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
/**
|
|
* Manages lockpick mini-game sessions.
|
|
*
|
|
* <p>Extracted from {@link MiniGameSessionManager} (M15 split) to give lockpick
|
|
* sessions their own focused manager. Singleton, thread-safe via ConcurrentHashMap.
|
|
*/
|
|
public class LockpickSessionManager {
|
|
|
|
private static final LockpickSessionManager INSTANCE =
|
|
new LockpickSessionManager();
|
|
|
|
/**
|
|
* Active lockpick mini-game sessions by player UUID
|
|
*/
|
|
private final Map<UUID, LockpickMiniGameState> lockpickSessions =
|
|
new ConcurrentHashMap<>();
|
|
|
|
private LockpickSessionManager() {}
|
|
|
|
public static LockpickSessionManager getInstance() {
|
|
return INSTANCE;
|
|
}
|
|
|
|
/**
|
|
* Start a new lockpick session for a player.
|
|
* If player already has an active session, it will be replaced (handles ESC cancel case).
|
|
*
|
|
* @param player The server player
|
|
* @param targetSlot The bondage slot being picked
|
|
* @param sweetSpotWidth The width of the sweet spot (based on tool)
|
|
* @return The new session
|
|
*/
|
|
public LockpickMiniGameState startLockpickSession(
|
|
ServerPlayer player,
|
|
int targetSlot,
|
|
float sweetSpotWidth
|
|
) {
|
|
UUID playerId = player.getUUID();
|
|
|
|
// Check for existing session - remove it (handles ESC cancel case)
|
|
LockpickMiniGameState existing = lockpickSessions.get(playerId);
|
|
if (existing != null) {
|
|
TiedUpMod.LOGGER.debug(
|
|
"[LockpickSessionManager] Replacing existing lockpick session for {}",
|
|
player.getName().getString()
|
|
);
|
|
lockpickSessions.remove(playerId);
|
|
}
|
|
|
|
// Create new session
|
|
LockpickMiniGameState session = new LockpickMiniGameState(
|
|
playerId,
|
|
targetSlot,
|
|
sweetSpotWidth
|
|
);
|
|
lockpickSessions.put(playerId, session);
|
|
|
|
TiedUpMod.LOGGER.info(
|
|
"[LockpickSessionManager] Started lockpick session {} for {} (slot: {}, width: {}%)",
|
|
session.getSessionId().toString().substring(0, 8),
|
|
player.getName().getString(),
|
|
targetSlot,
|
|
(int) (sweetSpotWidth * 100)
|
|
);
|
|
|
|
// Notify nearby guards about lockpicking attempt
|
|
GuardNotificationHelper.notifyNearbyKidnappersOfStruggle(player);
|
|
|
|
return session;
|
|
}
|
|
|
|
/**
|
|
* Play lockpick attempt sound and notify guards.
|
|
* Called when player attempts to pick (tests position).
|
|
*
|
|
* @param player The player attempting to pick
|
|
*/
|
|
public void onLockpickAttempt(ServerPlayer player) {
|
|
// Play metallic clicking sound
|
|
player
|
|
.serverLevel()
|
|
.playSound(
|
|
null,
|
|
player.getX(),
|
|
player.getY(),
|
|
player.getZ(),
|
|
SoundEvents.CHAIN_HIT,
|
|
SoundSource.PLAYERS,
|
|
0.6f,
|
|
1.2f + player.getRandom().nextFloat() * 0.3f
|
|
);
|
|
|
|
// Notify guards
|
|
GuardNotificationHelper.notifyNearbyKidnappersOfStruggle(player);
|
|
}
|
|
|
|
/**
|
|
* Get active lockpick session for a player.
|
|
*
|
|
* @param playerId The player UUID
|
|
* @return The session, or null if none active
|
|
*/
|
|
@Nullable
|
|
public LockpickMiniGameState getLockpickSession(UUID playerId) {
|
|
LockpickMiniGameState session = lockpickSessions.get(playerId);
|
|
if (session != null && session.isExpired()) {
|
|
lockpickSessions.remove(playerId);
|
|
return null;
|
|
}
|
|
return session;
|
|
}
|
|
|
|
/**
|
|
* Validate a lockpick session.
|
|
*
|
|
* @param playerId The player UUID
|
|
* @param sessionId The session UUID to validate
|
|
* @return true if session is valid and active
|
|
*/
|
|
public boolean validateLockpickSession(UUID playerId, UUID sessionId) {
|
|
LockpickMiniGameState session = getLockpickSession(playerId);
|
|
if (session == null) {
|
|
return false;
|
|
}
|
|
return session.getSessionId().equals(sessionId);
|
|
}
|
|
|
|
/**
|
|
* End a lockpick session.
|
|
*
|
|
* @param playerId The player UUID
|
|
* @param success Whether the session ended in success
|
|
*/
|
|
public void endLockpickSession(UUID playerId, boolean success) {
|
|
LockpickMiniGameState session = lockpickSessions.remove(playerId);
|
|
if (session != null) {
|
|
TiedUpMod.LOGGER.info(
|
|
"[LockpickSessionManager] Ended lockpick session for player {} (success: {})",
|
|
playerId.toString().substring(0, 8),
|
|
success
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clean up all lockpick sessions for a player (called on disconnect).
|
|
*
|
|
* @param playerId The player UUID
|
|
*/
|
|
public void cleanupPlayer(UUID playerId) {
|
|
lockpickSessions.remove(playerId);
|
|
}
|
|
|
|
/**
|
|
* Periodic cleanup of expired lockpick sessions.
|
|
* Should be called from server tick handler.
|
|
*/
|
|
public void tickCleanup(long currentTick) {
|
|
// Only run every 100 ticks (5 seconds)
|
|
if (currentTick % 100 != 0) {
|
|
return;
|
|
}
|
|
|
|
lockpickSessions
|
|
.entrySet()
|
|
.removeIf(entry -> entry.getValue().isExpired());
|
|
}
|
|
|
|
/**
|
|
* Get count of active lockpick sessions (for debugging).
|
|
*/
|
|
public int getActiveSessionCount() {
|
|
return lockpickSessions.size();
|
|
}
|
|
}
|