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,243 @@
package com.tiedup.remake.events.captivity;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.v2.BodyRegionV2;
import com.tiedup.remake.entities.LeashProxyEntity;
import com.tiedup.remake.items.base.ItemCollar;
import com.tiedup.remake.state.IPlayerLeashAccess;
import com.tiedup.remake.state.IBondageState;
import com.tiedup.remake.state.PlayerBindState;
import com.tiedup.remake.util.KidnappedHelper;
import com.tiedup.remake.core.SettingsAccessor;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
/**
* Event handler for master-slave (enslavement) interactions.
*
* <h2>Key Mechanisms</h2>
* <ul>
* <li><b>Enslavement:</b> Right-click with Lead on tied player → enslaves them</li>
* <li><b>Freeing:</b> Right-click with empty hand on your slave → frees them</li>
* </ul>
*
* <h2>Leash System</h2>
* Uses a proxy-based leash system where a {@link LeashProxyEntity} follows the player
* and holds the leash. The player does NOT mount anything - traction is applied via push().
*
* @see PlayerBindState#free()
* @see LeashProxyEntity
* @see IPlayerLeashAccess
*/
@Mod.EventBusSubscriber(modid = TiedUpMod.MOD_ID)
public class PlayerEnslavementHandler {
/**
* Prevent enslaved players from attacking/breaking their constraints.
* Handles Left-Click (Attack) events.
*/
@SubscribeEvent
public static void onPlayerAttackEntity(
net.minecraftforge.event.entity.player.AttackEntityEvent event
) {
Player player = event.getEntity();
Entity target = event.getTarget();
// Check if player is leashed (enslaved) via proxy system
if (
player instanceof IPlayerLeashAccess access &&
access.tiedup$isLeashed()
) {
// Prevent breaking the LeashKnot or the LeashProxy itself
if (
target instanceof
net.minecraft.world.entity.decoration.LeashFenceKnotEntity ||
target instanceof LeashProxyEntity
) {
event.setCanceled(true);
}
}
}
/**
* Handle player interactions with other players for enslavement/freeing.
*
* Uses IBondageState for condition checks (isEnslavable)
* Note: Enslavement system (getEnslavedBy, free) remains PlayerBindState-specific
*/
@SubscribeEvent
public static void onPlayerInteractEntity(
PlayerInteractEvent.EntityInteract event
) {
Player master = event.getEntity();
Entity target = event.getTarget();
// 1. Prevention Logic: Slaves cannot interact with leash knots or proxies
if (
master instanceof IPlayerLeashAccess access &&
access.tiedup$isLeashed()
) {
if (
target instanceof
net.minecraft.world.entity.decoration.LeashFenceKnotEntity ||
target instanceof LeashProxyEntity
) {
event.setCanceled(true);
return;
}
}
// Only handle player-to-player interactions for enslavement logic
if (!(target instanceof Player)) {
return;
}
Player slave = (Player) target;
// Server-side only
if (master.level().isClientSide) {
return;
}
// Only handle MAIN_HAND to avoid double processing
if (event.getHand() != net.minecraft.world.InteractionHand.MAIN_HAND) {
return;
}
// Check if enslavement is enabled
if (!SettingsAccessor.isEnslavementEnabled(master.level().getGameRules())) {
return;
}
// Get IBondageState for condition checks
IBondageState slaveKidnappedState = KidnappedHelper.getKidnappedState(
slave
);
if (slaveKidnappedState == null) {
return;
}
// Get PlayerBindState for enslavement operations (Player-only system)
PlayerBindState masterState = PlayerBindState.getInstance(master);
PlayerBindState slaveState = PlayerBindState.getInstance(slave);
if (masterState == null || slaveState == null) {
return;
}
ItemStack heldItem = master.getItemInHand(event.getHand());
// ========================================
// Scenario 1: Enslavement with Lead
// ========================================
if (heldItem.is(Items.LEAD)) {
// Check if target is enslavable (using IBondageState)
if (!slaveKidnappedState.isEnslavable()) {
// Exception: collar owner can capture even if not tied
boolean canCapture = false;
if (slaveKidnappedState.hasCollar()) {
ItemStack collar = slaveKidnappedState.getEquipment(BodyRegionV2.NECK);
if (collar.getItem() instanceof ItemCollar collarItem) {
if (
collarItem
.getOwners(collar)
.contains(master.getUUID())
) {
canCapture = true;
}
}
}
if (!canCapture) {
TiedUpMod.LOGGER.debug(
"[PlayerEnslavementHandler] {} cannot be enslaved - not tied and not collar owner",
slave.getName().getString()
);
return;
}
}
// Phase 17: Check if not already captured (Player-specific check)
if (slaveState.isCaptive()) {
TiedUpMod.LOGGER.debug(
"[PlayerEnslavementHandler] {} is already captured",
slave.getName().getString()
);
return;
}
// Attempt capture
boolean success = slaveState.getCapturedBy(
masterState.getCaptorManager()
);
if (success) {
heldItem.shrink(1);
TiedUpMod.LOGGER.info(
"[PlayerEnslavementHandler] {} enslaved {} (lead consumed)",
master.getName().getString(),
slave.getName().getString()
);
event.setCanceled(true);
} else {
TiedUpMod.LOGGER.warn(
"[PlayerEnslavementHandler] Failed to enslave {} by {}",
slave.getName().getString(),
master.getName().getString()
);
}
}
// ========================================
// Scenario 2: Freeing with Empty Hand
// ========================================
else if (heldItem.isEmpty()) {
// Phase 17: isSlave → isCaptive
if (!slaveState.isCaptive()) return;
// Phase 17: getMaster → getCaptor, getSlaveHolderManager → getCaptorManager
if (slaveState.getCaptor() != masterState.getCaptorManager()) {
TiedUpMod.LOGGER.debug(
"[PlayerEnslavementHandler] {} tried to free {} but is not the captor",
master.getName().getString(),
slave.getName().getString()
);
return;
}
slaveState.free();
TiedUpMod.LOGGER.info(
"[PlayerEnslavementHandler] {} freed {}",
master.getName().getString(),
slave.getName().getString()
);
event.setCanceled(true);
}
}
/**
* Periodic check for enslaved players.
*
* Phase 14.1.5: Remains PlayerBindState-specific (enslavement system is Player-only)
*/
@SubscribeEvent
public static void onPlayerTick(TickEvent.PlayerTickEvent event) {
if (event.phase != TickEvent.Phase.END) return;
Player player = event.player;
if (player.level().isClientSide) return;
if (player.tickCount % 20 != 0) return;
PlayerBindState state = PlayerBindState.getInstance(player);
if (state == null) return;
// Phase 17: isSlave → isCaptive, checkStillSlave → checkStillCaptive
if (state.isCaptive()) {
state.checkStillCaptive();
}
// Phase 17: getSlaveHolderManager → getCaptorManager, cleanupInvalidSlaves → cleanupInvalidCaptives
state.getCaptorManager().cleanupInvalidCaptives();
}
}