package com.tiedup.remake.blocks; import com.tiedup.remake.blocks.entity.KidnapBombBlockEntity; import com.tiedup.remake.core.SystemMessageManager; import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.entities.EntityKidnapBomb; import com.tiedup.remake.util.BondageItemLoaderUtility; import java.util.List; 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.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.SoundType; import net.minecraft.world.level.block.TntBlock; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.level.storage.loot.LootParams; import net.minecraft.world.level.storage.loot.parameters.LootContextParams; import net.minecraft.world.phys.BlockHitResult; /** * Kidnap Bomb Block - TNT that applies bondage on explosion. * * * Features: * - TNT-like block that can be ignited * - Stores bondage items via BlockEntity * - On explosion, applies items to entities in radius (no block damage) * - Can be loaded by right-clicking with bondage items * * Based on original BlockKidnapBomb from 1.12.2 */ public class BlockKidnapBomb extends TntBlock implements EntityBlock, ICanBeLoaded { public BlockKidnapBomb() { super( BlockBehaviour.Properties.of() .strength(0.0f) .sound(SoundType.GRASS) .ignitedByLava() ); } // BLOCK ENTITY @Nullable @Override public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new KidnapBombBlockEntity(pos, state); } @Nullable public KidnapBombBlockEntity getBombEntity( BlockGetter level, BlockPos pos ) { BlockEntity be = level.getBlockEntity(pos); return be instanceof KidnapBombBlockEntity ? (KidnapBombBlockEntity) be : null; } // EXPLOSION HANDLING @Override public void onCaughtFire( BlockState state, Level level, BlockPos pos, @Nullable net.minecraft.core.Direction face, @Nullable LivingEntity igniter ) { if (!level.isClientSide) { KidnapBombBlockEntity bombTile = getBombEntity(level, pos); explode(level, pos, bombTile, igniter); } } /** * Spawn the primed kidnap bomb entity. */ public void explode( Level level, BlockPos pos, @Nullable KidnapBombBlockEntity bombTile, @Nullable LivingEntity igniter ) { if (!level.isClientSide) { EntityKidnapBomb entity = new EntityKidnapBomb( level, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, igniter, bombTile ); level.addFreshEntity(entity); level.playSound( null, entity.getX(), entity.getY(), entity.getZ(), SoundEvents.TNT_PRIMED, SoundSource.BLOCKS, 1.0f, 1.0f ); level.gameEvent(igniter, GameEvent.PRIME_FUSE, pos); TiedUpMod.LOGGER.info( "[BlockKidnapBomb] Bomb primed at {} by {}", pos, igniter != null ? igniter.getName().getString() : "unknown" ); } } // LOADING ITEMS @Override public InteractionResult use( BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit ) { ItemStack heldItem = player.getItemInHand(hand); // First check if it's flint and steel (default TNT behavior) if ( heldItem.is(Items.FLINT_AND_STEEL) || heldItem.is(Items.FIRE_CHARGE) ) { return super.use(state, level, pos, player, hand, hit); } if (hand != InteractionHand.MAIN_HAND) { return InteractionResult.PASS; } if (heldItem.isEmpty()) { return InteractionResult.PASS; } // Check if it's a bondage item if (!BondageItemLoaderUtility.isLoadableBondageItem(heldItem)) { return InteractionResult.PASS; } // Server-side only if (level.isClientSide) { return InteractionResult.SUCCESS; } KidnapBombBlockEntity bomb = getBombEntity(level, pos); if (bomb == null) { return InteractionResult.PASS; } // Try to load the held item into the appropriate slot if ( BondageItemLoaderUtility.loadItemIntoHolder(bomb, heldItem, player) ) { SystemMessageManager.sendToPlayer( player, "Item loaded into bomb", ChatFormatting.YELLOW ); return InteractionResult.SUCCESS; } return InteractionResult.PASS; } // DROPS WITH NBT @Override public List getDrops( BlockState state, LootParams.Builder params ) { BlockEntity be = params.getOptionalParameter( LootContextParams.BLOCK_ENTITY ); ItemStack stack = new ItemStack(this); if (be instanceof KidnapBombBlockEntity bomb) { CompoundTag beTag = new CompoundTag(); bomb.writeBondageData(beTag); if (!beTag.isEmpty()) { stack.addTagElement("BlockEntityTag", beTag); } } return List.of(stack); } // TOOLTIP @Override public void appendHoverText( ItemStack stack, @Nullable BlockGetter level, List tooltip, TooltipFlag flag ) { tooltip.add( Component.translatable("block.tiedup.kidnap_bomb.desc").withStyle( ChatFormatting.GRAY ) ); CompoundTag nbt = stack.getTag(); if (nbt != null && nbt.contains("BlockEntityTag")) { CompoundTag beTag = nbt.getCompound("BlockEntityTag"); // Check if loaded with any items if ( beTag.contains("bind") || beTag.contains("gag") || beTag.contains("blindfold") || beTag.contains("earplugs") || beTag.contains("collar") ) { tooltip.add( Component.literal("Loaded:").withStyle( ChatFormatting.YELLOW ) ); // List loaded items 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" ); BondageItemLoaderUtility.addItemToTooltip( tooltip, beTag, "clothes" ); } else { tooltip.add( Component.literal("Empty").withStyle(ChatFormatting.GREEN) ); } } else { tooltip.add( Component.literal("Empty").withStyle(ChatFormatting.GREEN) ); } } }