Phase 1 (state): PlayerBindState, PlayerCaptorManager, PlayerEquipment, PlayerDataRetrieval, PlayerLifecycle, PlayerShockCollar, StruggleAccessory Phase 2 (client): AnimationTickHandler, NpcAnimationTickHandler, 5 render handlers, DamselModel, 3 client mixins, SelfBondageInputHandler, SlaveManagementScreen, ActionPanel, SlaveEntryWidget, ModKeybindings Phase 3 (entities): 28 entity/AI files migrated to CollarHelper, BindModeHelper, PoseTypeHelper, createStack() Phase 4 (network): PacketSlaveAction, PacketMasterEquip, PacketAssignCellToCollar, PacketNpcCommand, PacketFurnitureForcemount Phase 5 (events): RestraintTaskTickHandler, PetPlayRestrictionHandler, PlayerEnslavementHandler, ChatEventHandler, LaborAttackPunishmentHandler Phase 6 (commands): BondageSubCommand, CollarCommand, NPCCommand, KidnapSetCommand Phase 7 (compat): MCAKidnappedAdapter, MCA mixins Phase 8 (misc): GagTalkManager, PetRequestManager, HangingCagePiece, BondageItemBlockEntity, TrappedChestBlockEntity, DispenserBehaviors, BondageItemLoaderUtility, RestraintApplicator, StruggleSessionManager, MovementStyleResolver, CampLifecycleManager Some files retain dual V1/V2 checks (instanceof V1 || V2Helper) for coexistence — V1-only branches removed in Branch D.
86 lines
3.1 KiB
Java
86 lines
3.1 KiB
Java
package com.tiedup.remake.events.camp;
|
|
|
|
import com.tiedup.remake.cells.CampLifecycleManager;
|
|
import com.tiedup.remake.core.TiedUpMod;
|
|
import com.tiedup.remake.entities.EntityMaid;
|
|
import com.tiedup.remake.entities.EntitySlaveTrader;
|
|
import com.tiedup.remake.v2.bondage.BindModeHelper;
|
|
import java.util.UUID;
|
|
import net.minecraft.ChatFormatting;
|
|
import net.minecraft.network.chat.Component;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.world.entity.Entity;
|
|
import net.minecraft.world.entity.player.Player;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
|
import net.minecraftforge.eventbus.api.EventPriority;
|
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
import net.minecraftforge.fml.common.Mod;
|
|
|
|
/**
|
|
* Protects camp NPCs (Trader and Maid) from being captured by players.
|
|
* When a player attempts to restrain a camp NPC:
|
|
* 1. The attempt is cancelled
|
|
* 2. The entire camp (trader, maid, all kidnappers) is alerted to attack
|
|
* 3. The player receives a warning message
|
|
*/
|
|
@Mod.EventBusSubscriber(modid = TiedUpMod.MOD_ID)
|
|
public class CampNpcProtectionHandler {
|
|
|
|
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
|
public static void onPlayerInteractEntity(
|
|
PlayerInteractEvent.EntityInteract event
|
|
) {
|
|
Player player = event.getEntity();
|
|
Entity target = event.getTarget();
|
|
|
|
// Server-side only
|
|
if (player.level().isClientSide) return;
|
|
if (!(player.level() instanceof ServerLevel serverLevel)) return;
|
|
|
|
// Check if player is holding restraint item
|
|
ItemStack heldItem = player.getItemInHand(event.getHand());
|
|
if (!BindModeHelper.isBindItem(heldItem)) return;
|
|
|
|
// Check if target is trader or maid with active camp
|
|
UUID campId = null;
|
|
boolean isTrader = false;
|
|
|
|
if (target instanceof EntitySlaveTrader trader) {
|
|
if (trader.isTiedUp()) return; // Already captured
|
|
campId = trader.getCampUUID();
|
|
isTrader = true;
|
|
} else if (target instanceof EntityMaid maid) {
|
|
if (maid.isTiedUp() || maid.isFreed()) return; // Already captured or freed
|
|
campId = maid.getCampUUID();
|
|
isTrader = false;
|
|
} else {
|
|
return; // Not a protected NPC
|
|
}
|
|
|
|
if (campId == null) return; // No active camp
|
|
|
|
// CANCEL THE ATTEMPT
|
|
event.setCanceled(true);
|
|
|
|
// ALERT THE CAMP
|
|
CampLifecycleManager.alertCampToDefend(campId, player, serverLevel);
|
|
|
|
// Log the attempt
|
|
TiedUpMod.LOGGER.warn(
|
|
"[CampNpcProtection] {} attempted to restrain {} - camp alerted!",
|
|
player.getName().getString(),
|
|
isTrader ? "trader" : "maid"
|
|
);
|
|
|
|
// Send warning message to player
|
|
player.sendSystemMessage(
|
|
Component.literal(
|
|
isTrader
|
|
? "The camp defends their leader! You are now under attack!"
|
|
: "The camp defends their servant! You are now under attack!"
|
|
).withStyle(ChatFormatting.RED, ChatFormatting.BOLD)
|
|
);
|
|
}
|
|
}
|