package com.tiedup.remake.dialogue; import com.tiedup.remake.entities.EntityDamsel; import com.tiedup.remake.personality.NpcCommand; import com.tiedup.remake.personality.NpcNeeds; import com.tiedup.remake.personality.PersonalityState; import net.minecraft.world.entity.player.Player; import org.jetbrains.annotations.Nullable; /** * System for selecting proactive dialogues based on NPC state. * Makes NPCs feel alive by having them speak about their needs, mood, and environment. * * Personality System Living NPCs */ public class DialogueTriggerSystem { /** * Select a proactive dialogue ID based on NPC's current state. * Returns null if no dialogue should be triggered. * * @param npc The damsel entity * @return Dialogue ID or null */ @Nullable public static String selectProactiveDialogue(EntityDamsel npc) { PersonalityState state = npc.getPersonalityState(); if (state == null) { return null; } NpcNeeds needs = state.getNeeds(); // Priority 1: Critical needs (starving) if (needs.isStarving()) { return "needs.starving"; } // Priority 2: Very low mood if (state.getMood() < 20) { return "mood.miserable"; } // Priority 4: Non-critical needs if (needs.isHungry()) { return "needs.hungry"; } if (needs.isTired()) { return "needs.dignity_low"; } // Priority 5: Low mood if (state.getMood() < 40) { return "mood.sad"; } // Priority 6: Job-specific idle (if doing a job) if (state.getActiveCommand().type == NpcCommand.CommandType.JOB) { return selectJobIdleDialogue(npc, state); } // Priority 7: Generic idle return selectIdleDialogue(npc, state); } /** * Select dialogue for approaching player. * No fear/relationship system — returns generic approach dialogue. * * @param npc The damsel entity * @param player The approaching player * @return Dialogue ID */ public static String selectApproachDialogue( EntityDamsel npc, Player player ) { return "reaction.approach.stranger"; } /** * Select job-specific idle dialogue. */ @Nullable private static String selectJobIdleDialogue( EntityDamsel npc, PersonalityState state ) { NpcCommand job = state.getActiveCommand(); if (job.type != NpcCommand.CommandType.JOB) { return null; } // Check mood first if (state.getMood() < 30) { return "mood.working_unhappy"; } // Job-specific idle return "jobs.idle." + job.name().toLowerCase(); } /** * Select generic idle dialogue. */ @Nullable private static String selectIdleDialogue( EntityDamsel npc, PersonalityState state ) { // High mood = positive idle if (state.getMood() > 70) { return "idle.content"; } // Normal idle return "idle.neutral"; } /** * Select environmental dialogue based on weather/time. * * @param npc The damsel entity * @return Dialogue ID or null */ @Nullable public static String selectEnvironmentDialogue(EntityDamsel npc) { // Check if outdoors (can see sky) if (!npc.level().canSeeSky(npc.blockPosition())) { return null; } // Thunder takes priority if (npc.level().isThundering()) { return "environment.thunder"; } // Rain if ( npc.level().isRaining() && npc.level().isRainingAt(npc.blockPosition()) ) { return "environment.rain"; } // Night (only if dark enough) long dayTime = npc.level().getDayTime() % 24000; if (dayTime >= 13000 && dayTime <= 23000) { return "environment.night"; } return null; } }