diff --git a/src/main/java/com/tiedup/remake/blocks/entity/BondageItemBlockEntity.java b/src/main/java/com/tiedup/remake/blocks/entity/BondageItemBlockEntity.java index 8cea85b..279bb5c 100644 --- a/src/main/java/com/tiedup/remake/blocks/entity/BondageItemBlockEntity.java +++ b/src/main/java/com/tiedup/remake/blocks/entity/BondageItemBlockEntity.java @@ -6,6 +6,14 @@ import com.tiedup.remake.items.base.ItemCollar; import com.tiedup.remake.items.base.ItemEarplugs; import com.tiedup.remake.items.base.ItemGag; import com.tiedup.remake.items.clothes.GenericClothes; +import com.tiedup.remake.v2.BodyRegionV2; +import com.tiedup.remake.v2.bondage.BindModeHelper; +import com.tiedup.remake.v2.bondage.CollarHelper; +import com.tiedup.remake.v2.bondage.component.ComponentType; +import com.tiedup.remake.v2.bondage.component.GaggingComponent; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemDefinition; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemRegistry; import javax.annotation.Nullable; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; @@ -191,55 +199,45 @@ public abstract class BondageItemBlockEntity @Override public void readBondageData(CompoundTag tag) { - // Read bind with type validation + // Read bind with type validation (V1 ItemBind or V2 ARMS-region item) if (tag.contains("bind")) { ItemStack bindStack = ItemStack.of(tag.getCompound("bind")); - if ( - !bindStack.isEmpty() && bindStack.getItem() instanceof ItemBind - ) { + if (!bindStack.isEmpty() && (bindStack.getItem() instanceof ItemBind || BindModeHelper.isBindItem(bindStack))) { this.bind = bindStack; } } - // Read gag with type validation + // Read gag with type validation (V1 ItemGag or V2 GAGGING component) if (tag.contains("gag")) { ItemStack gagStack = ItemStack.of(tag.getCompound("gag")); - if (!gagStack.isEmpty() && gagStack.getItem() instanceof ItemGag) { + if (!gagStack.isEmpty() && (gagStack.getItem() instanceof ItemGag + || DataDrivenBondageItem.getComponent(gagStack, ComponentType.GAGGING, GaggingComponent.class) != null)) { this.gag = gagStack; } } - // Read blindfold with type validation + // Read blindfold with type validation (V1 ItemBlindfold or V2 EYES-region item) if (tag.contains("blindfold")) { - ItemStack blindfoldStack = ItemStack.of( - tag.getCompound("blindfold") - ); - if ( - !blindfoldStack.isEmpty() && - blindfoldStack.getItem() instanceof ItemBlindfold - ) { + ItemStack blindfoldStack = ItemStack.of(tag.getCompound("blindfold")); + if (!blindfoldStack.isEmpty() && (blindfoldStack.getItem() instanceof ItemBlindfold + || isDataDrivenForRegion(blindfoldStack, BodyRegionV2.EYES))) { this.blindfold = blindfoldStack; } } - // Read earplugs with type validation + // Read earplugs with type validation (V1 ItemEarplugs or V2 EARS-region item) if (tag.contains("earplugs")) { ItemStack earplugsStack = ItemStack.of(tag.getCompound("earplugs")); - if ( - !earplugsStack.isEmpty() && - earplugsStack.getItem() instanceof ItemEarplugs - ) { + if (!earplugsStack.isEmpty() && (earplugsStack.getItem() instanceof ItemEarplugs + || isDataDrivenForRegion(earplugsStack, BodyRegionV2.EARS))) { this.earplugs = earplugsStack; } } - // Read collar with type validation + // Read collar with type validation (V1 ItemCollar or V2 collar) if (tag.contains("collar")) { ItemStack collarStack = ItemStack.of(tag.getCompound("collar")); - if ( - !collarStack.isEmpty() && - collarStack.getItem() instanceof ItemCollar - ) { + if (!collarStack.isEmpty() && (collarStack.getItem() instanceof ItemCollar || CollarHelper.isCollar(collarStack))) { this.collar = collarStack; } } @@ -279,6 +277,14 @@ public abstract class BondageItemBlockEntity return tag; } + // V2 HELPERS + + /** Check if a stack is a data-driven item occupying the given body region. */ + private static boolean isDataDrivenForRegion(ItemStack stack, BodyRegionV2 region) { + DataDrivenItemDefinition def = DataDrivenItemRegistry.get(stack); + return def != null && def.occupiedRegions().contains(region); + } + // NETWORK SYNC /** diff --git a/src/main/java/com/tiedup/remake/blocks/entity/TrappedChestBlockEntity.java b/src/main/java/com/tiedup/remake/blocks/entity/TrappedChestBlockEntity.java index e4db192..73dd2da 100644 --- a/src/main/java/com/tiedup/remake/blocks/entity/TrappedChestBlockEntity.java +++ b/src/main/java/com/tiedup/remake/blocks/entity/TrappedChestBlockEntity.java @@ -1,7 +1,19 @@ package com.tiedup.remake.blocks.entity; -import com.tiedup.remake.items.base.*; +import com.tiedup.remake.items.base.ItemBind; +import com.tiedup.remake.items.base.ItemBlindfold; +import com.tiedup.remake.items.base.ItemCollar; +import com.tiedup.remake.items.base.ItemEarplugs; +import com.tiedup.remake.items.base.ItemGag; import com.tiedup.remake.items.clothes.GenericClothes; +import com.tiedup.remake.v2.BodyRegionV2; +import com.tiedup.remake.v2.bondage.BindModeHelper; +import com.tiedup.remake.v2.bondage.CollarHelper; +import com.tiedup.remake.v2.bondage.component.ComponentType; +import com.tiedup.remake.v2.bondage.component.GaggingComponent; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemDefinition; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemRegistry; import javax.annotation.Nullable; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; @@ -45,7 +57,7 @@ public class TrappedChestBlockEntity @Override public void setBind(ItemStack stack) { - if (stack.isEmpty() || stack.getItem() instanceof ItemBind) { + if (stack.isEmpty() || stack.getItem() instanceof ItemBind || BindModeHelper.isBindItem(stack)) { this.bind = stack; setChangedAndSync(); } @@ -58,7 +70,8 @@ public class TrappedChestBlockEntity @Override public void setGag(ItemStack stack) { - if (stack.isEmpty() || stack.getItem() instanceof ItemGag) { + if (stack.isEmpty() || stack.getItem() instanceof ItemGag + || DataDrivenBondageItem.getComponent(stack, ComponentType.GAGGING, GaggingComponent.class) != null) { this.gag = stack; setChangedAndSync(); } @@ -71,7 +84,8 @@ public class TrappedChestBlockEntity @Override public void setBlindfold(ItemStack stack) { - if (stack.isEmpty() || stack.getItem() instanceof ItemBlindfold) { + if (stack.isEmpty() || stack.getItem() instanceof ItemBlindfold + || isDataDrivenForRegion(stack, BodyRegionV2.EYES)) { this.blindfold = stack; setChangedAndSync(); } @@ -84,7 +98,8 @@ public class TrappedChestBlockEntity @Override public void setEarplugs(ItemStack stack) { - if (stack.isEmpty() || stack.getItem() instanceof ItemEarplugs) { + if (stack.isEmpty() || stack.getItem() instanceof ItemEarplugs + || isDataDrivenForRegion(stack, BodyRegionV2.EARS)) { this.earplugs = stack; setChangedAndSync(); } @@ -97,7 +112,7 @@ public class TrappedChestBlockEntity @Override public void setCollar(ItemStack stack) { - if (stack.isEmpty() || stack.getItem() instanceof ItemCollar) { + if (stack.isEmpty() || stack.getItem() instanceof ItemCollar || CollarHelper.isCollar(stack)) { this.collar = stack; setChangedAndSync(); } @@ -183,6 +198,14 @@ public class TrappedChestBlockEntity writeBondageData(tag); } + // V2 HELPERS + + /** Check if a stack is a data-driven item occupying the given body region. */ + private static boolean isDataDrivenForRegion(ItemStack stack, BodyRegionV2 region) { + DataDrivenItemDefinition def = DataDrivenItemRegistry.get(stack); + return def != null && def.occupiedRegions().contains(region); + } + // NETWORK SYNC /** diff --git a/src/main/java/com/tiedup/remake/cells/CampLifecycleManager.java b/src/main/java/com/tiedup/remake/cells/CampLifecycleManager.java index c1bc7e8..948d8ad 100644 --- a/src/main/java/com/tiedup/remake/cells/CampLifecycleManager.java +++ b/src/main/java/com/tiedup/remake/cells/CampLifecycleManager.java @@ -2,8 +2,8 @@ package com.tiedup.remake.cells; import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.items.base.ILockable; -import com.tiedup.remake.items.base.ItemCollar; import com.tiedup.remake.prison.PrisonerManager; +import com.tiedup.remake.v2.bondage.CollarHelper; import com.tiedup.remake.state.IRestrainable; import com.tiedup.remake.util.KidnappedHelper; import com.tiedup.remake.v2.BodyRegionV2; @@ -231,7 +231,7 @@ public final class CampLifecycleManager { } // Suppress collar removal alerts - this is a legitimate release (camp death) - ItemCollar.runWithSuppressedAlert(() -> { + CollarHelper.runWithSuppressedAlert(() -> { // Unlock collar if owned by the dead camp/trader unlockCollarIfOwnedBy(prisoner, state, traderUUID); @@ -285,8 +285,8 @@ public final class CampLifecycleManager { return; } - if (collar.getItem() instanceof ItemCollar collarItem) { - List owners = collarItem.getOwners(collar); + if (CollarHelper.isCollar(collar)) { + List owners = CollarHelper.getOwners(collar); // If the dead trader/camp is an owner, unlock the collar if (owners.contains(ownerUUID)) { diff --git a/src/main/java/com/tiedup/remake/client/FirstPersonMittensRenderer.java b/src/main/java/com/tiedup/remake/client/FirstPersonMittensRenderer.java index 5ab94da..3a7dd40 100644 --- a/src/main/java/com/tiedup/remake/client/FirstPersonMittensRenderer.java +++ b/src/main/java/com/tiedup/remake/client/FirstPersonMittensRenderer.java @@ -3,8 +3,8 @@ package com.tiedup.remake.client; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import com.tiedup.remake.core.TiedUpMod; -import com.tiedup.remake.items.GenericBind; -import com.tiedup.remake.items.base.BindVariant; +import com.tiedup.remake.items.base.PoseType; +import com.tiedup.remake.v2.bondage.PoseTypeHelper; import com.tiedup.remake.state.PlayerBindState; import com.tiedup.remake.v2.BodyRegionV2; import com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper; @@ -141,12 +141,7 @@ public class FirstPersonMittensRenderer { net.minecraft.world.item.ItemStack bindStack = V2EquipmentHelper.getInRegion(player, BodyRegionV2.ARMS); if (bindStack.isEmpty()) return false; - if (bindStack.getItem() instanceof GenericBind bind) { - BindVariant variant = bind.getVariant(); - return ( - variant == BindVariant.WRAP || variant == BindVariant.LATEX_SACK - ); - } - return false; + PoseType poseType = PoseTypeHelper.getPoseType(bindStack); + return poseType == PoseType.WRAP || poseType == PoseType.LATEX_SACK; } } diff --git a/src/main/java/com/tiedup/remake/client/ModKeybindings.java b/src/main/java/com/tiedup/remake/client/ModKeybindings.java index 549c617..11e60d5 100644 --- a/src/main/java/com/tiedup/remake/client/ModKeybindings.java +++ b/src/main/java/com/tiedup/remake/client/ModKeybindings.java @@ -6,7 +6,7 @@ import com.tiedup.remake.client.gui.screens.UnifiedBondageScreen; import com.tiedup.remake.core.ModConfig; import com.tiedup.remake.core.TiedUpMod; 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.network.ModNetwork; import com.tiedup.remake.network.action.PacketForceSeatModifier; import com.tiedup.remake.network.action.PacketStruggle; @@ -428,11 +428,8 @@ public class ModKeybindings { target, BodyRegionV2.NECK ); - if ( - !collarStack.isEmpty() && - collarStack.getItem() instanceof ItemCollar collar - ) { - return collar.isOwner(collarStack, player); + if (!collarStack.isEmpty() && CollarHelper.isCollar(collarStack)) { + return CollarHelper.isOwner(collarStack, player); } return false; } diff --git a/src/main/java/com/tiedup/remake/client/animation/render/DogPoseRenderHandler.java b/src/main/java/com/tiedup/remake/client/animation/render/DogPoseRenderHandler.java index fa799f5..f61f877 100644 --- a/src/main/java/com/tiedup/remake/client/animation/render/DogPoseRenderHandler.java +++ b/src/main/java/com/tiedup/remake/client/animation/render/DogPoseRenderHandler.java @@ -1,8 +1,8 @@ package com.tiedup.remake.client.animation.render; import com.tiedup.remake.core.TiedUpMod; -import com.tiedup.remake.items.base.ItemBind; import com.tiedup.remake.items.base.PoseType; +import com.tiedup.remake.v2.bondage.PoseTypeHelper; import com.tiedup.remake.state.HumanChairHelper; import com.tiedup.remake.state.PlayerBindState; import com.tiedup.remake.v2.BodyRegionV2; @@ -93,14 +93,11 @@ public class DogPoseRenderHandler { } ItemStack bindForPose = state.getEquipment(BodyRegionV2.ARMS); - if ( - bindForPose.isEmpty() || - !(bindForPose.getItem() instanceof ItemBind itemBind) - ) { + if (bindForPose.isEmpty()) { return; } - PoseType bindPoseType = itemBind.getPoseType(); + PoseType bindPoseType = PoseTypeHelper.getPoseType(bindForPose); // Check for humanChairMode NBT override bindPoseType = HumanChairHelper.resolveEffectivePose( bindPoseType, diff --git a/src/main/java/com/tiedup/remake/client/animation/render/PetBedRenderHandler.java b/src/main/java/com/tiedup/remake/client/animation/render/PetBedRenderHandler.java index d057531..53e0bbd 100644 --- a/src/main/java/com/tiedup/remake/client/animation/render/PetBedRenderHandler.java +++ b/src/main/java/com/tiedup/remake/client/animation/render/PetBedRenderHandler.java @@ -2,8 +2,8 @@ package com.tiedup.remake.client.animation.render; import com.tiedup.remake.client.state.PetBedClientState; import com.tiedup.remake.core.TiedUpMod; -import com.tiedup.remake.items.base.ItemBind; import com.tiedup.remake.items.base.PoseType; +import com.tiedup.remake.v2.bondage.PoseTypeHelper; import com.tiedup.remake.state.HumanChairHelper; import com.tiedup.remake.state.PlayerBindState; import com.tiedup.remake.v2.BodyRegionV2; @@ -83,11 +83,9 @@ public class PetBedRenderHandler { PlayerBindState state = PlayerBindState.getInstance(player); if (state == null) return false; ItemStack bind = state.getEquipment(BodyRegionV2.ARMS); - if ( - bind.isEmpty() || !(bind.getItem() instanceof ItemBind itemBind) - ) return false; + if (bind.isEmpty()) return false; PoseType pose = HumanChairHelper.resolveEffectivePose( - itemBind.getPoseType(), + PoseTypeHelper.getPoseType(bind), bind ); return pose == PoseType.DOG || pose == PoseType.HUMAN_CHAIR; diff --git a/src/main/java/com/tiedup/remake/client/animation/render/PlayerArmHideEventHandler.java b/src/main/java/com/tiedup/remake/client/animation/render/PlayerArmHideEventHandler.java index e7773f6..3dd08a7 100644 --- a/src/main/java/com/tiedup/remake/client/animation/render/PlayerArmHideEventHandler.java +++ b/src/main/java/com/tiedup/remake/client/animation/render/PlayerArmHideEventHandler.java @@ -2,8 +2,8 @@ package com.tiedup.remake.client.animation.render; import com.tiedup.remake.client.renderer.layers.ClothesRenderHelper; import com.tiedup.remake.core.TiedUpMod; -import com.tiedup.remake.items.base.ItemBind; import com.tiedup.remake.items.base.PoseType; +import com.tiedup.remake.v2.bondage.PoseTypeHelper; import com.tiedup.remake.items.clothes.ClothesProperties; import com.tiedup.remake.state.PlayerBindState; import com.tiedup.remake.v2.BodyRegionV2; @@ -71,10 +71,8 @@ public class PlayerArmHideEventHandler { // === HIDE ARMS (wrap/latex_sack poses) === if (state.hasArmsBound()) { ItemStack bind = state.getEquipment(BodyRegionV2.ARMS); - if ( - !bind.isEmpty() && bind.getItem() instanceof ItemBind itemBind - ) { - PoseType poseType = itemBind.getPoseType(); + if (!bind.isEmpty()) { + PoseType poseType = PoseTypeHelper.getPoseType(bind); // Only hide arms for wrap/sack poses (arms are covered by the item) if ( diff --git a/src/main/java/com/tiedup/remake/client/animation/tick/AnimationTickHandler.java b/src/main/java/com/tiedup/remake/client/animation/tick/AnimationTickHandler.java index 70bc8a2..4b31a49 100644 --- a/src/main/java/com/tiedup/remake/client/animation/tick/AnimationTickHandler.java +++ b/src/main/java/com/tiedup/remake/client/animation/tick/AnimationTickHandler.java @@ -14,8 +14,9 @@ import com.tiedup.remake.client.gltf.GltfAnimationApplier; import com.tiedup.remake.client.state.ClothesClientCache; import com.tiedup.remake.client.state.MovementStyleClientState; import com.tiedup.remake.client.state.PetBedClientState; -import com.tiedup.remake.items.base.ItemBind; import com.tiedup.remake.items.base.PoseType; +import com.tiedup.remake.v2.bondage.BindModeHelper; +import com.tiedup.remake.v2.bondage.PoseTypeHelper; import com.tiedup.remake.state.HumanChairHelper; import com.tiedup.remake.state.PlayerBindState; import com.tiedup.remake.v2.BodyRegionV2; @@ -249,14 +250,10 @@ public class AnimationTickHandler { PlayerBindState state ) { ItemStack bind = state.getEquipment(BodyRegionV2.ARMS); - PoseType poseType = PoseType.STANDARD; + PoseType poseType = PoseTypeHelper.getPoseType(bind); - if (bind.getItem() instanceof ItemBind itemBind) { - poseType = itemBind.getPoseType(); - - // Human chair mode: override DOG pose to HUMAN_CHAIR (straight limbs) - poseType = HumanChairHelper.resolveEffectivePose(poseType, bind); - } + // Human chair mode: override DOG pose to HUMAN_CHAIR (straight limbs) + poseType = HumanChairHelper.resolveEffectivePose(poseType, bind); // Derive bound state from V2 regions (works client-side, synced via capability) boolean armsBound = V2EquipmentHelper.isRegionOccupied( @@ -268,10 +265,10 @@ public class AnimationTickHandler { BodyRegionV2.LEGS ); - // V1 fallback: if no V2 regions are set but player is tied, derive from ItemBind NBT - if (!armsBound && !legsBound && bind.getItem() instanceof ItemBind) { - armsBound = ItemBind.hasArmsBound(bind); - legsBound = ItemBind.hasLegsBound(bind); + // V1 fallback: if no V2 regions are set but player is tied, derive from bind mode NBT + if (!armsBound && !legsBound && BindModeHelper.isBindItem(bind)) { + armsBound = BindModeHelper.hasArmsBound(bind); + legsBound = BindModeHelper.hasLegsBound(bind); } boolean isStruggling = state.isStruggling(); diff --git a/src/main/java/com/tiedup/remake/client/animation/tick/NpcAnimationTickHandler.java b/src/main/java/com/tiedup/remake/client/animation/tick/NpcAnimationTickHandler.java index ae0e805..828c994 100644 --- a/src/main/java/com/tiedup/remake/client/animation/tick/NpcAnimationTickHandler.java +++ b/src/main/java/com/tiedup/remake/client/animation/tick/NpcAnimationTickHandler.java @@ -9,8 +9,9 @@ import com.tiedup.remake.client.gltf.GltfAnimationApplier; import com.tiedup.remake.entities.AbstractTiedUpNpc; import com.tiedup.remake.entities.EntityMaster; import com.tiedup.remake.entities.ai.master.MasterState; -import com.tiedup.remake.items.base.ItemBind; import com.tiedup.remake.items.base.PoseType; +import com.tiedup.remake.v2.bondage.BindModeHelper; +import com.tiedup.remake.v2.bondage.PoseTypeHelper; import com.tiedup.remake.v2.BodyRegionV2; import com.tiedup.remake.v2.bondage.IV2BondageEquipment; import com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper; @@ -161,13 +162,8 @@ public class NpcAnimationTickHandler { net.minecraft.world.item.ItemStack bind = entity.getEquipment( BodyRegionV2.ARMS ); - PoseType poseType = PoseType.STANDARD; - boolean hasBind = false; - - if (bind.getItem() instanceof ItemBind itemBind) { - poseType = itemBind.getPoseType(); - hasBind = true; - } + PoseType poseType = PoseTypeHelper.getPoseType(bind); + boolean hasBind = BindModeHelper.isBindItem(bind); // Derive bound state from V2 regions (AbstractTiedUpNpc implements IV2EquipmentHolder) boolean armsBound = V2EquipmentHelper.isRegionOccupied( @@ -179,10 +175,10 @@ public class NpcAnimationTickHandler { BodyRegionV2.LEGS ); - // V1 fallback: if no V2 regions set but NPC has a bind, derive from ItemBind NBT - if (!armsBound && !legsBound && bind.getItem() instanceof ItemBind) { - armsBound = ItemBind.hasArmsBound(bind); - legsBound = ItemBind.hasLegsBound(bind); + // V1 fallback: if no V2 regions set but NPC has a bind, derive from bind mode NBT + if (!armsBound && !legsBound && BindModeHelper.isBindItem(bind)) { + armsBound = BindModeHelper.hasArmsBound(bind); + legsBound = BindModeHelper.hasLegsBound(bind); } boolean isStruggling = entity.isStruggling(); diff --git a/src/main/java/com/tiedup/remake/client/events/LeashProxyClientHandler.java b/src/main/java/com/tiedup/remake/client/events/LeashProxyClientHandler.java index 8a3c237..fb1676b 100644 --- a/src/main/java/com/tiedup/remake/client/events/LeashProxyClientHandler.java +++ b/src/main/java/com/tiedup/remake/client/events/LeashProxyClientHandler.java @@ -1,8 +1,8 @@ package com.tiedup.remake.client.events; import com.tiedup.remake.core.TiedUpMod; -import com.tiedup.remake.items.ModItems; -import com.tiedup.remake.items.base.BindVariant; +import com.tiedup.remake.items.base.PoseType; +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; @@ -138,7 +138,7 @@ public class LeashProxyClientHandler { ItemStack bind = state.getEquipment(BodyRegionV2.ARMS); if ( !bind.isEmpty() && - bind.getItem() == ModItems.getBind(BindVariant.DOGBINDER) + PoseTypeHelper.getPoseType(bind) == PoseType.DOG ) { return DOGWALK_Y_OFFSET; } diff --git a/src/main/java/com/tiedup/remake/client/events/SelfBondageInputHandler.java b/src/main/java/com/tiedup/remake/client/events/SelfBondageInputHandler.java index a06ba1d..b876fbd 100644 --- a/src/main/java/com/tiedup/remake/client/events/SelfBondageInputHandler.java +++ b/src/main/java/com/tiedup/remake/client/events/SelfBondageInputHandler.java @@ -1,13 +1,20 @@ package com.tiedup.remake.client.events; -import com.tiedup.remake.items.base.*; +import com.tiedup.remake.items.base.ItemCollar; import com.tiedup.remake.network.ModNetwork; import com.tiedup.remake.network.selfbondage.PacketSelfBondage; +import com.tiedup.remake.v2.bondage.BindModeHelper; +import com.tiedup.remake.v2.bondage.CollarHelper; import com.tiedup.remake.v2.bondage.IV2BondageItem; +import com.tiedup.remake.v2.bondage.component.BlindingComponent; +import com.tiedup.remake.v2.bondage.component.ComponentType; +import com.tiedup.remake.v2.bondage.component.GaggingComponent; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemDefinition; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemRegistry; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; import net.minecraft.world.InteractionHand; -import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @@ -70,7 +77,7 @@ public class SelfBondageInputHandler { if (!event.getLevel().isClientSide()) return; ItemStack stack = event.getItemStack(); - if (isSelfBondageItem(stack.getItem())) { + if (isSelfBondageItem(stack)) { event.setCanceled(true); startSelfBondage(); } @@ -87,11 +94,11 @@ public class SelfBondageInputHandler { InteractionHand hand = InteractionHand.MAIN_HAND; ItemStack stack = player.getMainHandItem(); - if (!isSelfBondageItem(stack.getItem())) { + if (!isSelfBondageItem(stack)) { stack = player.getOffhandItem(); hand = InteractionHand.OFF_HAND; - if (!isSelfBondageItem(stack.getItem())) { + if (!isSelfBondageItem(stack)) { return; // No bondage item in either hand } } @@ -130,7 +137,7 @@ public class SelfBondageInputHandler { // Check if still holding bondage item in the active hand ItemStack stack = player.getItemInHand(activeHand); - if (!isSelfBondageItem(stack.getItem())) { + if (!isSelfBondageItem(stack)) { stopSelfBondage(); return; } @@ -153,27 +160,31 @@ public class SelfBondageInputHandler { } /** - * Check if an item supports self-bondage. + * Check if a stack supports self-bondage. * Collar is explicitly excluded. */ - private static boolean isSelfBondageItem(Item item) { - // Collar cannot be self-equipped (V1 collar guard) - if (item instanceof ItemCollar) { + private static boolean isSelfBondageItem(ItemStack stack) { + if (stack.isEmpty()) return false; + + // Collar cannot be self-equipped (V1 collar guard + V2 ownership component) + if (stack.getItem() instanceof ItemCollar || CollarHelper.isCollar(stack)) { return false; } // V2 bondage items support self-bondage (left-click hold with tying duration) - if (item instanceof IV2BondageItem) { + if (stack.getItem() instanceof IV2BondageItem) { return true; } - // V1 bondage items (legacy) - return ( - item instanceof ItemBind || - item instanceof ItemGag || - item instanceof ItemBlindfold || - item instanceof ItemMittens || - item instanceof ItemEarplugs - ); + // V2 data-driven items: check if it occupies any bondage region + DataDrivenItemDefinition def = DataDrivenItemRegistry.get(stack); + if (def != null) { + return true; + } + + // V1 fallback: bind items + return BindModeHelper.isBindItem(stack) + || DataDrivenBondageItem.getComponent(stack, ComponentType.GAGGING, GaggingComponent.class) != null + || DataDrivenBondageItem.getComponent(stack, ComponentType.BLINDING, BlindingComponent.class) != null; } } diff --git a/src/main/java/com/tiedup/remake/client/gui/screens/SlaveManagementScreen.java b/src/main/java/com/tiedup/remake/client/gui/screens/SlaveManagementScreen.java index e597979..52d895f 100644 --- a/src/main/java/com/tiedup/remake/client/gui/screens/SlaveManagementScreen.java +++ b/src/main/java/com/tiedup/remake/client/gui/screens/SlaveManagementScreen.java @@ -3,7 +3,7 @@ package com.tiedup.remake.client.gui.screens; import com.tiedup.remake.client.gui.util.GuiColors; import com.tiedup.remake.client.gui.util.GuiLayoutConstants; import com.tiedup.remake.client.gui.widgets.SlaveEntryWidget; -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.slave.PacketSlaveAction; import com.tiedup.remake.state.IBondageState; @@ -145,8 +145,8 @@ public class SlaveManagementScreen extends BaseScreen { ItemStack collarStack = kidnapped.getEquipment( BodyRegionV2.NECK ); - if (collarStack.getItem() instanceof ItemCollar collar) { - if (collar.isOwner(collarStack, player)) { + if (CollarHelper.isCollar(collarStack)) { + if (CollarHelper.isOwner(collarStack, player)) { addSlaveEntry(kidnapped); addedUUIDs.add(entity.getUUID()); } diff --git a/src/main/java/com/tiedup/remake/client/gui/widgets/ActionPanel.java b/src/main/java/com/tiedup/remake/client/gui/widgets/ActionPanel.java index 9bf0801..72fe69a 100644 --- a/src/main/java/com/tiedup/remake/client/gui/widgets/ActionPanel.java +++ b/src/main/java/com/tiedup/remake/client/gui/widgets/ActionPanel.java @@ -7,7 +7,7 @@ import com.tiedup.remake.items.ItemLockpick; import com.tiedup.remake.items.ModItems; import com.tiedup.remake.items.base.IHasResistance; 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.network.ModNetwork; import com.tiedup.remake.network.action.PacketSetKnifeCutTarget; import com.tiedup.remake.network.minigame.PacketLockpickMiniGameStart; @@ -474,10 +474,10 @@ public class ActionPanel extends AbstractWidget { // Bondage Service toggle (NECK collar only, prison configured) if ( selectedRegion == BodyRegionV2.NECK && - selectedItem.getItem() instanceof ItemCollar collar + CollarHelper.isCollar(selectedItem) ) { - if (collar.hasCellAssigned(selectedItem)) { - boolean svcEnabled = collar.isBondageServiceEnabled( + if (CollarHelper.hasCellAssigned(selectedItem)) { + boolean svcEnabled = CollarHelper.isBondageServiceEnabled( selectedItem ); String svcKey = svcEnabled diff --git a/src/main/java/com/tiedup/remake/client/gui/widgets/SlaveEntryWidget.java b/src/main/java/com/tiedup/remake/client/gui/widgets/SlaveEntryWidget.java index 86c610c..00fdb2d 100644 --- a/src/main/java/com/tiedup/remake/client/gui/widgets/SlaveEntryWidget.java +++ b/src/main/java/com/tiedup/remake/client/gui/widgets/SlaveEntryWidget.java @@ -5,7 +5,7 @@ import static com.tiedup.remake.client.gui.util.GuiLayoutConstants.*; import com.google.common.collect.ImmutableList; import com.tiedup.remake.client.gui.util.GuiColors; import com.tiedup.remake.items.ItemGpsCollar; -import com.tiedup.remake.items.base.ItemCollar; +import com.tiedup.remake.v2.bondage.CollarHelper; import com.tiedup.remake.state.IBondageState; import com.tiedup.remake.v2.BodyRegionV2; import java.util.ArrayList; @@ -560,19 +560,13 @@ public class SlaveEntryWidget private boolean hasShockCollar() { if (!slave.hasCollar()) return false; ItemStack collar = slave.getEquipment(BodyRegionV2.NECK); - return ( - collar.getItem() instanceof ItemCollar itemCollar && - itemCollar.canShock() - ); + return CollarHelper.canShock(collar); } private boolean hasGPSCollar() { if (!slave.hasCollar()) return false; ItemStack collar = slave.getEquipment(BodyRegionV2.NECK); - return ( - collar.getItem() instanceof ItemCollar itemCollar && - itemCollar.hasGPS() - ); + return CollarHelper.hasGPS(collar); } private boolean isInAnySafeZone( @@ -580,7 +574,7 @@ public class SlaveEntryWidget ItemStack collarStack, LivingEntity entity ) { - if (!gps.isActive(collarStack)) return true; + if (!CollarHelper.isActive(collarStack)) return true; var safeSpots = gps.getSafeSpots(collarStack); if (safeSpots.isEmpty()) return true; diff --git a/src/main/java/com/tiedup/remake/client/model/DamselModel.java b/src/main/java/com/tiedup/remake/client/model/DamselModel.java index 9668e95..80e1567 100644 --- a/src/main/java/com/tiedup/remake/client/model/DamselModel.java +++ b/src/main/java/com/tiedup/remake/client/model/DamselModel.java @@ -9,8 +9,9 @@ import com.tiedup.remake.entities.AbstractTiedUpNpc; import com.tiedup.remake.entities.EntityKidnapperArcher; import com.tiedup.remake.entities.EntityMaster; import com.tiedup.remake.entities.ai.master.MasterState; -import com.tiedup.remake.items.base.ItemBind; import com.tiedup.remake.items.base.PoseType; +import com.tiedup.remake.v2.bondage.BindModeHelper; +import com.tiedup.remake.v2.bondage.PoseTypeHelper; import com.tiedup.remake.items.clothes.GenericClothes; import com.tiedup.remake.v2.BodyRegionV2; import com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper; @@ -230,11 +231,7 @@ public class DamselModel if (inPose) { ItemStack bind = entity.getEquipment(BodyRegionV2.ARMS); - PoseType poseType = PoseType.STANDARD; - - if (bind.getItem() instanceof ItemBind itemBind) { - poseType = itemBind.getPoseType(); - } + PoseType poseType = PoseTypeHelper.getPoseType(bind); // Hide arms for wrap/latex_sack poses if (poseType == PoseType.WRAP || poseType == PoseType.LATEX_SACK) { @@ -252,9 +249,7 @@ public class DamselModel PoseType currentPoseType = PoseType.STANDARD; if (inPose) { ItemStack bindForPoseType = entity.getEquipment(BodyRegionV2.ARMS); - if (bindForPoseType.getItem() instanceof ItemBind itemBindForType) { - currentPoseType = itemBindForType.getPoseType(); - } + currentPoseType = PoseTypeHelper.getPoseType(bindForPoseType); } // Check if this is a Master in human chair mode (head should look around freely) @@ -306,11 +301,7 @@ public class DamselModel // Animation not yet active (1-frame delay) - apply static pose as fallback // This ensures immediate visual feedback when bind is applied ItemStack bind = entity.getEquipment(BodyRegionV2.ARMS); - PoseType fallbackPoseType = PoseType.STANDARD; - - if (bind.getItem() instanceof ItemBind itemBind) { - fallbackPoseType = itemBind.getPoseType(); - } + PoseType fallbackPoseType = PoseTypeHelper.getPoseType(bind); // Derive bound state from V2 regions (AbstractTiedUpNpc implements IV2EquipmentHolder) boolean armsBound = V2EquipmentHelper.isRegionOccupied( @@ -323,10 +314,10 @@ public class DamselModel ); if ( - !armsBound && !legsBound && bind.getItem() instanceof ItemBind + !armsBound && !legsBound && BindModeHelper.isBindItem(bind) ) { - armsBound = ItemBind.hasArmsBound(bind); - legsBound = ItemBind.hasLegsBound(bind); + armsBound = BindModeHelper.hasArmsBound(bind); + legsBound = BindModeHelper.hasLegsBound(bind); } // Apply static pose directly to model parts diff --git a/src/main/java/com/tiedup/remake/commands/CollarCommand.java b/src/main/java/com/tiedup/remake/commands/CollarCommand.java index fc26120..7384090 100644 --- a/src/main/java/com/tiedup/remake/commands/CollarCommand.java +++ b/src/main/java/com/tiedup/remake/commands/CollarCommand.java @@ -7,8 +7,8 @@ import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.tiedup.remake.cells.CellDataV2; import com.tiedup.remake.cells.CellRegistryV2; -import com.tiedup.remake.items.base.ItemCollar; import com.tiedup.remake.state.PlayerBindState; +import com.tiedup.remake.v2.bondage.CollarHelper; import com.tiedup.remake.util.teleport.Position; import com.tiedup.remake.util.teleport.TeleportHelper; import com.tiedup.remake.v2.BodyRegionV2; @@ -160,8 +160,8 @@ public class CollarCommand { } if (source.getEntity() instanceof ServerPlayer executor) { - if (collar.getItem() instanceof ItemCollar collarItem) { - collarItem.addOwner(collar, executor); + if (CollarHelper.isCollar(collar)) { + CollarHelper.addOwner(collar, executor); source.sendSuccess( () -> Component.literal( @@ -195,8 +195,8 @@ public class CollarCommand { } if (source.getEntity() instanceof ServerPlayer executor) { - if (collar.getItem() instanceof ItemCollar collarItem) { - collarItem.removeOwner(collar, executor.getUUID()); + if (CollarHelper.isCollar(collar)) { + CollarHelper.removeOwner(collar, executor.getUUID()); source.sendSuccess( () -> Component.literal( @@ -230,8 +230,8 @@ public class CollarCommand { return 0; } - if (collar.getItem() instanceof ItemCollar collarItem) { - collarItem.setNickname(collar, name); + if (CollarHelper.isCollar(collar)) { + CollarHelper.setNickname(collar, name); source.sendSuccess( () -> Component.literal( @@ -261,8 +261,8 @@ public class CollarCommand { return 0; } - if (collar.getItem() instanceof ItemCollar collarItem) { - collarItem.addOwner(collar, owner); + if (CollarHelper.isCollar(collar)) { + CollarHelper.addOwner(collar, owner); source.sendSuccess( () -> Component.literal( @@ -296,8 +296,8 @@ public class CollarCommand { return 0; } - if (collar.getItem() instanceof ItemCollar collarItem) { - collarItem.removeOwner(collar, owner.getUUID()); + if (CollarHelper.isCollar(collar)) { + CollarHelper.removeOwner(collar, owner.getUUID()); source.sendSuccess( () -> Component.literal( @@ -348,8 +348,8 @@ public class CollarCommand { return 0; } - if (collar.getItem() instanceof ItemCollar collarItem) { - collarItem.setCellId(collar, cell.getId()); + if (CollarHelper.isCollar(collar)) { + CollarHelper.setCellId(collar, cell.getId()); source.sendSuccess( () -> Component.literal( @@ -388,8 +388,8 @@ public class CollarCommand { return 0; } - if (collar.getItem() instanceof ItemCollar collarItem) { - if (!collarItem.hasCellAssigned(collar)) { + if (CollarHelper.isCollar(collar)) { + if (!CollarHelper.hasCellAssigned(collar)) { source.sendFailure( Component.literal("No cell assigned to collar") ); @@ -397,7 +397,7 @@ public class CollarCommand { } // Get cell position and teleport - java.util.UUID cellId = collarItem.getCellId(collar); + java.util.UUID cellId = CollarHelper.getCellId(collar); ServerLevel serverLevel = source.getLevel(); CellDataV2 cell = CellRegistryV2.get(serverLevel).getCell(cellId); @@ -449,7 +449,7 @@ public class CollarCommand { return 0; } - if (collar.getItem() instanceof ItemCollar collarItem) { + if (CollarHelper.isCollar(collar)) { source.sendSuccess( () -> Component.literal( @@ -460,24 +460,24 @@ public class CollarCommand { false ); - String nickname = collarItem.getNickname(collar); + String nickname = CollarHelper.getNickname(collar); source.sendSuccess( () -> Component.literal( "§7Nickname: §f" + - (nickname.isEmpty() ? "None" : nickname) + (nickname == null || nickname.isEmpty() ? "None" : nickname) ), false ); source.sendSuccess( () -> Component.literal( - "§7Has Owner: §f" + collarItem.hasOwner(collar) + "§7Has Owner: §f" + CollarHelper.hasOwner(collar) ), false ); // Cell assignment - java.util.UUID cellId = collarItem.getCellId(collar); + java.util.UUID cellId = CollarHelper.getCellId(collar); if (cellId != null) { ServerLevel serverLevel = source.getLevel(); CellRegistryV2 registry = CellRegistryV2.get(serverLevel); @@ -510,10 +510,12 @@ public class CollarCommand { ); } + boolean locked = collar.getItem() instanceof com.tiedup.remake.items.base.ILockable lockable + && lockable.isLocked(collar); source.sendSuccess( () -> Component.literal( - "§7Locked: §f" + collarItem.isLocked(collar) + "§7Locked: §f" + locked ), false ); diff --git a/src/main/java/com/tiedup/remake/commands/KidnapSetCommand.java b/src/main/java/com/tiedup/remake/commands/KidnapSetCommand.java index d555007..a269e13 100644 --- a/src/main/java/com/tiedup/remake/commands/KidnapSetCommand.java +++ b/src/main/java/com/tiedup/remake/commands/KidnapSetCommand.java @@ -4,12 +4,10 @@ import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; 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.EarplugsVariant; -import com.tiedup.remake.items.base.GagVariant; import com.tiedup.remake.items.base.KnifeVariant; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem; import java.util.Optional; +import net.minecraft.resources.ResourceLocation; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import net.minecraft.network.chat.Component; @@ -82,42 +80,18 @@ public class KidnapSetCommand { int given = 0; // Binds - given += giveItem( - player, - new ItemStack(ModItems.getBind(BindVariant.ROPES), 8) - ); - given += giveItem( - player, - new ItemStack(ModItems.getBind(BindVariant.CHAIN), 4) - ); - given += giveItem( - player, - new ItemStack(ModItems.getBind(BindVariant.LEATHER_STRAPS), 4) - ); + given += giveDataDrivenItems(player, "ropes", 8); + given += giveDataDrivenItems(player, "chain", 4); + given += giveDataDrivenItems(player, "leather_straps", 4); // Gags - given += giveItem( - player, - new ItemStack(ModItems.getGag(GagVariant.CLOTH_GAG), 4) - ); - given += giveItem( - player, - new ItemStack(ModItems.getGag(GagVariant.BALL_GAG), 4) - ); - given += giveItem( - player, - new ItemStack(ModItems.getGag(GagVariant.TAPE_GAG), 4) - ); + given += giveDataDrivenItems(player, "cloth_gag", 4); + given += giveDataDrivenItems(player, "ball_gag", 4); + given += giveDataDrivenItems(player, "tape_gag", 4); // Blindfolds - given += giveItem( - player, - new ItemStack(ModItems.getBlindfold(BlindfoldVariant.CLASSIC), 4) - ); - given += giveItem( - player, - new ItemStack(ModItems.getBlindfold(BlindfoldVariant.MASK), 2) - ); + given += giveDataDrivenItems(player, "classic_blindfold", 4); + given += giveDataDrivenItems(player, "blindfold_mask", 2); // Collars given += giveItem( @@ -155,10 +129,7 @@ public class KidnapSetCommand { given += giveItem(player, new ItemStack(ModItems.MASTER_KEY.get(), 1)); // Earplugs - given += giveItem( - player, - new ItemStack(ModItems.getEarplugs(EarplugsVariant.CLASSIC), 4) - ); + given += giveDataDrivenItems(player, "classic_earplugs", 4); // Rope arrows given += giveItem(player, new ItemStack(ModItems.ROPE_ARROW.get(), 16)); @@ -182,6 +153,18 @@ public class KidnapSetCommand { return finalGiven; } + private static int giveDataDrivenItems(ServerPlayer player, String itemName, int count) { + int given = 0; + for (int i = 0; i < count; i++) { + ItemStack stack = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", itemName)); + if (!stack.isEmpty()) { + giveItem(player, stack); + given++; + } + } + return given; + } + private static int giveItem(ServerPlayer player, ItemStack stack) { if (!player.getInventory().add(stack)) { // Drop on ground if inventory full diff --git a/src/main/java/com/tiedup/remake/commands/NPCCommand.java b/src/main/java/com/tiedup/remake/commands/NPCCommand.java index 88d0251..d2960a1 100644 --- a/src/main/java/com/tiedup/remake/commands/NPCCommand.java +++ b/src/main/java/com/tiedup/remake/commands/NPCCommand.java @@ -7,11 +7,9 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.tiedup.remake.entities.*; import com.tiedup.remake.entities.skins.EliteKidnapperSkinManager; 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.EarplugsVariant; -import com.tiedup.remake.items.base.GagVariant; import com.tiedup.remake.state.IBondageState; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem; +import net.minecraft.resources.ResourceLocation; import com.tiedup.remake.v2.BodyRegionV2; import java.util.List; import java.util.Optional; @@ -507,7 +505,7 @@ public class NPCCommand { npc.equip( BodyRegionV2.ARMS, - new ItemStack(ModItems.getBind(BindVariant.ROPES)) + DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "ropes")) ); context .getSource() @@ -538,7 +536,7 @@ public class NPCCommand { npc.equip( BodyRegionV2.MOUTH, - new ItemStack(ModItems.getGag(GagVariant.CLOTH_GAG)) + DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "cloth_gag")) ); context .getSource() @@ -571,7 +569,7 @@ public class NPCCommand { npc.equip( BodyRegionV2.EYES, - new ItemStack(ModItems.getBlindfold(BlindfoldVariant.CLASSIC)) + DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "classic_blindfold")) ); context .getSource() @@ -656,10 +654,10 @@ public class NPCCommand { com.tiedup.remake.entities.AbstractTiedUpNpc npcEntity ) { npcEntity.applyBondage( - new ItemStack(ModItems.getBind(BindVariant.ROPES)), - new ItemStack(ModItems.getGag(GagVariant.CLOTH_GAG)), - new ItemStack(ModItems.getBlindfold(BlindfoldVariant.CLASSIC)), - new ItemStack(ModItems.getEarplugs(EarplugsVariant.CLASSIC)), + DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "ropes")), + DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "cloth_gag")), + DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "classic_blindfold")), + DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "classic_earplugs")), new ItemStack(ModItems.CLASSIC_COLLAR.get()), ItemStack.EMPTY // No clothes ); diff --git a/src/main/java/com/tiedup/remake/commands/subcommands/BondageSubCommand.java b/src/main/java/com/tiedup/remake/commands/subcommands/BondageSubCommand.java index 96f85a6..3e53e76 100644 --- a/src/main/java/com/tiedup/remake/commands/subcommands/BondageSubCommand.java +++ b/src/main/java/com/tiedup/remake/commands/subcommands/BondageSubCommand.java @@ -9,12 +9,10 @@ import com.tiedup.remake.commands.CommandHelper; import com.tiedup.remake.core.SystemMessageManager; import com.tiedup.remake.items.ModItems; import com.tiedup.remake.items.base.AdjustmentHelper; -import com.tiedup.remake.items.base.BindVariant; -import com.tiedup.remake.items.base.BlindfoldVariant; -import com.tiedup.remake.items.base.EarplugsVariant; -import com.tiedup.remake.items.base.GagVariant; -import com.tiedup.remake.items.base.ItemCollar; import com.tiedup.remake.network.ModNetwork; +import com.tiedup.remake.v2.bondage.CollarHelper; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem; +import net.minecraft.resources.ResourceLocation; import com.tiedup.remake.network.sync.PacketSyncBindState; import com.tiedup.remake.state.PlayerBindState; import net.minecraft.commands.CommandSourceStack; @@ -256,7 +254,7 @@ public class BondageSubCommand { return 0; } - ItemStack ropes = new ItemStack(ModItems.getBind(BindVariant.ROPES)); + ItemStack ropes = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "ropes")); state.putBindOn(ropes); CommandHelper.syncPlayerState(targetPlayer, state); @@ -387,7 +385,7 @@ public class BondageSubCommand { return 0; } - ItemStack gag = new ItemStack(ModItems.getGag(GagVariant.CLOTH_GAG)); + ItemStack gag = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "cloth_gag")); state.putGagOn(gag); CommandHelper.syncPlayerState(targetPlayer, state); @@ -440,9 +438,7 @@ public class BondageSubCommand { return 0; } - ItemStack blindfold = new ItemStack( - ModItems.getBlindfold(BlindfoldVariant.CLASSIC) - ); + ItemStack blindfold = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "classic_blindfold")); state.putBlindfoldOn(blindfold); CommandHelper.syncPlayerState(targetPlayer, state); @@ -500,8 +496,7 @@ public class BondageSubCommand { ItemStack collar = new ItemStack(ModItems.CLASSIC_COLLAR.get()); if (context.getSource().getEntity() instanceof ServerPlayer executor) { - ItemCollar collarItem = (ItemCollar) collar.getItem(); - collarItem.addOwner(collar, executor); + CollarHelper.addOwner(collar, executor); } state.putCollarOn(collar); @@ -1021,9 +1016,7 @@ public class BondageSubCommand { return 0; } - ItemStack earplugs = new ItemStack( - ModItems.getEarplugs(EarplugsVariant.CLASSIC) - ); + ItemStack earplugs = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "classic_earplugs")); state.putEarplugsOn(earplugs); CommandHelper.syncPlayerState(targetPlayer, state); @@ -1067,25 +1060,19 @@ public class BondageSubCommand { int applied = 0; if (!state.isTiedUp()) { - ItemStack ropes = new ItemStack( - ModItems.getBind(BindVariant.ROPES) - ); + ItemStack ropes = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "ropes")); state.putBindOn(ropes); applied++; } if (!state.isGagged()) { - ItemStack gag = new ItemStack( - ModItems.getGag(GagVariant.CLOTH_GAG) - ); + ItemStack gag = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "cloth_gag")); state.putGagOn(gag); applied++; } if (!state.isBlindfolded()) { - ItemStack blindfold = new ItemStack( - ModItems.getBlindfold(BlindfoldVariant.CLASSIC) - ); + ItemStack blindfold = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "classic_blindfold")); state.putBlindfoldOn(blindfold); applied++; } @@ -1095,17 +1082,14 @@ public class BondageSubCommand { if ( context.getSource().getEntity() instanceof ServerPlayer executor ) { - ItemCollar collarItem = (ItemCollar) collar.getItem(); - collarItem.addOwner(collar, executor); + CollarHelper.addOwner(collar, executor); } state.putCollarOn(collar); applied++; } if (!state.hasEarplugs()) { - ItemStack earplugs = new ItemStack( - ModItems.getEarplugs(EarplugsVariant.CLASSIC) - ); + ItemStack earplugs = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "classic_earplugs")); state.putEarplugsOn(earplugs); applied++; } @@ -1167,21 +1151,15 @@ public class BondageSubCommand { // First fully restrain if (!state.isTiedUp()) { - ItemStack ropes = new ItemStack( - ModItems.getBind(BindVariant.ROPES) - ); + ItemStack ropes = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "ropes")); state.putBindOn(ropes); } if (!state.isGagged()) { - ItemStack gag = new ItemStack( - ModItems.getGag(GagVariant.CLOTH_GAG) - ); + ItemStack gag = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "cloth_gag")); state.putGagOn(gag); } if (!state.isBlindfolded()) { - ItemStack blindfold = new ItemStack( - ModItems.getBlindfold(BlindfoldVariant.CLASSIC) - ); + ItemStack blindfold = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "classic_blindfold")); state.putBlindfoldOn(blindfold); } if (!state.hasCollar()) { @@ -1189,15 +1167,12 @@ public class BondageSubCommand { if ( context.getSource().getEntity() instanceof ServerPlayer executor ) { - ItemCollar collarItem = (ItemCollar) collar.getItem(); - collarItem.addOwner(collar, executor); + CollarHelper.addOwner(collar, executor); } state.putCollarOn(collar); } if (!state.hasEarplugs()) { - ItemStack earplugs = new ItemStack( - ModItems.getEarplugs(EarplugsVariant.CLASSIC) - ); + ItemStack earplugs = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "classic_earplugs")); state.putEarplugsOn(earplugs); } diff --git a/src/main/java/com/tiedup/remake/compat/mca/capability/MCAKidnappedAdapter.java b/src/main/java/com/tiedup/remake/compat/mca/capability/MCAKidnappedAdapter.java index cd2c349..2d10de1 100644 --- a/src/main/java/com/tiedup/remake/compat/mca/capability/MCAKidnappedAdapter.java +++ b/src/main/java/com/tiedup/remake/compat/mca/capability/MCAKidnappedAdapter.java @@ -2,8 +2,10 @@ package com.tiedup.remake.compat.mca.capability; import com.tiedup.remake.compat.mca.MCABondageManager; import com.tiedup.remake.compat.mca.MCACompat; -import com.tiedup.remake.items.base.IHasBlindingEffect; -import com.tiedup.remake.items.base.IHasGaggingEffect; +import com.tiedup.remake.v2.bondage.component.BlindingComponent; +import com.tiedup.remake.v2.bondage.component.ComponentType; +import com.tiedup.remake.v2.bondage.component.GaggingComponent; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem; import com.tiedup.remake.items.base.IHasResistance; import com.tiedup.remake.items.base.ILockable; import com.tiedup.remake.items.base.ItemBind; @@ -277,16 +279,17 @@ public class MCAKidnappedAdapter implements IRestrainable { @Override public boolean hasGaggingEffect() { ItemStack gag = cap.getGag(); - return !gag.isEmpty() && gag.getItem() instanceof IHasGaggingEffect; + if (gag.isEmpty()) return false; + 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 = cap.getBlindfold(); - return ( - !blindfold.isEmpty() && - blindfold.getItem() instanceof IHasBlindingEffect - ); + if (blindfold.isEmpty()) return false; + if (DataDrivenBondageItem.getComponent(blindfold, ComponentType.BLINDING, BlindingComponent.class) != null) return true; + return blindfold.getItem() instanceof com.tiedup.remake.items.base.IHasBlindingEffect; } @Override diff --git a/src/main/java/com/tiedup/remake/dialogue/GagTalkManager.java b/src/main/java/com/tiedup/remake/dialogue/GagTalkManager.java index b822fa5..585e687 100644 --- a/src/main/java/com/tiedup/remake/dialogue/GagTalkManager.java +++ b/src/main/java/com/tiedup/remake/dialogue/GagTalkManager.java @@ -5,6 +5,9 @@ import static com.tiedup.remake.util.GameConstants.*; import com.tiedup.remake.dialogue.EmotionalContext.EmotionType; import com.tiedup.remake.items.base.ItemGag; import com.tiedup.remake.state.IBondageState; +import com.tiedup.remake.v2.bondage.component.ComponentType; +import com.tiedup.remake.v2.bondage.component.GaggingComponent; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem; import com.tiedup.remake.util.GagMaterial; import com.tiedup.remake.util.PhoneticMapper; import com.tiedup.remake.util.SyllableAnalyzer; @@ -58,7 +61,12 @@ public class GagTalkManager { ) { LivingEntity entity = kidnapped.asLivingEntity(); GagMaterial material = GagMaterial.CLOTH; - if (gagStack.getItem() instanceof ItemGag gag) { + // V2: check data-driven GaggingComponent first + GaggingComponent gaggingComp = DataDrivenBondageItem.getComponent( + gagStack, ComponentType.GAGGING, GaggingComponent.class); + if (gaggingComp != null && gaggingComp.getMaterial() != null) { + material = gaggingComp.getMaterial(); + } else if (gagStack.getItem() instanceof ItemGag gag) { material = gag.getGagMaterial(); } @@ -514,8 +522,15 @@ public class GagTalkManager { } GagMaterial material = GagMaterial.CLOTH; - if (gagStack != null && gagStack.getItem() instanceof ItemGag gag) { - material = gag.getGagMaterial(); + if (gagStack != null && !gagStack.isEmpty()) { + // V2: check data-driven GaggingComponent first + GaggingComponent comp = DataDrivenBondageItem.getComponent( + gagStack, ComponentType.GAGGING, GaggingComponent.class); + if (comp != null && comp.getMaterial() != null) { + material = comp.getMaterial(); + } else if (gagStack.getItem() instanceof ItemGag gag) { + material = gag.getGagMaterial(); + } } StringBuilder muffled = new StringBuilder(); diff --git a/src/main/java/com/tiedup/remake/dialogue/conversation/PetRequestManager.java b/src/main/java/com/tiedup/remake/dialogue/conversation/PetRequestManager.java index 85c0770..ba9dd8b 100644 --- a/src/main/java/com/tiedup/remake/dialogue/conversation/PetRequestManager.java +++ b/src/main/java/com/tiedup/remake/dialogue/conversation/PetRequestManager.java @@ -5,9 +5,9 @@ import com.tiedup.remake.dialogue.DialogueBridge; import com.tiedup.remake.entities.EntityMaster; import com.tiedup.remake.entities.ai.master.MasterPlaceBlockGoal; import com.tiedup.remake.entities.ai.master.MasterState; -import com.tiedup.remake.items.ModItems; -import com.tiedup.remake.items.base.BindVariant; import com.tiedup.remake.network.ModNetwork; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem; +import net.minecraft.resources.ResourceLocation; import com.tiedup.remake.network.master.PacketOpenPetRequestMenu; import com.tiedup.remake.state.PlayerBindState; import com.tiedup.remake.v2.BodyRegionV2; @@ -171,9 +171,7 @@ public class PetRequestManager { // Put dogbind on player (if not already tied) if (!state.isTiedUp()) { - ItemStack dogbind = new ItemStack( - ModItems.getBind(BindVariant.DOGBINDER) - ); + ItemStack dogbind = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "dogbinder")); state.equip(BodyRegionV2.ARMS, dogbind); TiedUpMod.LOGGER.debug( "[PetRequestManager] Equipped dogbind on {} for walk", @@ -228,7 +226,7 @@ public class PetRequestManager { } // Master equips armbinder on pet (classic pet play restraint) - ItemStack bind = new ItemStack(ModItems.getBind(BindVariant.ARMBINDER)); + ItemStack bind = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "armbinder")); state.equip(BodyRegionV2.ARMS, bind); DialogueBridge.talkTo(master, pet, "petplay.tie_accept"); diff --git a/src/main/java/com/tiedup/remake/entities/AbstractTiedUpNpc.java b/src/main/java/com/tiedup/remake/entities/AbstractTiedUpNpc.java index ded0b0d..85f3945 100644 --- a/src/main/java/com/tiedup/remake/entities/AbstractTiedUpNpc.java +++ b/src/main/java/com/tiedup/remake/entities/AbstractTiedUpNpc.java @@ -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 diff --git a/src/main/java/com/tiedup/remake/entities/BondageServiceHandler.java b/src/main/java/com/tiedup/remake/entities/BondageServiceHandler.java index 689871b..f8c554d 100644 --- a/src/main/java/com/tiedup/remake/entities/BondageServiceHandler.java +++ b/src/main/java/com/tiedup/remake/entities/BondageServiceHandler.java @@ -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( diff --git a/src/main/java/com/tiedup/remake/entities/EntityDamsel.java b/src/main/java/com/tiedup/remake/entities/EntityDamsel.java index 790a3ac..7cda2a3 100644 --- a/src/main/java/com/tiedup/remake/entities/EntityDamsel.java +++ b/src/main/java/com/tiedup/remake/entities/EntityDamsel.java @@ -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"; } } diff --git a/src/main/java/com/tiedup/remake/entities/EntityKidnapper.java b/src/main/java/com/tiedup/remake/entities/EntityKidnapper.java index 21d8129..30f0104 100644 --- a/src/main/java/com/tiedup/remake/entities/EntityKidnapper.java +++ b/src/main/java/com/tiedup/remake/entities/EntityKidnapper.java @@ -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) */ diff --git a/src/main/java/com/tiedup/remake/entities/EntityKidnapperMerchant.java b/src/main/java/com/tiedup/remake/entities/EntityKidnapperMerchant.java index edb0e86..b874d21 100644 --- a/src/main/java/com/tiedup/remake/entities/EntityKidnapperMerchant.java +++ b/src/main/java/com/tiedup/remake/entities/EntityKidnapperMerchant.java @@ -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 collectAllModItems() { List 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 diff --git a/src/main/java/com/tiedup/remake/entities/EntityRopeArrow.java b/src/main/java/com/tiedup/remake/entities/EntityRopeArrow.java index 5640e32..d9410af 100644 --- a/src/main/java/com/tiedup/remake/entities/EntityRopeArrow.java +++ b/src/main/java/com/tiedup/remake/entities/EntityRopeArrow.java @@ -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); diff --git a/src/main/java/com/tiedup/remake/entities/KidnapperCaptureEquipment.java b/src/main/java/com/tiedup/remake/entities/KidnapperCaptureEquipment.java index 243b53d..dce8890 100644 --- a/src/main/java/com/tiedup/remake/entities/KidnapperCaptureEquipment.java +++ b/src/main/java/com/tiedup/remake/entities/KidnapperCaptureEquipment.java @@ -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")); } /** diff --git a/src/main/java/com/tiedup/remake/entities/KidnapperCollarConfig.java b/src/main/java/com/tiedup/remake/entities/KidnapperCollarConfig.java index 0dc88a4..06112d6 100644 --- a/src/main/java/com/tiedup/remake/entities/KidnapperCollarConfig.java +++ b/src/main/java/com/tiedup/remake/entities/KidnapperCollarConfig.java @@ -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 { * */ 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 whitelist = itemCollar.getWhitelist(collarStack); + List 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); } } diff --git a/src/main/java/com/tiedup/remake/entities/KidnapperItemSelector.java b/src/main/java/com/tiedup/remake/entities/KidnapperItemSelector.java index 90b459f..75a655f 100644 --- a/src/main/java/com/tiedup/remake/entities/KidnapperItemSelector.java +++ b/src/main/java/com/tiedup/remake/entities/KidnapperItemSelector.java @@ -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 diff --git a/src/main/java/com/tiedup/remake/entities/KidnapperJobManager.java b/src/main/java/com/tiedup/remake/entities/KidnapperJobManager.java index 7d2499b..1914b32 100644 --- a/src/main/java/com/tiedup/remake/entities/KidnapperJobManager.java +++ b/src/main/java/com/tiedup/remake/entities/KidnapperJobManager.java @@ -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); diff --git a/src/main/java/com/tiedup/remake/entities/LeashProxyEntity.java b/src/main/java/com/tiedup/remake/entities/LeashProxyEntity.java index 9600210..84d53f9 100644 --- a/src/main/java/com/tiedup/remake/entities/LeashProxyEntity.java +++ b/src/main/java/com/tiedup/remake/entities/LeashProxyEntity.java @@ -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) } diff --git a/src/main/java/com/tiedup/remake/entities/ai/kidnapper/KidnapperBringToCellGoal.java b/src/main/java/com/tiedup/remake/entities/ai/kidnapper/KidnapperBringToCellGoal.java index 43b2550..741d4f9 100644 --- a/src/main/java/com/tiedup/remake/entities/ai/kidnapper/KidnapperBringToCellGoal.java +++ b/src/main/java/com/tiedup/remake/entities/ai/kidnapper/KidnapperBringToCellGoal.java @@ -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( diff --git a/src/main/java/com/tiedup/remake/entities/ai/kidnapper/KidnapperCaptureGoal.java b/src/main/java/com/tiedup/remake/entities/ai/kidnapper/KidnapperCaptureGoal.java index ff9437b..8725141 100644 --- a/src/main/java/com/tiedup/remake/entities/ai/kidnapper/KidnapperCaptureGoal.java +++ b/src/main/java/com/tiedup/remake/entities/ai/kidnapper/KidnapperCaptureGoal.java @@ -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 owners = collarItem.getOwners( + if (CollarHelper.isCollar(existingCollar)) { + java.util.List 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); + } } } diff --git a/src/main/java/com/tiedup/remake/entities/ai/kidnapper/KidnapperWalkPrisonerGoal.java b/src/main/java/com/tiedup/remake/entities/ai/kidnapper/KidnapperWalkPrisonerGoal.java index a0c5534..d035b58 100644 --- a/src/main/java/com/tiedup/remake/entities/ai/kidnapper/KidnapperWalkPrisonerGoal.java +++ b/src/main/java/com/tiedup/remake/entities/ai/kidnapper/KidnapperWalkPrisonerGoal.java @@ -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); } diff --git a/src/main/java/com/tiedup/remake/entities/ai/maid/goals/MaidReturnGoal.java b/src/main/java/com/tiedup/remake/entities/ai/maid/goals/MaidReturnGoal.java index 5d31ded..6128d5e 100644 --- a/src/main/java/com/tiedup/remake/entities/ai/maid/goals/MaidReturnGoal.java +++ b/src/main/java/com/tiedup/remake/entities/ai/maid/goals/MaidReturnGoal.java @@ -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") ) ); } diff --git a/src/main/java/com/tiedup/remake/entities/ai/master/MasterHumanChairGoal.java b/src/main/java/com/tiedup/remake/entities/ai/master/MasterHumanChairGoal.java index 37f0716..9fb0909 100644 --- a/src/main/java/com/tiedup/remake/entities/ai/master/MasterHumanChairGoal.java +++ b/src/main/java/com/tiedup/remake/entities/ai/master/MasterHumanChairGoal.java @@ -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); diff --git a/src/main/java/com/tiedup/remake/entities/ai/master/MasterPunishGoal.java b/src/main/java/com/tiedup/remake/entities/ai/master/MasterPunishGoal.java index 28c97db..d985c62 100644 --- a/src/main/java/com/tiedup/remake/entities/ai/master/MasterPunishGoal.java +++ b/src/main/java/com/tiedup/remake/entities/ai/master/MasterPunishGoal.java @@ -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; diff --git a/src/main/java/com/tiedup/remake/entities/ai/master/MasterRandomEventGoal.java b/src/main/java/com/tiedup/remake/entities/ai/master/MasterRandomEventGoal.java index bec353d..3ca03b7 100644 --- a/src/main/java/com/tiedup/remake/entities/ai/master/MasterRandomEventGoal.java +++ b/src/main/java/com/tiedup/remake/entities/ai/master/MasterRandomEventGoal.java @@ -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); } diff --git a/src/main/java/com/tiedup/remake/entities/ai/master/MasterTaskWatchGoal.java b/src/main/java/com/tiedup/remake/entities/ai/master/MasterTaskWatchGoal.java index 444d754..9931feb 100644 --- a/src/main/java/com/tiedup/remake/entities/ai/master/MasterTaskWatchGoal.java +++ b/src/main/java/com/tiedup/remake/entities/ai/master/MasterTaskWatchGoal.java @@ -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() diff --git a/src/main/java/com/tiedup/remake/entities/ai/personality/NpcFollowCommandGoal.java b/src/main/java/com/tiedup/remake/entities/ai/personality/NpcFollowCommandGoal.java index 33a29f3..a6557b4 100644 --- a/src/main/java/com/tiedup/remake/entities/ai/personality/NpcFollowCommandGoal.java +++ b/src/main/java/com/tiedup/remake/entities/ai/personality/NpcFollowCommandGoal.java @@ -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()); diff --git a/src/main/java/com/tiedup/remake/entities/ai/personality/NpcGuardCommandGoal.java b/src/main/java/com/tiedup/remake/entities/ai/personality/NpcGuardCommandGoal.java index 0f44bb5..1f1f632 100644 --- a/src/main/java/com/tiedup/remake/entities/ai/personality/NpcGuardCommandGoal.java +++ b/src/main/java/com/tiedup/remake/entities/ai/personality/NpcGuardCommandGoal.java @@ -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 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 owners = collarItem.getOwners(collar); + if (CollarHelper.isCollar(collar)) { + java.util.List owners = CollarHelper.getOwners(collar); if (!owners.isEmpty()) { return owners.get(0); } diff --git a/src/main/java/com/tiedup/remake/entities/damsel/components/DamselBondageManager.java b/src/main/java/com/tiedup/remake/entities/damsel/components/DamselBondageManager.java index 351c61e..073bc11 100644 --- a/src/main/java/com/tiedup/remake/entities/damsel/components/DamselBondageManager.java +++ b/src/main/java/com/tiedup/remake/entities/damsel/components/DamselBondageManager.java @@ -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 diff --git a/src/main/java/com/tiedup/remake/entities/damsel/components/DamselPersonalitySystem.java b/src/main/java/com/tiedup/remake/entities/damsel/components/DamselPersonalitySystem.java index aeff9f9..52d1eee 100644 --- a/src/main/java/com/tiedup/remake/entities/damsel/components/DamselPersonalitySystem.java +++ b/src/main/java/com/tiedup/remake/entities/damsel/components/DamselPersonalitySystem.java @@ -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 owners = collarItem.getOwners(collar); + if (CollarHelper.isCollar(collar)) { + List owners = CollarHelper.getOwners(collar); if (!owners.isEmpty()) { masterUUID = owners.get(0); } diff --git a/src/main/java/com/tiedup/remake/entities/damsel/components/NpcEquipmentManager.java b/src/main/java/com/tiedup/remake/entities/damsel/components/NpcEquipmentManager.java index e13007d..2d4d1c5 100644 --- a/src/main/java/com/tiedup/remake/entities/damsel/components/NpcEquipmentManager.java +++ b/src/main/java/com/tiedup/remake/entities/damsel/components/NpcEquipmentManager.java @@ -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 diff --git a/src/main/java/com/tiedup/remake/entities/kidnapper/components/KidnapperCaptiveManager.java b/src/main/java/com/tiedup/remake/entities/kidnapper/components/KidnapperCaptiveManager.java index 0143e9e..925e247 100644 --- a/src/main/java/com/tiedup/remake/entities/kidnapper/components/KidnapperCaptiveManager.java +++ b/src/main/java/com/tiedup/remake/entities/kidnapper/components/KidnapperCaptiveManager.java @@ -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(), diff --git a/src/main/java/com/tiedup/remake/entities/kidnapper/components/KidnapperTargetSelector.java b/src/main/java/com/tiedup/remake/entities/kidnapper/components/KidnapperTargetSelector.java index 4f9f659..2d60782 100644 --- a/src/main/java/com/tiedup/remake/entities/kidnapper/components/KidnapperTargetSelector.java +++ b/src/main/java/com/tiedup/remake/entities/kidnapper/components/KidnapperTargetSelector.java @@ -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 owners = collarItem.getOwners(collar); + if (CollarHelper.isCollar(collar)) { + java.util.List owners = CollarHelper.getOwners(collar); // Filter out self-collar (owner == wearer = exploit) java.util.List 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 owners = collarItem.getOwners(collar); + if (CollarHelper.isCollar(collar)) { + java.util.List 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) { diff --git a/src/main/java/com/tiedup/remake/entities/master/components/MasterPetManager.java b/src/main/java/com/tiedup/remake/entities/master/components/MasterPetManager.java index 61d4541..ddd5b01 100644 --- a/src/main/java/com/tiedup/remake/entities/master/components/MasterPetManager.java +++ b/src/main/java/com/tiedup/remake/entities/master/components/MasterPetManager.java @@ -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() diff --git a/src/main/java/com/tiedup/remake/events/camp/CampNpcProtectionHandler.java b/src/main/java/com/tiedup/remake/events/camp/CampNpcProtectionHandler.java index adee72d..9162606 100644 --- a/src/main/java/com/tiedup/remake/events/camp/CampNpcProtectionHandler.java +++ b/src/main/java/com/tiedup/remake/events/camp/CampNpcProtectionHandler.java @@ -4,7 +4,7 @@ import com.tiedup.remake.cells.CampLifecycleManager; import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.entities.EntityMaid; import com.tiedup.remake.entities.EntitySlaveTrader; -import com.tiedup.remake.items.base.ItemBind; +import com.tiedup.remake.v2.bondage.BindModeHelper; import java.util.UUID; import net.minecraft.ChatFormatting; import net.minecraft.network.chat.Component; @@ -40,7 +40,7 @@ public class CampNpcProtectionHandler { // Check if player is holding restraint item ItemStack heldItem = player.getItemInHand(event.getHand()); - if (!(heldItem.getItem() instanceof ItemBind)) return; + if (!BindModeHelper.isBindItem(heldItem)) return; // Check if target is trader or maid with active camp UUID campId = null; diff --git a/src/main/java/com/tiedup/remake/events/captivity/PlayerEnslavementHandler.java b/src/main/java/com/tiedup/remake/events/captivity/PlayerEnslavementHandler.java index 4078620..db1547e 100644 --- a/src/main/java/com/tiedup/remake/events/captivity/PlayerEnslavementHandler.java +++ b/src/main/java/com/tiedup/remake/events/captivity/PlayerEnslavementHandler.java @@ -3,8 +3,8 @@ package com.tiedup.remake.events.captivity; import com.tiedup.remake.core.SettingsAccessor; import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.entities.LeashProxyEntity; -import com.tiedup.remake.items.base.ItemCollar; import com.tiedup.remake.state.IBondageState; +import com.tiedup.remake.v2.bondage.CollarHelper; import com.tiedup.remake.state.IPlayerLeashAccess; import com.tiedup.remake.state.PlayerBindState; import com.tiedup.remake.util.KidnappedHelper; @@ -146,9 +146,9 @@ public class PlayerEnslavementHandler { ItemStack collar = slaveKidnappedState.getEquipment( BodyRegionV2.NECK ); - if (collar.getItem() instanceof ItemCollar collarItem) { + if (CollarHelper.isCollar(collar)) { if ( - collarItem + CollarHelper .getOwners(collar) .contains(master.getUUID()) ) { diff --git a/src/main/java/com/tiedup/remake/events/combat/LaborAttackPunishmentHandler.java b/src/main/java/com/tiedup/remake/events/combat/LaborAttackPunishmentHandler.java index 901c57d..9363db1 100644 --- a/src/main/java/com/tiedup/remake/events/combat/LaborAttackPunishmentHandler.java +++ b/src/main/java/com/tiedup/remake/events/combat/LaborAttackPunishmentHandler.java @@ -4,8 +4,8 @@ import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.entities.EntityKidnapper; import com.tiedup.remake.entities.EntityMaid; import com.tiedup.remake.entities.EntitySlaveTrader; -import com.tiedup.remake.items.base.ItemBind; import com.tiedup.remake.prison.LaborRecord; +import com.tiedup.remake.v2.bondage.BindModeHelper; import com.tiedup.remake.prison.PrisonerManager; import com.tiedup.remake.prison.PrisonerRecord; import com.tiedup.remake.prison.PrisonerState; @@ -145,7 +145,7 @@ public class LaborAttackPunishmentHandler { // Check if player is holding a restraint item (rope, chain, etc.) ItemStack heldItem = serverPlayer.getItemInHand(hand); - if (!(heldItem.getItem() instanceof ItemBind)) { + if (!BindModeHelper.isBindItem(heldItem)) { return; // Not a restraint item } diff --git a/src/main/java/com/tiedup/remake/events/restriction/PetPlayRestrictionHandler.java b/src/main/java/com/tiedup/remake/events/restriction/PetPlayRestrictionHandler.java index 46dd127..6d38333 100644 --- a/src/main/java/com/tiedup/remake/events/restriction/PetPlayRestrictionHandler.java +++ b/src/main/java/com/tiedup/remake/events/restriction/PetPlayRestrictionHandler.java @@ -2,8 +2,8 @@ package com.tiedup.remake.events.restriction; import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.entities.EntityMaster; -import com.tiedup.remake.items.ItemChokeCollar; import com.tiedup.remake.state.PlayerBindState; +import com.tiedup.remake.v2.bondage.CollarHelper; import com.tiedup.remake.v2.BodyRegionV2; import com.tiedup.remake.v2.blocks.PetBedManager; import net.minecraft.core.BlockPos; @@ -284,8 +284,8 @@ public class PetPlayRestrictionHandler { if (bindState == null || !bindState.hasCollar()) return; ItemStack collar = bindState.getEquipment(BodyRegionV2.NECK); - if (collar.getItem() instanceof ItemChokeCollar chokeCollar) { - if (chokeCollar.isChoking(collar)) { + if (CollarHelper.isChokeCollar(collar)) { + if (CollarHelper.isChoking(collar)) { // Apply ChokeEffect (short duration, re-applied each active tick) if ( !player.hasEffect( diff --git a/src/main/java/com/tiedup/remake/events/restriction/RestraintTaskTickHandler.java b/src/main/java/com/tiedup/remake/events/restriction/RestraintTaskTickHandler.java index b65339b..fe38d36 100644 --- a/src/main/java/com/tiedup/remake/events/restriction/RestraintTaskTickHandler.java +++ b/src/main/java/com/tiedup/remake/events/restriction/RestraintTaskTickHandler.java @@ -3,8 +3,8 @@ package com.tiedup.remake.events.restriction; import com.tiedup.remake.core.SettingsAccessor; import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.entities.EntityKidnapper; -import com.tiedup.remake.items.base.ItemCollar; import com.tiedup.remake.minigame.StruggleSessionManager; +import com.tiedup.remake.v2.bondage.CollarHelper; import com.tiedup.remake.network.ModNetwork; import com.tiedup.remake.network.personality.PacketSlaveBeingFreed; import com.tiedup.remake.state.IBondageState; @@ -642,14 +642,11 @@ public class RestraintTaskTickHandler { if (!(slave.level() instanceof ServerLevel serverLevel)) return; ItemStack collar = slave.getEquipment(BodyRegionV2.NECK); - if ( - collar.isEmpty() || - !(collar.getItem() instanceof ItemCollar collarItem) - ) { + if (collar.isEmpty() || !CollarHelper.isCollar(collar)) { return; } - List owners = collarItem.getOwners(collar); + List owners = CollarHelper.getOwners(collar); if (owners.isEmpty()) return; // Create alert packet diff --git a/src/main/java/com/tiedup/remake/events/system/ChatEventHandler.java b/src/main/java/com/tiedup/remake/events/system/ChatEventHandler.java index 8420334..96ff8d1 100644 --- a/src/main/java/com/tiedup/remake/events/system/ChatEventHandler.java +++ b/src/main/java/com/tiedup/remake/events/system/ChatEventHandler.java @@ -7,6 +7,9 @@ import com.tiedup.remake.dialogue.GagTalkManager; import com.tiedup.remake.items.base.ItemGag; import com.tiedup.remake.state.IBondageState; import com.tiedup.remake.util.GagMaterial; +import com.tiedup.remake.v2.bondage.component.ComponentType; +import com.tiedup.remake.v2.bondage.component.GaggingComponent; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem; import com.tiedup.remake.util.KidnappedHelper; import com.tiedup.remake.util.TiedUpUtils; import com.tiedup.remake.v2.BodyRegionV2; @@ -54,12 +57,22 @@ public class ChatEventHandler { BodyRegionV2.MOUTH ); - if ( - !gagStack.isEmpty() && - gagStack.getItem() instanceof ItemGag gagItem - ) { + // V2: check gagging component, V1 fallback: instanceof ItemGag + GaggingComponent gaggingComp = DataDrivenBondageItem.getComponent( + gagStack, ComponentType.GAGGING, GaggingComponent.class); + boolean isGagItem = gaggingComp != null + || gagStack.getItem() instanceof ItemGag; + + if (!gagStack.isEmpty() && isGagItem) { String originalMessage = event.getRawText(); - GagMaterial material = gagItem.getGagMaterial(); + // V2: get material from component, V1 fallback: from ItemGag + GagMaterial material = null; + if (gaggingComp != null) { + material = gaggingComp.getMaterial(); + } + if (material == null && gagStack.getItem() instanceof ItemGag gagItem) { + material = gagItem.getGagMaterial(); + } // 1. Process the message through our GagTalkManager V2 Component muffledMessage = GagTalkManager.processGagMessage( @@ -83,7 +96,9 @@ public class ChatEventHandler { .append("> ") .append(muffledMessage); - double range = material.getTalkRange(); + double range = material != null + ? material.getTalkRange() + : (gaggingComp != null ? gaggingComp.getRange() : 10.0); List nearbyPlayers = TiedUpUtils.getPlayersAround( diff --git a/src/main/java/com/tiedup/remake/minigame/StruggleSessionManager.java b/src/main/java/com/tiedup/remake/minigame/StruggleSessionManager.java index c628c41..258721f 100644 --- a/src/main/java/com/tiedup/remake/minigame/StruggleSessionManager.java +++ b/src/main/java/com/tiedup/remake/minigame/StruggleSessionManager.java @@ -1,9 +1,8 @@ package com.tiedup.remake.minigame; import com.tiedup.remake.core.TiedUpMod; -import com.tiedup.remake.items.ItemShockCollar; -import com.tiedup.remake.items.base.ItemBind; -import com.tiedup.remake.items.base.ItemCollar; +import com.tiedup.remake.items.base.IHasResistance; +import com.tiedup.remake.v2.bondage.CollarHelper; import com.tiedup.remake.minigame.ContinuousStruggleMiniGameState.TickResult; import com.tiedup.remake.minigame.ContinuousStruggleMiniGameState.UpdateType; import com.tiedup.remake.network.ModNetwork; @@ -544,11 +543,11 @@ public class StruggleSessionManager { if (collar.isEmpty()) return false; // Only shock collars can trigger during struggle - if (!(collar.getItem() instanceof ItemShockCollar)) return false; + if (!CollarHelper.canShock(collar)) return false; // Must be locked - if (collar.getItem() instanceof ItemCollar collarItem) { - return collarItem.isLocked(collar); + if (collar.getItem() instanceof com.tiedup.remake.items.base.ILockable lockable) { + return lockable.isLocked(collar); } return false; } @@ -643,14 +642,13 @@ public class StruggleSessionManager { player, BodyRegionV2.ARMS ); - if ( - bindStack.isEmpty() || - !(bindStack.getItem() instanceof ItemBind bind) - ) { + if (bindStack.isEmpty()) { return; } - - bind.setCurrentResistance(bindStack, session.getCurrentResistance()); + if (bindStack.getItem() instanceof IHasResistance resistanceItem) { + resistanceItem.setCurrentResistance(bindStack, session.getCurrentResistance()); + V2EquipmentHelper.sync(player); + } } /** diff --git a/src/main/java/com/tiedup/remake/mixin/MixinMCAVillagerInteraction.java b/src/main/java/com/tiedup/remake/mixin/MixinMCAVillagerInteraction.java index b25ef92..5552eab 100644 --- a/src/main/java/com/tiedup/remake/mixin/MixinMCAVillagerInteraction.java +++ b/src/main/java/com/tiedup/remake/mixin/MixinMCAVillagerInteraction.java @@ -4,7 +4,7 @@ import com.tiedup.remake.compat.mca.MCACompat; import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.items.ItemKey; import com.tiedup.remake.items.ItemMasterKey; -import com.tiedup.remake.items.base.ItemCollar; +import com.tiedup.remake.v2.bondage.CollarHelper; import com.tiedup.remake.state.IBondageState; import com.tiedup.remake.v2.BodyRegionV2; import com.tiedup.remake.v2.bondage.IV2BondageItem; @@ -182,8 +182,8 @@ public abstract class MixinMCAVillagerInteraction { // Can leash if player is a collar owner if (state.hasCollar()) { ItemStack collar = state.getEquipment(BodyRegionV2.NECK); - if (collar.getItem() instanceof ItemCollar collarItem) { - return collarItem.getOwners(collar).contains(player.getUUID()); + if (CollarHelper.isCollar(collar)) { + return CollarHelper.isOwner(collar, player); } } diff --git a/src/main/java/com/tiedup/remake/mixin/MixinMCAVillagerLeash.java b/src/main/java/com/tiedup/remake/mixin/MixinMCAVillagerLeash.java index a6d11d6..c59c150 100644 --- a/src/main/java/com/tiedup/remake/mixin/MixinMCAVillagerLeash.java +++ b/src/main/java/com/tiedup/remake/mixin/MixinMCAVillagerLeash.java @@ -1,7 +1,7 @@ package com.tiedup.remake.mixin; import com.tiedup.remake.compat.mca.MCACompat; -import com.tiedup.remake.items.base.ItemCollar; +import com.tiedup.remake.v2.bondage.CollarHelper; import com.tiedup.remake.state.IBondageState; import com.tiedup.remake.v2.BodyRegionV2; import net.minecraft.world.entity.LivingEntity; @@ -71,8 +71,8 @@ public class MixinMCAVillagerLeash { // Can be leashed if player is collar owner if (state.hasCollar()) { ItemStack collar = state.getEquipment(BodyRegionV2.NECK); - if (collar.getItem() instanceof ItemCollar collarItem) { - if (collarItem.getOwners(collar).contains(player.getUUID())) { + if (CollarHelper.isCollar(collar)) { + if (CollarHelper.isOwner(collar, player)) { cir.setReturnValue(true); return; } diff --git a/src/main/java/com/tiedup/remake/mixin/client/MixinCamera.java b/src/main/java/com/tiedup/remake/mixin/client/MixinCamera.java index c7a94a9..814cf5c 100644 --- a/src/main/java/com/tiedup/remake/mixin/client/MixinCamera.java +++ b/src/main/java/com/tiedup/remake/mixin/client/MixinCamera.java @@ -1,7 +1,7 @@ package com.tiedup.remake.mixin.client; -import com.tiedup.remake.items.base.ItemBind; import com.tiedup.remake.items.base.PoseType; +import com.tiedup.remake.v2.bondage.PoseTypeHelper; import com.tiedup.remake.state.HumanChairHelper; import com.tiedup.remake.state.PlayerBindState; import com.tiedup.remake.v2.BodyRegionV2; @@ -57,11 +57,11 @@ public abstract class MixinCamera { } ItemStack bind = state.getEquipment(BodyRegionV2.ARMS); - if (bind.isEmpty() || !(bind.getItem() instanceof ItemBind itemBind)) { + if (bind.isEmpty()) { return; } - if (itemBind.getPoseType() != PoseType.DOG) { + if (PoseTypeHelper.getPoseType(bind) != PoseType.DOG) { return; } diff --git a/src/main/java/com/tiedup/remake/mixin/client/MixinPlayerModel.java b/src/main/java/com/tiedup/remake/mixin/client/MixinPlayerModel.java index 9e3153a..0a37cbc 100644 --- a/src/main/java/com/tiedup/remake/mixin/client/MixinPlayerModel.java +++ b/src/main/java/com/tiedup/remake/mixin/client/MixinPlayerModel.java @@ -2,8 +2,8 @@ package com.tiedup.remake.mixin.client; import com.tiedup.remake.client.animation.render.DogPoseRenderHandler; import com.tiedup.remake.client.animation.util.DogPoseHelper; -import com.tiedup.remake.items.base.ItemBind; import com.tiedup.remake.items.base.PoseType; +import com.tiedup.remake.v2.bondage.PoseTypeHelper; import com.tiedup.remake.state.PlayerBindState; import com.tiedup.remake.v2.BodyRegionV2; import net.minecraft.client.model.PlayerModel; @@ -45,11 +45,11 @@ public class MixinPlayerModel { } ItemStack bind = state.getEquipment(BodyRegionV2.ARMS); - if (bind.isEmpty() || !(bind.getItem() instanceof ItemBind itemBind)) { + if (bind.isEmpty()) { return; } - if (itemBind.getPoseType() != PoseType.DOG) { + if (PoseTypeHelper.getPoseType(bind) != PoseType.DOG) { return; } diff --git a/src/main/java/com/tiedup/remake/mixin/client/MixinVillagerEntityBaseModelMCA.java b/src/main/java/com/tiedup/remake/mixin/client/MixinVillagerEntityBaseModelMCA.java index 044abe1..b86c14a 100644 --- a/src/main/java/com/tiedup/remake/mixin/client/MixinVillagerEntityBaseModelMCA.java +++ b/src/main/java/com/tiedup/remake/mixin/client/MixinVillagerEntityBaseModelMCA.java @@ -4,8 +4,9 @@ import com.tiedup.remake.client.animation.BondageAnimationManager; import com.tiedup.remake.client.animation.StaticPoseApplier; import com.tiedup.remake.client.animation.util.AnimationIdBuilder; import com.tiedup.remake.compat.mca.MCACompat; -import com.tiedup.remake.items.base.ItemBind; import com.tiedup.remake.items.base.PoseType; +import com.tiedup.remake.v2.bondage.BindModeHelper; +import com.tiedup.remake.v2.bondage.PoseTypeHelper; import com.tiedup.remake.state.IBondageState; import com.tiedup.remake.v2.BodyRegionV2; import com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper; @@ -78,11 +79,7 @@ public class MixinVillagerEntityBaseModelMCA { // Get pose info from bind item ItemStack bind = state.getEquipment(BodyRegionV2.ARMS); - PoseType poseType = PoseType.STANDARD; - - if (bind.getItem() instanceof ItemBind itemBind) { - poseType = itemBind.getPoseType(); - } + PoseType poseType = PoseTypeHelper.getPoseType(bind); // Derive bound state from V2 regions, fallback to V1 bind mode NBT boolean armsBound = V2EquipmentHelper.isRegionOccupied( @@ -94,9 +91,9 @@ public class MixinVillagerEntityBaseModelMCA { BodyRegionV2.LEGS ); - if (!armsBound && !legsBound && bind.getItem() instanceof ItemBind) { - armsBound = ItemBind.hasArmsBound(bind); - legsBound = ItemBind.hasLegsBound(bind); + if (!armsBound && !legsBound && BindModeHelper.isBindItem(bind)) { + armsBound = BindModeHelper.hasArmsBound(bind); + legsBound = BindModeHelper.hasLegsBound(bind); } // MCA doesn't track struggling state - use false for now diff --git a/src/main/java/com/tiedup/remake/network/cell/PacketAssignCellToCollar.java b/src/main/java/com/tiedup/remake/network/cell/PacketAssignCellToCollar.java index 1094b8a..5291f01 100644 --- a/src/main/java/com/tiedup/remake/network/cell/PacketAssignCellToCollar.java +++ b/src/main/java/com/tiedup/remake/network/cell/PacketAssignCellToCollar.java @@ -5,8 +5,8 @@ import com.tiedup.remake.cells.CellRegistryV2; import com.tiedup.remake.core.SystemMessageManager; import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.entities.EntityDamsel; -import com.tiedup.remake.items.base.ItemCollar; import com.tiedup.remake.network.PacketRateLimiter; +import com.tiedup.remake.v2.bondage.CollarHelper; import com.tiedup.remake.network.sync.SyncManager; import com.tiedup.remake.personality.PersonalityState; import com.tiedup.remake.state.IBondageState; @@ -14,9 +14,9 @@ import com.tiedup.remake.util.KidnappedHelper; import com.tiedup.remake.v2.BodyRegionV2; import java.util.UUID; import java.util.function.Supplier; +import net.minecraft.nbt.CompoundTag; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; @@ -96,7 +96,7 @@ public class PacketAssignCellToCollar { } ItemStack collarStack = state.getEquipment(BodyRegionV2.NECK); - if (!(collarStack.getItem() instanceof ItemCollar collar)) { + if (!CollarHelper.isCollar(collarStack)) { TiedUpMod.LOGGER.debug( "[PacketAssignCellToCollar] Invalid collar item" ); @@ -105,7 +105,7 @@ public class PacketAssignCellToCollar { // Security: Verify sender owns the collar (or is admin) if ( - !collar.isOwner(collarStack, sender) && + !CollarHelper.isOwner(collarStack, sender) && !sender.hasPermissions(2) ) { TiedUpMod.LOGGER.debug( @@ -139,7 +139,15 @@ public class PacketAssignCellToCollar { } // Set the cell ID on the collar - collar.setCellId(collarStack, msg.cellId); + if (msg.cellId != null) { + CollarHelper.setCellId(collarStack, msg.cellId); + } else { + // Clear cell assignment + CompoundTag collarTag = collarStack.getTag(); + if (collarTag != null) { + collarTag.remove("cellId"); + } + } // Sync PersonalityState for damsels if (target instanceof EntityDamsel damsel) { diff --git a/src/main/java/com/tiedup/remake/network/personality/PacketNpcCommand.java b/src/main/java/com/tiedup/remake/network/personality/PacketNpcCommand.java index 72adc86..9fe2ef9 100644 --- a/src/main/java/com/tiedup/remake/network/personality/PacketNpcCommand.java +++ b/src/main/java/com/tiedup/remake/network/personality/PacketNpcCommand.java @@ -7,8 +7,8 @@ import com.tiedup.remake.dialogue.EntityDialogueManager.DialogueCategory; import com.tiedup.remake.entities.EntityDamsel; import com.tiedup.remake.items.ItemCommandWand; import com.tiedup.remake.items.ModItems; -import com.tiedup.remake.items.base.ItemCollar; import com.tiedup.remake.network.ModNetwork; +import com.tiedup.remake.v2.bondage.CollarHelper; import com.tiedup.remake.network.PacketRateLimiter; import com.tiedup.remake.personality.JobExperience; import com.tiedup.remake.personality.NpcCommand; @@ -390,11 +390,11 @@ public class PacketNpcCommand { } ItemStack collar = damsel.getEquipment(BodyRegionV2.NECK); - if (!(collar.getItem() instanceof ItemCollar collarItem)) { + if (!CollarHelper.isCollar(collar)) { return false; } - if (!collarItem.getOwners(collar).contains(sender.getUUID())) { + if (!CollarHelper.isOwner(collar, sender)) { SystemMessageManager.sendToPlayer( sender, SystemMessageManager.MessageCategory.ERROR, diff --git a/src/main/java/com/tiedup/remake/network/slave/PacketMasterEquip.java b/src/main/java/com/tiedup/remake/network/slave/PacketMasterEquip.java index daccf5f..5b656ce 100644 --- a/src/main/java/com/tiedup/remake/network/slave/PacketMasterEquip.java +++ b/src/main/java/com/tiedup/remake/network/slave/PacketMasterEquip.java @@ -1,7 +1,7 @@ package com.tiedup.remake.network.slave; -import com.tiedup.remake.items.base.ItemCollar; import com.tiedup.remake.network.PacketRateLimiter; +import com.tiedup.remake.v2.bondage.CollarHelper; import com.tiedup.remake.state.IBondageState; import com.tiedup.remake.util.KidnappedHelper; import com.tiedup.remake.v2.BodyRegionV2; @@ -75,9 +75,9 @@ public class PacketMasterEquip { ); if (targetState == null || !targetState.hasCollar()) return; ItemStack collarStack = targetState.getEquipment(BodyRegionV2.NECK); - if (collarStack.getItem() instanceof ItemCollar collar) { + if (CollarHelper.isCollar(collarStack)) { if ( - !collar.isOwner(collarStack, sender) && + !CollarHelper.isOwner(collarStack, sender) && !sender.hasPermissions(2) ) return; } diff --git a/src/main/java/com/tiedup/remake/network/slave/PacketSlaveAction.java b/src/main/java/com/tiedup/remake/network/slave/PacketSlaveAction.java index 25bfbc8..652beba 100644 --- a/src/main/java/com/tiedup/remake/network/slave/PacketSlaveAction.java +++ b/src/main/java/com/tiedup/remake/network/slave/PacketSlaveAction.java @@ -2,10 +2,8 @@ package com.tiedup.remake.network.slave; import com.tiedup.remake.core.SystemMessageManager; import com.tiedup.remake.core.TiedUpMod; -import com.tiedup.remake.items.ItemGpsCollar; -import com.tiedup.remake.items.ItemShockCollar; -import com.tiedup.remake.items.base.ItemCollar; import com.tiedup.remake.state.IBondageState; +import com.tiedup.remake.v2.bondage.CollarHelper; import com.tiedup.remake.state.IRestrainable; import com.tiedup.remake.state.PlayerBindState; import com.tiedup.remake.state.PlayerCaptorManager; @@ -128,8 +126,8 @@ public class PacketSlaveAction { ItemStack collarStack = kidnapped.getEquipment( BodyRegionV2.NECK ); - if (collarStack.getItem() instanceof ItemCollar collar) { - if (collar.isOwner(collarStack, sender)) { + if (CollarHelper.isCollar(collarStack)) { + if (CollarHelper.isOwner(collarStack, sender)) { targetCaptive = kidnapped; break; } @@ -219,10 +217,7 @@ public class PacketSlaveAction { } ItemStack collarStack = target.getEquipment(BodyRegionV2.NECK); - if ( - !(collarStack.getItem() instanceof ItemCollar collar) || - !collar.canShock() - ) { + if (!CollarHelper.canShock(collarStack)) { SystemMessageManager.sendToPlayer( sender, SystemMessageManager.MessageCategory.ERROR, @@ -232,14 +227,8 @@ public class PacketSlaveAction { } // Check if sender is owner of the collar or collar is public - // FIX: Always check permissions for ANY collar that can shock, not just ItemShockCollar - boolean isOwner = collar.isOwner(collarStack, sender); - boolean isPublic = false; - - // ItemShockCollar has additional "public mode" that allows anyone to shock - if (collarStack.getItem() instanceof ItemShockCollar shockCollar) { - isPublic = shockCollar.isPublic(collarStack); - } + boolean isOwner = CollarHelper.isOwner(collarStack, sender); + boolean isPublic = CollarHelper.isPublicShock(collarStack); if (!isOwner && !isPublic) { SystemMessageManager.sendToPlayer( @@ -285,10 +274,7 @@ public class PacketSlaveAction { } ItemStack collarStack = target.getEquipment(BodyRegionV2.NECK); - if ( - !(collarStack.getItem() instanceof ItemCollar collar) || - !collar.hasGPS() - ) { + if (!CollarHelper.hasGPS(collarStack)) { SystemMessageManager.sendToPlayer( sender, SystemMessageManager.MessageCategory.ERROR, @@ -298,18 +284,16 @@ public class PacketSlaveAction { } // Check permissions - if (collarStack.getItem() instanceof ItemGpsCollar gpsCollar) { - boolean isOwner = collar.isOwner(collarStack, sender); - boolean isPublic = gpsCollar.hasPublicTracking(collarStack); + boolean isOwner = CollarHelper.isOwner(collarStack, sender); + boolean isPublic = CollarHelper.hasPublicTracking(collarStack); - if (!isOwner && !isPublic) { - SystemMessageManager.sendToPlayer( - sender, - SystemMessageManager.MessageCategory.ERROR, - "You don't have permission to track " + name + "!" - ); - return; - } + if (!isOwner && !isPublic) { + SystemMessageManager.sendToPlayer( + sender, + SystemMessageManager.MessageCategory.ERROR, + "You don't have permission to track " + name + "!" + ); + return; } // Check same dimension @@ -367,8 +351,8 @@ public class PacketSlaveAction { } else { // For collar-owned entities, just remove collar ownership ItemStack collarStack = target.getEquipment(BodyRegionV2.NECK); - if (collarStack.getItem() instanceof ItemCollar collar) { - collar.removeOwner(collarStack, sender.getUUID()); + if (CollarHelper.isCollar(collarStack)) { + CollarHelper.removeOwner(collarStack, sender.getUUID()); SystemMessageManager.sendToPlayer( sender, "Released collar control of " + name + "!", diff --git a/src/main/java/com/tiedup/remake/personality/ToolMode.java b/src/main/java/com/tiedup/remake/personality/ToolMode.java index 11e230a..f16e739 100644 --- a/src/main/java/com/tiedup/remake/personality/ToolMode.java +++ b/src/main/java/com/tiedup/remake/personality/ToolMode.java @@ -1,6 +1,6 @@ package com.tiedup.remake.personality; -import com.tiedup.remake.items.base.ItemBind; +import com.tiedup.remake.v2.bondage.BindModeHelper; import net.minecraft.world.item.AxeItem; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.PickaxeItem; @@ -48,7 +48,7 @@ public enum ToolMode { if (item instanceof AxeItem) { return WOODCUTTING; } - if (item instanceof ItemBind) { + if (BindModeHelper.isBindItem(mainHand)) { return CAPTURE; } diff --git a/src/main/java/com/tiedup/remake/state/IBondageState.java b/src/main/java/com/tiedup/remake/state/IBondageState.java index 6245034..73e430b 100644 --- a/src/main/java/com/tiedup/remake/state/IBondageState.java +++ b/src/main/java/com/tiedup/remake/state/IBondageState.java @@ -1,8 +1,8 @@ package com.tiedup.remake.state; import com.tiedup.remake.items.base.ILockable; -import com.tiedup.remake.items.base.ItemBind; import com.tiedup.remake.v2.BodyRegionV2; +import com.tiedup.remake.v2.bondage.BindModeHelper; import java.util.function.Supplier; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; @@ -97,7 +97,7 @@ public interface IBondageState extends ICapturable { if (!isTiedUp()) return false; ItemStack bind = getEquipment(BodyRegionV2.ARMS); if (bind.isEmpty()) return false; - return ItemBind.hasArmsBound(bind); + return BindModeHelper.hasArmsBound(bind); } /** @@ -111,7 +111,7 @@ public interface IBondageState extends ICapturable { if (!isTiedUp()) return false; ItemStack bind = getEquipment(BodyRegionV2.ARMS); if (bind.isEmpty()) return false; - return ItemBind.hasLegsBound(bind); + return BindModeHelper.hasLegsBound(bind); } /** @@ -121,10 +121,10 @@ public interface IBondageState extends ICapturable { * @return "full", "arms", or "legs" */ default String getBindModeId() { - if (!isTiedUp()) return ItemBind.BIND_MODE_FULL; + if (!isTiedUp()) return BindModeHelper.MODE_FULL; ItemStack bind = getEquipment(BodyRegionV2.ARMS); - if (bind.isEmpty()) return ItemBind.BIND_MODE_FULL; - return ItemBind.getBindModeId(bind); + if (bind.isEmpty()) return BindModeHelper.MODE_FULL; + return BindModeHelper.getBindModeId(bind); } /** diff --git a/src/main/java/com/tiedup/remake/state/PlayerBindState.java b/src/main/java/com/tiedup/remake/state/PlayerBindState.java index 77bb59f..a571d9a 100644 --- a/src/main/java/com/tiedup/remake/state/PlayerBindState.java +++ b/src/main/java/com/tiedup/remake/state/PlayerBindState.java @@ -3,8 +3,8 @@ package com.tiedup.remake.state; import com.tiedup.remake.core.ModSounds; import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.entities.LeashProxyEntity; -import com.tiedup.remake.items.base.ItemBind; -import com.tiedup.remake.items.base.ItemCollar; +import com.tiedup.remake.items.base.ILockable; +import com.tiedup.remake.v2.bondage.CollarHelper; import com.tiedup.remake.network.sync.SyncManager; import com.tiedup.remake.state.components.PlayerCaptivity; import com.tiedup.remake.state.components.PlayerClothesPermission; @@ -737,8 +737,8 @@ public class PlayerBindState implements IRestrainable, IPlayerBindStateHost { ItemStack collar = getCurrentCollar(); return ( !collar.isEmpty() && - collar.getItem() instanceof ItemCollar collarItem && - collarItem.isLocked(collar) + collar.getItem() instanceof ILockable lockable && + lockable.isLocked(collar) ); } @@ -1211,9 +1211,9 @@ public class PlayerBindState implements IRestrainable, IPlayerBindStateHost { ItemStack collar = getEquipment(BodyRegionV2.NECK); if ( !collar.isEmpty() && - collar.getItem() instanceof ItemCollar collarItem + collar.getItem() instanceof ILockable lockable ) { - collarItem.setLocked(collar, false); + lockable.setLocked(collar, false); } // Drop all items diff --git a/src/main/java/com/tiedup/remake/state/PlayerCaptorManager.java b/src/main/java/com/tiedup/remake/state/PlayerCaptorManager.java index d247c63..cfc970c 100644 --- a/src/main/java/com/tiedup/remake/state/PlayerCaptorManager.java +++ b/src/main/java/com/tiedup/remake/state/PlayerCaptorManager.java @@ -1,8 +1,8 @@ package com.tiedup.remake.state; import com.tiedup.remake.core.TiedUpMod; -import com.tiedup.remake.items.base.ItemCollar; import com.tiedup.remake.v2.BodyRegionV2; +import com.tiedup.remake.v2.bondage.CollarHelper; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @@ -144,9 +144,9 @@ public class PlayerCaptorManager implements ICaptor { // Check if target has collar with this captor as owner if (target.hasCollar()) { ItemStack collar = target.getEquipment(BodyRegionV2.NECK); - if (collar.getItem() instanceof ItemCollar collarItem) { + if (CollarHelper.isCollar(collar)) { if ( - collarItem.getOwners(collar).contains(this.captor.getUUID()) + CollarHelper.getOwners(collar).contains(this.captor.getUUID()) ) { return true; } diff --git a/src/main/java/com/tiedup/remake/state/components/PlayerDataRetrieval.java b/src/main/java/com/tiedup/remake/state/components/PlayerDataRetrieval.java index 73d9db0..21fe85e 100644 --- a/src/main/java/com/tiedup/remake/state/components/PlayerDataRetrieval.java +++ b/src/main/java/com/tiedup/remake/state/components/PlayerDataRetrieval.java @@ -1,7 +1,7 @@ package com.tiedup.remake.state.components; -import com.tiedup.remake.items.base.ItemCollar; import com.tiedup.remake.state.hosts.IPlayerBindStateHost; +import com.tiedup.remake.v2.bondage.CollarHelper; import com.tiedup.remake.v2.BodyRegionV2; import com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper; import net.minecraft.world.entity.LivingEntity; @@ -87,12 +87,9 @@ public class PlayerDataRetrieval { Player player = host.getPlayer(); ItemStack collar = getCurrentCollar(); - if ( - !collar.isEmpty() && - collar.getItem() instanceof ItemCollar collarItem - ) { + if (!collar.isEmpty() && CollarHelper.isCollar(collar)) { // Try to get nickname from collar NBT - String nickname = collarItem.getNickname(collar); + String nickname = CollarHelper.getNickname(collar); if (nickname != null && !nickname.isEmpty()) { return nickname; } @@ -109,8 +106,8 @@ public class PlayerDataRetrieval { ItemStack collar = getCurrentCollar(); if (collar.isEmpty()) return false; - if (collar.getItem() instanceof ItemCollar collarItem) { - String nickname = collarItem.getNickname(collar); + if (CollarHelper.isCollar(collar)) { + String nickname = CollarHelper.getNickname(collar); return nickname != null && !nickname.isEmpty(); } return false; diff --git a/src/main/java/com/tiedup/remake/state/components/PlayerEquipment.java b/src/main/java/com/tiedup/remake/state/components/PlayerEquipment.java index 8294d3a..b19dae4 100644 --- a/src/main/java/com/tiedup/remake/state/components/PlayerEquipment.java +++ b/src/main/java/com/tiedup/remake/state/components/PlayerEquipment.java @@ -1,8 +1,6 @@ package com.tiedup.remake.state.components; import com.tiedup.remake.items.base.ILockable; -import com.tiedup.remake.items.base.ItemBind; -import com.tiedup.remake.items.base.ItemCollar; import com.tiedup.remake.state.hosts.IPlayerBindStateHost; import com.tiedup.remake.v2.BodyRegionV2; import com.tiedup.remake.v2.bondage.IV2BondageEquipment; @@ -154,9 +152,9 @@ public class PlayerEquipment { ); if (collar.isEmpty()) return ItemStack.EMPTY; - if (collar.getItem() instanceof ItemCollar collarItem) { - if (!force && collarItem.isLocked(collar)) return ItemStack.EMPTY; - collarItem.setLocked(collar, false); + if (collar.getItem() instanceof ILockable lockable) { + if (!force && lockable.isLocked(collar)) return ItemStack.EMPTY; + lockable.setLocked(collar, false); } return V2EquipmentHelper.unequipFromRegion(player, BodyRegionV2.NECK); } diff --git a/src/main/java/com/tiedup/remake/state/components/PlayerLifecycle.java b/src/main/java/com/tiedup/remake/state/components/PlayerLifecycle.java index 55d1cba..180d822 100644 --- a/src/main/java/com/tiedup/remake/state/components/PlayerLifecycle.java +++ b/src/main/java/com/tiedup/remake/state/components/PlayerLifecycle.java @@ -3,8 +3,8 @@ 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.bondage.BindModeHelper; import com.tiedup.remake.v2.BodyRegionV2; import java.util.UUID; import net.minecraft.server.level.ServerLevel; @@ -148,7 +148,7 @@ public class PlayerLifecycle { */ private boolean hasLegsBound(ItemStack bind) { if (bind.isEmpty()) return false; - if (!(bind.getItem() instanceof ItemBind)) return false; - return ItemBind.hasLegsBound(bind); + if (!BindModeHelper.isBindItem(bind)) return false; + return BindModeHelper.hasLegsBound(bind); } } diff --git a/src/main/java/com/tiedup/remake/util/BondageItemLoaderUtility.java b/src/main/java/com/tiedup/remake/util/BondageItemLoaderUtility.java index b6c8d8f..b25395b 100644 --- a/src/main/java/com/tiedup/remake/util/BondageItemLoaderUtility.java +++ b/src/main/java/com/tiedup/remake/util/BondageItemLoaderUtility.java @@ -1,7 +1,19 @@ package com.tiedup.remake.util; import com.tiedup.remake.blocks.entity.IBondageItemHolder; -import com.tiedup.remake.items.base.*; +import com.tiedup.remake.items.base.ItemBind; +import com.tiedup.remake.items.base.ItemBlindfold; +import com.tiedup.remake.items.base.ItemCollar; +import com.tiedup.remake.items.base.ItemEarplugs; +import com.tiedup.remake.items.base.ItemGag; +import com.tiedup.remake.v2.BodyRegionV2; +import com.tiedup.remake.v2.bondage.BindModeHelper; +import com.tiedup.remake.v2.bondage.CollarHelper; +import com.tiedup.remake.v2.bondage.component.ComponentType; +import com.tiedup.remake.v2.bondage.component.GaggingComponent; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemDefinition; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemRegistry; import java.util.List; import net.minecraft.ChatFormatting; import net.minecraft.nbt.CompoundTag; @@ -41,36 +53,32 @@ public final class BondageItemLoaderUtility { ItemStack stack, Player player ) { - if (stack.getItem() instanceof ItemBind && holder.getBind().isEmpty()) { + if ((stack.getItem() instanceof ItemBind || BindModeHelper.isBindItem(stack)) && holder.getBind().isEmpty()) { holder.setBind(stack.copyWithCount(1)); if (!player.isCreative()) stack.shrink(1); return true; } - if (stack.getItem() instanceof ItemGag && holder.getGag().isEmpty()) { + if ((stack.getItem() instanceof ItemGag + || DataDrivenBondageItem.getComponent(stack, ComponentType.GAGGING, GaggingComponent.class) != null) + && holder.getGag().isEmpty()) { holder.setGag(stack.copyWithCount(1)); if (!player.isCreative()) stack.shrink(1); return true; } - if ( - stack.getItem() instanceof ItemBlindfold && - holder.getBlindfold().isEmpty() - ) { + if ((stack.getItem() instanceof ItemBlindfold || isDataDrivenForRegion(stack, BodyRegionV2.EYES)) + && holder.getBlindfold().isEmpty()) { holder.setBlindfold(stack.copyWithCount(1)); if (!player.isCreative()) stack.shrink(1); return true; } - if ( - stack.getItem() instanceof ItemEarplugs && - holder.getEarplugs().isEmpty() - ) { + if ((stack.getItem() instanceof ItemEarplugs || isDataDrivenForRegion(stack, BodyRegionV2.EARS)) + && holder.getEarplugs().isEmpty()) { holder.setEarplugs(stack.copyWithCount(1)); if (!player.isCreative()) stack.shrink(1); return true; } - if ( - stack.getItem() instanceof ItemCollar && - holder.getCollar().isEmpty() - ) { + if ((stack.getItem() instanceof ItemCollar || CollarHelper.isCollar(stack)) + && holder.getCollar().isEmpty()) { holder.setCollar(stack.copyWithCount(1)); if (!player.isCreative()) stack.shrink(1); return true; @@ -87,13 +95,28 @@ public final class BondageItemLoaderUtility { * @return true if the item can be loaded into a bondage item holder */ public static boolean isLoadableBondageItem(ItemStack stack) { - return ( - (stack.getItem() instanceof ItemBind) || - (stack.getItem() instanceof ItemGag) || - (stack.getItem() instanceof ItemBlindfold) || - (stack.getItem() instanceof ItemEarplugs) || - (stack.getItem() instanceof ItemCollar) - ); + if (stack.isEmpty()) return false; + // V1 item types + if (stack.getItem() instanceof ItemBind + || stack.getItem() instanceof ItemGag + || stack.getItem() instanceof ItemBlindfold + || stack.getItem() instanceof ItemEarplugs + || stack.getItem() instanceof ItemCollar) { + return true; + } + // V2 data-driven items: bind, gag, blindfold, earplugs, collar + if (BindModeHelper.isBindItem(stack)) return true; + if (DataDrivenBondageItem.getComponent(stack, ComponentType.GAGGING, GaggingComponent.class) != null) return true; + if (isDataDrivenForRegion(stack, BodyRegionV2.EYES)) return true; + if (isDataDrivenForRegion(stack, BodyRegionV2.EARS)) return true; + if (CollarHelper.isCollar(stack)) return true; + return false; + } + + /** Check if a stack is a data-driven item occupying the given body region. */ + private static boolean isDataDrivenForRegion(ItemStack stack, BodyRegionV2 region) { + DataDrivenItemDefinition def = DataDrivenItemRegistry.get(stack); + return def != null && def.occupiedRegions().contains(region); } /** diff --git a/src/main/java/com/tiedup/remake/util/RestraintApplicator.java b/src/main/java/com/tiedup/remake/util/RestraintApplicator.java index 28ed1a0..b9f8493 100644 --- a/src/main/java/com/tiedup/remake/util/RestraintApplicator.java +++ b/src/main/java/com/tiedup/remake/util/RestraintApplicator.java @@ -2,9 +2,8 @@ package com.tiedup.remake.util; import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.items.base.IHasResistance; -import com.tiedup.remake.items.base.ItemBind; -import com.tiedup.remake.items.base.ItemCollar; import com.tiedup.remake.state.IBondageState; +import com.tiedup.remake.v2.bondage.CollarHelper; import com.tiedup.remake.v2.BodyRegionV2; import java.util.UUID; import net.minecraft.ChatFormatting; @@ -60,7 +59,7 @@ public final class RestraintApplicator { } // Tighten existing bind - reset resistance to max - if (currentBind.getItem() instanceof ItemBind bindItem) { + if (currentBind.getItem() instanceof IHasResistance bindItem) { int maxResistance = bindItem.getBaseResistance(target); state.setCurrentBindResistance(maxResistance); return true; @@ -286,11 +285,8 @@ public final class RestraintApplicator { ItemStack collarCopy = collar.copy(); // Add owner if provided - if ( - ownerUUID != null && - collarCopy.getItem() instanceof ItemCollar collarItem - ) { - collarItem.addOwner( + if (ownerUUID != null && CollarHelper.isCollar(collarCopy)) { + CollarHelper.addOwner( collarCopy, ownerUUID, ownerName != null ? ownerName : "Unknown" diff --git a/src/main/java/com/tiedup/remake/v2/bondage/movement/MovementStyleResolver.java b/src/main/java/com/tiedup/remake/v2/bondage/movement/MovementStyleResolver.java index d58482e..1c1e2f4 100644 --- a/src/main/java/com/tiedup/remake/v2/bondage/movement/MovementStyleResolver.java +++ b/src/main/java/com/tiedup/remake/v2/bondage/movement/MovementStyleResolver.java @@ -1,7 +1,8 @@ package com.tiedup.remake.v2.bondage.movement; -import com.tiedup.remake.items.base.ItemBind; import com.tiedup.remake.items.base.PoseType; +import com.tiedup.remake.v2.bondage.BindModeHelper; +import com.tiedup.remake.v2.bondage.PoseTypeHelper; import com.tiedup.remake.v2.BodyRegionV2; import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemDefinition; import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemRegistry; @@ -19,7 +20,7 @@ import org.jetbrains.annotations.Nullable; * default speed/jump values. Modifiers from lower-severity items are ignored.

* *

V1 Compatibility (H6 fix)

- *

V1 items ({@link ItemBind}) stored in V2 capability + *

V1 items (ItemBind) stored in V2 capability * do not have data-driven definitions. This resolver provides a fallback that * maps V1 bind mode + pose type to a {@link MovementStyle} with speed values matching * the original V1 behavior, preventing double stacking between the legacy @@ -122,7 +123,7 @@ public final class MovementStyleResolver { // ==================== V1 Fallback ==================== /** - * Attempt to derive a movement style from a V1 {@link ItemBind} item. + * Attempt to derive a movement style from a V1 bind item. * *

Only items with legs bound produce a movement style. The mapping preserves * the original V1 speed values:

@@ -137,15 +138,15 @@ public final class MovementStyleResolver { */ @Nullable private static V1Fallback resolveV1Fallback(ItemStack stack) { - if (!(stack.getItem() instanceof ItemBind bindItem)) { + if (!BindModeHelper.isBindItem(stack)) { return null; } - if (!ItemBind.hasLegsBound(stack)) { + if (!BindModeHelper.hasLegsBound(stack)) { return null; } - PoseType poseType = bindItem.getPoseType(); + PoseType poseType = PoseTypeHelper.getPoseType(stack); return switch (poseType) { case WRAP, LATEX_SACK -> new V1Fallback( diff --git a/src/main/java/com/tiedup/remake/v2/furniture/network/PacketFurnitureForcemount.java b/src/main/java/com/tiedup/remake/v2/furniture/network/PacketFurnitureForcemount.java index 39eef2f..1a09c32 100644 --- a/src/main/java/com/tiedup/remake/v2/furniture/network/PacketFurnitureForcemount.java +++ b/src/main/java/com/tiedup/remake/v2/furniture/network/PacketFurnitureForcemount.java @@ -1,8 +1,8 @@ package com.tiedup.remake.v2.furniture.network; import com.tiedup.remake.core.TiedUpMod; -import com.tiedup.remake.items.base.ItemCollar; import com.tiedup.remake.network.PacketRateLimiter; +import com.tiedup.remake.v2.bondage.CollarHelper; import com.tiedup.remake.state.IBondageState; import com.tiedup.remake.util.KidnappedHelper; import com.tiedup.remake.v2.BodyRegionV2; @@ -28,7 +28,7 @@ import net.minecraftforge.network.NetworkEvent; * Client-to-server packet: master forces a captive onto a furniture seat. * *

The sender must own the captive's collar (verified via - * {@link ItemCollar#isOwner(ItemStack, net.minecraft.world.entity.player.Player)}), + * {@link CollarHelper#isOwner(ItemStack, net.minecraft.world.entity.player.Player)}), * the captive must be alive and within 5 blocks of both sender and furniture, * and the furniture must have an available seat.

* @@ -132,10 +132,7 @@ public class PacketFurnitureForcemount { } ItemStack collarStack = captiveState.getEquipment(BodyRegionV2.NECK); - if ( - collarStack.isEmpty() || - !(collarStack.getItem() instanceof ItemCollar collar) - ) { + if (!CollarHelper.isCollar(collarStack)) { TiedUpMod.LOGGER.debug( "[PacketFurnitureForcemount] Invalid collar item on captive" ); @@ -143,7 +140,7 @@ public class PacketFurnitureForcemount { } // Collar must be owned by sender (or sender has admin permission) - if (!collar.isOwner(collarStack, sender) && !sender.hasPermissions(2)) { + if (!CollarHelper.isOwner(collarStack, sender) && !sender.hasPermissions(2)) { TiedUpMod.LOGGER.debug( "[PacketFurnitureForcemount] {} is not the collar owner of {}", sender.getName().getString(), diff --git a/src/main/java/com/tiedup/remake/worldgen/HangingCagePiece.java b/src/main/java/com/tiedup/remake/worldgen/HangingCagePiece.java index d5c333b..06c8256 100644 --- a/src/main/java/com/tiedup/remake/worldgen/HangingCagePiece.java +++ b/src/main/java/com/tiedup/remake/worldgen/HangingCagePiece.java @@ -3,17 +3,20 @@ package com.tiedup.remake.worldgen; import com.tiedup.remake.blocks.ModBlocks; import com.tiedup.remake.blocks.entity.TrappedChestBlockEntity; import com.tiedup.remake.core.TiedUpMod; -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.v2.V2Blocks; +import com.tiedup.remake.v2.BodyRegionV2; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemDefinition; +import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemRegistry; import com.tiedup.remake.v2.blocks.PetCageBlock; import com.tiedup.remake.v2.blocks.PetCagePartBlock; +import java.util.List; +import java.util.stream.Collectors; import javax.annotation.Nullable; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; import net.minecraft.nbt.DoubleTag; import net.minecraft.nbt.FloatTag; import net.minecraft.nbt.ListTag; @@ -540,38 +543,46 @@ public class HangingCagePiece extends StructurePiece { BlockEntity be = level.getBlockEntity(chestPos); if (be instanceof TrappedChestBlockEntity trappedChest) { - // Random bind - BindVariant[] bindVariants = BindVariant.values(); - BindVariant chosenBind = bindVariants[random.nextInt( - bindVariants.length - )]; - ItemStack bindStack = new ItemStack(ModItems.getBind(chosenBind)); - trappedChest.setBind(bindStack); + // Random bind from data-driven ARMS items + trappedChest.setBind(randomItemForRegion(random, BodyRegionV2.ARMS, FALLBACK_BINDS)); // Random gag (50% chance) if (random.nextFloat() < 0.50f) { - GagVariant[] gagVariants = GagVariant.values(); - GagVariant chosenGag = gagVariants[random.nextInt( - gagVariants.length - )]; - ItemStack gagStack = new ItemStack(ModItems.getGag(chosenGag)); - trappedChest.setGag(gagStack); + trappedChest.setGag(randomItemForRegion(random, BodyRegionV2.MOUTH, FALLBACK_GAGS)); } // Random blindfold (30% chance) if (random.nextFloat() < 0.30f) { - BlindfoldVariant[] bfVariants = BlindfoldVariant.values(); - BlindfoldVariant chosenBf = bfVariants[random.nextInt( - bfVariants.length - )]; - ItemStack bfStack = new ItemStack( - ModItems.getBlindfold(chosenBf) - ); - trappedChest.setBlindfold(bfStack); + trappedChest.setBlindfold(randomItemForRegion(random, BodyRegionV2.EYES, FALLBACK_BLINDFOLDS)); } } } + // Fallback item IDs for worldgen when DataDrivenItemRegistry is empty (race with reload) + private static final ResourceLocation[] FALLBACK_BINDS = { + new ResourceLocation("tiedup", "ropes"), + new ResourceLocation("tiedup", "chain"), + new ResourceLocation("tiedup", "armbinder") + }; + private static final ResourceLocation[] FALLBACK_GAGS = { + new ResourceLocation("tiedup", "cloth_gag"), + new ResourceLocation("tiedup", "ball_gag") + }; + private static final ResourceLocation[] FALLBACK_BLINDFOLDS = { + new ResourceLocation("tiedup", "classic_blindfold") + }; + + private static ItemStack randomItemForRegion(RandomSource random, BodyRegionV2 region, ResourceLocation[] fallbacks) { + List defs = DataDrivenItemRegistry.getAll().stream() + .filter(d -> d.occupiedRegions().contains(region)) + .collect(Collectors.toList()); + if (!defs.isEmpty()) { + return DataDrivenBondageItem.createStack(defs.get(random.nextInt(defs.size())).id()); + } + // Fallback for worldgen race condition (registry not loaded yet) + return DataDrivenBondageItem.createStack(fallbacks[random.nextInt(fallbacks.length)]); + } + static void safeSetBlock( WorldGenLevel level, BlockPos pos, @@ -629,9 +640,7 @@ public class HangingCagePiece extends StructurePiece { entityTag.putUUID("UUID", java.util.UUID.randomUUID()); // Random bind item — the damsel spawns already restrained - BindVariant[] variants = BindVariant.values(); - BindVariant chosenBind = variants[random.nextInt(variants.length)]; - ItemStack bindStack = new ItemStack(ModItems.getBind(chosenBind)); + ItemStack bindStack = randomItemForRegion(random, BodyRegionV2.ARMS, FALLBACK_BINDS); bindStack.getOrCreateTag().putString("bindMode", "full"); entityTag.put("Bind", bindStack.save(new CompoundTag())); @@ -640,9 +649,8 @@ public class HangingCagePiece extends StructurePiece { if (chunk instanceof ProtoChunk protoChunk) { protoChunk.addEntity(entityTag); TiedUpMod.LOGGER.info( - "[HangingCage] Scheduled {} damsel with {} at {}", + "[HangingCage] Scheduled {} damsel at {}", shiny ? "shiny" : "regular", - chosenBind.getRegistryName(), masterPos.toShortString() ); }