package ar.com.companeros.identity; import java.util.*; import net.minecraft.nbt.*; import net.minecraft.server.MinecraftServer; import net.minecraft.world.level.saveddata.SavedData; /** Especialización persistente; los investigadores siguen teniendo necesidades físicas. */ public final class AgentRoles extends SavedData { public enum Role { GENERALISTA, INVESTIGADOR } private final Map roles = new HashMap<>(); public static AgentRoles get(MinecraftServer server) { if (!server.isSameThread()) throw new IllegalStateException("Roles fuera del hilo servidor"); return server.overworld().getDataStorage().computeIfAbsent(AgentRoles::load, AgentRoles::new, "raps_roles"); } public Role role(UUID actor) { return roles.getOrDefault(actor, Role.GENERALISTA); } public void assign(UUID actor, Role role) { Objects.requireNonNull(actor); Objects.requireNonNull(role); if (!roles.containsKey(actor) && roles.size() >= 256) throw new IllegalStateException("Registro de roles lleno"); roles.put(actor, role); setDirty(); } // Los roles acotan proyectos; defensa, comida, movimiento y comunicación siguen disponibles. public boolean allows(UUID actor, String tool) { return role(actor) != Role.INVESTIGADOR || !Set.of("mine_block", "place_block", "craft", "store", "parasite_upgrade_apply", "parasite_appearance").contains(tool); } @Override public CompoundTag save(CompoundTag tag) { tag.putInt("Schema", 1); ListTag entries = new ListTag(); roles.forEach((id, role) -> { CompoundTag row = new CompoundTag(); row.putUUID("Agent", id); row.putString("Role", role.name()); entries.add(row); }); tag.put("Entries", entries); return tag; } public static AgentRoles load(CompoundTag tag) { if (tag.getInt("Schema") != 1) throw new IllegalStateException("Formato de roles desconocido"); AgentRoles result = new AgentRoles(); ListTag rows = tag.getList("Entries", Tag.TAG_COMPOUND); if (rows.size() > 256) throw new IllegalStateException("Registro de roles demasiado grande"); for (Tag item : rows) { CompoundTag row = (CompoundTag)item; if (result.roles.putIfAbsent(row.getUUID("Agent"), Role.valueOf(row.getString("Role"))) != null) throw new IllegalStateException("Rol duplicado"); } return result; } }