Strip all Phase references, TODO/FUTURE roadmap notes, and internal planning comments from the codebase. Run Prettier for consistent formatting across all Java files.
246 lines
8.1 KiB
Java
246 lines
8.1 KiB
Java
package com.tiedup.remake.blocks;
|
|
|
|
import com.tiedup.remake.blocks.entity.TrappedChestBlockEntity;
|
|
import com.tiedup.remake.core.SystemMessageManager;
|
|
import com.tiedup.remake.items.base.*;
|
|
import com.tiedup.remake.state.IBondageState;
|
|
import com.tiedup.remake.util.BondageItemLoaderUtility;
|
|
import com.tiedup.remake.util.KidnappedHelper;
|
|
import java.util.List;
|
|
import java.util.function.Supplier;
|
|
import javax.annotation.Nullable;
|
|
import net.minecraft.ChatFormatting;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.network.chat.Component;
|
|
import net.minecraft.world.InteractionHand;
|
|
import net.minecraft.world.InteractionResult;
|
|
import net.minecraft.world.entity.player.Player;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.world.item.TooltipFlag;
|
|
import net.minecraft.world.level.BlockGetter;
|
|
import net.minecraft.world.level.Level;
|
|
import net.minecraft.world.level.block.ChestBlock;
|
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
|
import net.minecraft.world.level.block.entity.ChestBlockEntity;
|
|
import net.minecraft.world.level.block.state.BlockBehaviour;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.world.level.storage.loot.LootParams;
|
|
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
|
import net.minecraft.world.phys.BlockHitResult;
|
|
|
|
/**
|
|
* Trapped Chest Block - Chest that traps players when opened.
|
|
*
|
|
*
|
|
* Extends vanilla ChestBlock for proper chest behavior.
|
|
* Sneak + right-click to load bondage items.
|
|
* Normal open triggers the trap if armed.
|
|
*/
|
|
public class BlockTrappedChest extends ChestBlock implements ICanBeLoaded {
|
|
|
|
public BlockTrappedChest() {
|
|
super(BlockBehaviour.Properties.of().strength(2.5f).noOcclusion(), () ->
|
|
com.tiedup.remake.blocks.entity.ModBlockEntities.TRAPPED_CHEST.get()
|
|
);
|
|
}
|
|
|
|
// BLOCK ENTITY
|
|
|
|
@Override
|
|
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
|
return new TrappedChestBlockEntity(pos, state);
|
|
}
|
|
|
|
@Nullable
|
|
public TrappedChestBlockEntity getTrapEntity(
|
|
BlockGetter level,
|
|
BlockPos pos
|
|
) {
|
|
BlockEntity be = level.getBlockEntity(pos);
|
|
return be instanceof TrappedChestBlockEntity
|
|
? (TrappedChestBlockEntity) be
|
|
: null;
|
|
}
|
|
|
|
// INTERACTION - TRAP TRIGGER
|
|
|
|
@Override
|
|
public InteractionResult use(
|
|
BlockState state,
|
|
Level level,
|
|
BlockPos pos,
|
|
Player player,
|
|
InteractionHand hand,
|
|
BlockHitResult hit
|
|
) {
|
|
if (hand != InteractionHand.MAIN_HAND) {
|
|
return InteractionResult.PASS;
|
|
}
|
|
|
|
ItemStack heldItem = player.getItemInHand(hand);
|
|
|
|
// Check if holding a bondage item = load it (don't open chest)
|
|
if (BondageItemLoaderUtility.isLoadableBondageItem(heldItem)) {
|
|
// Server-side only
|
|
if (!level.isClientSide) {
|
|
TrappedChestBlockEntity chest = getTrapEntity(level, pos);
|
|
if (
|
|
chest != null &&
|
|
BondageItemLoaderUtility.loadItemIntoHolder(
|
|
chest,
|
|
heldItem,
|
|
player
|
|
)
|
|
) {
|
|
SystemMessageManager.sendToPlayer(
|
|
player,
|
|
"Item loaded into trap",
|
|
ChatFormatting.YELLOW
|
|
);
|
|
}
|
|
}
|
|
return InteractionResult.SUCCESS;
|
|
}
|
|
|
|
// Normal open - check for trap trigger first (server-side)
|
|
if (!level.isClientSide) {
|
|
TrappedChestBlockEntity chest = getTrapEntity(level, pos);
|
|
if (chest != null && chest.isArmed()) {
|
|
IBondageState playerState = KidnappedHelper.getKidnappedState(
|
|
player
|
|
);
|
|
if (playerState != null && !playerState.isTiedUp()) {
|
|
// Apply bondage
|
|
playerState.applyBondage(
|
|
chest.getBind(),
|
|
chest.getGag(),
|
|
chest.getBlindfold(),
|
|
chest.getEarplugs(),
|
|
chest.getCollar(),
|
|
chest.getClothes()
|
|
);
|
|
|
|
// Clear the chest trap contents
|
|
chest.setBind(ItemStack.EMPTY);
|
|
chest.setGag(ItemStack.EMPTY);
|
|
chest.setBlindfold(ItemStack.EMPTY);
|
|
chest.setEarplugs(ItemStack.EMPTY);
|
|
chest.setCollar(ItemStack.EMPTY);
|
|
chest.setClothes(ItemStack.EMPTY);
|
|
|
|
SystemMessageManager.sendToPlayer(
|
|
player,
|
|
SystemMessageManager.MessageCategory.WARNING,
|
|
"You fell into a trap!"
|
|
);
|
|
|
|
// FIX: Don't open chest GUI after trap triggers
|
|
return InteractionResult.SUCCESS;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Normal chest behavior (open GUI) - only if trap didn't trigger
|
|
return super.use(state, level, pos, player, hand, hit);
|
|
}
|
|
|
|
// DROPS WITH NBT
|
|
|
|
@Override
|
|
public List<ItemStack> getDrops(
|
|
BlockState state,
|
|
LootParams.Builder params
|
|
) {
|
|
List<ItemStack> drops = super.getDrops(state, params);
|
|
|
|
BlockEntity be = params.getOptionalParameter(
|
|
LootContextParams.BLOCK_ENTITY
|
|
);
|
|
if (be instanceof TrappedChestBlockEntity chest && chest.isArmed()) {
|
|
// Add trap data to the first drop (the chest itself)
|
|
if (!drops.isEmpty()) {
|
|
ItemStack stack = drops.get(0);
|
|
CompoundTag beTag = new CompoundTag();
|
|
chest.writeBondageData(beTag);
|
|
if (!beTag.isEmpty()) {
|
|
stack.addTagElement("BlockEntityTag", beTag);
|
|
}
|
|
}
|
|
}
|
|
|
|
return drops;
|
|
}
|
|
|
|
// TOOLTIP
|
|
|
|
@Override
|
|
public void appendHoverText(
|
|
ItemStack stack,
|
|
@Nullable BlockGetter level,
|
|
List<Component> tooltip,
|
|
TooltipFlag flag
|
|
) {
|
|
tooltip.add(
|
|
Component.translatable("block.tiedup.trapped_chest.desc").withStyle(
|
|
ChatFormatting.GRAY
|
|
)
|
|
);
|
|
|
|
CompoundTag nbt = stack.getTag();
|
|
if (nbt != null && nbt.contains("BlockEntityTag")) {
|
|
CompoundTag beTag = nbt.getCompound("BlockEntityTag");
|
|
|
|
if (
|
|
beTag.contains("bind") ||
|
|
beTag.contains("gag") ||
|
|
beTag.contains("blindfold") ||
|
|
beTag.contains("earplugs") ||
|
|
beTag.contains("collar")
|
|
) {
|
|
tooltip.add(
|
|
Component.literal("Armed").withStyle(
|
|
ChatFormatting.DARK_RED
|
|
)
|
|
);
|
|
BondageItemLoaderUtility.addItemToTooltip(
|
|
tooltip,
|
|
beTag,
|
|
"bind"
|
|
);
|
|
BondageItemLoaderUtility.addItemToTooltip(
|
|
tooltip,
|
|
beTag,
|
|
"gag"
|
|
);
|
|
BondageItemLoaderUtility.addItemToTooltip(
|
|
tooltip,
|
|
beTag,
|
|
"blindfold"
|
|
);
|
|
BondageItemLoaderUtility.addItemToTooltip(
|
|
tooltip,
|
|
beTag,
|
|
"earplugs"
|
|
);
|
|
BondageItemLoaderUtility.addItemToTooltip(
|
|
tooltip,
|
|
beTag,
|
|
"collar"
|
|
);
|
|
} else {
|
|
tooltip.add(
|
|
Component.literal("Disarmed").withStyle(
|
|
ChatFormatting.GREEN
|
|
)
|
|
);
|
|
}
|
|
} else {
|
|
tooltip.add(
|
|
Component.literal("Disarmed").withStyle(ChatFormatting.GREEN)
|
|
);
|
|
}
|
|
}
|
|
}
|