Files
TiedUp-/src/main/java/com/tiedup/remake/items/ItemGpsLocator.java
NotEvil 099cd0d984 feat(D-01/D): V1 cleanup — delete 28 files, ~5400 lines removed
D1: ThreadLocal alert suppression moved from ItemCollar to CollarHelper.
    onCollarRemoved() logic (kidnapper alert) moved to CollarHelper.

D2+D3: Deleted 17 V1 item classes + 4 V1-only interfaces:
  ItemBind, ItemGag, ItemBlindfold, ItemCollar, ItemEarplugs, ItemMittens,
  ItemColor, ItemClassicCollar, ItemShockCollar, ItemShockCollarAuto,
  ItemGpsCollar, ItemChokeCollar, ItemHood, ItemMedicalGag,
  IBondageItem, IHasGaggingEffect, IHasBlindingEffect, IAdjustable

D4: KidnapperTheme/KidnapperItemSelector/DispenserBehaviors migrated
    from variant enums to string-based DataDrivenItemRegistry IDs.

D5: Deleted 11 variant enums + Generic* factories + ItemBallGag3D:
  BindVariant, GagVariant, BlindfoldVariant, EarplugsVariant, MittensVariant,
  GenericBind, GenericGag, GenericBlindfold, GenericEarplugs, GenericMittens

D6: ModItems cleaned — all V1 bondage registrations removed.
D7: ModCreativeTabs rewritten — iterates DataDrivenItemRegistry.
D8+D9: All V2 helpers cleaned (V1 fallbacks removed), orphan imports removed.

Zero V1 bondage code references remain (only Javadoc comments).
All bondage items are now data-driven via 47 JSON definitions.
2026-04-15 01:55:16 +02:00

244 lines
8.7 KiB
Java

package com.tiedup.remake.items;
import com.tiedup.remake.core.SystemMessageManager;
import com.tiedup.remake.items.base.ItemOwnerTarget;
import com.tiedup.remake.v2.bondage.CollarHelper;
import com.tiedup.remake.state.IBondageState;
import com.tiedup.remake.util.KidnappedHelper;
import com.tiedup.remake.v2.BodyRegionV2;
import java.util.List;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable;
public class ItemGpsLocator extends ItemOwnerTarget {
public ItemGpsLocator() {
super(new net.minecraft.world.item.Item.Properties().stacksTo(1));
}
@Override
public void appendHoverText(
ItemStack stack,
@Nullable Level level,
List<Component> tooltip,
TooltipFlag flag
) {
super.appendHoverText(stack, level, tooltip, flag);
appendOwnerTooltip(stack, tooltip, "Right-click a player");
if (hasTarget(stack)) {
String displayName = resolveTargetDisplayName(stack, level);
tooltip.add(
Component.literal("Target: ")
.withStyle(ChatFormatting.BLUE)
.append(
Component.literal(displayName).withStyle(
ChatFormatting.WHITE
)
)
);
}
}
@Override
public InteractionResultHolder<ItemStack> use(
Level level,
Player player,
InteractionHand hand
) {
ItemStack stack = player.getItemInHand(hand);
if (level.isClientSide) return InteractionResultHolder.success(stack);
if (!hasOwner(stack)) {
SystemMessageManager.sendToPlayer(
player,
SystemMessageManager.MessageCategory.ERROR,
"You must claim this locator first! (Right-click a player)"
);
return InteractionResultHolder.fail(stack);
}
if (!isOwner(stack, player)) {
SystemMessageManager.sendToPlayer(
player,
SystemMessageManager.MessageCategory.LOCATOR_NOT_OWNER
);
return InteractionResultHolder.fail(stack);
}
if (hasTarget(stack)) {
// Use server player list for cross-dimension tracking
Player target = level
.getServer()
.getPlayerList()
.getPlayer(getTargetId(stack));
if (target != null) {
IBondageState targetState = KidnappedHelper.getKidnappedState(
target
);
if (targetState != null && targetState.hasCollar()) {
ItemStack collarStack = targetState.getEquipment(
BodyRegionV2.NECK
);
if (CollarHelper.hasGPS(collarStack)) {
if (
CollarHelper.isOwner(collarStack, player) ||
CollarHelper.hasPublicTracking(collarStack)
) {
// Check if same dimension
boolean sameDimension = player
.level()
.dimension()
.equals(target.level().dimension());
if (sameDimension) {
double distance = player.distanceTo(target);
String direction = getDirection(player, target);
SystemMessageManager.sendToPlayer(
player,
SystemMessageManager.MessageCategory.LOCATOR_DETECTED,
(int) distance + "m [" + direction + "]"
);
} else {
// Cross-dimension: show dimension name
String dimName = getDimensionDisplayName(
target
.level()
.dimension()
.location()
.getPath()
);
SystemMessageManager.sendToPlayer(
player,
SystemMessageManager.MessageCategory.LOCATOR_DETECTED,
"Target is in [" + dimName + "]"
);
}
playLocatorSound(player);
} else {
SystemMessageManager.sendToPlayer(
player,
SystemMessageManager.MessageCategory.ERROR,
"You are not allowed to access this GPS Collar!"
);
}
} else {
SystemMessageManager.sendToPlayer(
player,
SystemMessageManager.MessageCategory.ERROR,
"Target is not wearing a GPS Collar!"
);
}
}
} else {
SystemMessageManager.sendToPlayer(
player,
SystemMessageManager.MessageCategory.ERROR,
"Unable to locate target! (Offline)"
);
}
} else {
SystemMessageManager.sendToPlayer(
player,
SystemMessageManager.MessageCategory.ERROR,
"No target connected!"
);
}
return InteractionResultHolder.success(stack);
}
/**
*/
@Override
public InteractionResult interactLivingEntity(
ItemStack stack,
Player player,
LivingEntity target,
InteractionHand hand
) {
if (player.level().isClientSide) return InteractionResult.SUCCESS;
IBondageState playerState = KidnappedHelper.getKidnappedState(player);
if (
playerState != null && playerState.isTiedUp()
) return InteractionResult.FAIL;
if (!hasOwner(stack)) {
setOwner(stack, player);
SystemMessageManager.sendToPlayer(
player,
SystemMessageManager.MessageCategory.LOCATOR_CLAIMED
);
} else if (!isOwner(stack, player)) {
SystemMessageManager.sendToPlayer(
player,
SystemMessageManager.MessageCategory.LOCATOR_NOT_OWNER
);
return InteractionResult.FAIL;
}
IBondageState targetState = KidnappedHelper.getKidnappedState(target);
if (targetState != null) {
setTarget(stack, target);
player.setItemInHand(hand, stack); // Force sync
SystemMessageManager.sendChatToPlayer(
player,
"Connected to " + target.getName().getString(),
ChatFormatting.GREEN
);
return InteractionResult.SUCCESS;
}
return InteractionResult.PASS;
}
private String getDirection(Player source, Player target) {
double dx = target.getX() - source.getX();
double dz = target.getZ() - source.getZ();
if (Math.abs(dx) > Math.abs(dz)) {
return dx > 0 ? "EAST" : "WEST";
} else {
return dz > 0 ? "SOUTH" : "NORTH";
}
}
private void playLocatorSound(Player player) {
player
.level()
.playSound(
null,
player.blockPosition(),
com.tiedup.remake.core.ModSounds.SHOCKER_ACTIVATED.get(),
net.minecraft.sounds.SoundSource.PLAYERS,
0.5f,
1.0f
);
}
/**
* Get a user-friendly display name for a dimension.
*/
private String getDimensionDisplayName(String dimensionPath) {
return switch (dimensionPath) {
case "overworld" -> "Overworld";
case "the_nether" -> "The Nether";
case "the_end" -> "The End";
default -> dimensionPath.replace("_", " ");
};
}
}