Files
TiedUp-/src/main/java/com/tiedup/remake/entities/KidnapperItemSelector.java
NotEvil 099cd0d984 feat(D-01/D): V1 cleanup — delete 28 files, ~5400 lines removed
D1: ThreadLocal alert suppression moved from ItemCollar to CollarHelper.
    onCollarRemoved() logic (kidnapper alert) moved to CollarHelper.

D2+D3: Deleted 17 V1 item classes + 4 V1-only interfaces:
  ItemBind, ItemGag, ItemBlindfold, ItemCollar, ItemEarplugs, ItemMittens,
  ItemColor, ItemClassicCollar, ItemShockCollar, ItemShockCollarAuto,
  ItemGpsCollar, ItemChokeCollar, ItemHood, ItemMedicalGag,
  IBondageItem, IHasGaggingEffect, IHasBlindingEffect, IAdjustable

D4: KidnapperTheme/KidnapperItemSelector/DispenserBehaviors migrated
    from variant enums to string-based DataDrivenItemRegistry IDs.

D5: Deleted 11 variant enums + Generic* factories + ItemBallGag3D:
  BindVariant, GagVariant, BlindfoldVariant, EarplugsVariant, MittensVariant,
  GenericBind, GenericGag, GenericBlindfold, GenericEarplugs, GenericMittens

D6: ModItems cleaned — all V1 bondage registrations removed.
D7: ModCreativeTabs rewritten — iterates DataDrivenItemRegistry.
D8+D9: All V2 helpers cleaned (V1 fallbacks removed), orphan imports removed.

Zero V1 bondage code references remain (only Javadoc comments).
All bondage items are now data-driven via 47 JSON definitions.
2026-04-15 01:55:16 +02:00

255 lines
8.2 KiB
Java

package com.tiedup.remake.entities;
import com.tiedup.remake.items.base.*;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem;
import java.util.Random;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.Nullable;
/**
* Helper class for selecting themed items for kidnappers.
* Handles probability-based item selection and color application.
*
* All bondage items are now created via DataDrivenBondageItem.createStack().
*
* Item selection order (most to least common):
* 1. Bind (arms) - 100% (always)
* 2. Gag - 50%
* 3. Mittens - 40%
* 4. Earplugs - 30%
* 5. Blindfold - 20% (last, most restrictive)
*
* Elite kidnappers get significant bonuses to all probabilities.
*/
public class KidnapperItemSelector {
private static final Random RANDOM = new Random();
/** NBT key for item color */
public static final String NBT_ITEM_COLOR = "ItemColor";
// === BASE PROBABILITIES (Regular Kidnapper) ===
public static final double PROB_BIND = 1.0; // 100%
public static final double PROB_GAG = 0.5; // 50%
public static final double PROB_MITTENS = 0.4; // 40%
public static final double PROB_EARPLUGS = 0.3; // 30%
public static final double PROB_BLINDFOLD = 0.2; // 20%
// === ELITE KIDNAPPER BONUSES ===
public static final double ELITE_GAG_BONUS = 0.5; // +50% = 100%
public static final double ELITE_MITTENS_BONUS = 0.4; // +40% = 80%
public static final double ELITE_EARPLUGS_BONUS = 0.3; // +30% = 60%
public static final double ELITE_BLINDFOLD_BONUS = 0.2; // +20% = 40%
// === ARCHER KIDNAPPER PENALTIES (relies on arrows) ===
public static final double ARCHER_GAG_PENALTY = 0.2; // -20% = 30%
public static final double ARCHER_MITTENS_PENALTY = 0.2; // -20% = 20%
public static final double ARCHER_EARPLUGS_PENALTY = 0.15; // -15% = 15%
public static final double ARCHER_BLINDFOLD_PENALTY = 0.1; // -10% = 10%
/**
* Result of item selection for a kidnapper.
* Contains theme, color, and all selected items.
*/
public static class SelectionResult {
public final KidnapperTheme theme;
public final ItemColor color; // null if theme doesn't support colors
public final ItemStack bind;
public final ItemStack gag;
public final ItemStack mittens;
public final ItemStack earplugs;
public final ItemStack blindfold;
public SelectionResult(
KidnapperTheme theme,
ItemColor color,
ItemStack bind,
ItemStack gag,
ItemStack mittens,
ItemStack earplugs,
ItemStack blindfold
) {
this.theme = theme;
this.color = color;
this.bind = bind;
this.gag = gag;
this.mittens = mittens;
this.earplugs = earplugs;
this.blindfold = blindfold;
}
public boolean hasGag() { return !gag.isEmpty(); }
public boolean hasMittens() { return !mittens.isEmpty(); }
public boolean hasEarplugs() { return !earplugs.isEmpty(); }
public boolean hasBlindfold() { return !blindfold.isEmpty(); }
}
/**
* Select items for a regular kidnapper.
*/
public static SelectionResult selectForKidnapper() {
return selectItems(false, false);
}
/**
* Select items for an elite kidnapper (higher probabilities).
*/
public static SelectionResult selectForEliteKidnapper() {
return selectItems(true, false);
}
/**
* Select items for an archer kidnapper (lower probabilities - relies on arrows).
*/
public static SelectionResult selectForArcherKidnapper() {
return selectItems(false, true);
}
private static double getAdjustedProbability(
double baseProb,
double eliteBonus,
double archerPenalty,
boolean isElite,
boolean isArcher
) {
double prob = baseProb;
if (isElite) prob += eliteBonus;
if (isArcher) prob -= archerPenalty;
return prob;
}
private static SelectionResult selectItems(
boolean isElite,
boolean isArcher
) {
// 1. Select random theme
KidnapperTheme theme = KidnapperTheme.getRandomWeighted();
// 2. Select color (if theme supports it)
ItemColor color = theme.supportsColor()
? ItemColor.getRandomStandard()
: null;
// 3. Create bind (always)
ItemStack bind = createItemById(theme.getBindId(), color);
// 4. Roll for gag
ItemStack gag = ItemStack.EMPTY;
double gagProb = getAdjustedProbability(
PROB_GAG, ELITE_GAG_BONUS, ARCHER_GAG_PENALTY, isElite, isArcher
);
if (RANDOM.nextDouble() < gagProb) {
gag = createItemById(theme.getRandomGagId(), color);
}
// 5. Roll for mittens
ItemStack mittens = ItemStack.EMPTY;
double mittensProb = getAdjustedProbability(
PROB_MITTENS, ELITE_MITTENS_BONUS, ARCHER_MITTENS_PENALTY, isElite, isArcher
);
if (RANDOM.nextDouble() < mittensProb) {
mittens = createMittens();
}
// 6. Roll for earplugs
ItemStack earplugs = ItemStack.EMPTY;
double earplugsProb = getAdjustedProbability(
PROB_EARPLUGS, ELITE_EARPLUGS_BONUS, ARCHER_EARPLUGS_PENALTY, isElite, isArcher
);
if (RANDOM.nextDouble() < earplugsProb) {
earplugs = createEarplugs();
}
// 7. Roll for blindfold
ItemStack blindfold = ItemStack.EMPTY;
double blindfoldProb = getAdjustedProbability(
PROB_BLINDFOLD, ELITE_BLINDFOLD_BONUS, ARCHER_BLINDFOLD_PENALTY, isElite, isArcher
);
if (theme.hasBlindfolds() && RANDOM.nextDouble() < blindfoldProb) {
blindfold = createItemById(theme.getRandomBlindfoldId(), color);
}
return new SelectionResult(
theme, color, bind, gag, mittens, earplugs, blindfold
);
}
// ITEM CREATION METHODS
/**
* Create a data-driven bondage item by registry name, with optional color.
*/
public static ItemStack createItemById(String id, @Nullable ItemColor color) {
ItemStack stack = DataDrivenBondageItem.createStack(
new ResourceLocation("tiedup", id)
);
if (color != null) {
applyColor(stack, color);
}
return stack;
}
/**
* Create mittens ItemStack.
*/
public static ItemStack createMittens() {
return DataDrivenBondageItem.createStack(
new ResourceLocation("tiedup", "leather_mittens")
);
}
/**
* Create earplugs ItemStack.
*/
public static ItemStack createEarplugs() {
return DataDrivenBondageItem.createStack(
new ResourceLocation("tiedup", "classic_earplugs")
);
}
// COLOR METHODS
/** NBT key for CustomModelData (used for model overrides) */
public static final String NBT_CUSTOM_MODEL_DATA = "CustomModelData";
/**
* Apply color NBT to an ItemStack.
*/
public static void applyColor(ItemStack stack, ItemColor color) {
if (stack.isEmpty() || color == null) return;
CompoundTag tag = stack.getOrCreateTag();
tag.putString(NBT_ITEM_COLOR, color.getName());
tag.putInt(NBT_CUSTOM_MODEL_DATA, color.getModelId());
}
/**
* Get color from an ItemStack.
* @return The color, or null if no color is set
*/
@Nullable
public static ItemColor getColor(ItemStack stack) {
if (stack.isEmpty()) return null;
CompoundTag tag = stack.getTag();
if (tag == null || !tag.contains(NBT_ITEM_COLOR)) return null;
return ItemColor.fromName(tag.getString(NBT_ITEM_COLOR));
}
/**
* Check if an ItemStack has a color applied.
*/
public static boolean hasColor(ItemStack stack) {
return getColor(stack) != null;
}
/**
* Get the texture suffix for an item's color.
*/
public static String getColorSuffix(ItemStack stack) {
ItemColor color = getColor(stack);
return color != null ? "_" + color.getName() : "";
}
}