Clean repo for open source release

Remove build artifacts, dev tool configs, unused dependencies,
and third-party source dumps. Add proper README, update .gitignore,
clean up Makefile.
This commit is contained in:
NotEvil
2026-04-12 00:51:22 +02:00
parent 2e7a1d403b
commit f6466360b6
1947 changed files with 238025 additions and 1 deletions

View File

@@ -0,0 +1,429 @@
package com.tiedup.remake.state.components;
import com.tiedup.remake.v2.bondage.IV2BondageItem;
import com.tiedup.remake.items.base.ILockable;
import com.tiedup.remake.items.base.ItemBind;
import com.tiedup.remake.items.base.ItemCollar;
import com.tiedup.remake.state.hosts.IPlayerBindStateHost;
import com.tiedup.remake.v2.BodyRegionV2;
import com.tiedup.remake.v2.bondage.IV2BondageEquipment;
import com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper;
import java.util.function.Supplier;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
/**
* Component responsible for bondage equipment management.
* Handles putting on, taking off, and replacing all bondage items.
*
* Single Responsibility: Equipment lifecycle management
* Complexity: MEDIUM (V2 equipment coupling)
* Risk: MEDIUM (core equipment system)
*
* Epic 5F: Uses V2EquipmentHelper.
* Uses low-level setInRegion for equips because V1 items (IBondageItem) do not
* implement IV2BondageItem, so V2EquipmentHelper.equipItem() would reject them.
*/
public class PlayerEquipment {
private final IPlayerBindStateHost host;
public PlayerEquipment(IPlayerBindStateHost host) {
this.host = host;
}
// ========== Put On Methods ==========
/** Equips a bind item and applies speed reduction. */
public void putBindOn(ItemStack bind) {
equipInRegion(BodyRegionV2.ARMS, bind);
}
/** Equips a gag (enables gag talk if implemented). Issue #14 fix: now calls onEquipped. */
public void putGagOn(ItemStack gag) {
equipInRegion(BodyRegionV2.MOUTH, gag);
}
/** Equips a blindfold (restricts vision). Issue #14 fix: now calls onEquipped. */
public void putBlindfoldOn(ItemStack blindfold) {
equipInRegion(BodyRegionV2.EYES, blindfold);
}
/** Equips a collar (starts GPS/Shock monitoring). Issue #14 fix: now calls onEquipped. */
public void putCollarOn(ItemStack collar) {
equipInRegion(BodyRegionV2.NECK, collar);
}
/** Issue #14 fix: now calls onEquipped. Syncs clothes config to all clients. */
public void putClothesOn(ItemStack clothes) {
equipInRegion(BodyRegionV2.TORSO, clothes);
// Sync clothes config (dynamic textures, etc.) to all tracking clients
host.syncClothesConfig();
}
/** Equips mittens (blocks hand interactions). Phase 14.4: Mittens system. Issue #14 fix: now calls onEquipped. */
public void putMittensOn(ItemStack mittens) {
equipInRegion(BodyRegionV2.HANDS, mittens);
checkMittensAfterApply();
}
/** Equips earplugs (muffles sounds). Issue #14 fix: now calls onEquipped. */
public void putEarplugsOn(ItemStack earplugs) {
equipInRegion(BodyRegionV2.EARS, earplugs);
checkEarplugsAfterApply();
}
// ========== Take Off Methods ==========
/** Removes binds and restores speed. */
public ItemStack takeBindOff() {
return V2EquipmentHelper.unequipFromRegion(host.getPlayer(), BodyRegionV2.ARMS);
}
public ItemStack takeGagOff() {
return V2EquipmentHelper.unequipFromRegion(host.getPlayer(), BodyRegionV2.MOUTH);
}
public ItemStack takeBlindfoldOff() {
return V2EquipmentHelper.unequipFromRegion(host.getPlayer(), BodyRegionV2.EYES);
}
public ItemStack takeCollarOff() {
return V2EquipmentHelper.unequipFromRegion(host.getPlayer(), BodyRegionV2.NECK);
}
/** Removes mittens. Phase 14.4: Mittens system */
public ItemStack takeMittensOff() {
ItemStack mittens = V2EquipmentHelper.getInRegion(host.getPlayer(), BodyRegionV2.HANDS);
if (isLocked(mittens, false)) {
return ItemStack.EMPTY;
}
return V2EquipmentHelper.unequipFromRegion(host.getPlayer(), BodyRegionV2.HANDS);
}
public ItemStack takeEarplugsOff() {
ItemStack earplugs = V2EquipmentHelper.getInRegion(host.getPlayer(), BodyRegionV2.EARS);
if (isLocked(earplugs, false)) {
return ItemStack.EMPTY;
}
return V2EquipmentHelper.unequipFromRegion(host.getPlayer(), BodyRegionV2.EARS);
}
public ItemStack takeClothesOff() {
ItemStack clothes = V2EquipmentHelper.unequipFromRegion(host.getPlayer(), BodyRegionV2.TORSO);
// Sync clothes removal to all tracking clients
host.syncClothesConfig();
return clothes;
}
/**
* Tries to remove the collar. Fails if locked unless forced.
*/
public ItemStack takeCollarOff(boolean force) {
Player player = host.getPlayer();
ItemStack collar = V2EquipmentHelper.getInRegion(player, BodyRegionV2.NECK);
if (collar.isEmpty()) return ItemStack.EMPTY;
if (collar.getItem() instanceof ItemCollar collarItem) {
if (!force && collarItem.isLocked(collar)) return ItemStack.EMPTY;
collarItem.setLocked(collar, false);
}
return V2EquipmentHelper.unequipFromRegion(player, BodyRegionV2.NECK);
}
// ========== Replacement Methods ==========
/** Replaces the blindfold and returns the old one. Issue #14 fix: now calls lifecycle hooks. */
public ItemStack replaceBlindfold(ItemStack newBlindfold) {
ItemStack current = V2EquipmentHelper.getInRegion(host.getPlayer(), BodyRegionV2.EYES);
if (current.isEmpty()) return ItemStack.EMPTY;
return replaceInRegion(BodyRegionV2.EYES, newBlindfold);
}
/** Replaces the gag and returns the old one. Issue #14 fix: now calls lifecycle hooks. */
public ItemStack replaceGag(ItemStack newGag) {
ItemStack current = V2EquipmentHelper.getInRegion(host.getPlayer(), BodyRegionV2.MOUTH);
if (current.isEmpty()) return ItemStack.EMPTY;
return replaceInRegion(BodyRegionV2.MOUTH, newGag);
}
/** Replaces the collar and returns the old one. Issue #14 fix: now calls lifecycle hooks. */
public ItemStack replaceCollar(ItemStack newCollar) {
ItemStack current = V2EquipmentHelper.getInRegion(host.getPlayer(), BodyRegionV2.NECK);
if (current.isEmpty()) return ItemStack.EMPTY;
return replaceInRegion(BodyRegionV2.NECK, newCollar);
}
/**
* Thread Safety: Synchronized to prevent inventory tearing (gap between remove and add).
*/
public synchronized ItemStack replaceBind(ItemStack newBind) {
ItemStack old = takeBindOff();
if (!old.isEmpty()) {
putBindOn(newBind);
}
return old;
}
/**
* Thread Safety: Synchronized to prevent inventory tearing (gap between remove and add).
*/
public synchronized ItemStack replaceBind(
ItemStack newBind,
boolean force
) {
// Safety: Don't remove current bind if newBind is empty
if (newBind.isEmpty()) {
return ItemStack.EMPTY;
}
ItemStack current = V2EquipmentHelper.getInRegion(host.getPlayer(), BodyRegionV2.ARMS);
if (isLocked(current, force)) {
return ItemStack.EMPTY;
}
ItemStack old = takeBindOff();
if (!old.isEmpty()) {
putBindOn(newBind);
}
return old;
}
public ItemStack replaceGag(ItemStack newGag, boolean force) {
ItemStack current = V2EquipmentHelper.getInRegion(host.getPlayer(), BodyRegionV2.MOUTH);
if (isLocked(current, force)) {
return ItemStack.EMPTY;
}
ItemStack old = V2EquipmentHelper.unequipFromRegion(host.getPlayer(), BodyRegionV2.MOUTH);
putGagOn(newGag);
return old;
}
public ItemStack replaceBlindfold(ItemStack newBlindfold, boolean force) {
ItemStack current = V2EquipmentHelper.getInRegion(host.getPlayer(), BodyRegionV2.EYES);
if (isLocked(current, force)) {
return ItemStack.EMPTY;
}
ItemStack old = V2EquipmentHelper.unequipFromRegion(host.getPlayer(), BodyRegionV2.EYES);
putBlindfoldOn(newBlindfold);
return old;
}
public ItemStack replaceCollar(ItemStack newCollar, boolean force) {
ItemStack current = V2EquipmentHelper.getInRegion(host.getPlayer(), BodyRegionV2.NECK);
if (isLocked(current, force)) {
return ItemStack.EMPTY;
}
ItemStack old = takeCollarOff(force);
putCollarOn(newCollar);
return old;
}
public ItemStack replaceEarplugs(ItemStack newEarplugs) {
return replaceEarplugs(newEarplugs, false);
}
public ItemStack replaceEarplugs(ItemStack newEarplugs, boolean force) {
ItemStack current = V2EquipmentHelper.getInRegion(host.getPlayer(), BodyRegionV2.EARS);
if (isLocked(current, force)) {
return ItemStack.EMPTY;
}
ItemStack old = takeEarplugsOff();
putEarplugsOn(newEarplugs);
return old;
}
public ItemStack replaceMittens(ItemStack newMittens) {
return replaceMittens(newMittens, false);
}
public ItemStack replaceMittens(ItemStack newMittens, boolean force) {
ItemStack current = V2EquipmentHelper.getInRegion(host.getPlayer(), BodyRegionV2.HANDS);
if (isLocked(current, force)) {
return ItemStack.EMPTY;
}
ItemStack old = takeMittensOff();
if (!old.isEmpty() || !hasMittens()) {
putMittensOn(newMittens);
}
return old;
}
// ========== Resistance Methods ==========
/**
* Phase 14.1.7: Now part of IRestrainable interface
*/
public synchronized int getCurrentBindResistance() {
Player player = host.getPlayer();
ItemStack stack = V2EquipmentHelper.getInRegion(player, BodyRegionV2.ARMS);
if (
stack.isEmpty() || !(stack.getItem() instanceof ItemBind bind)
) return 0;
return bind.getCurrentResistance(stack, player);
}
/**
* Phase 14.1.7: Now part of IRestrainable interface
*/
public synchronized void setCurrentBindResistance(int resistance) {
Player player = host.getPlayer();
ItemStack stack = V2EquipmentHelper.getInRegion(player, BodyRegionV2.ARMS);
if (
stack.isEmpty() || !(stack.getItem() instanceof ItemBind bind)
) return;
bind.setCurrentResistance(stack, resistance);
}
/**
* Phase 14.1.7: Added for IRestrainable interface
*/
public synchronized int getCurrentCollarResistance() {
Player player = host.getPlayer();
ItemStack stack = V2EquipmentHelper.getInRegion(player, BodyRegionV2.NECK);
if (
stack.isEmpty() || !(stack.getItem() instanceof ItemCollar collar)
) return 0;
return collar.getCurrentResistance(stack, player);
}
/**
* Phase 14.1.7: Added for IRestrainable interface
*/
public synchronized void setCurrentCollarResistance(int resistance) {
Player player = host.getPlayer();
ItemStack stack = V2EquipmentHelper.getInRegion(player, BodyRegionV2.NECK);
if (
stack.isEmpty() || !(stack.getItem() instanceof ItemCollar collar)
) return;
collar.setCurrentResistance(stack, resistance);
}
// ========== Helper Methods ==========
/** Helper to drop an item at the kidnapped player's feet. */
public void kidnappedDropItem(ItemStack stack) {
if (stack.isEmpty() || host.getPlayer() == null) return;
host.getPlayer().drop(stack, false);
}
/**
* Helper to take a bondage item if it's unlocked, and drop it.
*/
public void takeBondageItemIfUnlocked(
ItemStack item,
Supplier<ItemStack> takeOffMethod
) {
if (isLocked(item, false)) {
return; // Item is locked, cannot remove
}
ItemStack removed = takeOffMethod.get();
if (!removed.isEmpty()) {
kidnappedDropItem(removed);
}
}
/**
* Check if an item is locked.
* @param stack The item to check
* @param force If true, returns false (bypasses lock)
* @return true if locked and not forced
*/
public boolean isLocked(ItemStack stack, boolean force) {
if (force) return false;
if (stack.isEmpty()) return false;
if (stack.getItem() instanceof ILockable lockable) {
return lockable.isLocked(stack);
}
return false;
}
private boolean hasMittens() {
return V2EquipmentHelper.isRegionOccupied(host.getPlayer(), BodyRegionV2.HANDS);
}
// ========== Low-level V2 equipment operations ==========
/**
* Low-level equip: writes to V2 capability, calls IBondageItem lifecycle hooks, syncs.
* Uses setInRegion directly because V1 items do not implement IV2BondageItem.
*/
private void equipInRegion(BodyRegionV2 region, ItemStack stack) {
Player player = host.getPlayer();
if (player == null || player.level().isClientSide) return;
if (stack.isEmpty()) return;
IV2BondageEquipment equip = V2EquipmentHelper.getEquipment(player);
if (equip == null) return;
// Check if already occupied
if (equip.isRegionOccupied(region)) return;
// Check canEquip via V1 IBondageItem interface
if (stack.getItem() instanceof IV2BondageItem bondageItem) {
if (!bondageItem.canEquip(stack, player)) return;
}
equip.setInRegion(region, stack.copy());
// Fire lifecycle hook
if (stack.getItem() instanceof IV2BondageItem bondageItem) {
bondageItem.onEquipped(stack, player);
}
V2EquipmentHelper.sync(player);
}
/**
* Low-level replace: unequips old item with lifecycle hooks, equips new item.
* Unequips old item (with onUnequipped hook), sets new item, fires onEquipped.
*/
private ItemStack replaceInRegion(BodyRegionV2 region, ItemStack newStack) {
Player player = host.getPlayer();
if (player == null || player.level().isClientSide) return ItemStack.EMPTY;
IV2BondageEquipment equip = V2EquipmentHelper.getEquipment(player);
if (equip == null) return ItemStack.EMPTY;
ItemStack oldStack = equip.getInRegion(region);
// Call onUnequipped for the old item
if (!oldStack.isEmpty() && oldStack.getItem() instanceof IV2BondageItem oldItem) {
oldItem.onUnequipped(oldStack, player);
}
// Set the new item
equip.setInRegion(region, newStack.copy());
// Call onEquipped for the new item
if (!newStack.isEmpty() && newStack.getItem() instanceof IV2BondageItem newItem) {
newItem.onEquipped(newStack, player);
}
V2EquipmentHelper.sync(player);
return oldStack;
}
// ========== Callbacks ==========
public void checkGagAfterApply() {
// Gag talk handled via ChatEventHandler + GagTalkManager (event-based)
// No initialization needed here - effects apply automatically on chat
}
public void checkBlindfoldAfterApply() {
// Effects applied client-side via rendering
}
public void checkEarplugsAfterApply() {
// Effects applied client-side via sound system
}
public void checkCollarAfterApply() {
// Collar timers/GPS handled elsewhere
}
public void checkMittensAfterApply() {
// Mittens effects handled elsewhere
}
}