Files
TiedUp-/src/main/java/com/tiedup/remake/v2/bondage/BindModeHelper.java
NotEvil 751bad418d feat(D-01/A): poseType, helpers, OWNERSHIP ComponentType (A4, A5, A6)
- DataDrivenItemDefinition: add poseType field, parsed from JSON "pose_type"
- PoseTypeHelper: resolves PoseType from V2 definition or V1 ItemBind fallback
- BindModeHelper: static bind mode NBT utilities (isBindItem, hasArmsBound,
  hasLegsBound, cycleBindModeId) — works for V1 and V2 items
- CollarHelper: complete static utility class for collar operations with
  dual-path V2/V1 dispatch (ownership, features, shock, GPS, choke, alert)
- ComponentType: add OWNERSHIP enum value
- OwnershipComponent: stub class (lifecycle hooks added in next commit)
2026-04-14 15:23:08 +02:00

96 lines
3.4 KiB
Java

package com.tiedup.remake.v2.bondage;
import com.tiedup.remake.items.base.ItemBind;
import com.tiedup.remake.v2.BodyRegionV2;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemDefinition;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemRegistry;
import java.util.Map;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;
/**
* Static utilities for bind mode operations on any bondage item stack (V1 or V2).
*
* <p>Bind mode determines whether a bind restrains arms, legs, or both.
* The mode is stored in the stack's NBT tag {@code "bindMode"}.</p>
*/
public final class BindModeHelper {
private BindModeHelper() {}
private static final String NBT_BIND_MODE = "bindMode";
public static final String MODE_FULL = "full";
public static final String MODE_ARMS = "arms";
public static final String MODE_LEGS = "legs";
private static final String[] MODE_CYCLE = { MODE_FULL, MODE_ARMS, MODE_LEGS };
private static final Map<String, String> MODE_TRANSLATION_KEYS = Map.of(
MODE_FULL, "tiedup.bindmode.full",
MODE_ARMS, "tiedup.bindmode.arms",
MODE_LEGS, "tiedup.bindmode.legs"
);
/**
* Check if the given stack is a bind item (V2 ARMS-region item or V1 ItemBind).
*/
public static boolean isBindItem(ItemStack stack) {
if (stack.isEmpty()) return false;
// V2: check data-driven definition
DataDrivenItemDefinition def = DataDrivenItemRegistry.get(stack);
if (def != null) {
return def.occupiedRegions().contains(BodyRegionV2.ARMS);
}
// V1 fallback
return stack.getItem() instanceof ItemBind;
}
/**
* Get the bind mode ID from the stack's NBT.
* @return "full", "arms", or "legs" (defaults to "full")
*/
public static String getBindModeId(ItemStack stack) {
if (stack.isEmpty()) return MODE_FULL;
CompoundTag tag = stack.getTag();
if (tag == null || !tag.contains(NBT_BIND_MODE)) return MODE_FULL;
String value = tag.getString(NBT_BIND_MODE);
if (MODE_ARMS.equals(value) || MODE_LEGS.equals(value)) return value;
return MODE_FULL;
}
/** True if arms are restrained (mode is "arms" or "full"). */
public static boolean hasArmsBound(ItemStack stack) {
String mode = getBindModeId(stack);
return MODE_ARMS.equals(mode) || MODE_FULL.equals(mode);
}
/** True if legs are restrained (mode is "legs" or "full"). */
public static boolean hasLegsBound(ItemStack stack) {
String mode = getBindModeId(stack);
return MODE_LEGS.equals(mode) || MODE_FULL.equals(mode);
}
/**
* Cycle bind mode: full → arms → legs → full.
* @return the new mode ID
*/
public static String cycleBindModeId(ItemStack stack) {
String current = getBindModeId(stack);
String next = MODE_FULL;
for (int i = 0; i < MODE_CYCLE.length; i++) {
if (MODE_CYCLE[i].equals(current)) {
next = MODE_CYCLE[(i + 1) % MODE_CYCLE.length];
break;
}
}
stack.getOrCreateTag().putString(NBT_BIND_MODE, next);
return next;
}
/** Get the translation key for the current bind mode. */
public static String getBindModeTranslationKey(ItemStack stack) {
return MODE_TRANSLATION_KEYS.getOrDefault(getBindModeId(stack), "tiedup.bindmode.full");
}
}