Files
shacraft-core/scripts/catalog_extract.java

86 lines
4.9 KiB
Java

// Copyright Shacraft contributors. MIT OR Apache-2.0.
// Public API calls only: extract factual registries and collision measurements.
// Run by catalog_generate.py; never starts a server or accepts an EULA.
import java.nio.file.*;
import java.util.*;
import com.google.gson.*;
import net.minecraft.SharedConstants;
import net.minecraft.server.Bootstrap;
import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.attributes.DefaultAttributes;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
class catalog_extract {
static JsonArray boxes(VoxelShape shape) {
var result = new JsonArray();
for (var b : shape.toAabbs()) {
var box = new JsonArray();
for (double x : new double[]{b.minX,b.minY,b.minZ,b.maxX,b.maxY,b.maxZ}) box.add(x);
result.add(box);
}
return result;
}
static class SampleWorld implements BlockGetter {
final BlockState center, other;
SampleWorld(BlockState center, BlockState other) { this.center=center; this.other=other; }
public BlockEntity getBlockEntity(BlockPos pos) { return null; }
public BlockState getBlockState(BlockPos pos) { return pos.equals(BlockPos.ZERO)?center:other; }
public FluidState getFluidState(BlockPos pos) { return getBlockState(pos).getFluidState(); }
public int getHeight() { return 384; }
public int getMinY() { return -64; }
}
public static void main(String[] args) throws Exception {
SharedConstants.tryDetectVersion(); Bootstrap.bootStrap();
var root = new JsonObject(); var states = new JsonObject(); var entities = new JsonObject();
var air = Block.stateById(0);
var stone = BuiltInRegistries.BLOCK.getValue(net.minecraft.resources.Identifier.parse("minecraft:stone")).defaultBlockState();
int errors=0, contextual=0;
for (var block : BuiltInRegistries.BLOCK) for (var state : block.getStateDefinition().getPossibleStates()) {
var out = new JsonObject();
var world = new SampleWorld(state,air);
try {
var shape = boxes(state.getCollisionShape(world,BlockPos.ZERO,CollisionContext.empty()));
out.add("collision",shape);
boolean context = !shape.equals(boxes(state.getCollisionShape(new SampleWorld(state,stone),BlockPos.ZERO,CollisionContext.empty())))
|| !shape.equals(boxes(state.getCollisionShape(world,BlockPos.ZERO,CollisionContext.positionContext(10))))
|| !shape.equals(boxes(state.getCollisionShape(world,BlockPos.ZERO,CollisionContext.positionContext(-10))));
out.addProperty("sample_context_dependent",context); if(context)contextual++;
out.addProperty("air",state.isAir()); out.addProperty("light",state.getLightEmission());
out.addProperty("hardness",state.getDestroySpeed(world,BlockPos.ZERO));
} catch (Throwable e) { out.addProperty("error",e.toString()); errors++; }
states.add(Integer.toString(Block.getId(state)),out);
}
for(var entity : BuiltInRegistries.ENTITY_TYPE) {
var out = new JsonObject();
out.addProperty("width",entity.getWidth()); out.addProperty("height",entity.getHeight());
out.addProperty("eye_height",entity.getDimensions().eyeHeight());
out.addProperty("fixed_dimensions",entity.getDimensions().fixed());
out.addProperty("category",entity.getCategory().getName());
out.addProperty("summonable",entity.canSummon()); out.addProperty("serializable",entity.canSerialize());
out.addProperty("fire_immune",entity.fireImmune()); out.addProperty("tracking_range",entity.clientTrackingRange());
out.addProperty("update_interval",entity.updateInterval()); out.addProperty("peaceful_allowed",entity.isAllowedInPeaceful());
var attrs = new JsonObject();
if(DefaultAttributes.hasSupplier(entity)) {
var supplier = DefaultAttributes.getSupplier((EntityType)entity);
for(var holder : BuiltInRegistries.ATTRIBUTE.listElements().toList())
if(supplier.hasAttribute(holder)) attrs.addProperty(holder.unwrapKey().get().identifier().toString(),supplier.getBaseValue(holder));
}
out.add("attributes",attrs);
entities.add(EntityType.getKey(entity).toString(),out);
}
root.add("states",states); root.add("entities",entities);
root.addProperty("errors",errors); root.addProperty("context_dependent_samples",contextual);
Files.writeString(Path.of(args[0]),new GsonBuilder().create().toJson(root));
System.out.println("Extracted "+states.size()+" states, "+entities.size()+" entities, "+errors+" errors, "+contextual+" contextual sample differences");
if(errors!=0)System.exit(2);
}
}