package ar.com.companeros; import java.util.ArrayList; import java.util.List; import net.minecraft.core.BlockPos; import net.minecraft.tags.ItemTags; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.Blocks; /** Refugio 5×5: paredes de tres bloques, techo, entrada y mesa de trabajo. */ public final class Shelter { private Shelter() { } public static List blueprint(BlockPos home) { List positions = new ArrayList<>(); for (int y = 0; y < 3; y++) for (int z = -2; z <= 2; z++) for (int x = -2; x <= 2; x++) { if (Math.abs(x) != 2 && Math.abs(z) != 2) continue; if (x == 0 && z == -2 && y < 2) continue; positions.add(home.offset(x, y, z)); } for (int z = -2; z <= 2; z++) for (int x = -2; x <= 2; x++) positions.add(home.offset(x, 3, z)); positions.add(home.offset(0, 0, -2)); return positions; } public static boolean clearSite(Companion bot, BlockPos home) { for (BlockPos pos : BlockPos.betweenClosed(home.offset(-2, 0, -2), home.offset(2, 3, 2))) { if (!bot.serverLevel().hasChunkAt(pos) || !bot.level().getBlockState(pos).isAir() || WorkArea.get(bot.serverLevel()).contains(pos)) return false; } for (int x = -2; x <= 2; x++) for (int z = -2; z <= 2; z++) { BlockPos floor = home.offset(x, -1, z); if (!bot.level().getBlockState(floor).isCollisionShapeFullBlock(bot.level(), floor)) return false; } return true; } public static boolean complete(Companion bot) { return bot.shelterStep >= blueprint(bot.home).size(); } public static void step(Companion bot) { var plan = blueprint(bot.home); if (bot.shelterStep >= plan.size()) { bot.activity = "Campamento listo"; return; } BlockPos pos = plan.get(bot.shelterStep); boolean door = bot.shelterStep == plan.size() - 1; var state = bot.level().getBlockState(pos); if (!state.isAir()) { // Sólo acepta su pared previamente construida. Una intervención humana pausa la obra. if ((state.is(net.minecraft.tags.BlockTags.PLANKS) || door && state.is(net.minecraft.tags.BlockTags.WOODEN_DOORS)) && !WorkArea.get(bot.serverLevel()).contains(pos)) bot.shelterStep++; else { bot.building = false; bot.activity = "Campamento ocupado"; } return; } if (bot.position().distanceToSqr(net.minecraft.world.phys.Vec3.atCenterOf(bot.home)) > 2.6) { bot.getNavigation().moveTo(bot.home.getX() + .5, bot.home.getY(), bot.home.getZ() + .5, 1); return; } for (int i = 0; i < bot.bag.getContainerSize(); i++) { ItemStack stack = bot.bag.getItem(i); if (stack.is(door ? ItemTags.WOODEN_DOORS : ItemTags.PLANKS)) { if (WorldActions.place(bot, pos, stack)) bot.shelterStep++; else { bot.building = false; bot.activity = "Construcción detenida"; } return; } } } }