chore(P2): V1 zombie comments cleanup + i18n events/network/items

Zombie comments (14 files):
- Replace references to deleted V1 classes (ItemBind, ItemCollar, IBondageItem,
  BindVariant, etc.) with V2 equivalents or past-tense historical notes
- "V1 path" → "legacy slot-index path" for still-active legacy codepaths
- Clean misleading javadoc that implied V1 code was still present

i18n (13 files, 31 new keys):
- Events: 12 Component.literal() → translatable (labor tools, gag eat,
  death escape, debt, punishment, grace, camp protection, chest, maid)
- Network: 12 Component.literal() → translatable (trader messages,
  lockpick jam, slave freedom warnings)
- Items: 2 Component.literal() → translatable (ItemOwnerTarget tooltips)
This commit is contained in:
NotEvil
2026-04-16 11:20:17 +02:00
parent 371a138b71
commit 9b2c5dec8e
28 changed files with 114 additions and 89 deletions

View File

@@ -201,11 +201,11 @@ public class AnimationTickHandler {
context,
allOwnedParts
);
// Clear V1 tracking so transition back works
// Clear legacy tracking so transition back works
AnimationStateRegistry.getLastAnimId().remove(uuid);
}
// No V2 items with GLB models — nothing to animate.
// V1 items without data-driven definitions are not animated.
// Items without data-driven GLB definitions are not animated.
} else if (wasTied) {
// Was tied, now free - stop all animations
if (GltfAnimationApplier.hasActiveState(player)) {

View File

@@ -82,7 +82,7 @@ public class NpcAnimationTickHandler {
* (base posture) and an item layer (GLB-driven bones). Sitting and kneeling are
* handled by the context resolver, so the V2 path now covers all postures.
*
* <p>V1 fallback: if no V2 GLB model is found, falls back to JSON-based
* <p>Legacy fallback: if no GLB model is found, falls back to JSON-based
* PlayerAnimator animations via {@link BondageAnimationManager}.
*/
private static void updateNpcAnimation(AbstractTiedUpNpc entity) {
@@ -120,7 +120,7 @@ public class NpcAnimationTickHandler {
);
lastNpcAnimId.remove(uuid);
} else {
// V1 fallback: JSON-based PlayerAnimator animations
// Legacy fallback: JSON-based PlayerAnimator animations
if (GltfAnimationApplier.hasActiveState(entity)) {
GltfAnimationApplier.clearV2Animation(entity);
}
@@ -148,7 +148,7 @@ public class NpcAnimationTickHandler {
}
/**
* Build animation ID for an NPC from its current state (V1 path).
* Build animation ID for an NPC from its current state (legacy JSON path).
*/
private static String buildNpcAnimationId(AbstractTiedUpNpc entity) {
// Determine position prefix for SIT/KNEEL poses
@@ -175,7 +175,7 @@ public class NpcAnimationTickHandler {
BodyRegionV2.LEGS
);
// V1 fallback: if no V2 regions set but NPC has a bind, derive from bind mode NBT
// Legacy 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);

View File

@@ -215,7 +215,7 @@ public class MCACompatEvents {
IBondageState state = MCACompat.getKidnappedState(livingTarget);
if (state != null) {
// Priority: Untie > Ungag > Unblindfold > etc.
// This mimics EntityDamsel logic or ItemBind.interactLivingEntity logic for untying
// This mimics EntityDamsel logic or TyingInteractionHelper logic for untying
// No collar ownership check — any player can untie MCA villagers by design
// (MCA villagers use a separate relationship system, not TiedUp collars)

View File

@@ -160,7 +160,7 @@ public class SettingsAccessor {
* <p><b>BUG-003 fix:</b> Previously, {@code IHasResistance.getBaseResistance()}
* called {@code ModGameRules.getResistance()} which only knew 4 types (rope, gag,
* blindfold, collar) and returned hardcoded 100 for the other 10 types. Meanwhile
* the old BindVariant.getResistance() read from ModConfig which had all 14 types.
* the old {@code BindVariant.getResistance()} (now removed) read from ModConfig which had all 14 types.
* This caused a display-vs-struggle desync (display: 250, struggle: 100).
* Now both paths use this method.
*

View File

@@ -89,8 +89,8 @@ public class CampChestHandler {
if (entity instanceof Player player) {
player.displayClientMessage(
Component.literal(
"This chest is locked by the camp!"
Component.translatable(
"msg.tiedup.event.chest_locked_by_camp"
).withStyle(ChatFormatting.RED),
true
);

View File

@@ -286,10 +286,9 @@ public class CampManagementHandler {
.getPlayer(prisonerId);
if (player != null) {
player.sendSystemMessage(
Component.literal(
"A new maid, " +
maidName +
", has arrived. Work resumes."
Component.translatable(
"msg.tiedup.event.new_maid_arrived",
maidName
).withStyle(ChatFormatting.GOLD)
);
}

View File

@@ -75,10 +75,10 @@ public class CampNpcProtectionHandler {
// Send warning message to player
player.sendSystemMessage(
Component.literal(
Component.translatable(
isTrader
? "The camp defends their leader! You are now under attack!"
: "The camp defends their servant! You are now under attack!"
? "msg.tiedup.event.camp_defends_trader"
: "msg.tiedup.event.camp_defends_maid"
).withStyle(ChatFormatting.RED, ChatFormatting.BOLD)
);
}

View File

@@ -48,8 +48,8 @@ public class GraceEventHandler {
record.setProtectionExpiry(0);
player.displayClientMessage(
Component.literal(
"You attacked a kidnapper - protection lost!"
Component.translatable(
"msg.tiedup.event.grace_lost"
).withStyle(ChatFormatting.RED),
true
);

View File

@@ -209,12 +209,10 @@ public class LaborAttackPunishmentHandler {
manager.increaseDebt(prisoner.getUUID(), DEBT_INCREASE_PER_ATTACK);
prisoner.sendSystemMessage(
Component.literal(
String.format(
"Your debt has increased by %d emeralds for attacking %s!",
DEBT_INCREASE_PER_ATTACK,
targetName
)
Component.translatable(
"msg.tiedup.event.debt_increased",
DEBT_INCREASE_PER_ATTACK,
targetName
).withStyle(ChatFormatting.RED, ChatFormatting.BOLD)
);
}
@@ -282,8 +280,8 @@ public class LaborAttackPunishmentHandler {
// 4. Warning message
prisoner.sendSystemMessage(
Component.literal(
"Your task has been marked as failed. You will not be paid for your work."
Component.translatable(
"msg.tiedup.event.task_failed"
).withStyle(ChatFormatting.DARK_RED)
);
@@ -315,8 +313,8 @@ public class LaborAttackPunishmentHandler {
laborRecord.setEscortMaidId(null);
prisoner.sendSystemMessage(
Component.literal(
"You have been returned to your cell for your insolence!"
Component.translatable(
"msg.tiedup.event.returned_to_cell"
).withStyle(ChatFormatting.RED, ChatFormatting.BOLD)
);

View File

@@ -363,8 +363,8 @@ public class PlayerStateEventHandler {
// Send death escape message if applicable
if (pendingDeathEscapeMessage.remove(player.getUUID())) {
player.sendSystemMessage(
net.minecraft.network.chat.Component.literal(
"You died and escaped captivity. Your items remain in the camp chest."
net.minecraft.network.chat.Component.translatable(
"msg.tiedup.event.death_escape"
).withStyle(net.minecraft.ChatFormatting.YELLOW)
);
}

View File

@@ -473,7 +473,7 @@ public class BondageItemRestrictionHandler {
if (state != null && state.isGagged()) {
event.setCanceled(true);
player.displayClientMessage(
Component.literal("You can't eat with a gag on.").withStyle(
Component.translatable("msg.tiedup.event.cant_eat_gagged").withStyle(
ChatFormatting.RED
),
true

View File

@@ -79,7 +79,7 @@ public class LaborToolProtectionHandler {
);
} else {
player.displayClientMessage(
Component.literal("You cannot drop labor tools!"),
Component.translatable("msg.tiedup.event.cant_drop_labor_tools"),
true
);
}
@@ -124,7 +124,7 @@ public class LaborToolProtectionHandler {
);
} else {
player.displayClientMessage(
Component.literal("You cannot store labor tools!"),
Component.translatable("msg.tiedup.event.cant_store_labor_tools"),
true
);
}

View File

@@ -63,7 +63,7 @@ public class ChatEventHandler {
if (!gagStack.isEmpty() && isGagItem) {
String originalMessage = event.getRawText();
// V2: get material from component, V1 fallback: from ItemGag
// V2: get material from GaggingComponent
GagMaterial material = null;
if (gaggingComp != null) {
material = gaggingComp.getMaterial();

View File

@@ -157,7 +157,7 @@ public abstract class ItemOwnerTarget extends Item {
) {
if (hasOwner(stack)) {
tooltip.add(
Component.literal("Owner: ")
Component.translatable("item.tiedup.owner_target.owner")
.withStyle(ChatFormatting.GOLD)
.append(
Component.literal(getOwnerName(stack)).withStyle(
@@ -167,8 +167,8 @@ public abstract class ItemOwnerTarget extends Item {
);
} else {
tooltip.add(
Component.literal(
"Unclaimed (" + unclaimedHint + ")"
Component.translatable(
"item.tiedup.owner_target.unclaimed", unclaimedHint
).withStyle(ChatFormatting.GRAY)
);
}

View File

@@ -46,8 +46,8 @@ public class StruggleSessionManager {
> continuousSessions = new ConcurrentHashMap<>();
/**
* Mapping from legacy V1 slot indices to V2 BodyRegionV2.
* Used to convert V1 session targetSlot ordinals to V2 regions.
* Mapping from legacy slot indices to V2 BodyRegionV2.
* Used to convert legacy session targetSlot ordinals to V2 regions.
* Index: 0=ARMS, 1=MOUTH, 2=EYES, 3=EARS, 4=NECK, 5=TORSO, 6=HANDS.
*/
private static final BodyRegionV2[] SLOT_TO_REGION = {
@@ -611,7 +611,7 @@ public class StruggleSessionManager {
}
if (session.isAccessoryStruggle()) {
// Handle accessory resistance update (V1 path -- slot index is legacy ordinal)
// Handle accessory resistance update (legacy slot-index path)
Integer slotIndex = session.getTargetSlot();
if (
slotIndex == null ||
@@ -680,7 +680,7 @@ public class StruggleSessionManager {
if (session.isV2Struggle()) {
com.tiedup.remake.v2.BodyRegionV2 region =
session.getTargetRegion();
// BUG-001 fix: break lock before unequip (consistent with V1 accessory escape)
// BUG-001 fix: break lock before unequip (consistent with legacy accessory escape)
ItemStack stackInRegion =
com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper.getInRegion(
player,
@@ -718,7 +718,7 @@ public class StruggleSessionManager {
}
}
} else {
// Handle accessory escape (V1 path -- slot index is legacy ordinal)
// Handle accessory escape (legacy slot-index path)
Integer slotIndex = session.getTargetSlot();
if (
slotIndex != null &&

View File

@@ -345,8 +345,8 @@ public class PacketLockpickAttempt {
jammed = true;
player.sendSystemMessage(
Component.literal(
"The lock jammed! Only struggle can open it now."
Component.translatable(
"msg.tiedup.network.lock_jammed"
).withStyle(ChatFormatting.RED)
);

View File

@@ -85,7 +85,7 @@ public class PacketSlaveBeingFreed {
// Build alert message
Component message = Component.literal("")
.append(
Component.literal("[WARNING] ").withStyle(
Component.translatable("msg.tiedup.network.warning_prefix").withStyle(
ChatFormatting.RED,
ChatFormatting.BOLD
)
@@ -96,14 +96,18 @@ public class PacketSlaveBeingFreed {
)
)
.append(
Component.literal(" is trying to free ").withStyle(
Component.translatable("msg.tiedup.network.is_trying_to_free").withStyle(
ChatFormatting.RED
)
)
.append(
Component.literal(slaveName).withStyle(ChatFormatting.YELLOW)
)
.append(Component.literal(" at ").withStyle(ChatFormatting.RED))
.append(
Component.translatable("msg.tiedup.network.at_location").withStyle(
ChatFormatting.RED
)
)
.append(
Component.literal(
"[" + x + ", " + y + ", " + z + "]"

View File

@@ -77,7 +77,7 @@ public class PacketBuyCaptive {
Entity traderEntity = level.getEntity(traderEntityId);
if (!(traderEntity instanceof EntitySlaveTrader trader)) {
buyer.sendSystemMessage(
Component.literal("Trader not found.").withStyle(
Component.translatable("msg.tiedup.network.trader_not_found").withStyle(
ChatFormatting.RED
)
);
@@ -92,7 +92,7 @@ public class PacketBuyCaptive {
// Verify player has token
if (!EntityKidnapper.hasTokenInInventory(buyer)) {
buyer.sendSystemMessage(
Component.literal("You need a token to trade.").withStyle(
Component.translatable("msg.tiedup.network.need_token").withStyle(
ChatFormatting.RED
)
);
@@ -103,7 +103,7 @@ public class PacketBuyCaptive {
UUID campId = trader.getCampUUID();
if (campId == null) {
buyer.sendSystemMessage(
Component.literal("This trader has no camp.").withStyle(
Component.translatable("msg.tiedup.network.trader_no_camp").withStyle(
ChatFormatting.RED
)
);
@@ -114,7 +114,7 @@ public class PacketBuyCaptive {
CampOwnership.CampData campData = ownership.getCamp(campId);
if (campData == null) {
buyer.sendSystemMessage(
Component.literal("Camp not found.").withStyle(
Component.translatable("msg.tiedup.network.camp_not_found").withStyle(
ChatFormatting.RED
)
);
@@ -137,7 +137,7 @@ public class PacketBuyCaptive {
if (targetCell == null) {
buyer.sendSystemMessage(
Component.literal("Captive not found in camp.").withStyle(
Component.translatable("msg.tiedup.network.captive_not_in_camp").withStyle(
ChatFormatting.RED
)
);
@@ -170,7 +170,7 @@ public class PacketBuyCaptive {
if (kidnappedState == null || !kidnappedState.isForSell()) {
buyer.sendSystemMessage(
Component.literal("This captive is not for sale.").withStyle(
Component.translatable("msg.tiedup.network.captive_not_for_sale").withStyle(
ChatFormatting.RED
)
);
@@ -181,7 +181,7 @@ public class PacketBuyCaptive {
ItemTask price = kidnappedState.getSalePrice();
if (price == null) {
buyer.sendSystemMessage(
Component.literal("Price not set for this captive.").withStyle(
Component.translatable("msg.tiedup.network.price_not_set").withStyle(
ChatFormatting.RED
)
);
@@ -194,14 +194,11 @@ public class PacketBuyCaptive {
if (available < required) {
buyer.sendSystemMessage(
Component.literal(
"You need " +
required +
"x " +
price.getItem().getDescription().getString() +
" (have " +
available +
")"
Component.translatable(
"msg.tiedup.network.not_enough_items",
required,
price.getItem().getDescription().getString(),
available
).withStyle(ChatFormatting.RED)
);
return;
@@ -229,8 +226,8 @@ public class PacketBuyCaptive {
);
buyer.sendSystemMessage(
Component.literal(
"Purchase complete! The maid will deliver your captive."
Component.translatable(
"msg.tiedup.network.purchase_maid_delivery"
).withStyle(ChatFormatting.GREEN)
);
} else {

View File

@@ -23,7 +23,7 @@ public enum ToolMode {
/** AxeItem - chop wood near master */
WOODCUTTING,
/** IBondageItem (BIND type) - capture untied damsels */
/** ARMS-region bondage item - capture untied damsels */
CAPTURE;
/**

View File

@@ -195,7 +195,7 @@ public interface IBondageState extends ICapturable {
/**
* Check if gag item has gagging sound effect.
* @return true if gag implements ItemGaggingEffect
* @return true if gag has a GaggingComponent
*/
boolean hasGaggingEffect();

View File

@@ -19,8 +19,8 @@ import net.minecraft.world.item.ItemStack;
* Risk: MEDIUM (core equipment system)
*
* Epic 5F: Uses V2EquipmentHelper.
* Uses low-level setInRegion for equips because V1 items (IBondageItem) do not
* implement IV2BondageItem, so V2EquipmentHelper.equipItem() would reject them.
* Uses low-level setInRegion for equips because force-equip paths (commands, NPC AI,
* NBT restore) should bypass V2EquipmentManager conflict resolution.
*/
public class PlayerEquipment {
@@ -423,14 +423,11 @@ public class PlayerEquipment {
// ========== Low-level V2 equipment operations ==========
/**
* Low-level equip: writes to V2 capability, calls IBondageItem lifecycle hooks, syncs.
* Low-level equip: writes to V2 capability, calls IV2BondageItem lifecycle hooks, syncs.
*
* <p>INTENTIONALLY bypasses V2EquipmentManager.tryEquip() because:
* <ul>
* <li>V1 items (IBondageItem) do not implement IV2BondageItem, so tryEquip() rejects them</li>
* <li>All callers (commands, NPC AI, NBT restore) are force-equip paths that should not
* be subject to V2 conflict resolution (SMELL-003 reviewed — bypass is by design)</li>
* </ul>
* <p>INTENTIONALLY bypasses V2EquipmentManager.tryEquip() because all callers
* (commands, NPC AI, NBT restore) are force-equip paths that should not be subject
* to V2 conflict resolution (SMELL-003 reviewed — bypass is by design).
* <p>Basic safety (isRegionOccupied, canEquip) is still checked here.</p>
*/
private void equipInRegion(BodyRegionV2 region, ItemStack stack) {
@@ -444,7 +441,7 @@ public class PlayerEquipment {
// Check if already occupied
if (equip.isRegionOccupied(region)) return;
// Check canEquip via V1 IBondageItem interface
// Check canEquip via IV2BondageItem interface
if (stack.getItem() instanceof IV2BondageItem bondageItem) {
if (!bondageItem.canEquip(stack, player)) return;
}

View File

@@ -143,7 +143,7 @@ public class TyingPlayerTask extends TyingTask {
/**
* Send progress packets to both kidnapper and target (if players).
* Called every tick from ItemBind or RestraintTaskTickHandler.
* Called every tick from RestraintTaskTickHandler.
*/
@Override
public void sendProgressPackets() {

View File

@@ -16,8 +16,8 @@ import org.jetbrains.annotations.Nullable;
/**
* Helper class for common bondage equipment interaction logic.
*
* This class extracts the duplicated interactLivingEntity pattern
* from ItemGag, ItemBlindfold, ItemMittens, ItemEarplugs, and ItemCollar.
* This class extracts the common interactLivingEntity pattern
* for bondage equipment items (gags, blindfolds, mittens, earplugs, collars).
*/
public class EquipmentInteractionHelper {

View File

@@ -32,7 +32,7 @@ public final class BindModeHelper {
);
/**
* Check if the given stack is a bind item (V2 ARMS-region item or V1 ItemBind).
* Check if the given stack is a bind item (ARMS-region data-driven item).
*/
public static boolean isBindItem(ItemStack stack) {
if (stack.isEmpty()) return false;

View File

@@ -24,8 +24,8 @@ import net.minecraft.world.phys.AABB;
import org.jetbrains.annotations.Nullable;
/**
* Static utility for collar operations bridging V1 (ItemCollar subclasses)
* and V2 (data-driven items with OwnershipComponent).
* Static utility for collar operations using V2 data-driven items
* with OwnershipComponent.
*/
public final class CollarHelper {

View File

@@ -6,10 +6,10 @@ import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemRegistry;
import net.minecraft.world.item.ItemStack;
/**
* Resolves the {@link PoseType} for any bondage item stack (V1 or V2).
* Resolves the {@link PoseType} for any bondage item stack.
*
* <p>V2 items read from the data-driven definition's {@code pose_type} field.
* V1 items fall back to {@code ItemBind.getPoseType()}.</p>
* <p>Reads from the data-driven definition's {@code pose_type} field,
* falling back to {@link PoseType#STANDARD} if absent.</p>
*/
public final class PoseTypeHelper {

View File

@@ -20,8 +20,8 @@ import net.minecraft.world.item.ItemStack;
/**
* Handles the tying interaction flow for V2 data-driven ARMS items.
*
* <p>Extracted from {@code ItemBind.interactLivingEntity()} to support
* the same tying task flow for data-driven items.</p>
* <p>Originally extracted from the former {@code ItemBind.interactLivingEntity()},
* now the canonical tying flow for all data-driven ARMS items.</p>
*/
public final class TyingInteractionHelper {

View File

@@ -968,5 +968,35 @@
"item.tiedup.leather_mittens": "Leather Mittens",
"item.tiedup.ball_gag_3d": "Ball Gag",
"item.tiedup.taser": "Taser",
"item.tiedup.debug_wand": "Debug Wand"
"item.tiedup.debug_wand": "Debug Wand",
"msg.tiedup.event.cant_drop_labor_tools": "You cannot drop labor tools!",
"msg.tiedup.event.cant_store_labor_tools": "You cannot store labor tools!",
"msg.tiedup.event.cant_eat_gagged": "You can't eat with a gag on.",
"msg.tiedup.event.death_escape": "You died and escaped captivity. Your items remain in the camp chest.",
"msg.tiedup.event.debt_increased": "Your debt has increased by %1$s emeralds for attacking %2$s!",
"msg.tiedup.event.task_failed": "Your task has been marked as failed. You will not be paid for your work.",
"msg.tiedup.event.returned_to_cell": "You have been returned to your cell for your insolence!",
"msg.tiedup.event.grace_lost": "You attacked a kidnapper - protection lost!",
"msg.tiedup.event.camp_defends_trader": "The camp defends their leader! You are now under attack!",
"msg.tiedup.event.camp_defends_maid": "The camp defends their servant! You are now under attack!",
"msg.tiedup.event.chest_locked_by_camp": "This chest is locked by the camp!",
"msg.tiedup.event.new_maid_arrived": "A new maid, %1$s, has arrived. Work resumes.",
"msg.tiedup.network.trader_not_found": "Trader not found.",
"msg.tiedup.network.need_token": "You need a token to trade.",
"msg.tiedup.network.trader_no_camp": "This trader has no camp.",
"msg.tiedup.network.camp_not_found": "Camp not found.",
"msg.tiedup.network.captive_not_in_camp": "Captive not found in camp.",
"msg.tiedup.network.captive_not_for_sale": "This captive is not for sale.",
"msg.tiedup.network.price_not_set": "Price not set for this captive.",
"msg.tiedup.network.not_enough_items": "You need %1$sx %2$s (have %3$s)",
"msg.tiedup.network.purchase_maid_delivery": "Purchase complete! The maid will deliver your captive.",
"msg.tiedup.network.lock_jammed": "The lock jammed! Only struggle can open it now.",
"msg.tiedup.network.warning_prefix": "[WARNING] ",
"msg.tiedup.network.is_trying_to_free": " is trying to free ",
"msg.tiedup.network.at_location": " at ",
"item.tiedup.owner_target.owner": "Owner: ",
"item.tiedup.owner_target.unclaimed": "Unclaimed (%1$s)"
}