Files
TiedUp-/src/main/java/com/tiedup/remake/mixin/MixinMCAVillagerLeash.java
NotEvil 449178f57b feat(D-01/C): consumer migration — 85 files migrated to V2 helpers
Phase 1 (state): PlayerBindState, PlayerCaptorManager, PlayerEquipment,
  PlayerDataRetrieval, PlayerLifecycle, PlayerShockCollar, StruggleAccessory
Phase 2 (client): AnimationTickHandler, NpcAnimationTickHandler, 5 render
  handlers, DamselModel, 3 client mixins, SelfBondageInputHandler,
  SlaveManagementScreen, ActionPanel, SlaveEntryWidget, ModKeybindings
Phase 3 (entities): 28 entity/AI files migrated to CollarHelper,
  BindModeHelper, PoseTypeHelper, createStack()
Phase 4 (network): PacketSlaveAction, PacketMasterEquip,
  PacketAssignCellToCollar, PacketNpcCommand, PacketFurnitureForcemount
Phase 5 (events): RestraintTaskTickHandler, PetPlayRestrictionHandler,
  PlayerEnslavementHandler, ChatEventHandler, LaborAttackPunishmentHandler
Phase 6 (commands): BondageSubCommand, CollarCommand, NPCCommand,
  KidnapSetCommand
Phase 7 (compat): MCAKidnappedAdapter, MCA mixins
Phase 8 (misc): GagTalkManager, PetRequestManager, HangingCagePiece,
  BondageItemBlockEntity, TrappedChestBlockEntity, DispenserBehaviors,
  BondageItemLoaderUtility, RestraintApplicator, StruggleSessionManager,
  MovementStyleResolver, CampLifecycleManager

Some files retain dual V1/V2 checks (instanceof V1 || V2Helper) for
coexistence — V1-only branches removed in Branch D.
2026-04-15 00:16:50 +02:00

85 lines
2.7 KiB
Java

package com.tiedup.remake.mixin;
import com.tiedup.remake.compat.mca.MCACompat;
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;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
/**
* Mixin to allow vanilla leash attachment to MCA villagers when tied or collar owner.
*
* <p>By default, MCA villagers cannot be leashed. This mixin overrides
* the canBeLeashed check to allow leashing when:
* <ul>
* <li>The villager is tied up (any bind), OR</li>
* <li>The player is a collar owner</li>
* </ul>
*
* <p>Uses @Pseudo annotation - mixin is optional and will be skipped if MCA is not installed.
*/
@Pseudo
@Mixin(targets = "forge.net.mca.entity.VillagerEntityMCA", remap = false)
public class MixinMCAVillagerLeash {
/**
* Override canBeLeashed to allow TiedUp leash mechanics.
*
* <p>The canBeLeashed method is a vanilla method (remapped), so we use remap = true.
*
* @param player The player trying to leash
* @param cir Callback info for returning the result
*/
@Inject(
method = "canBeLeashed",
at = @At("HEAD"),
cancellable = true,
remap = true
)
private void tiedup$overrideCanBeLeashed(
Player player,
CallbackInfoReturnable<Boolean> cir
) {
LivingEntity entity = (LivingEntity) (Object) this;
IBondageState state = MCACompat.getKidnappedState(entity);
// No TiedUp state - let vanilla/MCA handle it
if (state == null) {
return;
}
// Already leashed - cannot leash again
if (entity instanceof Mob mob && mob.isLeashed()) {
cir.setReturnValue(false);
return;
}
// Can be leashed if tied up
if (state.isTiedUp()) {
cir.setReturnValue(true);
return;
}
// Can be leashed if player is collar owner
if (state.hasCollar()) {
ItemStack collar = state.getEquipment(BodyRegionV2.NECK);
if (CollarHelper.isCollar(collar)) {
if (CollarHelper.isOwner(collar, player)) {
cir.setReturnValue(true);
return;
}
}
}
// Default: let MCA handle it (usually returns false)
}
}