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:
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user