feat(D-01/A): OwnershipComponent lifecycle hooks (A7)

- onEquipped: register collar owners in CollarRegistry (server-side only)
- onUnequipped: alert kidnappers + unregister from CollarRegistry
- Guards: client-side check, ServerLevel cast, empty owners skip, try-catch
- appendTooltip: nickname, owner count, shock/GPS/choke capabilities
- Delegates alert suppression to ItemCollar.isRemovalAlertSuppressed()
This commit is contained in:
NotEvil
2026-04-14 15:29:31 +02:00
parent 751bad418d
commit b79225d684

View File

@@ -1,6 +1,21 @@
package com.tiedup.remake.v2.bondage.component;
import com.google.gson.JsonObject;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.items.base.ItemCollar;
import com.tiedup.remake.state.CollarRegistry;
import com.tiedup.remake.v2.bondage.CollarHelper;
import java.util.HashSet;
import java.util.List;
import java.util.UUID;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable;
/**
* Component: collar ownership behavior for data-driven items.
@@ -17,4 +32,88 @@ public class OwnershipComponent implements IItemComponent {
public static IItemComponent fromJson(JsonObject config) {
return new OwnershipComponent();
}
@Override
public void onEquipped(ItemStack stack, LivingEntity entity) {
if (entity.level().isClientSide()) return;
if (!(entity.level() instanceof ServerLevel serverLevel)) return;
List<UUID> owners = CollarHelper.getOwners(stack);
if (owners.isEmpty()) {
TiedUpMod.LOGGER.debug(
"[OwnershipComponent] Collar equipped on {} with no owners in NBT — skipping registry",
entity.getName().getString()
);
return;
}
try {
CollarRegistry registry = CollarRegistry.get(serverLevel);
registry.registerCollar(entity.getUUID(), new HashSet<>(owners));
TiedUpMod.LOGGER.debug(
"[OwnershipComponent] Registered collar for {} with {} owner(s)",
entity.getName().getString(), owners.size()
);
} catch (Exception e) {
TiedUpMod.LOGGER.warn(
"[OwnershipComponent] Failed to register collar for {}: {}",
entity.getName().getString(), e.getMessage()
);
}
}
@Override
public void onUnequipped(ItemStack stack, LivingEntity entity) {
if (entity.level().isClientSide()) return;
if (!(entity.level() instanceof ServerLevel serverLevel)) return;
// Alert kidnappers if removal wasn't suppressed
if (!CollarHelper.isRemovalAlertSuppressed()) {
ItemCollar.onCollarRemoved(entity, true);
}
try {
CollarRegistry registry = CollarRegistry.get(serverLevel);
registry.unregisterWearer(entity.getUUID());
TiedUpMod.LOGGER.debug(
"[OwnershipComponent] Unregistered collar for {}",
entity.getName().getString()
);
} catch (Exception e) {
TiedUpMod.LOGGER.warn(
"[OwnershipComponent] Failed to unregister collar for {}: {}",
entity.getName().getString(), e.getMessage()
);
}
}
@Override
public void appendTooltip(ItemStack stack, @Nullable Level level, List<Component> tooltip, TooltipFlag flag) {
String nickname = CollarHelper.getNickname(stack);
if (nickname != null && !nickname.isEmpty()) {
tooltip.add(Component.translatable("item.tiedup.tooltip.nickname", nickname)
.withStyle(ChatFormatting.LIGHT_PURPLE));
}
List<UUID> owners = CollarHelper.getOwners(stack);
if (!owners.isEmpty()) {
tooltip.add(Component.translatable("item.tiedup.tooltip.owners", owners.size())
.withStyle(ChatFormatting.GOLD));
}
if (CollarHelper.canShock(stack)) {
tooltip.add(Component.translatable("item.tiedup.tooltip.shock_capable")
.withStyle(ChatFormatting.DARK_RED));
}
if (CollarHelper.hasGPS(stack)) {
tooltip.add(Component.translatable("item.tiedup.tooltip.gps_capable")
.withStyle(ChatFormatting.AQUA));
}
if (CollarHelper.isChokeCollar(stack)) {
tooltip.add(Component.translatable("item.tiedup.tooltip.choke_capable")
.withStyle(ChatFormatting.DARK_PURPLE));
}
}
}