Clean repo for open source release
Remove build artifacts, dev tool configs, unused dependencies, and third-party source dumps. Add proper README, update .gitignore, clean up Makefile.
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
package com.tiedup.remake.mixin;
|
||||
|
||||
import com.tiedup.remake.compat.mca.MCACompat;
|
||||
import com.tiedup.remake.v2.BodyRegionV2;
|
||||
import com.tiedup.remake.core.TiedUpMod;
|
||||
import com.tiedup.remake.items.ItemKey;
|
||||
import com.tiedup.remake.items.ItemMasterKey;
|
||||
import com.tiedup.remake.v2.bondage.IV2BondageItem;
|
||||
import com.tiedup.remake.items.base.ItemCollar;
|
||||
import com.tiedup.remake.state.IBondageState;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Pseudo;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
/**
|
||||
* Mixin to manage TiedUp vs MCA interaction priority.
|
||||
*
|
||||
* <p>Handles TiedUp interactions DIRECTLY instead of just blocking MCA,
|
||||
* because vanilla leash/item handling happens at different points in the
|
||||
* interaction chain that MCA may bypass.
|
||||
*
|
||||
* <p>Priority rules:
|
||||
* <ol>
|
||||
* <li>Empty hand + leashed → detach leash</li>
|
||||
* <li>Holding lead + (tied OR collar owner) → attach leash</li>
|
||||
* <li>Holding key + collared → call key.interactLivingEntity()</li>
|
||||
* <li>Shift+click + tied + empty hand → let event handler untie</li>
|
||||
* <li>Holding bondage item → let item handle tying</li>
|
||||
* <li>Otherwise → let MCA handle</li>
|
||||
* </ol>
|
||||
*
|
||||
* <p>Uses @Pseudo - mixin is optional and will be skipped if MCA is not installed.
|
||||
*/
|
||||
@Pseudo
|
||||
@Mixin(targets = "forge.net.mca.entity.VillagerEntityMCA", remap = false)
|
||||
public abstract class MixinMCAVillagerInteraction {
|
||||
|
||||
/**
|
||||
* Inject at HEAD of mobInteract to handle TiedUp interactions.
|
||||
* Method: InteractionResult mobInteract(Player, InteractionHand)
|
||||
*/
|
||||
@Inject(
|
||||
method = "m_6071_",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true,
|
||||
remap = false
|
||||
)
|
||||
private void tiedup$handleMobInteract(
|
||||
Player player,
|
||||
InteractionHand hand,
|
||||
CallbackInfoReturnable<InteractionResult> cir
|
||||
) {
|
||||
InteractionResult result = tiedup$handleInteraction(player, hand);
|
||||
if (result != null) {
|
||||
cir.setReturnValue(result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject at HEAD of interactAt to handle TiedUp interactions BEFORE MCA opens its menu.
|
||||
* Method: InteractionResult interactAt(Player, Vec3, InteractionHand)
|
||||
*/
|
||||
@Inject(
|
||||
method = "m_7111_",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true,
|
||||
remap = false
|
||||
)
|
||||
private void tiedup$handleInteractAt(
|
||||
Player player,
|
||||
net.minecraft.world.phys.Vec3 vec,
|
||||
InteractionHand hand,
|
||||
CallbackInfoReturnable<InteractionResult> cir
|
||||
) {
|
||||
InteractionResult result = tiedup$handleInteraction(player, hand);
|
||||
if (result != null) {
|
||||
cir.setReturnValue(result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Common interaction handling logic for both mobInteract and interactAt.
|
||||
*
|
||||
* @param player The player interacting
|
||||
* @param hand The hand used for interaction
|
||||
* @return InteractionResult to return, or null to let MCA handle
|
||||
*/
|
||||
@Unique
|
||||
private InteractionResult tiedup$handleInteraction(
|
||||
Player player,
|
||||
InteractionHand hand
|
||||
) {
|
||||
Mob mob = (Mob) (Object) this;
|
||||
IBondageState state = MCACompat.getKidnappedState(mob);
|
||||
ItemStack heldItem = player.getItemInHand(hand);
|
||||
boolean isClientSide = player.level().isClientSide;
|
||||
|
||||
// 1. LEASH DETACHMENT: Empty hand + leashed → drop leash
|
||||
if (mob.isLeashed() && heldItem.isEmpty()) {
|
||||
if (!isClientSide) {
|
||||
mob.dropLeash(true, !player.getAbilities().instabuild);
|
||||
TiedUpMod.LOGGER.debug("[MCA] Detached leash from villager");
|
||||
}
|
||||
return InteractionResult.sidedSuccess(isClientSide);
|
||||
}
|
||||
|
||||
// 2. LEASH ATTACHMENT: Holding lead + (tied OR collar owner)
|
||||
if (heldItem.is(Items.LEAD) && !mob.isLeashed()) {
|
||||
if (tiedup$canLeash(player, state)) {
|
||||
if (!isClientSide) {
|
||||
mob.setLeashedTo(player, true);
|
||||
if (!player.getAbilities().instabuild) {
|
||||
heldItem.shrink(1);
|
||||
}
|
||||
TiedUpMod.LOGGER.debug("[MCA] Attached leash to villager");
|
||||
}
|
||||
return InteractionResult.sidedSuccess(isClientSide);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. KEY INTERACTION: Key + collared → call key's interactLivingEntity
|
||||
if (state != null && state.hasCollar()) {
|
||||
if (heldItem.getItem() instanceof ItemKey key) {
|
||||
return key.interactLivingEntity(heldItem, player, mob, hand);
|
||||
}
|
||||
if (heldItem.getItem() instanceof ItemMasterKey masterKey) {
|
||||
return masterKey.interactLivingEntity(
|
||||
heldItem,
|
||||
player,
|
||||
mob,
|
||||
hand
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. UNTYING: Shift+click + tied + empty hand → let event handler process
|
||||
if (
|
||||
state != null &&
|
||||
state.isTiedUp() &&
|
||||
heldItem.isEmpty() &&
|
||||
player.isShiftKeyDown()
|
||||
) {
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
|
||||
// 5. BONDAGE ITEM: Let TiedUp item's interactLivingEntity handle tying
|
||||
if (heldItem.getItem() instanceof IV2BondageItem) {
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
|
||||
// Let MCA handle
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a player can leash this MCA villager.
|
||||
*
|
||||
* @param player The player trying to leash
|
||||
* @param state The villager's IBondageState state (may be null)
|
||||
* @return true if leashing is allowed
|
||||
*/
|
||||
@Unique
|
||||
private boolean tiedup$canLeash(Player player, IBondageState state) {
|
||||
if (state == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Can leash if villager is tied up
|
||||
if (state.isTiedUp()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user