Strip all Phase references, TODO/FUTURE roadmap notes, and internal planning comments from the codebase. Run Prettier for consistent formatting across all Java files.
161 lines
5.1 KiB
Java
161 lines
5.1 KiB
Java
package com.tiedup.remake.state.components;
|
|
|
|
import com.tiedup.remake.state.hosts.IPlayerBindStateHost;
|
|
import com.tiedup.remake.v2.BodyRegionV2;
|
|
import com.tiedup.remake.v2.bondage.IV2BondageEquipment;
|
|
import com.tiedup.remake.v2.bondage.IV2BondageItem;
|
|
import com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper;
|
|
import net.minecraft.world.entity.player.Player;
|
|
import net.minecraft.world.item.ItemStack;
|
|
|
|
/**
|
|
* Component responsible for clothes permission and management.
|
|
* Handles who can remove/change clothes and manages clothes replacement with network sync.
|
|
*
|
|
* Single Responsibility: Clothes permissions and synchronization
|
|
* Complexity: MEDIUM (network sync coordination)
|
|
* Risk: MEDIUM (must coordinate SyncManager calls)
|
|
*
|
|
* Epic 5F: Uses V2EquipmentHelper/BodyRegionV2.
|
|
*/
|
|
public class PlayerClothesPermission {
|
|
|
|
private final IPlayerBindStateHost host;
|
|
|
|
public PlayerClothesPermission(IPlayerBindStateHost host) {
|
|
this.host = host;
|
|
}
|
|
|
|
// ========== Permission Checks ==========
|
|
|
|
/**
|
|
* Check if a specific player can take off this player's clothes.
|
|
* Currently permissive - anyone can take off clothes.
|
|
* Future: Could check if 'player' is owner/master when tied up.
|
|
*
|
|
* @param player The player attempting to remove clothes
|
|
* @return true if allowed
|
|
*/
|
|
public boolean canTakeOffClothes(Player player) {
|
|
// Currently permissive - anyone can take off clothes
|
|
// Future: Could check if 'player' is owner/master when tied up
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check if a specific player can change this player's clothes.
|
|
* Currently permissive - anyone can change clothes.
|
|
* Future: Could check if 'player' is owner/master when tied up.
|
|
*
|
|
* @param player The player attempting to change clothes
|
|
* @return true if allowed
|
|
*/
|
|
public boolean canChangeClothes(Player player) {
|
|
// Currently permissive - anyone can change clothes
|
|
// Future: Could check if 'player' is owner/master when tied up
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check if clothes can be changed (no specific player context).
|
|
* Checks if no clothes are equipped, or if clothes are not locked.
|
|
*
|
|
* @return true if clothes can be changed
|
|
*/
|
|
public boolean canChangeClothes() {
|
|
ItemStack clothes = V2EquipmentHelper.getInRegion(
|
|
host.getPlayer(),
|
|
BodyRegionV2.TORSO
|
|
);
|
|
if (clothes.isEmpty()) return true;
|
|
|
|
// Check if clothes are locked
|
|
return !isLocked(clothes, false);
|
|
}
|
|
|
|
// ========== Clothes Management ==========
|
|
|
|
/**
|
|
* Replace current clothes with new clothes.
|
|
* Removes old clothes and equips new ones.
|
|
* Syncs clothes config to all clients.
|
|
*
|
|
* @param newClothes The new clothes to equip
|
|
* @return The old clothes, or empty if none
|
|
*/
|
|
public ItemStack replaceClothes(ItemStack newClothes) {
|
|
return replaceClothes(newClothes, false);
|
|
}
|
|
|
|
/**
|
|
* Replace current clothes with new clothes, with optional force.
|
|
* If force is true, bypasses lock checks.
|
|
* Syncs clothes config to all clients.
|
|
*
|
|
* @param newClothes The new clothes to equip
|
|
* @param force true to bypass lock checks
|
|
* @return The old clothes, or empty if none
|
|
*/
|
|
public ItemStack replaceClothes(ItemStack newClothes, boolean force) {
|
|
Player player = host.getPlayer();
|
|
if (
|
|
player == null || player.level().isClientSide
|
|
) return ItemStack.EMPTY;
|
|
|
|
IV2BondageEquipment equip = V2EquipmentHelper.getEquipment(player);
|
|
if (equip == null) return ItemStack.EMPTY;
|
|
|
|
// Take off old clothes
|
|
ItemStack old = V2EquipmentHelper.unequipFromRegion(
|
|
player,
|
|
BodyRegionV2.TORSO
|
|
);
|
|
|
|
// Equip new clothes if we successfully removed old ones
|
|
if (!old.isEmpty()) {
|
|
equip.setInRegion(BodyRegionV2.TORSO, newClothes.copy());
|
|
|
|
// Fire lifecycle hook for new item
|
|
if (
|
|
!newClothes.isEmpty() &&
|
|
newClothes.getItem() instanceof IV2BondageItem newItem
|
|
) {
|
|
newItem.onEquipped(newClothes, player);
|
|
}
|
|
|
|
V2EquipmentHelper.sync(player);
|
|
|
|
// CRITICAL: Sync clothes config to all tracking clients
|
|
// This ensures dynamic textures and other clothes properties are synced
|
|
host.syncClothesConfig();
|
|
}
|
|
|
|
return old;
|
|
}
|
|
|
|
// ========== Helper Methods ==========
|
|
|
|
/**
|
|
* Check if an item is locked.
|
|
* Helper method for lock checking.
|
|
*
|
|
* @param stack The item to check
|
|
* @param force If true, returns false (bypasses lock)
|
|
* @return true if locked and not forced
|
|
*/
|
|
private boolean isLocked(ItemStack stack, boolean force) {
|
|
if (force) return false;
|
|
if (stack.isEmpty()) return false;
|
|
|
|
// Check if item has locked property
|
|
if (
|
|
stack.getItem() instanceof
|
|
com.tiedup.remake.items.base.ILockable lockable
|
|
) {
|
|
return lockable.isLocked(stack);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|