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,460 @@
package com.tiedup.remake.compat.mca;
import com.tiedup.remake.compat.mca.ai.MCABondageAIController;
import com.tiedup.remake.compat.mca.ai.MCABondageAILevel;
import com.tiedup.remake.compat.mca.dialogue.MCADialogueManager;
import com.tiedup.remake.compat.mca.personality.MCAMoodManager;
import com.tiedup.remake.compat.mca.personality.MCAPersonality;
import com.tiedup.remake.compat.mca.personality.MCAPersonalityManager;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.state.IRestrainable;
import java.util.Map;
import java.util.WeakHashMap;
import org.jetbrains.annotations.Nullable;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
/**
* Central coordinator for all MCA-TiedUp integration.
*
* Responsibilities:
* - Manages AI state for tied MCA villagers
* - Coordinates sync operations
* - Provides unified API for bondage operations
* - Handles capture/release lifecycle
*
* This is the main entry point for all MCA bondage operations.
* Other code should go through this manager rather than directly
* manipulating capabilities or AI.
*/
public class MCABondageManager {
// Singleton instance
private static final MCABondageManager INSTANCE = new MCABondageManager();
// Track AI controllers for villagers (weak ref to avoid memory leaks)
private final Map<LivingEntity, MCABondageAIController> aiControllers =
new WeakHashMap<>();
private MCABondageManager() {
// Private constructor for singleton
}
/**
* Get the singleton instance.
*/
public static MCABondageManager getInstance() {
return INSTANCE;
}
// ========================================
// LIFECYCLE EVENTS
// ========================================
/** Dialogue broadcast radius in blocks */
private static final double DIALOGUE_RADIUS = 16.0;
/**
* Called when MCA villager is tied up.
* Initializes or updates AI control and syncs state.
*
* @param villager The MCA villager entity
* @param bind The bind item being applied
*/
public void onVillagerTied(LivingEntity villager, ItemStack bind) {
if (!MCACompat.isMCAVillager(villager)) return;
MCAPersonality personality =
MCAPersonalityManager.getInstance().getPersonality(villager);
TiedUpMod.LOGGER.debug(
"[MCA Manager] Villager tied: {} with {} (personality: {})",
villager.getName().getString(),
bind.getItem().getClass().getSimpleName(),
personality.getMcaId()
);
// Update AI level with personality
MCABondageAIController controller = getOrCreateAIController(villager);
controller.setPersonality(personality);
controller.updateAILevel();
// Mood change
MCAMoodManager.getInstance().onTied(villager);
// Dialogue
String dialogue = MCADialogueManager.getBeingTiedDialogue(villager);
MCADialogueManager.broadcastDialogue(
villager,
dialogue,
DIALOGUE_RADIUS
);
// Sync to clients
syncBondageState(villager);
}
/**
* Called when MCA villager is untied.
* Updates AI control and syncs state.
*
* @param villager The MCA villager entity
*/
public void onVillagerUntied(LivingEntity villager) {
if (!MCACompat.isMCAVillager(villager)) return;
TiedUpMod.LOGGER.debug(
"[MCA Manager] Villager untied: {}",
villager.getName().getString()
);
// Update AI level (may restore normal behavior)
MCABondageAIController controller = aiControllers.get(villager);
if (controller != null) {
controller.updateAILevel();
// If fully free, cleanup controller
if (controller.getCurrentLevel() == MCABondageAILevel.NONE) {
controller.cleanup();
aiControllers.remove(villager);
}
}
// Sync to clients
syncBondageState(villager);
}
/**
* Called when MCA villager is captured (leashed to a captor).
*
* @param villager The MCA villager entity
* @param captor The entity capturing the villager
*/
public void onVillagerCaptured(LivingEntity villager, Entity captor) {
if (!MCACompat.isMCAVillager(villager)) return;
TiedUpMod.LOGGER.debug(
"[MCA Manager] Villager captured: {} by {}",
villager.getName().getString(),
captor.getName().getString()
);
// Update AI to include follow behavior
MCABondageAIController controller = getOrCreateAIController(villager);
controller.updateAILevel();
// Sync to clients
syncBondageState(villager);
}
/**
* Called when MCA villager is freed from capture.
*
* @param villager The MCA villager entity
*/
public void onVillagerFreed(LivingEntity villager) {
if (!MCACompat.isMCAVillager(villager)) return;
TiedUpMod.LOGGER.debug(
"[MCA Manager] Villager freed: {}",
villager.getName().getString()
);
// Update AI level
MCABondageAIController controller = aiControllers.get(villager);
if (controller != null) {
controller.updateAILevel();
}
// Mood change (happy to be freed, usually)
MCAMoodManager.getInstance().onFreed(villager);
// Dialogue
String dialogue = MCADialogueManager.getFreedDialogue(villager);
MCADialogueManager.broadcastDialogue(
villager,
dialogue,
DIALOGUE_RADIUS
);
// Sync to clients
syncBondageState(villager);
}
/**
* Called when collar is added/removed.
*
* @param villager The MCA villager entity
* @param hasCollar Whether the villager now has a collar
*/
public void onCollarChanged(LivingEntity villager, boolean hasCollar) {
if (!MCACompat.isMCAVillager(villager)) return;
TiedUpMod.LOGGER.debug(
"[MCA Manager] Collar changed for {}: {}",
villager.getName().getString(),
hasCollar ? "added" : "removed"
);
// Update AI level
MCABondageAIController controller = getOrCreateAIController(villager);
controller.updateAILevel();
// Mood and dialogue
if (hasCollar) {
MCAMoodManager.getInstance().onCollared(villager);
String dialogue = MCADialogueManager.getCollarPutOnDialogue(
villager
);
MCADialogueManager.broadcastDialogue(
villager,
dialogue,
DIALOGUE_RADIUS
);
} else {
MCAMoodManager.getInstance().onCollarRemoved(villager);
}
// Sync to clients
syncBondageState(villager);
}
/**
* Called when gag state changes.
*
* @param villager The MCA villager entity
* @param isGagged Whether the villager is now gagged
*/
public void onGagChanged(LivingEntity villager, boolean isGagged) {
if (!MCACompat.isMCAVillager(villager)) return;
// Update AI level (gagged+blindfolded = OVERRIDE)
MCABondageAIController controller = aiControllers.get(villager);
if (controller != null) {
controller.updateAILevel();
}
// Mood change
if (isGagged) {
MCAMoodManager.getInstance().onGagged(villager);
}
// Sync to clients
syncBondageState(villager);
}
/**
* Called when blindfold state changes.
*
* @param villager The MCA villager entity
* @param isBlindfolded Whether the villager is now blindfolded
*/
public void onBlindfoldChanged(
LivingEntity villager,
boolean isBlindfolded
) {
if (!MCACompat.isMCAVillager(villager)) return;
// Update AI level (gagged+blindfolded = OVERRIDE)
MCABondageAIController controller = aiControllers.get(villager);
if (controller != null) {
controller.updateAILevel();
}
// Mood change
if (isBlindfolded) {
MCAMoodManager.getInstance().onBlindfolded(villager);
}
// Sync to clients
syncBondageState(villager);
}
/**
* Called when any sensory restriction changes (gag/blindfold).
* Legacy method for compatibility.
*
* @param villager The MCA villager entity
*/
public void onSensoryRestrictionChanged(LivingEntity villager) {
if (!MCACompat.isMCAVillager(villager)) return;
// Update AI level (gagged+blindfolded = OVERRIDE)
MCABondageAIController controller = aiControllers.get(villager);
if (controller != null) {
controller.updateAILevel();
}
// Sync to clients
syncBondageState(villager);
}
// ========================================
// AI CONTROL
// ========================================
/**
* Get or create AI controller for villager.
*
* @param villager The MCA villager entity
* @return The AI controller (never null for valid MCA villagers)
*/
public MCABondageAIController getOrCreateAIController(
LivingEntity villager
) {
return aiControllers.computeIfAbsent(
villager,
MCABondageAIController::new
);
}
/**
* Get AI controller for villager if it exists.
*
* @param villager The MCA villager entity
* @return The AI controller, or null if none exists
*/
@Nullable
public MCABondageAIController getAIController(LivingEntity villager) {
return aiControllers.get(villager);
}
/**
* Get current AI level for villager.
*
* @param villager The MCA villager entity
* @return The AI level (NONE if no controller exists)
*/
public MCABondageAILevel getAILevel(LivingEntity villager) {
MCABondageAIController controller = aiControllers.get(villager);
return controller != null
? controller.getCurrentLevel()
: MCABondageAILevel.NONE;
}
/**
* Force a specific AI level (for debugging/commands).
*
* @param villager The MCA villager entity
* @param level The AI level to set
*/
public void setAILevel(LivingEntity villager, MCABondageAILevel level) {
MCABondageAIController controller = getOrCreateAIController(villager);
controller.setLevel(level);
}
/**
* Check if villager should have restricted AI.
*
* @param villager The MCA villager entity
* @return true if AI is restricted in any way
*/
public boolean shouldRestrictAI(LivingEntity villager) {
return getAILevel(villager) != MCABondageAILevel.NONE;
}
// ========================================
// SYNC
// ========================================
/**
* Sync all bondage state to tracking clients.
* Delegates to MCANetworkHandler.
*
* @param villager The MCA villager entity
*/
public void syncBondageState(LivingEntity villager) {
if (villager.level().isClientSide()) return;
if (!MCACompat.isMCAVillager(villager)) return;
villager
.getCapability(MCACompat.MCA_KIDNAPPED)
.ifPresent(cap -> {
com.tiedup.remake.compat.mca.network.MCANetworkHandler.syncBondageState(
villager,
cap
);
});
}
/**
* Sync bondage state to a specific player.
* Used when player starts tracking the villager.
*
* @param villager The MCA villager entity
* @param tracker The player to sync to
*/
public void syncBondageStateTo(
LivingEntity villager,
net.minecraft.server.level.ServerPlayer tracker
) {
if (villager.level().isClientSide()) return;
if (!MCACompat.isMCAVillager(villager)) return;
villager
.getCapability(MCACompat.MCA_KIDNAPPED)
.ifPresent(cap -> {
com.tiedup.remake.compat.mca.network.MCANetworkHandler.syncBondageStateTo(
villager,
cap,
tracker
);
});
}
// ========================================
// QUERIES
// ========================================
/**
* Get IRestrainable adapter for MCA villager.
* Convenience method that delegates to MCACompat.
*
* @param villager The MCA villager entity
* @return IRestrainable adapter, or null if not an MCA villager
*/
@Nullable
public IRestrainable getKidnappedState(LivingEntity villager) {
return MCACompat.getKidnappedState(villager);
}
/**
* Check if entity is a managed MCA villager.
*
* @param entity The entity to check
* @return true if this entity is tracked by the manager
*/
public boolean isManaged(Entity entity) {
if (!(entity instanceof LivingEntity living)) return false;
return aiControllers.containsKey(living);
}
// ========================================
// CLEANUP
// ========================================
/**
* Remove all tracking for a villager.
* Called when villager dies or is removed.
*
* @param villager The MCA villager entity
*/
public void removeVillager(LivingEntity villager) {
MCABondageAIController controller = aiControllers.remove(villager);
if (controller != null) {
controller.cleanup();
}
}
/**
* Clear all tracking data.
* Called on world unload.
*/
public void clearAll() {
for (MCABondageAIController controller : aiControllers.values()) {
controller.cleanup();
}
aiControllers.clear();
}
}