Files
TiedUp-/src/main/java/com/tiedup/remake/entities/KidnapperTheme.java
NotEvil dfa7024e21 fix(D-01/D): blindfold ID mismatch + dispenser V2 registration (review)
KidnapperTheme: fix "mask_blindfold" → "blindfold_mask" across 8 themes.
The incorrect ID produced ghost items with no definition.

DispenserBehaviors: register GenericBondageDispenseBehavior.forAnyDataDriven()
for the V2 DATA_DRIVEN_ITEM singleton. Dispatches by region from the stack's
definition. V1 per-variant registrations were deleted but V2 replacement
was missing.
2026-04-15 02:10:25 +02:00

266 lines
6.1 KiB
Java

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
}
}