Hypnosis subsystem
Hypnosis subsystem
Fully shipped. Trigger-word system that fires accidents on chat messages.
Lifecycle
- Crafting: cursed clock recipe (
Hypno.onPrepareCraft) — clock + book of Curse of Binding → Hypnosis Clock with PDC keyshypnosis(byte),crafted_by(name),crafted_by_uuid(UUID string), and a defaultHypnoTriggerWord(random fromHyponosisWords.yml). - Programming:
/hypno <word> <type>(type =wetting|messing) writes bothHypnoTriggerWordandHypnoTypePDC keys onto the held clock. The clock’s lore showsTrigger: <word>+Type: <type>to the crafter only (UUID-matched, follows the laxative pattern viaInventoryOpenEvent/InventoryCloseEvent/EntityPickupItemEvent); lore is null for everyone else. - Application: caster right-clicks target with the clock; 5-second boss-bar cast (
handleRightClickHold); on successhandleInteractionenforces opt-in (hypnoPermission0/1/2 = Off/CaregiversOnly/Anyone), caregiver gating, and theHypno_Max_Triggerscap, then adds aHypnoTrigger(word, type, expiry, casterUUID)to the target’sPlayerStats.hypnoTriggerslist. - Triggering:
Hypno.fireTriggers(message)is the single entry point for chat triggers; called fromHypno.onPlayerChat(sync-scheduled fromAsyncPlayerChatEvent, only when VentureChat is absent) and fromVentureChatHook.onVentureChat. For each online opted-in player it cleans expired triggers, then for each trigger whose word appears in the message it resets the expiry tonow + Hypno_Duration_Days, rolls a 20% silent chance, and callsHandleAccident.handleAccidentwithMessageTypeHypno_Wetting/Hypno_Messing/SILENT. Wetting and messing flags are tracked separately so the same word configured for both types fires both accidents simultaneously, but a duplicated word of the same type fires only once per message.
Persistence and config
- Persistence:
hypnoPermission(int) andhypnoTriggers(List<String>of pipe-delimitedword|type|yyyy-MM-dd HH:mm:ss|casterUUID) under theHypnofeature gate.LoadStatsmigrates legacymessingHypnoWord/wettingHypnoWordString fields into triggers with default duration on first load. - Settings UI:
SettingsMenushows a CLOCK item (gated on globalHypnoflag) — cycles0 → 1 → 2 → 0on click, but is locked whilestats.hasActiveHypnoTriggers()returns true (lore shows max-expiry remaining asXd Yh). - Config:
Secret_Menu.Hypno_Duration_Days(default 3) andSecret_Menu.Hypno_Max_Triggers(default 0 = unlimited) live underSecret_Menuand are loaded intoglobalConfigasHypno_Duration_Days(Long) andHypno_Max_Triggers(Integer).
Phase 5b — Nanny integration
Hypno.applyHypnosis(Player target, ItemStack clock) is the static helper that lets a Nanny apply a hypnosis trigger autonomously. The 4th HypnoTrigger arg (casterUUID) is a String, not UUID — Nanny passes null since it isn’t a player. See docs/wiki/nanny.md Phase 5b for the dispatch path.
Cursed items
BindingDiaper builds a cursed binding diaper (NamespacedKey cursed, PersistentDataType.BYTE, lore “Cursed: Binding Enchantment”) gated by Secret_Menu.Binding_Diapers. Hypno adds the cursed clock recipe and rejects ingredients tagged with the cursed key. The TutorialBook references “Cursed Diapers” as a hidden setting.