package com.tiedup.remake.minigame; import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.entities.EntityKidnapper; import com.tiedup.remake.entities.EntityMaid; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; /** * Helper for notifying nearby guards (Kidnappers, Maids, Traders) about * escape-related noise (struggle, lockpick, knife cutting). * *

Extracted from {@link MiniGameSessionManager} (M15 split) so that * any system can trigger guard alerts without depending on a session manager. */ public final class GuardNotificationHelper { /** * Radius in blocks for struggle noise to alert nearby NPCs. * 32 blocks is the standard hearing range for mobs in Minecraft. * NPCs within this range will be notified of struggle attempts. */ private static final double STRUGGLE_NOISE_RADIUS = 32.0; private GuardNotificationHelper() {} /** * Notify nearby guards about escape noise (struggle, lockpick, knife cutting). * Public entry point for external systems (e.g. GenericKnife). * * @param player The player who is making noise */ public static void notifyNearbyGuards(ServerPlayer player) { notifyNearbyKidnappersOfStruggle(player); } /** * Notify nearby guards (Kidnappers, Maids, Traders) when a player starts struggling. * This creates "noise" that guards can detect. * * Guards will only react if they have LINE OF SIGHT to the struggling prisoner. * If they see the prisoner, they will: * 1. Shock the prisoner (punishment) * 2. Approach to tighten their binds (reset resistance) * * @param player The player who started struggling */ public static void notifyNearbyKidnappersOfStruggle(ServerPlayer player) { if (player == null) return; ServerLevel level = player.serverLevel(); if (level == null) return; int notifiedCount = 0; // MEDIUM FIX: Performance optimization - use single entity search instead of 3 // Old code did 3 separate searches for EntityKidnapper, EntityMaid, EntitySlaveTrader // with the SAME bounding box, causing 3x iterations over entities in the area. // New code does 1 search for LivingEntity and filters by instanceof. java.util.List nearbyEntities = level.getEntitiesOfClass( net.minecraft.world.entity.LivingEntity.class, player.getBoundingBox().inflate(STRUGGLE_NOISE_RADIUS), e -> e.isAlive() ); for (net.minecraft.world.entity.LivingEntity entity : nearbyEntities) { if ( entity instanceof EntityKidnapper kidnapper && !kidnapper.isTiedUp() ) { kidnapper.onStruggleDetected(player); notifiedCount++; } else if ( entity instanceof EntityMaid maid && !maid.isTiedUp() && !maid.isFreed() ) { maid.onStruggleDetected(player); notifiedCount++; } else if ( entity instanceof com.tiedup.remake.entities.EntitySlaveTrader trader ) { trader.onStruggleDetected(player); notifiedCount++; } } if (notifiedCount > 0) { TiedUpMod.LOGGER.debug( "[GuardNotificationHelper] Notified {} guards about struggle from {}", notifiedCount, player.getName().getString() ); } } }