feat(D-01/C): consumer migration — 85 files migrated to V2 helpers

Phase 1 (state): PlayerBindState, PlayerCaptorManager, PlayerEquipment,
  PlayerDataRetrieval, PlayerLifecycle, PlayerShockCollar, StruggleAccessory
Phase 2 (client): AnimationTickHandler, NpcAnimationTickHandler, 5 render
  handlers, DamselModel, 3 client mixins, SelfBondageInputHandler,
  SlaveManagementScreen, ActionPanel, SlaveEntryWidget, ModKeybindings
Phase 3 (entities): 28 entity/AI files migrated to CollarHelper,
  BindModeHelper, PoseTypeHelper, createStack()
Phase 4 (network): PacketSlaveAction, PacketMasterEquip,
  PacketAssignCellToCollar, PacketNpcCommand, PacketFurnitureForcemount
Phase 5 (events): RestraintTaskTickHandler, PetPlayRestrictionHandler,
  PlayerEnslavementHandler, ChatEventHandler, LaborAttackPunishmentHandler
Phase 6 (commands): BondageSubCommand, CollarCommand, NPCCommand,
  KidnapSetCommand
Phase 7 (compat): MCAKidnappedAdapter, MCA mixins
Phase 8 (misc): GagTalkManager, PetRequestManager, HangingCagePiece,
  BondageItemBlockEntity, TrappedChestBlockEntity, DispenserBehaviors,
  BondageItemLoaderUtility, RestraintApplicator, StruggleSessionManager,
  MovementStyleResolver, CampLifecycleManager

Some files retain dual V1/V2 checks (instanceof V1 || V2Helper) for
coexistence — V1-only branches removed in Branch D.
This commit is contained in:
NotEvil
2026-04-15 00:16:50 +02:00
parent 52d1044e9a
commit 3d61c9e9e6
85 changed files with 2885 additions and 777 deletions

View File

@@ -4,7 +4,12 @@ import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.entities.damsel.components.*;
import com.tiedup.remake.entities.skins.Gender;
import com.tiedup.remake.items.base.ILockable;
import com.tiedup.remake.items.base.ItemCollar;
import com.tiedup.remake.v2.bondage.CollarHelper;
import com.tiedup.remake.v2.bondage.PoseTypeHelper;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem;
import com.tiedup.remake.v2.bondage.component.ComponentType;
import com.tiedup.remake.v2.bondage.component.GaggingComponent;
import com.tiedup.remake.v2.bondage.component.BlindingComponent;
import com.tiedup.remake.state.ICaptor;
import com.tiedup.remake.state.IRestrainable;
import com.tiedup.remake.state.IRestrainableEntity;
@@ -455,16 +460,8 @@ public abstract class AbstractTiedUpNpc
*/
public boolean isDogPose() {
ItemStack bind = this.getEquipment(BodyRegionV2.ARMS);
if (
bind.getItem() instanceof
com.tiedup.remake.items.base.ItemBind itemBind
) {
return (
itemBind.getPoseType() ==
com.tiedup.remake.items.base.PoseType.DOG
);
}
return false;
if (bind.isEmpty()) return false;
return PoseTypeHelper.getPoseType(bind) == com.tiedup.remake.items.base.PoseType.DOG;
}
/**
@@ -679,10 +676,8 @@ public abstract class AbstractTiedUpNpc
// Exception: collar owner can leash even if not tied
if (this.hasCollar()) {
ItemStack collar = this.getEquipment(BodyRegionV2.NECK);
if (collar.getItem() instanceof ItemCollar collarItem) {
if (collarItem.getOwners(collar).contains(player.getUUID())) {
return true;
}
if (CollarHelper.isOwner(collar, player)) {
return true;
}
}
@@ -801,20 +796,16 @@ public abstract class AbstractTiedUpNpc
public boolean hasGaggingEffect() {
ItemStack gag = this.getEquipment(BodyRegionV2.MOUTH);
if (gag.isEmpty()) return false;
return (
gag.getItem() instanceof
com.tiedup.remake.items.base.IHasGaggingEffect
);
if (DataDrivenBondageItem.getComponent(gag, ComponentType.GAGGING, GaggingComponent.class) != null) return true;
return gag.getItem() instanceof com.tiedup.remake.items.base.IHasGaggingEffect;
}
@Override
public boolean hasBlindingEffect() {
ItemStack blindfold = this.getEquipment(BodyRegionV2.EYES);
if (blindfold.isEmpty()) return false;
return (
blindfold.getItem() instanceof
com.tiedup.remake.items.base.IHasBlindingEffect
);
if (DataDrivenBondageItem.getComponent(blindfold, ComponentType.BLINDING, BlindingComponent.class) != null) return true;
return blindfold.getItem() instanceof com.tiedup.remake.items.base.IHasBlindingEffect;
}
@Override
@@ -990,9 +981,9 @@ public abstract class AbstractTiedUpNpc
ItemStack collar = this.getEquipment(BodyRegionV2.NECK);
if (collar.isEmpty()) return false;
if (!(collar.getItem() instanceof ItemCollar itemCollar)) return false;
if (!CollarHelper.isCollar(collar)) return false;
java.util.UUID cellId = itemCollar.getCellId(collar);
java.util.UUID cellId = CollarHelper.getCellId(collar);
if (cellId == null) return false;
// Get cell position from registry

View File

@@ -1,10 +1,9 @@
package com.tiedup.remake.entities;
import com.tiedup.remake.core.SystemMessageManager;
import com.tiedup.remake.items.ModItems;
import com.tiedup.remake.items.base.BindVariant;
import com.tiedup.remake.items.base.GagVariant;
import com.tiedup.remake.items.base.ItemCollar;
import com.tiedup.remake.v2.bondage.CollarHelper;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem;
import net.minecraft.resources.ResourceLocation;
import com.tiedup.remake.state.PlayerBindState;
import com.tiedup.remake.util.MessageDispatcher;
import com.tiedup.remake.util.teleport.Position;
@@ -53,13 +52,10 @@ public class BondageServiceHandler {
if (!npc.hasCollar()) return false;
ItemStack collar = npc.getEquipment(BodyRegionV2.NECK);
if (collar.getItem() instanceof ItemCollar itemCollar) {
return (
itemCollar.hasCellAssigned(collar) &&
itemCollar.isBondageServiceEnabled(collar)
);
}
return false;
return (
CollarHelper.hasCellAssigned(collar) &&
CollarHelper.isBondageServiceEnabled(collar)
);
}
/**
@@ -70,11 +66,9 @@ public class BondageServiceHandler {
public String getMessage() {
if (npc.hasCollar()) {
ItemStack collar = npc.getEquipment(BodyRegionV2.NECK);
if (collar.getItem() instanceof ItemCollar itemCollar) {
String message = itemCollar.getServiceSentence(collar);
if (message != null && !message.isEmpty()) {
return message;
}
String message = CollarHelper.getServiceSentence(collar);
if (message != null && !message.isEmpty()) {
return message;
}
}
return DEFAULT_MESSAGE;
@@ -119,9 +113,9 @@ public class BondageServiceHandler {
*/
private void capturePlayer(Player player) {
ItemStack collar = npc.getEquipment(BodyRegionV2.NECK);
if (!(collar.getItem() instanceof ItemCollar itemCollar)) return;
if (!CollarHelper.isCollar(collar)) return;
java.util.UUID cellId = itemCollar.getCellId(collar);
java.util.UUID cellId = CollarHelper.getCellId(collar);
if (cellId == null) return;
// Get cell position from registry
@@ -141,7 +135,7 @@ public class BondageServiceHandler {
);
// Warn masters if configured
warnOwners(player, itemCollar, collar);
warnOwners(player, collar);
// Get player's kidnapped state
PlayerBindState state = PlayerBindState.getInstance(player);
@@ -149,18 +143,18 @@ public class BondageServiceHandler {
// Apply bondage
state.equip(
BodyRegionV2.ARMS,
new ItemStack(ModItems.getBind(BindVariant.ROPES))
DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "ropes"))
);
state.equip(
BodyRegionV2.MOUTH,
new ItemStack(ModItems.getGag(GagVariant.BALL_GAG))
DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "ball_gag"))
);
// Teleport to cell
state.teleportToPosition(cellPosition);
// Tie to pole if configured on collar
if (itemCollar.shouldTieToPole(collar)) {
if (CollarHelper.shouldTieToPole(collar)) {
state.tieToClosestPole(3);
}
}
@@ -178,10 +172,9 @@ public class BondageServiceHandler {
*/
private void warnOwners(
Player capturedPlayer,
ItemCollar itemCollar,
ItemStack collarStack
) {
if (!itemCollar.shouldWarnMasters(collarStack)) {
if (!CollarHelper.shouldWarnMasters(collarStack)) {
return;
}
@@ -191,7 +184,7 @@ public class BondageServiceHandler {
capturedPlayer.getName().getString() +
" via bondage service!";
for (UUID ownerUUID : itemCollar.getOwners(collarStack)) {
for (UUID ownerUUID : CollarHelper.getOwners(collarStack)) {
Player owner = npc.level().getPlayerByUUID(ownerUUID);
if (owner != null) {
SystemMessageManager.sendChatToPlayer(

View File

@@ -5,7 +5,7 @@ import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.entities.damsel.components.*;
import com.tiedup.remake.entities.skins.DamselSkinManager;
import com.tiedup.remake.entities.skins.Gender;
import com.tiedup.remake.items.base.ItemCollar;
import com.tiedup.remake.v2.bondage.CollarHelper;
import com.tiedup.remake.state.ICaptor;
import com.tiedup.remake.v2.BodyRegionV2;
import java.util.UUID;
@@ -527,8 +527,8 @@ public class EntityDamsel
if (!this.hasCollar()) return false;
ItemStack collar = this.getEquipment(BodyRegionV2.NECK);
if (!(collar.getItem() instanceof ItemCollar collarItem)) return false;
if (!collarItem.getOwners(collar).contains(commander.getUUID())) {
if (!CollarHelper.isCollar(collar)) return false;
if (!CollarHelper.isOwner(collar, commander.getUUID())) {
if (!this.isGagged()) {
com.tiedup.remake.dialogue.EntityDialogueManager.talkByDialogueId(
this,
@@ -653,8 +653,8 @@ public class EntityDamsel
return net.minecraft.world.InteractionResult.FAIL;
}
ItemStack collar = this.getEquipment(BodyRegionV2.NECK);
if (collar.getItem() instanceof ItemCollar collarItem) {
if (!collarItem.isOwner(collar, player)) {
if (CollarHelper.isCollar(collar)) {
if (!CollarHelper.isOwner(collar, player)) {
if (
player instanceof
net.minecraft.server.level.ServerPlayer sp
@@ -693,9 +693,9 @@ public class EntityDamsel
this.hasCollar()
) {
ItemStack collar = this.getEquipment(BodyRegionV2.NECK);
if (collar.getItem() instanceof ItemCollar collarItem) {
if (CollarHelper.isCollar(collar)) {
if (
collarItem.isOwner(collar, player) &&
CollarHelper.isOwner(collar, player) &&
player instanceof
net.minecraft.server.level.ServerPlayer serverPlayer
) {
@@ -822,8 +822,8 @@ public class EntityDamsel
public String getTargetRelation(Player player) {
if (hasCollar()) {
ItemStack collar = getEquipment(BodyRegionV2.NECK);
if (collar.getItem() instanceof ItemCollar collarItem) {
if (collarItem.isOwner(collar, player)) {
if (CollarHelper.isCollar(collar)) {
if (CollarHelper.isOwner(collar, player)) {
return "master";
}
}

View File

@@ -12,7 +12,7 @@ import com.tiedup.remake.entities.kidnapper.components.KidnapperAggressionSystem
import com.tiedup.remake.entities.skins.Gender;
import com.tiedup.remake.entities.skins.KidnapperSkinManager;
import com.tiedup.remake.items.ModItems;
import com.tiedup.remake.items.base.ItemCollar;
import com.tiedup.remake.v2.bondage.CollarHelper;
import com.tiedup.remake.personality.PersonalityType;
import com.tiedup.remake.state.IBondageState;
import com.tiedup.remake.state.ICaptor;
@@ -1367,10 +1367,7 @@ public class EntityKidnapper
if (!this.hasCollar()) return false;
ItemStack collar = this.getEquipment(BodyRegionV2.NECK);
if (collar.getItem() instanceof ItemCollar collarItem) {
return collarItem.isOwner(collar, player);
}
return false;
return CollarHelper.isOwner(collar, player);
}
/** Damage reduction multiplier against monsters (50% damage taken) */

View File

@@ -18,6 +18,7 @@ import com.tiedup.remake.state.IBondageState;
import com.tiedup.remake.state.ICaptor;
import com.tiedup.remake.util.MessageDispatcher;
import com.tiedup.remake.v2.BodyRegionV2;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@@ -615,78 +616,82 @@ public class EntityKidnapperMerchant extends EntityKidnapperElite {
private List<ItemStack> collectAllModItems() {
List<ItemStack> items = new ArrayList<>();
// All binds (15)
// Items with colors get multiple variants (one per color)
// All binds — iterate V1 variants, create V2 stacks
for (BindVariant variant : BindVariant.values()) {
if (variant.supportsColor()) {
// Add one item per color (16 standard colors)
for (ItemColor color : ItemColor.values()) {
if (
color != ItemColor.CAUTION && color != ItemColor.CLEAR
) {
ItemStack stack = new ItemStack(
ModItems.getBind(variant)
ItemStack stack = DataDrivenBondageItem.createStack(
new net.minecraft.resources.ResourceLocation("tiedup", variant.getRegistryName())
);
KidnapperItemSelector.applyColor(stack, color);
items.add(stack);
}
}
} else {
// No color variants
items.add(new ItemStack(ModItems.getBind(variant)));
items.add(DataDrivenBondageItem.createStack(
new net.minecraft.resources.ResourceLocation("tiedup", variant.getRegistryName())
));
}
}
// All gags (19)
// All gags
for (GagVariant variant : GagVariant.values()) {
if (variant.supportsColor()) {
// Add one item per color
for (ItemColor color : ItemColor.values()) {
// TAPE_GAG can use caution/clear, others only standard colors
if (
variant == GagVariant.TAPE_GAG ||
(color != ItemColor.CAUTION && color != ItemColor.CLEAR)
) {
ItemStack stack = new ItemStack(
ModItems.getGag(variant)
ItemStack stack = DataDrivenBondageItem.createStack(
new net.minecraft.resources.ResourceLocation("tiedup", variant.getRegistryName())
);
KidnapperItemSelector.applyColor(stack, color);
items.add(stack);
}
}
} else {
items.add(new ItemStack(ModItems.getGag(variant)));
items.add(DataDrivenBondageItem.createStack(
new net.minecraft.resources.ResourceLocation("tiedup", variant.getRegistryName())
));
}
}
// All blindfolds (2) - BOTH support colors
// All blindfolds
for (BlindfoldVariant variant : BlindfoldVariant.values()) {
if (variant.supportsColor()) {
// Add one item per color (16 standard colors)
for (ItemColor color : ItemColor.values()) {
if (
color != ItemColor.CAUTION && color != ItemColor.CLEAR
) {
ItemStack stack = new ItemStack(
ModItems.getBlindfold(variant)
ItemStack stack = DataDrivenBondageItem.createStack(
new net.minecraft.resources.ResourceLocation("tiedup", variant.getRegistryName())
);
KidnapperItemSelector.applyColor(stack, color);
items.add(stack);
}
}
} else {
items.add(new ItemStack(ModItems.getBlindfold(variant)));
items.add(DataDrivenBondageItem.createStack(
new net.minecraft.resources.ResourceLocation("tiedup", variant.getRegistryName())
));
}
}
// Earplugs - no color support
for (EarplugsVariant variant : EarplugsVariant.values()) {
items.add(new ItemStack(ModItems.getEarplugs(variant)));
items.add(DataDrivenBondageItem.createStack(
new net.minecraft.resources.ResourceLocation("tiedup", variant.getRegistryName())
));
}
// Mittens - no color support
for (MittensVariant variant : MittensVariant.values()) {
items.add(new ItemStack(ModItems.getMittens(variant)));
items.add(DataDrivenBondageItem.createStack(
new net.minecraft.resources.ResourceLocation("tiedup", variant.getRegistryName())
));
}
// Knives - no color support

View File

@@ -94,10 +94,8 @@ public class EntityRopeArrow extends AbstractArrow {
int roll = this.random.nextInt(100) + 1;
if (roll <= bindChance) {
// Success! Bind the target
ItemStack ropeItem = new ItemStack(
ModItems.getBind(
com.tiedup.remake.items.base.BindVariant.ROPES
)
ItemStack ropeItem = com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem.createStack(
new net.minecraft.resources.ResourceLocation("tiedup", "ropes")
);
targetState.equip(BodyRegionV2.ARMS, ropeItem);

View File

@@ -1,7 +1,8 @@
package com.tiedup.remake.entities;
import com.tiedup.remake.items.ModItems;
import com.tiedup.remake.items.base.BindVariant;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem;
import net.minecraft.resources.ResourceLocation;
import com.tiedup.remake.v2.bondage.IV2BondageItem;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.ItemStack;
@@ -46,7 +47,7 @@ public class KidnapperCaptureEquipment {
) {
return mainHand;
}
return new ItemStack(ModItems.getBind(BindVariant.ROPES));
return DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "ropes"));
}
/**

View File

@@ -1,11 +1,9 @@
package com.tiedup.remake.entities;
import com.tiedup.remake.items.base.ItemCollar;
import com.tiedup.remake.util.teleport.Position;
import com.tiedup.remake.v2.BodyRegionV2;
import com.tiedup.remake.v2.bondage.CollarHelper;
import java.util.List;
import java.util.UUID;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.Nullable;
@@ -31,21 +29,7 @@ public class KidnapperCollarConfig {
this.kidnapper = kidnapper;
}
// COLLAR ITEM ACCESS
/**
* Get the collar item if equipped.
* @return ItemCollar or null if no collar or not an ItemCollar
*/
@Nullable
public ItemCollar getCollarItem() {
ItemStack collar = kidnapper.getEquipment(BodyRegionV2.NECK);
if (collar.isEmpty()) return null;
if (collar.getItem() instanceof ItemCollar itemCollar) {
return itemCollar;
}
return null;
}
// COLLAR STACK ACCESS
/**
* Get the collar ItemStack.
@@ -55,30 +39,29 @@ public class KidnapperCollarConfig {
return kidnapper.getEquipment(BodyRegionV2.NECK);
}
/**
* Check if the kidnapper has a valid collar.
*/
private boolean hasValidCollar() {
return kidnapper.hasCollar() && CollarHelper.isCollar(getCollarStack());
}
// KIDNAPPING MODE
/**
* Check if kidnapping mode is enabled via collar.
*/
public boolean isKidnappingModeEnabled() {
if (!kidnapper.hasCollar()) return false;
ItemCollar itemCollar = getCollarItem();
if (itemCollar == null) return false;
return itemCollar.isKidnappingModeEnabled(getCollarStack());
if (!hasValidCollar()) return false;
return CollarHelper.isKidnappingModeEnabled(getCollarStack());
}
/**
* Check if kidnapping mode is fully ready (enabled + prison set).
*/
public boolean isKidnappingModeReady() {
if (!kidnapper.hasCollar()) return false;
ItemCollar itemCollar = getCollarItem();
if (itemCollar == null) return false;
return itemCollar.isKidnappingModeReady(getCollarStack());
if (!hasValidCollar()) return false;
return CollarHelper.isKidnappingModeReady(getCollarStack());
}
// POSITION GETTERS
@@ -88,20 +71,16 @@ public class KidnapperCollarConfig {
*/
@Nullable
public java.util.UUID getCellId() {
ItemCollar itemCollar = getCollarItem();
if (itemCollar == null) return null;
return itemCollar.getCellId(getCollarStack());
if (!hasValidCollar()) return null;
return CollarHelper.getCellId(getCollarStack());
}
/**
* Check if collar has a cell assigned.
*/
public boolean hasCellAssigned() {
ItemCollar itemCollar = getCollarItem();
if (itemCollar == null) return false;
return itemCollar.hasCellAssigned(getCollarStack());
if (!hasValidCollar()) return false;
return CollarHelper.hasCellAssigned(getCollarStack());
}
// BEHAVIOR FLAGS
@@ -110,20 +89,16 @@ public class KidnapperCollarConfig {
* Check if should warn masters after capturing slave.
*/
public boolean shouldWarnMasters() {
ItemCollar itemCollar = getCollarItem();
if (itemCollar == null) return false;
return itemCollar.shouldWarnMasters(getCollarStack());
if (!hasValidCollar()) return false;
return CollarHelper.shouldWarnMasters(getCollarStack());
}
/**
* Check if should tie slave to pole in prison.
*/
public boolean shouldTieToPole() {
ItemCollar itemCollar = getCollarItem();
if (itemCollar == null) return false;
return itemCollar.shouldTieToPole(getCollarStack());
if (!hasValidCollar()) return false;
return CollarHelper.shouldTieToPole(getCollarStack());
}
// BLACKLIST/WHITELIST
@@ -139,19 +114,18 @@ public class KidnapperCollarConfig {
* </ul>
*/
public boolean isValidKidnappingTarget(Player player) {
ItemCollar itemCollar = getCollarItem();
if (itemCollar == null) return true; // No collar config = everyone is valid
if (!hasValidCollar()) return true; // No collar config = everyone is valid
ItemStack collarStack = getCollarStack();
UUID playerUUID = player.getUUID();
// If whitelist exists and is not empty, player MUST be on it
List<UUID> whitelist = itemCollar.getWhitelist(collarStack);
List<UUID> whitelist = CollarHelper.getWhitelist(collarStack);
if (!whitelist.isEmpty()) {
return whitelist.contains(playerUUID);
}
// Otherwise, check blacklist (blacklisted = not a valid target)
return !itemCollar.isBlacklisted(collarStack, playerUUID);
return !CollarHelper.isBlacklisted(collarStack, playerUUID);
}
}

View File

@@ -1,8 +1,9 @@
package com.tiedup.remake.entities;
import com.tiedup.remake.items.ModItems;
import com.tiedup.remake.items.base.*;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem;
import java.util.Random;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.Nullable;
@@ -242,7 +243,9 @@ public class KidnapperItemSelector {
BindVariant variant,
@Nullable ItemColor color
) {
ItemStack stack = new ItemStack(ModItems.getBind(variant));
ItemStack stack = DataDrivenBondageItem.createStack(
new ResourceLocation("tiedup", variant.getRegistryName())
);
if (color != null && variant.supportsColor()) {
applyColor(stack, color);
}
@@ -257,7 +260,9 @@ public class KidnapperItemSelector {
GagVariant variant,
@Nullable ItemColor color
) {
ItemStack stack = new ItemStack(ModItems.getGag(variant));
ItemStack stack = DataDrivenBondageItem.createStack(
new ResourceLocation("tiedup", variant.getRegistryName())
);
if (
color != null &&
variant.supportsColor() &&
@@ -276,7 +281,9 @@ public class KidnapperItemSelector {
BlindfoldVariant variant,
@Nullable ItemColor color
) {
ItemStack stack = new ItemStack(ModItems.getBlindfold(variant));
ItemStack stack = DataDrivenBondageItem.createStack(
new ResourceLocation("tiedup", variant.getRegistryName())
);
if (
color != null &&
variant.supportsColor() &&
@@ -292,7 +299,9 @@ public class KidnapperItemSelector {
* Mittens don't have color variants.
*/
public static ItemStack createMittens() {
return new ItemStack(ModItems.getMittens(MittensVariant.LEATHER));
return DataDrivenBondageItem.createStack(
new ResourceLocation("tiedup", "leather_mittens")
);
}
/**
@@ -300,7 +309,9 @@ public class KidnapperItemSelector {
* Earplugs don't have color variants.
*/
public static ItemStack createEarplugs() {
return new ItemStack(ModItems.getEarplugs(EarplugsVariant.CLASSIC));
return DataDrivenBondageItem.createStack(
new ResourceLocation("tiedup", "classic_earplugs")
);
}
// COLOR METHODS

View File

@@ -2,7 +2,7 @@ package com.tiedup.remake.entities;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.items.ModItems;
import com.tiedup.remake.items.base.ItemCollar;
import com.tiedup.remake.v2.bondage.CollarHelper;
import com.tiedup.remake.state.CollarRegistry;
import com.tiedup.remake.state.IBondageState;
import com.tiedup.remake.util.tasks.ItemTask;
@@ -162,15 +162,15 @@ public class KidnapperJobManager {
// Put a shock collar on the worker AFTER untie/free
ItemStack shockCollar = new ItemStack(ModItems.SHOCK_COLLAR_AUTO.get());
if (shockCollar.getItem() instanceof ItemCollar collarItem) {
// Add kidnapper as owner so the collar is linked
collarItem.addOwner(
shockCollar,
kidnapper.getUUID(),
kidnapper.getNpcName()
);
// Lock the collar so they can't remove it
shockCollar = collarItem.setLocked(shockCollar, true);
// Add kidnapper as owner so the collar is linked
CollarHelper.addOwner(
shockCollar,
kidnapper.getUUID(),
kidnapper.getNpcName()
);
// Lock the collar so they can't remove it
if (shockCollar.getItem() instanceof com.tiedup.remake.items.base.ILockable lockable) {
shockCollar = lockable.setLocked(shockCollar, true);
}
captive.equip(BodyRegionV2.NECK, shockCollar);

View File

@@ -1,7 +1,6 @@
package com.tiedup.remake.entities;
import com.tiedup.remake.items.ModItems;
import com.tiedup.remake.items.base.BindVariant;
import com.tiedup.remake.v2.bondage.PoseTypeHelper;
import com.tiedup.remake.state.IBondageState;
import com.tiedup.remake.util.KidnappedHelper;
import com.tiedup.remake.v2.BodyRegionV2;
@@ -108,7 +107,7 @@ public final class LeashProxyEntity extends Turtle {
ItemStack bind = state.getEquipment(BodyRegionV2.ARMS);
if (
!bind.isEmpty() &&
bind.getItem() == ModItems.getBind(BindVariant.DOGBINDER)
PoseTypeHelper.getPoseType(bind) == com.tiedup.remake.items.base.PoseType.DOG
) {
yOffset = 0.35D; // Lower for 4-legged dogwalk pose (back/hip level)
}

View File

@@ -11,7 +11,7 @@ import com.tiedup.remake.entities.EntityKidnapper;
import com.tiedup.remake.entities.EntityKidnapper.CaptivePriority;
import com.tiedup.remake.entities.ai.StuckDetector;
import com.tiedup.remake.entities.ai.WaypointNavigator;
import com.tiedup.remake.items.base.ItemCollar;
import com.tiedup.remake.v2.bondage.CollarHelper;
import com.tiedup.remake.prison.PrisonerManager;
import com.tiedup.remake.prison.PrisonerRecord;
import com.tiedup.remake.prison.PrisonerState;
@@ -260,7 +260,7 @@ public class KidnapperBringToCellGoal extends Goal {
);
IRestrainable captive = this.kidnapper.getCaptive();
if (captive != null) {
ItemCollar.runWithSuppressedAlert(() ->
CollarHelper.runWithSuppressedAlert(() ->
captive.free(false)
);
this.kidnapper.removeCaptive(captive, false);
@@ -1079,9 +1079,9 @@ public class KidnapperBringToCellGoal extends Goal {
ItemStack collar = captive.getEquipment(BodyRegionV2.NECK);
if (
!collar.isEmpty() &&
collar.getItem() instanceof ItemCollar collarItem
CollarHelper.isCollar(collar)
) {
collarItem.setCellId(collar, this.targetCell.getId());
CollarHelper.setCellId(collar, this.targetCell.getId());
}
TiedUpMod.LOGGER.info(

View File

@@ -8,7 +8,7 @@ import com.tiedup.remake.entities.EntityKidnapper;
import com.tiedup.remake.entities.ai.StuckDetector;
import com.tiedup.remake.items.ItemKey;
import com.tiedup.remake.items.ModItems;
import com.tiedup.remake.items.base.ItemCollar;
import com.tiedup.remake.v2.bondage.CollarHelper;
import com.tiedup.remake.network.ModNetwork;
import com.tiedup.remake.network.action.PacketTying;
import com.tiedup.remake.prison.PrisonerManager;
@@ -849,11 +849,8 @@ public class KidnapperCaptureGoal extends Goal {
// If already has collar, check ownership
if (state.hasCollar()) {
ItemStack existingCollar = state.getEquipment(BodyRegionV2.NECK);
if (
existingCollar.getItem() instanceof
com.tiedup.remake.items.base.ItemCollar collarItem
) {
java.util.List<java.util.UUID> owners = collarItem.getOwners(
if (CollarHelper.isCollar(existingCollar)) {
java.util.List<java.util.UUID> owners = CollarHelper.getOwners(
existingCollar
);
if (!owners.contains(this.kidnapper.getUUID())) {
@@ -885,9 +882,9 @@ public class KidnapperCaptureGoal extends Goal {
for (java.util.UUID oldOwner : new java.util.ArrayList<>(
owners
)) {
collarItem.removeOwner(existingCollar, oldOwner);
CollarHelper.removeOwner(existingCollar, oldOwner);
}
collarItem.addOwner(
CollarHelper.addOwner(
existingCollar,
this.kidnapper.getUUID(),
this.kidnapper.getNpcName()
@@ -929,9 +926,9 @@ public class KidnapperCaptureGoal extends Goal {
if (this.captureProgress >= COLLAR_APPLY_TIME) {
// Create a copy of the collar and configure it
ItemStack collarCopy = collar.copy();
if (collarCopy.getItem() instanceof ItemCollar collarItem) {
if (CollarHelper.isCollar(collarCopy)) {
// Add kidnapper as owner
collarItem.addOwner(
CollarHelper.addOwner(
collarCopy,
this.kidnapper.getUUID(),
this.kidnapper.getNpcName()
@@ -941,12 +938,17 @@ public class KidnapperCaptureGoal extends Goal {
ItemStack keyStack = new ItemStack(ModItems.COLLAR_KEY.get());
if (keyStack.getItem() instanceof ItemKey keyItem) {
UUID keyUUID = keyItem.getKeyUUID(keyStack);
collarItem.setLockedByKeyUUID(collarCopy, keyUUID);
// Lock via ILockable interface (collar must implement it)
if (collarCopy.getItem() instanceof com.tiedup.remake.items.base.ILockable lockable) {
lockable.setLockedByKeyUUID(collarCopy, keyUUID);
}
// Store the key on the kidnapper for potential drop on death
this.kidnapper.addCollarKey(keyStack);
} else {
// Fallback: just lock without a key
collarItem.setLocked(collarCopy, true);
if (collarCopy.getItem() instanceof com.tiedup.remake.items.base.ILockable lockable) {
lockable.setLocked(collarCopy, true);
}
}
}

View File

@@ -8,8 +8,8 @@ import com.tiedup.remake.entities.AbstractTiedUpNpc;
import com.tiedup.remake.entities.EntityKidnapper;
import com.tiedup.remake.entities.ai.StuckDetector;
import com.tiedup.remake.entities.ai.WaypointNavigator;
import com.tiedup.remake.items.ModItems;
import com.tiedup.remake.items.base.BindVariant;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem;
import net.minecraft.resources.ResourceLocation;
import com.tiedup.remake.state.IBondageState;
import com.tiedup.remake.util.KidnappedHelper;
import com.tiedup.remake.util.KidnapperAIHelper;
@@ -547,9 +547,7 @@ public class KidnapperWalkPrisonerGoal extends Goal {
);
// 3. Change bind to DOGBINDER
ItemStack dogBinder = new ItemStack(
ModItems.getBind(BindVariant.DOGBINDER)
);
ItemStack dogBinder = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "dogbinder"));
this.walkedPrisoner.equip(BodyRegionV2.ARMS, dogBinder);
TiedUpMod.LOGGER.debug(
@@ -738,7 +736,7 @@ public class KidnapperWalkPrisonerGoal extends Goal {
if (currentBind.isEmpty() || !prisoner.isTiedUp()) {
// They freed themselves - put dogbinder back on
ItemStack dogBinder = new ItemStack(
ModItems.getBind(BindVariant.DOGBINDER)
DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "dogbinder")).getItem()
);
prisoner.equip(BodyRegionV2.ARMS, dogBinder);
}

View File

@@ -338,10 +338,8 @@ public class MaidReturnGoal extends Goal {
// Fallback: use basic rope if no snapshot
cap.equip(
BodyRegionV2.ARMS,
new ItemStack(
com.tiedup.remake.items.ModItems.getBind(
com.tiedup.remake.items.base.BindVariant.ROPES
)
com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem.createStack(
new net.minecraft.resources.ResourceLocation("tiedup", "ropes")
)
);
}

View File

@@ -3,8 +3,8 @@ package com.tiedup.remake.entities.ai.master;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.dialogue.DialogueBridge;
import com.tiedup.remake.entities.EntityMaster;
import com.tiedup.remake.items.ModItems;
import com.tiedup.remake.items.base.BindVariant;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem;
import net.minecraft.resources.ResourceLocation;
import com.tiedup.remake.state.HumanChairHelper;
import com.tiedup.remake.state.PlayerBindState;
import com.tiedup.remake.v2.BodyRegionV2;
@@ -394,8 +394,8 @@ public class MasterHumanChairGoal extends Goal {
// Apply invisible dogbind for the pose animation
if (!bindState.isTiedUp()) {
ItemStack dogbind = new ItemStack(
ModItems.getBind(BindVariant.DOGBINDER)
ItemStack dogbind = DataDrivenBondageItem.createStack(
new ResourceLocation("tiedup", "dogbinder")
);
CompoundTag tag = dogbind.getOrCreateTag();
tag.putBoolean(NBT_HUMAN_CHAIR_BIND, true);

View File

@@ -3,12 +3,9 @@ package com.tiedup.remake.entities.ai.master;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.dialogue.DialogueBridge;
import com.tiedup.remake.entities.EntityMaster;
import com.tiedup.remake.items.ItemChokeCollar;
import com.tiedup.remake.items.ModItems;
import com.tiedup.remake.items.base.BindVariant;
import com.tiedup.remake.items.base.BlindfoldVariant;
import com.tiedup.remake.items.base.GagVariant;
import com.tiedup.remake.items.base.MittensVariant;
import com.tiedup.remake.v2.bondage.CollarHelper;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem;
import net.minecraft.resources.ResourceLocation;
import com.tiedup.remake.state.PlayerBindState;
import com.tiedup.remake.v2.BodyRegionV2;
import com.tiedup.remake.v2.bondage.IV2BondageEquipment;
@@ -261,7 +258,7 @@ public class MasterPunishGoal extends Goal {
// CHOKE: only if pet has choke collar
if (bindState != null && bindState.hasCollar()) {
ItemStack collar = bindState.getEquipment(BodyRegionV2.NECK);
if (collar.getItem() instanceof ItemChokeCollar) {
if (CollarHelper.isChokeCollar(collar)) {
available.add(PunishmentType.CHOKE_COLLAR);
}
}
@@ -393,8 +390,8 @@ public class MasterPunishGoal extends Goal {
PlayerBindState bindState = PlayerBindState.getInstance(pet);
if (bindState != null && bindState.hasCollar()) {
ItemStack collar = bindState.getEquipment(BodyRegionV2.NECK);
if (collar.getItem() instanceof ItemChokeCollar chokeCollar) {
chokeCollar.setChoking(collar, true);
if (CollarHelper.isChokeCollar(collar)) {
CollarHelper.setChoking(collar, true);
this.activeChokeCollar = collar;
this.chokeActiveTimer = 1;
@@ -457,12 +454,14 @@ public class MasterPunishGoal extends Goal {
*/
private ItemStack createAccessory(BodyRegionV2 region) {
return switch (region) {
case EYES -> new ItemStack(
ModItems.getBlindfold(BlindfoldVariant.CLASSIC)
case EYES -> DataDrivenBondageItem.createStack(
new ResourceLocation("tiedup", "classic_blindfold")
);
case MOUTH -> new ItemStack(ModItems.getGag(GagVariant.BALL_GAG));
case HANDS -> new ItemStack(
ModItems.getMittens(MittensVariant.LEATHER)
case MOUTH -> DataDrivenBondageItem.createStack(
new ResourceLocation("tiedup", "ball_gag")
);
case HANDS -> DataDrivenBondageItem.createStack(
new ResourceLocation("tiedup", "leather_mittens")
);
default -> ItemStack.EMPTY;
};
@@ -472,8 +471,8 @@ public class MasterPunishGoal extends Goal {
* Apply armbinder as punishment.
*/
private void applyTighten(ServerPlayer pet) {
ItemStack armbinder = new ItemStack(
ModItems.getBind(BindVariant.ARMBINDER)
ItemStack armbinder = DataDrivenBondageItem.createStack(
new ResourceLocation("tiedup", "armbinder")
);
// Mark as temporary
@@ -545,9 +544,9 @@ public class MasterPunishGoal extends Goal {
private void deactivateChoke() {
if (
!activeChokeCollar.isEmpty() &&
activeChokeCollar.getItem() instanceof ItemChokeCollar chokeCollar
CollarHelper.isChokeCollar(activeChokeCollar)
) {
chokeCollar.setChoking(activeChokeCollar, false);
CollarHelper.setChoking(activeChokeCollar, false);
}
this.activeChokeCollar = ItemStack.EMPTY;
this.chokeActiveTimer = 0;

View File

@@ -3,11 +3,8 @@ package com.tiedup.remake.entities.ai.master;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.dialogue.DialogueBridge;
import com.tiedup.remake.entities.EntityMaster;
import com.tiedup.remake.items.ModItems;
import com.tiedup.remake.items.base.BindVariant;
import com.tiedup.remake.items.base.BlindfoldVariant;
import com.tiedup.remake.items.base.GagVariant;
import com.tiedup.remake.items.base.MittensVariant;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem;
import net.minecraft.resources.ResourceLocation;
import com.tiedup.remake.state.PlayerBindState;
import com.tiedup.remake.v2.BodyRegionV2;
import com.tiedup.remake.v2.bondage.IV2BondageEquipment;
@@ -17,7 +14,6 @@ import java.util.List;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
/**
@@ -249,15 +245,18 @@ public class MasterRandomEventGoal extends Goal {
* Create a random accessory item for the given body region.
*/
private ItemStack createRandomAccessory(BodyRegionV2 region) {
Item item = switch (region) {
case EYES -> ModItems.getBlindfold(BlindfoldVariant.CLASSIC);
case MOUTH -> ModItems.getGag(GagVariant.BALL_GAG);
case HANDS -> ModItems.getMittens(MittensVariant.LEATHER);
default -> null;
return switch (region) {
case EYES -> DataDrivenBondageItem.createStack(
new ResourceLocation("tiedup", "classic_blindfold")
);
case MOUTH -> DataDrivenBondageItem.createStack(
new ResourceLocation("tiedup", "ball_gag")
);
case HANDS -> DataDrivenBondageItem.createStack(
new ResourceLocation("tiedup", "leather_mittens")
);
default -> ItemStack.EMPTY;
};
if (item == null) return ItemStack.EMPTY;
return new ItemStack(item);
}
/**
@@ -304,8 +303,8 @@ public class MasterRandomEventGoal extends Goal {
// Put pet in dogbind if not already tied
PlayerBindState bindState = PlayerBindState.getInstance(pet);
if (bindState != null && !bindState.isTiedUp()) {
ItemStack dogbind = new ItemStack(
ModItems.getBind(BindVariant.DOGBINDER)
ItemStack dogbind = DataDrivenBondageItem.createStack(
new ResourceLocation("tiedup", "dogbinder")
);
bindState.equip(BodyRegionV2.ARMS, dogbind);
}

View File

@@ -3,7 +3,7 @@ package com.tiedup.remake.entities.ai.master;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.dialogue.DialogueBridge;
import com.tiedup.remake.entities.EntityMaster;
import com.tiedup.remake.items.ItemChokeCollar;
import com.tiedup.remake.v2.bondage.CollarHelper;
import com.tiedup.remake.state.PlayerBindState;
import com.tiedup.remake.util.MessageDispatcher;
import com.tiedup.remake.v2.BodyRegionV2;
@@ -441,8 +441,8 @@ public class MasterTaskWatchGoal extends Goal {
if (bindState != null && bindState.hasCollar()) {
ItemStack collar = bindState.getEquipment(BodyRegionV2.NECK);
if (collar.getItem() instanceof ItemChokeCollar chokeCollar) {
chokeCollar.setChoking(collar, true);
if (CollarHelper.isChokeCollar(collar)) {
CollarHelper.setChoking(collar, true);
this.activeChokeCollar = collar;
this.chokeTimer = CHOKE_DURATION;
@@ -475,9 +475,9 @@ public class MasterTaskWatchGoal extends Goal {
private void deactivateChoke() {
if (
!activeChokeCollar.isEmpty() &&
activeChokeCollar.getItem() instanceof ItemChokeCollar chokeCollar
CollarHelper.isChokeCollar(activeChokeCollar)
) {
chokeCollar.setChoking(activeChokeCollar, false);
CollarHelper.setChoking(activeChokeCollar, false);
TiedUpMod.LOGGER.debug(
"[MasterTaskWatchGoal] {} deactivated choke",
master.getNpcName()

View File

@@ -1,7 +1,7 @@
package com.tiedup.remake.entities.ai.personality;
import com.tiedup.remake.entities.EntityDamsel;
import com.tiedup.remake.items.base.ItemBind;
import com.tiedup.remake.v2.bondage.BindModeHelper;
import com.tiedup.remake.personality.NpcCommand;
import com.tiedup.remake.personality.ToolMode;
import com.tiedup.remake.v2.BodyRegionV2;
@@ -506,7 +506,7 @@ public class NpcFollowCommandGoal extends Goal {
if (dist <= ATTACK_RANGE) {
// Try to capture using bind item
ItemStack bindItem = npc.getMainHandItem();
if (bindItem.getItem() instanceof ItemBind) {
if (BindModeHelper.isBindItem(bindItem)) {
// Apply bind to target
captureTarget.equip(BodyRegionV2.ARMS, bindItem.copy());

View File

@@ -1,8 +1,8 @@
package com.tiedup.remake.entities.ai.personality;
import com.tiedup.remake.entities.EntityDamsel;
import com.tiedup.remake.items.base.ItemBind;
import com.tiedup.remake.items.base.ItemCollar;
import com.tiedup.remake.v2.bondage.BindModeHelper;
import com.tiedup.remake.v2.bondage.CollarHelper;
import com.tiedup.remake.personality.NpcCommand;
import com.tiedup.remake.personality.PersonalityState;
import com.tiedup.remake.v2.BodyRegionV2;
@@ -426,7 +426,7 @@ public class NpcGuardCommandGoal extends Goal {
NonNullList<ItemStack> inventory = npc.getNpcInventory();
for (int i = 0; i < inventory.size(); i++) {
ItemStack stack = inventory.get(i);
if (stack.getItem() instanceof ItemBind) {
if (BindModeHelper.isBindItem(stack)) {
// Apply bind to slave
slave.equip(BodyRegionV2.ARMS, stack.copy());
stack.shrink(1);
@@ -486,8 +486,8 @@ public class NpcGuardCommandGoal extends Goal {
private UUID getCollarOwnerUUID(EntityDamsel slave) {
if (!slave.hasCollar()) return null;
ItemStack collar = slave.getEquipment(BodyRegionV2.NECK);
if (collar.getItem() instanceof ItemCollar collarItem) {
java.util.List<UUID> owners = collarItem.getOwners(collar);
if (CollarHelper.isCollar(collar)) {
java.util.List<UUID> owners = CollarHelper.getOwners(collar);
if (!owners.isEmpty()) {
return owners.get(0);
}

View File

@@ -3,7 +3,7 @@ package com.tiedup.remake.entities.damsel.components;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.entities.AbstractTiedUpNpc;
import com.tiedup.remake.entities.BondageServiceHandler;
import com.tiedup.remake.items.base.ItemCollar;
import com.tiedup.remake.v2.bondage.CollarHelper;
import com.tiedup.remake.state.ICaptor;
import com.tiedup.remake.state.IRestrainable;
import com.tiedup.remake.state.IRestrainableEntity;
@@ -565,9 +565,9 @@ public class DamselBondageManager implements IRestrainable {
ItemStack collar = getEquipment(BodyRegionV2.NECK);
if (collar.isEmpty()) return false;
if (!(collar.getItem() instanceof ItemCollar itemCollar)) return false;
if (!CollarHelper.isCollar(collar)) return false;
UUID cellId = itemCollar.getCellId(collar);
UUID cellId = CollarHelper.getCellId(collar);
if (cellId == null) return false;
// Get cell position from registry

View File

@@ -2,7 +2,7 @@ package com.tiedup.remake.entities.damsel.components;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.dialogue.EntityDialogueManager;
import com.tiedup.remake.items.base.ItemCollar;
import com.tiedup.remake.v2.bondage.CollarHelper;
import com.tiedup.remake.personality.*;
import com.tiedup.remake.v2.BodyRegionV2;
import java.util.*;
@@ -180,8 +180,8 @@ public class DamselPersonalitySystem {
UUID masterUUID = null;
if (context.hasCollar()) {
ItemStack collar = context.getEquipment(BodyRegionV2.NECK);
if (collar.getItem() instanceof ItemCollar collarItem) {
List<UUID> owners = collarItem.getOwners(collar);
if (CollarHelper.isCollar(collar)) {
List<UUID> owners = CollarHelper.getOwners(collar);
if (!owners.isEmpty()) {
masterUUID = owners.get(0);
}

View File

@@ -4,7 +4,11 @@ import com.tiedup.remake.core.ModConfig;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.entities.AbstractTiedUpNpc;
import com.tiedup.remake.items.base.ILockable;
import com.tiedup.remake.items.base.ItemCollar;
import com.tiedup.remake.v2.bondage.CollarHelper;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem;
import com.tiedup.remake.v2.bondage.component.ComponentType;
import com.tiedup.remake.v2.bondage.component.GaggingComponent;
import com.tiedup.remake.v2.bondage.component.BlindingComponent;
import com.tiedup.remake.state.IRestrainableEntity;
import com.tiedup.remake.util.RestraintEffectUtils;
import com.tiedup.remake.util.TiedUpSounds;
@@ -112,19 +116,15 @@ public class NpcEquipmentManager {
public boolean hasGaggingEffect() {
ItemStack gag = getCurrentGag();
if (gag.isEmpty()) return false;
return (
gag.getItem() instanceof
com.tiedup.remake.items.base.IHasGaggingEffect
);
if (DataDrivenBondageItem.getComponent(gag, ComponentType.GAGGING, GaggingComponent.class) != null) return true;
return gag.getItem() instanceof com.tiedup.remake.items.base.IHasGaggingEffect;
}
public boolean hasBlindingEffect() {
ItemStack blindfold = getCurrentBlindfold();
if (blindfold.isEmpty()) return false;
return (
blindfold.getItem() instanceof
com.tiedup.remake.items.base.IHasBlindingEffect
);
if (DataDrivenBondageItem.getComponent(blindfold, ComponentType.BLINDING, BlindingComponent.class) != null) return true;
return blindfold.getItem() instanceof com.tiedup.remake.items.base.IHasBlindingEffect;
}
public boolean hasKnives() {
@@ -768,8 +768,8 @@ public class NpcEquipmentManager {
public boolean isCollarOwner(Player player) {
if (!hasCollar()) return true;
ItemStack collar = getCurrentCollar();
if (!(collar.getItem() instanceof ItemCollar collarItem)) return true;
return collarItem.isOwner(collar, player);
if (!CollarHelper.isCollar(collar)) return true;
return CollarHelper.isOwner(collar, player);
}
// COERCION

View File

@@ -6,7 +6,7 @@ import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.dialogue.EntityDialogueManager;
import com.tiedup.remake.entities.EntityKidnapper;
import com.tiedup.remake.entities.ai.kidnapper.KidnapperState;
import com.tiedup.remake.items.base.ItemCollar;
import com.tiedup.remake.v2.bondage.CollarHelper;
import com.tiedup.remake.prison.PrisonerManager;
import com.tiedup.remake.prison.PrisonerRecord;
import com.tiedup.remake.prison.PrisonerState;
@@ -189,9 +189,9 @@ public class KidnapperCaptiveManager {
// If target has collar, verify we own it
if (target.hasCollar()) {
ItemStack collar = target.getEquipment(BodyRegionV2.NECK);
if (collar.getItem() instanceof ItemCollar collarItem) {
if (CollarHelper.isCollar(collar)) {
// Check if THIS kidnapper is owner
if (!collarItem.getOwners(collar).contains(host.getUUID())) {
if (!CollarHelper.getOwners(collar).contains(host.getUUID())) {
TiedUpMod.LOGGER.debug(
"[KidnapperCaptiveManager] {} can't capture {} - collar owned by someone else",
host.getNpcName(),

View File

@@ -7,7 +7,7 @@ import com.tiedup.remake.entities.EntityKidnapper;
import com.tiedup.remake.entities.EntityKidnapperElite;
import com.tiedup.remake.entities.ai.kidnapper.KidnapperState;
import com.tiedup.remake.items.ModItems;
import com.tiedup.remake.items.base.ItemCollar;
import com.tiedup.remake.v2.bondage.CollarHelper;
import com.tiedup.remake.prison.PrisonerManager;
import com.tiedup.remake.prison.PrisonerRecord;
import com.tiedup.remake.state.IBondageState;
@@ -206,8 +206,8 @@ public class KidnapperTargetSelector {
// Self-collared entities (exploit) are treated as uncolllared — kidnappers ignore self-collars
if (state.hasCollar()) {
ItemStack collar = state.getEquipment(BodyRegionV2.NECK);
if (collar.getItem() instanceof ItemCollar collarItem) {
java.util.List<UUID> owners = collarItem.getOwners(collar);
if (CollarHelper.isCollar(collar)) {
java.util.List<UUID> owners = CollarHelper.getOwners(collar);
// Filter out self-collar (owner == wearer = exploit)
java.util.List<UUID> realOwners = owners
.stream()
@@ -312,8 +312,8 @@ public class KidnapperTargetSelector {
// Other kidnappers' collars are fair game — kidnapper can steal from kidnapper
if (state != null && state.hasCollar()) {
ItemStack collar = state.getEquipment(BodyRegionV2.NECK);
if (collar.getItem() instanceof ItemCollar collarItem) {
java.util.List<UUID> owners = collarItem.getOwners(collar);
if (CollarHelper.isCollar(collar)) {
java.util.List<UUID> owners = CollarHelper.getOwners(collar);
if (!owners.isEmpty() && !owners.contains(host.getUUID())) {
// Check if any owner is a DIFFERENT player (not self-collared, not a kidnapper)
if (host.level() instanceof ServerLevel sl) {

View File

@@ -4,7 +4,7 @@ import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.entities.EntityMaster;
import com.tiedup.remake.entities.ai.master.MasterRandomEventGoal;
import com.tiedup.remake.entities.ai.master.MasterState;
import com.tiedup.remake.items.base.ItemCollar;
import com.tiedup.remake.v2.bondage.CollarHelper;
import com.tiedup.remake.minigame.StruggleSessionManager;
import com.tiedup.remake.state.IBondageState;
import com.tiedup.remake.util.KidnappedHelper;
@@ -126,22 +126,27 @@ public class MasterPetManager {
// Configure for pet play BEFORE equipping
if (
chokeCollar.getItem() instanceof
com.tiedup.remake.items.ItemChokeCollar collar
com.tiedup.remake.items.base.IHasResistance resistable
) {
collar.setCurrentResistance(chokeCollar, PET_COLLAR_RESISTANCE);
collar.setLocked(chokeCollar, true);
collar.setLockable(chokeCollar, false); // Cannot be lockpicked
collar.setCanBeStruggledOut(chokeCollar, true); // Can struggle, but very hard
// Add this Master as owner
collar.addOwner(chokeCollar, master.getUUID(), master.getNpcName());
// Set NBT flag for pet play mode
chokeCollar.getOrCreateTag().putBoolean("petPlayMode", true);
chokeCollar
.getOrCreateTag()
.putUUID("masterUUID", master.getUUID());
resistable.setCurrentResistance(chokeCollar, PET_COLLAR_RESISTANCE);
resistable.setCanBeStruggledOut(chokeCollar, true); // Can struggle, but very hard
}
if (
chokeCollar.getItem() instanceof
com.tiedup.remake.items.base.ILockable lockable
) {
lockable.setLocked(chokeCollar, true);
lockable.setLockable(chokeCollar, false); // Cannot be lockpicked
}
// Add this Master as owner
CollarHelper.addOwner(chokeCollar, master.getUUID(), master.getNpcName());
// Set NBT flag for pet play mode
CollarHelper.setPetPlayMode(chokeCollar, true);
chokeCollar
.getOrCreateTag()
.putUUID("masterUUID", master.getUUID());
// Replace any existing collar (force removal) with the choke collar
state.replaceEquipment(BodyRegionV2.NECK, chokeCollar, true);
@@ -186,9 +191,9 @@ public class MasterPetManager {
}
// Unlock the collar
if (collarStack.getItem() instanceof ItemCollar collar) {
collar.setLocked(collarStack, false);
collar.setLockable(collarStack, true);
if (collarStack.getItem() instanceof com.tiedup.remake.items.base.ILockable lockable) {
lockable.setLocked(collarStack, false);
lockable.setLockable(collarStack, true);
}
}
@@ -242,8 +247,8 @@ public class MasterPetManager {
);
if (collarStack.isEmpty()) return;
if (collarStack.getItem() instanceof ItemCollar collar) {
collar.setCurrentResistance(collarStack, PET_COLLAR_RESISTANCE);
if (collarStack.getItem() instanceof com.tiedup.remake.items.base.IHasResistance resistable) {
resistable.setCurrentResistance(collarStack, PET_COLLAR_RESISTANCE);
TiedUpMod.LOGGER.debug(
"[MasterPetManager] Reset collar resistance for {}",
pet.getName().getString()