feat(D-01/D): V1 cleanup — delete 28 files, ~5400 lines removed

D1: ThreadLocal alert suppression moved from ItemCollar to CollarHelper.
    onCollarRemoved() logic (kidnapper alert) moved to CollarHelper.

D2+D3: Deleted 17 V1 item classes + 4 V1-only interfaces:
  ItemBind, ItemGag, ItemBlindfold, ItemCollar, ItemEarplugs, ItemMittens,
  ItemColor, ItemClassicCollar, ItemShockCollar, ItemShockCollarAuto,
  ItemGpsCollar, ItemChokeCollar, ItemHood, ItemMedicalGag,
  IBondageItem, IHasGaggingEffect, IHasBlindingEffect, IAdjustable

D4: KidnapperTheme/KidnapperItemSelector/DispenserBehaviors migrated
    from variant enums to string-based DataDrivenItemRegistry IDs.

D5: Deleted 11 variant enums + Generic* factories + ItemBallGag3D:
  BindVariant, GagVariant, BlindfoldVariant, EarplugsVariant, MittensVariant,
  GenericBind, GenericGag, GenericBlindfold, GenericEarplugs, GenericMittens

D6: ModItems cleaned — all V1 bondage registrations removed.
D7: ModCreativeTabs rewritten — iterates DataDrivenItemRegistry.
D8+D9: All V2 helpers cleaned (V1 fallbacks removed), orphan imports removed.

Zero V1 bondage code references remain (only Javadoc comments).
All bondage items are now data-driven via 47 JSON definitions.
This commit is contained in:
NotEvil
2026-04-15 01:55:16 +02:00
parent fccb99ef9a
commit 099cd0d984
89 changed files with 2647 additions and 5423 deletions

View File

@@ -1,6 +1,5 @@
package com.tiedup.remake.v2.bondage;
import com.tiedup.remake.items.base.ItemBind;
import com.tiedup.remake.v2.BodyRegionV2;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemDefinition;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemRegistry;
@@ -42,8 +41,8 @@ public final class BindModeHelper {
if (def != null) {
return def.occupiedRegions().contains(BodyRegionV2.ARMS);
}
// V1 fallback
return stack.getItem() instanceof ItemBind;
// No V2 definition found
return false;
}
/**

View File

@@ -1,10 +1,9 @@
package com.tiedup.remake.v2.bondage;
import com.tiedup.remake.items.ItemChokeCollar;
import com.tiedup.remake.items.ItemGpsCollar;
import com.tiedup.remake.items.ItemShockCollar;
import com.tiedup.remake.items.ItemShockCollarAuto;
import com.tiedup.remake.items.base.ItemCollar;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.entities.EntityKidnapper;
import com.tiedup.remake.entities.ai.kidnapper.KidnapperState;
import com.tiedup.remake.state.CollarRegistry;
import com.tiedup.remake.v2.bondage.component.ChokingComponent;
import com.tiedup.remake.v2.bondage.component.ComponentType;
import com.tiedup.remake.v2.bondage.component.GpsComponent;
@@ -17,8 +16,11 @@ import java.util.UUID;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.AABB;
import org.jetbrains.annotations.Nullable;
/**
@@ -29,15 +31,16 @@ public final class CollarHelper {
private CollarHelper() {}
// Thread-local flag to suppress collar removal alerts during programmatic unequip
private static final ThreadLocal<Boolean> SUPPRESS_REMOVAL_ALERT =
ThreadLocal.withInitial(() -> false);
// ===== DETECTION =====
// True if the stack is any kind of collar (V2 ownership component or V1 ItemCollar)
// True if the stack is a collar (V2 data-driven item with OwnershipComponent)
public static boolean isCollar(ItemStack stack) {
if (stack.isEmpty()) return false;
if (DataDrivenBondageItem.getComponent(stack, ComponentType.OWNERSHIP, OwnershipComponent.class) != null) {
return true;
}
return stack.getItem() instanceof ItemCollar;
return DataDrivenBondageItem.getComponent(stack, ComponentType.OWNERSHIP, OwnershipComponent.class) != null;
}
// ===== OWNERSHIP (NBT: "owners") =====
@@ -267,13 +270,10 @@ public final class CollarHelper {
// ===== SHOCK =====
// True if the collar can shock (V2 ShockComponent or V1 ItemShockCollar)
// True if the collar can shock (V2 ShockComponent)
public static boolean canShock(ItemStack stack) {
if (stack.isEmpty()) return false;
if (DataDrivenBondageItem.getComponent(stack, ComponentType.SHOCK, ShockComponent.class) != null) {
return true;
}
return stack.getItem() instanceof ItemShockCollar;
return DataDrivenBondageItem.getComponent(stack, ComponentType.SHOCK, ShockComponent.class) != null;
}
public static boolean isPublicShock(ItemStack stack) {
@@ -285,27 +285,21 @@ public final class CollarHelper {
stack.getOrCreateTag().putBoolean("public_mode", publicMode);
}
// V2: from ShockComponent auto interval, V1: from ItemShockCollarAuto field, else 0
// V2: from ShockComponent auto interval, else 0
public static int getShockInterval(ItemStack stack) {
ShockComponent comp = DataDrivenBondageItem.getComponent(
stack, ComponentType.SHOCK, ShockComponent.class
);
if (comp != null) return comp.getAutoInterval();
if (stack.getItem() instanceof ItemShockCollarAuto auto) {
return auto.getInterval();
}
return 0;
}
// ===== GPS =====
// True if the collar has GPS capabilities
// True if the collar has GPS capabilities (V2 GpsComponent)
public static boolean hasGPS(ItemStack stack) {
if (stack.isEmpty()) return false;
if (DataDrivenBondageItem.getComponent(stack, ComponentType.GPS, GpsComponent.class) != null) {
return true;
}
return stack.getItem() instanceof ItemGpsCollar;
return DataDrivenBondageItem.getComponent(stack, ComponentType.GPS, GpsComponent.class) != null;
}
public static boolean hasPublicTracking(ItemStack stack) {
@@ -330,13 +324,10 @@ public final class CollarHelper {
// ===== CHOKE =====
// True if the collar is a choke collar
// True if the collar is a choke collar (V2 ChokingComponent)
public static boolean isChokeCollar(ItemStack stack) {
if (stack.isEmpty()) return false;
if (DataDrivenBondageItem.getComponent(stack, ComponentType.CHOKING, ChokingComponent.class) != null) {
return true;
}
return stack.getItem() instanceof ItemChokeCollar;
return DataDrivenBondageItem.getComponent(stack, ComponentType.CHOKING, ChokingComponent.class) != null;
}
public static boolean isChoking(ItemStack stack) {
@@ -361,11 +352,69 @@ public final class CollarHelper {
// Executes the action with collar removal alerts suppressed
public static void runWithSuppressedAlert(Runnable action) {
ItemCollar.runWithSuppressedAlert(action);
SUPPRESS_REMOVAL_ALERT.set(true);
try {
action.run();
} finally {
SUPPRESS_REMOVAL_ALERT.set(false);
}
}
// True if removal alerts are currently suppressed (ThreadLocal state)
public static boolean isRemovalAlertSuppressed() {
return ItemCollar.isRemovalAlertSuppressed();
return SUPPRESS_REMOVAL_ALERT.get();
}
// ===== COLLAR REMOVAL =====
/**
* Alert nearby kidnappers when a collar is forcibly removed.
* Handles CollarRegistry unregistration and kidnapper alerting.
*
* @param wearer The entity whose collar was removed
* @param forced Whether the removal was forced (struggle, lockpick, etc.)
*/
public static void onCollarRemoved(LivingEntity wearer, boolean forced) {
if (wearer == null || wearer.level().isClientSide()) {
return;
}
if (!forced) {
return; // Only alert on forced removals
}
if (!(wearer.level() instanceof ServerLevel serverLevel)) {
return;
}
TiedUpMod.LOGGER.info(
"[CollarHelper] {} collar was forcibly removed - alerting kidnappers",
wearer.getName().getString()
);
// Unregister from CollarRegistry
CollarRegistry registry = CollarRegistry.get(serverLevel);
if (registry != null) {
registry.unregisterWearer(wearer.getUUID());
}
// Find and alert nearby kidnappers
AABB searchBox = wearer.getBoundingBox().inflate(50, 20, 50);
List<EntityKidnapper> kidnappers = serverLevel.getEntitiesOfClass(
EntityKidnapper.class, searchBox
);
for (EntityKidnapper kidnapper : kidnappers) {
if (!kidnapper.hasCaptives() && !kidnapper.isTiedUp()) {
kidnapper.setAlertTarget(wearer);
kidnapper.setCurrentState(KidnapperState.ALERT);
kidnapper.broadcastAlert(wearer);
TiedUpMod.LOGGER.debug(
"[CollarHelper] Alerted kidnapper {} about collar removal",
kidnapper.getNpcName()
);
}
}
}
}

View File

@@ -1,6 +1,5 @@
package com.tiedup.remake.v2.bondage;
import com.tiedup.remake.items.base.ItemBind;
import com.tiedup.remake.items.base.PoseType;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemDefinition;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemRegistry;
@@ -26,10 +25,6 @@ public final class PoseTypeHelper {
return PoseType.STANDARD;
}
}
// V1 fallback
if (stack.getItem() instanceof ItemBind bind) {
return bind.getPoseType();
}
return PoseType.STANDARD;
}
}

View File

@@ -2,7 +2,6 @@ package com.tiedup.remake.v2.bondage.component;
import com.google.gson.JsonObject;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.items.base.ItemCollar;
import com.tiedup.remake.state.CollarRegistry;
import com.tiedup.remake.v2.bondage.CollarHelper;
import java.util.HashSet;
@@ -71,7 +70,7 @@ public class OwnershipComponent implements IItemComponent {
// onCollarRemoved handles both the alert AND the unregister call internally,
// so we do NOT call registry.unregisterWearer() separately to avoid double unregister.
if (!CollarHelper.isRemovalAlertSuppressed()) {
ItemCollar.onCollarRemoved(entity, true);
CollarHelper.onCollarRemoved(entity, true);
} else {
// Suppressed alert path: still need to unregister, just skip the alert
try {

View File

@@ -2,7 +2,7 @@ package com.tiedup.remake.v2.furniture;
import com.tiedup.remake.core.TiedUpMod;
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.state.PlayerBindState;
import com.tiedup.remake.state.PlayerCaptorManager;
@@ -713,11 +713,10 @@ public class EntityFurniture
);
if (
collarStack.isEmpty() ||
!(collarStack.getItem() instanceof
ItemCollar collar)
!CollarHelper.isCollar(collarStack)
) continue;
if (
!collar.isOwner(collarStack, serverPlayer) &&
!CollarHelper.isOwner(collarStack, serverPlayer) &&
!serverPlayer.hasPermissions(2)
) continue;