package com.tiedup.remake.entities; import java.util.Random; /** * Defines themed item sets for kidnappers. * Each theme groups compatible binds, gags, and blindfolds by registry name. * * Themes are selected randomly with weighted probabilities. * Higher weight = more common theme. * * Note: Natural themes (SLIME, VINE, WEB) are reserved for monsters. * * Registry names correspond to data-driven bondage item IDs in DataDrivenItemRegistry. */ public enum KidnapperTheme { // === ROPE THEMES (most common) === ROPE( "ropes", new String[] { "ropes_gag", "cloth_gag", "cleave_gag" }, new String[] { "classic_blindfold" }, true, // supportsColor 30 // weight (spawn probability) ), SHIBARI( "shibari", new String[] { "ropes_gag", "cloth_gag", "ribbon_gag" }, new String[] { "classic_blindfold" }, true, 15 ), // === TAPE THEME === TAPE( "duct_tape", new String[] { "tape_gag", "wrap_gag" }, new String[] { "blindfold_mask" }, true, 20 ), // === LEATHER/BDSM THEME === LEATHER( "leather_straps", new String[] { "ball_gag", "ball_gag_strap", "panel_gag" }, new String[] { "blindfold_mask" }, false, 15 ), // === CHAIN THEME === CHAIN( "chain", new String[] { "chain_panel_gag", "ball_gag_strap" }, new String[] { "blindfold_mask" }, false, 10 ), // === MEDICAL THEME === MEDICAL( "medical_straps", new String[] { "tube_gag", "sponge_gag", "ball_gag" }, new String[] { "blindfold_mask" }, false, 8 ), // === SCI-FI/BEAM THEME === BEAM( "beam_cuffs", new String[] { "beam_panel_gag", "latex_gag" }, new String[] { "blindfold_mask" }, false, 5 ), // === LATEX THEME (rare) === LATEX( "latex_sack", new String[] { "latex_gag", "tube_gag" }, new String[] { "blindfold_mask" }, false, 3 ), // === ASYLUM THEME (rare) === ASYLUM( "straitjacket", new String[] { "bite_gag", "sponge_gag", "ball_gag" }, new String[] { "blindfold_mask" }, false, 5 ), // === RIBBON THEME (cute/playful) === RIBBON( "ribbon", new String[] { "ribbon_gag", "cloth_gag" }, new String[] { "classic_blindfold" }, false, 8 ), // === WRAP THEME === WRAP( "wrap", new String[] { "wrap_gag", "tape_gag" }, new String[] { "blindfold_mask" }, false, 5 ); private static final Random RANDOM = new Random(); private final String bindId; private final String[] gagIds; private final String[] blindfoldIds; private final boolean supportsColor; private final int weight; KidnapperTheme( String bindId, String[] gagIds, String[] blindfoldIds, boolean supportsColor, int weight ) { this.bindId = bindId; this.gagIds = gagIds; this.blindfoldIds = blindfoldIds; this.supportsColor = supportsColor; this.weight = weight; } /** * Get the primary bind registry name for this theme. */ public String getBindId() { return bindId; } /** * Get compatible gag IDs for this theme (ordered by preference). */ public String[] getGagIds() { return gagIds; } /** * Get compatible blindfold IDs for this theme. */ public String[] getBlindfoldIds() { return blindfoldIds; } /** * Check if this theme supports color variations. * Only themes with colorable items (rope, shibari, tape) support colors. */ public boolean supportsColor() { return supportsColor; } /** * Get the spawn weight for this theme. * Higher weight = more common. */ public int getWeight() { return weight; } /** * Get primary gag ID (first in list). */ public String getPrimaryGagId() { return gagIds.length > 0 ? gagIds[0] : "ball_gag"; } /** * Get a random gag ID from this theme's compatible list. */ public String getRandomGagId() { if (gagIds.length == 0) return "ball_gag"; return gagIds[RANDOM.nextInt(gagIds.length)]; } /** * Get primary blindfold ID (first in list). */ public String getPrimaryBlindfoldId() { return blindfoldIds.length > 0 ? blindfoldIds[0] : "classic_blindfold"; } /** * Get a random blindfold ID from this theme's compatible list. */ public String getRandomBlindfoldId() { if (blindfoldIds.length == 0) return "classic_blindfold"; return blindfoldIds[RANDOM.nextInt(blindfoldIds.length)]; } /** * Check if this theme has any blindfolds. */ public boolean hasBlindfolds() { return blindfoldIds.length > 0; } /** * Get a random theme using weighted probability. * Higher weight themes are more likely to be selected. */ public static KidnapperTheme getRandomWeighted() { int totalWeight = 0; for (KidnapperTheme theme : values()) { totalWeight += theme.weight; } int roll = RANDOM.nextInt(totalWeight); int cumulative = 0; for (KidnapperTheme theme : values()) { cumulative += theme.weight; if (roll < cumulative) { return theme; } } return ROPE; // Fallback } /** * Get a random theme using a specific Random instance. */ public static KidnapperTheme getRandomWeighted(Random random) { int totalWeight = 0; for (KidnapperTheme theme : values()) { totalWeight += theme.weight; } int roll = random.nextInt(totalWeight); int cumulative = 0; for (KidnapperTheme theme : values()) { cumulative += theme.weight; if (roll < cumulative) { return theme; } } return ROPE; // Fallback } }