Volver al índice
src/main/java/ar/com/companeros/Shelter.java
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<BlockPos> blueprint(BlockPos home) {
List<BlockPos> 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;
}
}
}
}