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)
205 lines
6.8 KiB
Java
205 lines
6.8 KiB
Java
package com.tiedup.remake.util;
|
|
|
|
import com.tiedup.remake.core.TiedUpMod;
|
|
import com.tiedup.remake.network.sync.SyncManager;
|
|
import com.tiedup.remake.state.IBondageState;
|
|
import java.util.function.BiConsumer;
|
|
import java.util.function.BiFunction;
|
|
import java.util.function.Predicate;
|
|
import net.minecraft.server.level.ServerPlayer;
|
|
import net.minecraft.world.InteractionResult;
|
|
import net.minecraft.world.entity.LivingEntity;
|
|
import net.minecraft.world.entity.player.Player;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
/**
|
|
* Helper class for common bondage equipment interaction logic.
|
|
*
|
|
* This class extracts the common interactLivingEntity pattern
|
|
* for bondage equipment items (gags, blindfolds, mittens, earplugs, collars).
|
|
*/
|
|
public class EquipmentInteractionHelper {
|
|
|
|
/**
|
|
* Standard equipment interaction for bondage items.
|
|
*
|
|
* Handles the common flow: check state → equip or replace equipment.
|
|
*
|
|
* @param stack The item stack being used
|
|
* @param player The player using the item
|
|
* @param target The entity being equipped
|
|
* @param isEquipped Predicate to check if target already has this equipment
|
|
* @param putOn Consumer to equip the item on target (state, itemCopy)
|
|
* @param replace Function to replace existing equipment (state, itemCopy) → oldItem
|
|
* @param sendMessage Consumer to send message to target (player, target)
|
|
* @param logPrefix Log prefix for this equipment type
|
|
* @return InteractionResult
|
|
*/
|
|
public static InteractionResult equipOnTarget(
|
|
ItemStack stack,
|
|
Player player,
|
|
LivingEntity target,
|
|
Predicate<IBondageState> isEquipped,
|
|
BiConsumer<IBondageState, ItemStack> putOn,
|
|
BiFunction<IBondageState, ItemStack, ItemStack> replace,
|
|
BiConsumer<Player, LivingEntity> sendMessage,
|
|
String logPrefix
|
|
) {
|
|
return equipOnTarget(
|
|
stack,
|
|
player,
|
|
target,
|
|
isEquipped,
|
|
putOn,
|
|
replace,
|
|
sendMessage,
|
|
logPrefix,
|
|
null,
|
|
null,
|
|
null
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Equipment interaction with additional hooks for special items (like Collar).
|
|
*
|
|
* @param stack The item stack being used
|
|
* @param player The player using the item
|
|
* @param target The entity being equipped
|
|
* @param isEquipped Predicate to check if target already has this equipment
|
|
* @param putOn Consumer to equip the item on target (state, itemCopy)
|
|
* @param replace Function to replace existing equipment (state, itemCopy) → oldItem
|
|
* @param sendMessage Consumer to send message to target (player, target)
|
|
* @param logPrefix Log prefix for this equipment type
|
|
* @param preEquipHook Optional hook called before equipping (for owner registration, etc.)
|
|
* @param postEquipHook Optional hook called after equipping (for sound, particles, etc.)
|
|
* @param canReplace Optional predicate to check if replacement is allowed (for lock check)
|
|
* @return InteractionResult
|
|
*/
|
|
public static InteractionResult equipOnTarget(
|
|
ItemStack stack,
|
|
Player player,
|
|
LivingEntity target,
|
|
Predicate<IBondageState> isEquipped,
|
|
BiConsumer<IBondageState, ItemStack> putOn,
|
|
BiFunction<IBondageState, ItemStack, ItemStack> replace,
|
|
BiConsumer<Player, LivingEntity> sendMessage,
|
|
String logPrefix,
|
|
@Nullable EquipContext preEquipHook,
|
|
@Nullable EquipContext postEquipHook,
|
|
@Nullable ReplacePredicate canReplace
|
|
) {
|
|
// Server-side only
|
|
if (player.level().isClientSide) {
|
|
return InteractionResult.SUCCESS;
|
|
}
|
|
|
|
// Get target state
|
|
IBondageState targetState = KidnappedHelper.getKidnappedState(target);
|
|
if (targetState == null) {
|
|
return InteractionResult.PASS;
|
|
}
|
|
|
|
// Must be tied up
|
|
if (!targetState.isTiedUp()) {
|
|
return InteractionResult.PASS;
|
|
}
|
|
|
|
// Pre-equip hook (e.g., register collar owner)
|
|
if (preEquipHook != null) {
|
|
preEquipHook.execute(stack, player, target, targetState);
|
|
}
|
|
|
|
// Case 1: Not equipped - put on new
|
|
if (!isEquipped.test(targetState)) {
|
|
putOn.accept(targetState, stack.copy());
|
|
stack.shrink(1);
|
|
|
|
sendMessage.accept(player, target);
|
|
syncIfPlayer(target);
|
|
|
|
// Post-equip hook (e.g., play sound)
|
|
if (postEquipHook != null) {
|
|
postEquipHook.execute(stack, player, target, targetState);
|
|
}
|
|
|
|
TiedUpMod.LOGGER.info(
|
|
"[{}] {} put {} on {}",
|
|
logPrefix,
|
|
player.getName().getString(),
|
|
logPrefix.toLowerCase(),
|
|
target.getName().getString()
|
|
);
|
|
|
|
return InteractionResult.SUCCESS;
|
|
}
|
|
// Case 2: Already equipped - replace
|
|
else {
|
|
// Check if replacement is allowed (e.g., not locked)
|
|
if (
|
|
canReplace != null &&
|
|
!canReplace.canReplace(targetState, player)
|
|
) {
|
|
return InteractionResult.PASS;
|
|
}
|
|
|
|
ItemStack oldItem = replace.apply(targetState, stack.copy());
|
|
if (oldItem != null && !oldItem.isEmpty()) {
|
|
stack.shrink(1);
|
|
targetState.kidnappedDropItem(oldItem);
|
|
|
|
sendMessage.accept(player, target);
|
|
syncIfPlayer(target);
|
|
|
|
// Post-equip hook
|
|
if (postEquipHook != null) {
|
|
postEquipHook.execute(stack, player, target, targetState);
|
|
}
|
|
|
|
TiedUpMod.LOGGER.info(
|
|
"[{}] {} replaced {} on {}",
|
|
logPrefix,
|
|
player.getName().getString(),
|
|
logPrefix.toLowerCase(),
|
|
target.getName().getString()
|
|
);
|
|
|
|
return InteractionResult.SUCCESS;
|
|
}
|
|
}
|
|
|
|
return InteractionResult.PASS;
|
|
}
|
|
|
|
/**
|
|
* Sync inventory if target is a ServerPlayer.
|
|
*/
|
|
private static void syncIfPlayer(LivingEntity target) {
|
|
if (target instanceof ServerPlayer serverPlayer) {
|
|
SyncManager.syncInventory(serverPlayer);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Functional interface for pre/post equip hooks.
|
|
*/
|
|
@FunctionalInterface
|
|
public interface EquipContext {
|
|
void execute(
|
|
ItemStack stack,
|
|
Player player,
|
|
LivingEntity target,
|
|
IBondageState state
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Functional interface to check if replacement is allowed.
|
|
*/
|
|
@FunctionalInterface
|
|
public interface ReplacePredicate {
|
|
boolean canReplace(IBondageState state, Player player);
|
|
}
|
|
}
|