Remove build artifacts, dev tool configs, unused dependencies, and third-party source dumps. Add proper README, update .gitignore, clean up Makefile.
350 lines
11 KiB
Java
350 lines
11 KiB
Java
package com.tiedup.remake.util;
|
|
|
|
import com.tiedup.remake.core.TiedUpMod;
|
|
import com.tiedup.remake.v2.BodyRegionV2;
|
|
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 java.util.UUID;
|
|
import net.minecraft.ChatFormatting;
|
|
import net.minecraft.network.chat.Component;
|
|
import net.minecraft.server.level.ServerPlayer;
|
|
import net.minecraft.world.entity.LivingEntity;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
/**
|
|
* Utility class for applying restraints to entities.
|
|
*
|
|
* Phase 3: Refactoring - Centralizes restraint application logic
|
|
*
|
|
* This class provides methods for applying various restraints (binds, gags,
|
|
* blindfolds, etc.) to targets with consistent validation. Used by:
|
|
* - KidnapperCaptureGoal
|
|
* - KidnapperPunishGoal
|
|
* - EntityRopeArrow
|
|
* - Other capture/restraint mechanics
|
|
*/
|
|
public final class RestraintApplicator {
|
|
|
|
private RestraintApplicator() {
|
|
// Utility class - no instantiation
|
|
}
|
|
|
|
// ==================== BIND ====================
|
|
|
|
/**
|
|
* Apply a bind or tighten existing binds.
|
|
*
|
|
* @param target The target entity
|
|
* @param bind The bind item to apply if needed
|
|
* @return true if bind was applied or tightened
|
|
*/
|
|
public static boolean applyOrTightenBind(
|
|
LivingEntity target,
|
|
ItemStack bind
|
|
) {
|
|
IBondageState state = KidnappedHelper.getKidnappedState(target);
|
|
if (state == null) {
|
|
return false;
|
|
}
|
|
|
|
ItemStack currentBind = state.getEquipment(BodyRegionV2.ARMS);
|
|
if (currentBind.isEmpty()) {
|
|
// No bind - apply new one
|
|
if (bind != null && !bind.isEmpty()) {
|
|
state.equip(BodyRegionV2.ARMS, bind.copy());
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Tighten existing bind - reset resistance to max
|
|
if (currentBind.getItem() instanceof ItemBind bindItem) {
|
|
int maxResistance = bindItem.getBaseResistance(target);
|
|
state.setCurrentBindResistance(maxResistance);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Tighten an entity's binds, resetting resistance to max.
|
|
* This happens when a guard catches someone struggling.
|
|
*
|
|
* <p>Consolidated from EntityKidnapper, EntityMaid, EntitySlaveTrader, KidnapperPunishGoal.</p>
|
|
*
|
|
* @param state The prisoner's kidnapped state
|
|
* @param prisoner The prisoner entity
|
|
* @return true if binds were tightened, false if no binds equipped
|
|
*/
|
|
public static boolean tightenBind(
|
|
IBondageState state,
|
|
LivingEntity prisoner
|
|
) {
|
|
if (state == null) return false;
|
|
|
|
ItemStack bind = state.getEquipment(BodyRegionV2.ARMS);
|
|
if (bind.isEmpty()) {
|
|
return false;
|
|
}
|
|
|
|
if (bind.getItem() instanceof IHasResistance resistItem) {
|
|
int baseResistance = resistItem.getBaseResistance(prisoner);
|
|
resistItem.setCurrentResistance(bind, baseResistance);
|
|
|
|
// Notify the prisoner
|
|
if (prisoner instanceof ServerPlayer serverPlayer) {
|
|
serverPlayer.sendSystemMessage(
|
|
Component.literal(
|
|
"Your restraints have been tightened!"
|
|
).withStyle(ChatFormatting.RED)
|
|
);
|
|
}
|
|
|
|
TiedUpMod.LOGGER.debug(
|
|
"[RestraintApplicator] Tightened {}'s binds (resistance reset to {})",
|
|
prisoner.getName().getString(),
|
|
baseResistance
|
|
);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// ==================== GAG ====================
|
|
|
|
/**
|
|
* Apply a gag to the target.
|
|
*
|
|
* @param target The target entity
|
|
* @param gag The gag item to apply
|
|
* @return true if successfully applied, false if already gagged or invalid
|
|
*/
|
|
public static boolean applyGag(LivingEntity target, ItemStack gag) {
|
|
IBondageState state = KidnappedHelper.getKidnappedState(target);
|
|
if (state == null || gag == null || gag.isEmpty()) {
|
|
return false;
|
|
}
|
|
if (state.isGagged()) {
|
|
return false; // Already gagged
|
|
}
|
|
|
|
state.equip(BodyRegionV2.MOUTH, gag.copy());
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Apply a gag only if the target doesn't have one.
|
|
*
|
|
* @param target The target entity
|
|
* @param gag The gag item to apply
|
|
* @return true if gag was applied
|
|
*/
|
|
public static boolean applyGagIfMissing(
|
|
LivingEntity target,
|
|
ItemStack gag
|
|
) {
|
|
IBondageState state = KidnappedHelper.getKidnappedState(target);
|
|
if (state == null || gag == null || gag.isEmpty()) {
|
|
return false;
|
|
}
|
|
|
|
ItemStack currentGag = state.getEquipment(BodyRegionV2.MOUTH);
|
|
if (!currentGag.isEmpty()) {
|
|
return false; // Already has gag
|
|
}
|
|
|
|
state.equip(BodyRegionV2.MOUTH, gag.copy());
|
|
return true;
|
|
}
|
|
|
|
// ==================== BLINDFOLD ====================
|
|
|
|
/**
|
|
* Apply a blindfold to the target.
|
|
*
|
|
* @param target The target entity
|
|
* @param blindfold The blindfold item to apply
|
|
* @return true if successfully applied, false if already blindfolded or invalid
|
|
*/
|
|
public static boolean applyBlindfold(
|
|
LivingEntity target,
|
|
ItemStack blindfold
|
|
) {
|
|
IBondageState state = KidnappedHelper.getKidnappedState(target);
|
|
if (state == null || blindfold == null || blindfold.isEmpty()) {
|
|
return false;
|
|
}
|
|
if (state.isBlindfolded()) {
|
|
return false; // Already blindfolded
|
|
}
|
|
|
|
state.equip(BodyRegionV2.EYES, blindfold.copy());
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Apply a blindfold only if the target doesn't have one.
|
|
*
|
|
* @param target The target entity
|
|
* @param blindfold The blindfold item to apply
|
|
* @return true if blindfold was applied
|
|
*/
|
|
public static boolean applyBlindfoldIfMissing(
|
|
LivingEntity target,
|
|
ItemStack blindfold
|
|
) {
|
|
IBondageState state = KidnappedHelper.getKidnappedState(target);
|
|
if (state == null || blindfold == null || blindfold.isEmpty()) {
|
|
return false;
|
|
}
|
|
|
|
ItemStack currentBlindfold = state.getEquipment(BodyRegionV2.EYES);
|
|
if (!currentBlindfold.isEmpty()) {
|
|
return false; // Already has blindfold
|
|
}
|
|
|
|
state.equip(BodyRegionV2.EYES, blindfold.copy());
|
|
return true;
|
|
}
|
|
|
|
// ==================== MITTENS ====================
|
|
|
|
/**
|
|
* Apply mittens to the target.
|
|
*
|
|
* @param target The target entity
|
|
* @param mittens The mittens item to apply
|
|
* @return true if successfully applied, false if already has mittens or invalid
|
|
*/
|
|
public static boolean applyMittens(LivingEntity target, ItemStack mittens) {
|
|
IBondageState state = KidnappedHelper.getKidnappedState(target);
|
|
if (state == null || mittens == null || mittens.isEmpty()) {
|
|
return false;
|
|
}
|
|
if (state.hasMittens()) {
|
|
return false; // Already has mittens
|
|
}
|
|
|
|
state.equip(BodyRegionV2.HANDS, mittens.copy());
|
|
return true;
|
|
}
|
|
|
|
// ==================== EARPLUGS ====================
|
|
|
|
/**
|
|
* Apply earplugs to the target.
|
|
*
|
|
* @param target The target entity
|
|
* @param earplugs The earplugs item to apply
|
|
* @return true if successfully applied, false if already has earplugs or invalid
|
|
*/
|
|
public static boolean applyEarplugs(
|
|
LivingEntity target,
|
|
ItemStack earplugs
|
|
) {
|
|
IBondageState state = KidnappedHelper.getKidnappedState(target);
|
|
if (state == null || earplugs == null || earplugs.isEmpty()) {
|
|
return false;
|
|
}
|
|
if (state.hasEarplugs()) {
|
|
return false; // Already has earplugs
|
|
}
|
|
|
|
state.equip(BodyRegionV2.EARS, earplugs.copy());
|
|
return true;
|
|
}
|
|
|
|
// ==================== COLLAR ====================
|
|
|
|
/**
|
|
* Apply a collar to the target with owner information.
|
|
*
|
|
* @param target The target entity
|
|
* @param collar The collar item to apply
|
|
* @param ownerUUID The owner's UUID (can be null)
|
|
* @param ownerName The owner's name (can be null)
|
|
* @return true if successfully applied, false if already has collar or invalid
|
|
*/
|
|
public static boolean applyCollar(
|
|
LivingEntity target,
|
|
ItemStack collar,
|
|
@Nullable UUID ownerUUID,
|
|
@Nullable String ownerName
|
|
) {
|
|
IBondageState state = KidnappedHelper.getKidnappedState(target);
|
|
if (state == null || collar == null || collar.isEmpty()) {
|
|
return false;
|
|
}
|
|
if (state.hasCollar()) {
|
|
return false; // Already has collar
|
|
}
|
|
|
|
ItemStack collarCopy = collar.copy();
|
|
|
|
// Add owner if provided
|
|
if (
|
|
ownerUUID != null &&
|
|
collarCopy.getItem() instanceof ItemCollar collarItem
|
|
) {
|
|
collarItem.addOwner(
|
|
collarCopy,
|
|
ownerUUID,
|
|
ownerName != null ? ownerName : "Unknown"
|
|
);
|
|
}
|
|
|
|
state.equip(BodyRegionV2.NECK, collarCopy);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Apply a collar without owner information.
|
|
*
|
|
* @param target The target entity
|
|
* @param collar The collar item to apply
|
|
* @return true if successfully applied
|
|
*/
|
|
public static boolean applyCollar(LivingEntity target, ItemStack collar) {
|
|
return applyCollar(target, collar, null, null);
|
|
}
|
|
|
|
// ==================== BULK OPERATIONS ====================
|
|
|
|
/**
|
|
* Check if target has any restraints.
|
|
*
|
|
* @param target The target entity
|
|
* @return true if target has any restraints
|
|
*/
|
|
public static boolean hasAnyRestraint(LivingEntity target) {
|
|
IBondageState state = KidnappedHelper.getKidnappedState(target);
|
|
if (state == null) {
|
|
return false;
|
|
}
|
|
return (
|
|
state.isTiedUp() ||
|
|
state.isGagged() ||
|
|
state.isBlindfolded() ||
|
|
state.hasMittens() ||
|
|
state.hasEarplugs() ||
|
|
state.hasCollar()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get the kidnapped state for an entity.
|
|
*
|
|
* @param target The target entity
|
|
* @return The IBondageState state, or null if not available
|
|
*/
|
|
@Nullable
|
|
public static IBondageState getState(LivingEntity target) {
|
|
return KidnappedHelper.getKidnappedState(target);
|
|
}
|
|
}
|