feat(D-01/A): self-bondage region routing (A11)
- handleV2SelfBondage: split into region-based routing - NECK → blocked (cannot self-collar) - ARMS → handleV2SelfBind (tying task with progress bar) - Other → handleV2SelfAccessory (instant equip) - handleV2SelfAccessory: arms-bound check via BindModeHelper, locked check for swap, V2EquipmentHelper for conflict resolution
This commit is contained in:
@@ -14,8 +14,10 @@ import com.tiedup.remake.tasks.TyingTask;
|
||||
import com.tiedup.remake.tasks.V2TyingPlayerTask;
|
||||
import com.tiedup.remake.util.KidnappedHelper;
|
||||
import com.tiedup.remake.v2.BodyRegionV2;
|
||||
import com.tiedup.remake.v2.bondage.BindModeHelper;
|
||||
import com.tiedup.remake.v2.bondage.IV2BondageItem;
|
||||
import com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper;
|
||||
import com.tiedup.remake.v2.bondage.V2EquipResult;
|
||||
import java.util.function.Supplier;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
@@ -222,71 +224,112 @@ public class PacketSelfBondage {
|
||||
IV2BondageItem v2Item,
|
||||
IBondageState state
|
||||
) {
|
||||
java.util.Set<BodyRegionV2> regions = v2Item.getOccupiedRegions(stack);
|
||||
|
||||
// Cannot self-collar
|
||||
if (regions.contains(BodyRegionV2.NECK)) {
|
||||
TiedUpMod.LOGGER.debug("[SelfBondage] {} tried to self-collar — blocked", player.getName().getString());
|
||||
return;
|
||||
}
|
||||
|
||||
// ARMS: tying task with progress bar
|
||||
if (regions.contains(BodyRegionV2.ARMS)) {
|
||||
handleV2SelfBind(player, stack, v2Item, state);
|
||||
return;
|
||||
}
|
||||
|
||||
// Accessories (MOUTH, EYES, EARS, HANDS): instant equip
|
||||
handleV2SelfAccessory(player, stack, v2Item, state);
|
||||
}
|
||||
|
||||
private static void handleV2SelfBind(
|
||||
ServerPlayer player,
|
||||
ItemStack stack,
|
||||
IV2BondageItem v2Item,
|
||||
IBondageState state
|
||||
) {
|
||||
// Can't self-tie if already tied
|
||||
if (state.isTiedUp()) {
|
||||
TiedUpMod.LOGGER.debug("[SelfBondage] {} tried V2 self-tie but already tied", player.getName().getString());
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if all target regions are already occupied or blocked
|
||||
boolean allBlocked = true;
|
||||
for (BodyRegionV2 region : v2Item.getOccupiedRegions(stack)) {
|
||||
if (
|
||||
!V2EquipmentHelper.isRegionOccupied(player, region) &&
|
||||
!V2EquipmentHelper.isRegionBlocked(player, region)
|
||||
) {
|
||||
if (!V2EquipmentHelper.isRegionOccupied(player, region)
|
||||
&& !V2EquipmentHelper.isRegionBlocked(player, region)) {
|
||||
allBlocked = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (allBlocked) {
|
||||
TiedUpMod.LOGGER.debug(
|
||||
"[SelfBondage] {} tried V2 self-equip but all regions occupied",
|
||||
player.getName().getString()
|
||||
);
|
||||
TiedUpMod.LOGGER.debug("[SelfBondage] {} tried V2 self-equip but all regions occupied", player.getName().getString());
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerBindState playerState = PlayerBindState.getInstance(player);
|
||||
if (playerState == null) return;
|
||||
|
||||
int tyingSeconds = SettingsAccessor.getTyingPlayerTime(
|
||||
player.level().getGameRules()
|
||||
);
|
||||
int tyingSeconds = SettingsAccessor.getTyingPlayerTime(player.level().getGameRules());
|
||||
|
||||
// Create V2 tying task (uses V2EquipmentHelper on completion, NOT putBindOn)
|
||||
V2TyingPlayerTask newTask = new V2TyingPlayerTask(
|
||||
stack.copy(), // copy for display/matching
|
||||
stack, // live reference for consumption
|
||||
state,
|
||||
player, // target is self
|
||||
tyingSeconds,
|
||||
player.level(),
|
||||
player // kidnapper is also self
|
||||
stack.copy(), stack, state, player, tyingSeconds, player.level(), player
|
||||
);
|
||||
|
||||
TyingTask currentTask = playerState.getCurrentTyingTask();
|
||||
|
||||
if (
|
||||
currentTask == null ||
|
||||
!currentTask.isSameTarget(player) ||
|
||||
currentTask.isOutdated() ||
|
||||
!ItemStack.matches(currentTask.getBind(), stack)
|
||||
) {
|
||||
// Start new task
|
||||
if (currentTask == null
|
||||
|| !currentTask.isSameTarget(player)
|
||||
|| currentTask.isOutdated()
|
||||
|| !ItemStack.matches(currentTask.getBind(), stack)) {
|
||||
playerState.setCurrentTyingTask(newTask);
|
||||
newTask.start();
|
||||
|
||||
TiedUpMod.LOGGER.debug(
|
||||
"[SelfBondage] {} started V2 self-tying ({} seconds)",
|
||||
player.getName().getString(),
|
||||
tyingSeconds
|
||||
);
|
||||
} else {
|
||||
// Continue existing task — just mark active
|
||||
currentTask.update();
|
||||
}
|
||||
|
||||
// If we started a new task, mark it active too
|
||||
if (playerState.getCurrentTyingTask() == newTask) {
|
||||
newTask.update();
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleV2SelfAccessory(
|
||||
ServerPlayer player,
|
||||
ItemStack stack,
|
||||
IV2BondageItem v2Item,
|
||||
IBondageState state
|
||||
) {
|
||||
// Can't equip accessories if arms are fully bound
|
||||
ItemStack currentBind = V2EquipmentHelper.getInRegion(player, BodyRegionV2.ARMS);
|
||||
if (!currentBind.isEmpty() && BindModeHelper.hasArmsBound(currentBind)) {
|
||||
TiedUpMod.LOGGER.debug("[SelfBondage] {} can't self-accessory — arms bound", player.getName().getString());
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if region is occupied — try to swap
|
||||
for (BodyRegionV2 region : v2Item.getOccupiedRegions(stack)) {
|
||||
if (V2EquipmentHelper.isRegionOccupied(player, region)) {
|
||||
ItemStack existing = V2EquipmentHelper.getInRegion(player, region);
|
||||
// Can't swap if locked
|
||||
if (existing.getItem() instanceof ILockable lockable && lockable.isLocked(existing)) {
|
||||
TiedUpMod.LOGGER.debug("[SelfBondage] {} can't swap — current is locked", player.getName().getString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Equip via V2EquipmentHelper (handles conflict resolution, displaced items)
|
||||
V2EquipResult result = V2EquipmentHelper.equipItem(player, stack.copy());
|
||||
if (result.isSuccess()) {
|
||||
for (ItemStack displaced : result.displaced()) {
|
||||
player.spawnAtLocation(displaced);
|
||||
}
|
||||
stack.shrink(1);
|
||||
SyncManager.syncInventory(player);
|
||||
TiedUpMod.LOGGER.info("[SelfBondage] {} self-equipped V2 accessory", player.getName().getString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle self-equipping an accessory (gag, blindfold, mittens, earplugs).
|
||||
* Can be used anytime (no need to be tied).
|
||||
|
||||
Reference in New Issue
Block a user