Files
TiedUp-/src/main/java/com/tiedup/remake/dialogue/KidnapperDialogueTriggerSystem.java
NotEvil a71093ba9c Remove internal phase comments and format code
Strip all Phase references, TODO/FUTURE roadmap notes, and internal
planning comments from the codebase. Run Prettier for consistent
formatting across all Java files.
2026-04-12 01:25:55 +02:00

122 lines
3.5 KiB
Java

package com.tiedup.remake.dialogue;
import com.tiedup.remake.entities.EntityKidnapper;
import com.tiedup.remake.entities.ai.kidnapper.KidnapperState;
import net.minecraft.world.entity.player.Player;
import org.jetbrains.annotations.Nullable;
/**
* Proactive dialogue trigger system for Kidnappers.
*
* This system enables kidnappers to speak unprompted based on their current state.
* Should be called periodically from the kidnapper's tick method.
*
* Universal NPC Dialogue Support
*/
public class KidnapperDialogueTriggerSystem {
/** Minimum ticks between proactive dialogues (60 seconds) */
private static final int PROACTIVE_COOLDOWN = 1200;
/** Chance to trigger proactive dialogue (1/400 per check = ~0.25% per check) */
private static final int TRIGGER_CHANCE = 400;
/** Check interval (every 20 ticks = 1 second) */
private static final int CHECK_INTERVAL = 20;
/**
* Tick the dialogue trigger system for a kidnapper.
* Should be called every tick from the kidnapper.
*
* @param kidnapper The kidnapper to check
* @param tickCount Current tick counter
*/
public static void tick(EntityKidnapper kidnapper, int tickCount) {
// Only check periodically
if (tickCount % CHECK_INTERVAL != 0) {
return;
}
// Check cooldown
if (kidnapper.getDialogueCooldown() > 0) {
return;
}
// Random chance check
if (kidnapper.getRandom().nextInt(TRIGGER_CHANCE) != 0) {
return;
}
// Get dialogue ID based on current state
String dialogueId = selectProactiveDialogue(kidnapper);
if (dialogueId == null) {
return;
}
// Find nearest player to speak to
Player nearestPlayer = findNearestPlayer(kidnapper, 10.0);
if (nearestPlayer == null) {
return;
}
// Speak
DialogueBridge.talkTo(kidnapper, nearestPlayer, dialogueId);
}
/**
* Select a proactive dialogue ID based on the kidnapper's current state.
*
* @param kidnapper The kidnapper
* @return Dialogue ID or null if no dialogue for this state
*/
@Nullable
private static String selectProactiveDialogue(EntityKidnapper kidnapper) {
KidnapperState state = kidnapper.getCurrentState();
if (state == null) {
return null;
}
return switch (state) {
case GUARD -> "guard.idle";
case PATROL -> "patrol.idle";
case ALERT -> "patrol.alert";
case SELLING -> "idle.sale_waiting";
case IDLE -> null; // No proactive dialogue when idle
default -> null;
};
}
/**
* Find the nearest player within a radius.
*
* @param kidnapper The kidnapper
* @param radius Search radius
* @return Nearest player or null
*/
@Nullable
private static Player findNearestPlayer(
EntityKidnapper kidnapper,
double radius
) {
var nearbyPlayers = kidnapper
.level()
.getEntitiesOfClass(
Player.class,
kidnapper.getBoundingBox().inflate(radius)
);
Player nearest = null;
double nearestDistSq = Double.MAX_VALUE;
for (Player player : nearbyPlayers) {
double distSq = kidnapper.distanceToSqr(player);
if (distSq < nearestDistSq) {
nearestDistSq = distSq;
nearest = player;
}
}
return nearest;
}
}