Files
TiedUp-/src/main/java/com/tiedup/remake/state/components/PlayerLifecycle.java
NotEvil a71093ba9c Remove internal phase comments and format code
Strip all Phase references, TODO/FUTURE roadmap notes, and internal
planning comments from the codebase. Run Prettier for consistent
formatting across all Java files.
2026-04-12 01:25:55 +02:00

155 lines
5.3 KiB
Java

package com.tiedup.remake.state.components;
import com.tiedup.remake.cells.CampOwnership;
import com.tiedup.remake.cells.CellRegistryV2;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.items.base.ItemBind;
import com.tiedup.remake.state.hosts.IPlayerBindStateHost;
import com.tiedup.remake.v2.BodyRegionV2;
import java.util.UUID;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
/**
* Component responsible for player lifecycle management.
* Handles connection, death, respawn scenarios.
*
* Single Responsibility: Lifecycle events and registry coordination
* Complexity: HIGH (coordinates 4+ registries on death)
* Risk: HIGH (critical path, must maintain registry cleanup order)
*
* Registry Cleanup Order (on death):
* 1. CellRegistryV2 - remove from cells
* 2. PrisonerManager - release prisoner (via PrisonerService)
*/
public class PlayerLifecycle {
private final IPlayerBindStateHost host;
public PlayerLifecycle(IPlayerBindStateHost host) {
this.host = host;
}
// ========== Lifecycle Methods ==========
/**
* Resets the player instance upon reconnection or respawn.
*
* IMPORTANT: Handle transport restoration for pole binding.
* With proxy-based leash system, leashes are not persisted through disconnection.
* The leash proxy is ephemeral and will be recreated if needed.
*
* Leg Binding: Speed reduction based on hasLegsBound(), not isTiedUp().
*/
public void resetNewConnection(Player player) {
// Update player reference
host.setOnline(true);
host.setCaptor(null);
// Reset struggle animation state (prevent stuck animations)
host.setStrugglingClient(false);
// Leash proxy doesn't persist through disconnection
// If player was leashed, they are now freed
// H6 fix: V1 speed reduction re-application is no longer needed for players.
// MovementStyleManager (V2 tick-based system) re-resolves the active movement
// style on the first tick after login (clearMovementState() resets activeMovementStyle
// to null, triggering a fresh activation). The V1 RestraintEffectUtils call here would
// cause double stacking with the V2 MULTIPLY_BASE modifier.
}
/**
* Called when the kidnapped player dies.
* Comprehensive cleanup: unlock items, drop items, free captivity, cleanup registries.
*
* @param world The world/level where death occurred
* @return true if death was handled
*/
public boolean onDeathKidnapped(Level world) {
Player player = host.getPlayer();
// Mark player as offline
host.setOnline(false);
// Clean up all registries on death (server-side only)
if (world instanceof ServerLevel serverLevel) {
UUID playerId = player.getUUID();
cleanupRegistries(serverLevel, playerId);
}
TiedUpMod.LOGGER.debug(
"[PlayerLifecycle] {} died while kidnapped",
player.getName().getString()
);
return true;
}
/**
* Coordinates cleanup of all registries when player dies.
* Order matters: Cell → Camp → Ransom → Prisoner
*
* @param serverLevel The server level
* @param playerId The player's UUID
*/
private void cleanupRegistries(ServerLevel serverLevel, UUID playerId) {
String playerName = host.getPlayer().getName().getString();
// 1. Clean up CellRegistryV2 - remove from any cells
CellRegistryV2 cellRegistry = CellRegistryV2.get(serverLevel);
int cellsRemoved = cellRegistry.releasePrisonerFromAllCells(playerId);
if (cellsRemoved > 0) {
TiedUpMod.LOGGER.debug(
"[PlayerLifecycle] Removed {} from {} cells on death",
playerName,
cellsRemoved
);
}
// 2. Clean up prisoner state - release from imprisonment
com.tiedup.remake.prison.PrisonerManager manager =
com.tiedup.remake.prison.PrisonerManager.get(serverLevel);
com.tiedup.remake.prison.PrisonerState state = manager.getState(
playerId
);
// Release if imprisoned or working (player died)
if (
state == com.tiedup.remake.prison.PrisonerState.IMPRISONED ||
state == com.tiedup.remake.prison.PrisonerState.WORKING
) {
// Use centralized escape service for complete cleanup
com.tiedup.remake.prison.service.PrisonerService.get().escape(
serverLevel,
playerId,
"player_death"
);
}
}
// ========== Helper Methods ==========
/**
* Get the current bind ItemStack.
* Epic 5F: Migrated to V2EquipmentHelper.
*/
private ItemStack getCurrentBind() {
return com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper.getInRegion(
host.getPlayer(),
com.tiedup.remake.v2.BodyRegionV2.ARMS
);
}
/**
* Check if player has legs bound.
*/
private boolean hasLegsBound(ItemStack bind) {
if (bind.isEmpty()) return false;
if (!(bind.getItem() instanceof ItemBind)) return false;
return ItemBind.hasLegsBound(bind);
}
}