extractor: extract entities

This commit is contained in:
Alexander Medvedev 2024-12-26 22:10:12 +01:00
parent a0339728c7
commit 29ed502aea
8 changed files with 147 additions and 110 deletions

1
assets/entities.json Normal file

File diff suppressed because one or more lines are too long

View File

@ -11,4 +11,4 @@ kotlin_loader_version=1.13.0+kotlin.2.1.0
mod_version=1.0-SNAPSHOT mod_version=1.0-SNAPSHOT
maven_group=de.snowii maven_group=de.snowii
archives_base_name=extractor archives_base_name=extractor
fabric_version=0.112.1+1.21.4 fabric_version=0.113.0+1.21.4

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

5
extractor/gradlew vendored
View File

@ -86,8 +86,7 @@ done
# shellcheck disable=SC2034 # shellcheck disable=SC2034
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum
@ -203,7 +202,7 @@ fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' DEFAULT_JVM_OPTS='-Dfile.encoding=UTF-8 "-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command: # Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,

View File

@ -36,7 +36,7 @@ set APP_HOME=%DIRNAME%
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" set DEFAULT_JVM_OPTS=-Dfile.encoding=UTF-8 "-Xmx64m" "-Xms64m"
@rem Find java.exe @rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome if defined JAVA_HOME goto findJavaFromJavaHome

View File

@ -1,6 +1,5 @@
package de.snowii.extractor package de.snowii.extractor
import com.google.gson.Gson
import com.google.gson.GsonBuilder import com.google.gson.GsonBuilder
import com.google.gson.JsonElement import com.google.gson.JsonElement
import de.snowii.extractor.extractors.* import de.snowii.extractor.extractors.*
@ -31,6 +30,7 @@ class Extractor : ModInitializer {
Packets(), Packets(),
Screens(), Screens(),
Tags(), Tags(),
Entities(),
Items(), Items(),
Blocks(), Blocks(),
Tests(), Tests(),

View File

@ -0,0 +1,42 @@
package de.snowii.extractor.extractors
import com.google.gson.JsonArray
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import de.snowii.extractor.Extractor
import net.minecraft.entity.LivingEntity
import net.minecraft.entity.SpawnReason
import net.minecraft.registry.Registries
import net.minecraft.server.MinecraftServer
class Entities : Extractor.Extractor {
override fun fileName(): String {
return "entities.json"
}
override fun extract(server: MinecraftServer): JsonElement {
val entitiesJson = JsonObject()
for (entityType in Registries.ENTITY_TYPE) {
val entity = entityType.create(server.overworld!!, SpawnReason.NATURAL) ?: continue
val entityJson = JsonObject()
entityJson.addProperty("id", Registries.ENTITY_TYPE.getRawId(entityType))
if (entity is LivingEntity) {
entityJson.addProperty("max_health", entity.maxHealth)
}
entityJson.addProperty("attackable", entity.isAttackable)
entityJson.addProperty("summonable", entityType.isSummonable)
entityJson.addProperty("fire_immune", entityType.isFireImmune)
val dimension = JsonArray()
dimension.add(entityType.dimensions.width)
dimension.add(entityType.dimensions.height)
entityJson.add("dimension", dimension)
entitiesJson.add(
Registries.ENTITY_TYPE.getId(entityType).path, entityJson
)
}
return entitiesJson
}
}

View File

@ -1,8 +1,5 @@
package de.snowii.extractor.extractors package de.snowii.extractor.extractors
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.JsonArray import com.google.gson.JsonArray
import com.google.gson.JsonElement import com.google.gson.JsonElement
import de.snowii.extractor.Extractor import de.snowii.extractor.Extractor
@ -11,49 +8,42 @@ import net.minecraft.block.BlockState
import net.minecraft.block.Blocks import net.minecraft.block.Blocks
import net.minecraft.registry.BuiltinRegistries import net.minecraft.registry.BuiltinRegistries
import net.minecraft.registry.RegistryKeys import net.minecraft.registry.RegistryKeys
import net.minecraft.registry.RegistryWrapper
import net.minecraft.registry.RegistryWrapper.WrapperLookup
import net.minecraft.registry.entry.RegistryEntry.Reference
import net.minecraft.server.MinecraftServer import net.minecraft.server.MinecraftServer
import net.minecraft.util.math.noise.DoublePerlinNoiseSampler.NoiseParameters
import net.minecraft.util.math.ChunkPos import net.minecraft.util.math.ChunkPos
import net.minecraft.world.gen.chunk.AquiferSampler import net.minecraft.world.gen.chunk.*
import net.minecraft.world.gen.chunk.Blender import net.minecraft.world.gen.densityfunction.DensityFunction.EachApplier
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings import net.minecraft.world.gen.densityfunction.DensityFunction.NoisePos
import net.minecraft.world.gen.chunk.ChunkNoiseSampler
import net.minecraft.world.gen.chunk.GenerationShapeConfig
import net.minecraft.world.gen.densityfunction.DensityFunction.NoisePos;
import net.minecraft.world.gen.densityfunction.DensityFunction.EachApplier;
import net.minecraft.world.gen.densityfunction.DensityFunctionTypes import net.minecraft.world.gen.densityfunction.DensityFunctionTypes
import net.minecraft.world.gen.noise.NoiseConfig import net.minecraft.world.gen.noise.NoiseConfig
import java.lang.reflect.Method
import java.util.Arrays
import kotlin.reflect.full.createType
import kotlin.reflect.full.declaredFunctions
import kotlin.reflect.jvm.javaMethod
import kotlin.reflect.KFunction import kotlin.reflect.KFunction
import kotlin.reflect.full.declaredFunctions
class Tests : Extractor.Extractor { class Tests : Extractor.Extractor {
override fun fileName(): String = "chunk.json" override fun fileName(): String = "chunk.json"
private fun createFluidLevelSampler(settings: ChunkGeneratorSettings): AquiferSampler.FluidLevelSampler { private fun createFluidLevelSampler(settings: ChunkGeneratorSettings): AquiferSampler.FluidLevelSampler {
val fluidLevel = AquiferSampler.FluidLevel(-54, Blocks.LAVA.getDefaultState()); val fluidLevel = AquiferSampler.FluidLevel(-54, Blocks.LAVA.defaultState)
val i = settings.seaLevel(); val i = settings.seaLevel()
val fluidLevel2 = AquiferSampler.FluidLevel(i, settings.defaultFluid()); val fluidLevel2 = AquiferSampler.FluidLevel(i, settings.defaultFluid())
return AquiferSampler.FluidLevelSampler {_, y, _ -> if (y < Math.min(-54, i)) fluidLevel else fluidLevel2}; return AquiferSampler.FluidLevelSampler { _, y, _ -> if (y < Math.min(-54, i)) fluidLevel else fluidLevel2 }
} }
private fun get_index(config: GenerationShapeConfig, x: Int, y: Int, z: Int): Int { private fun get_index(config: GenerationShapeConfig, x: Int, y: Int, z: Int): Int {
if (x < 0 || y < 0 || z < 0) { if (x < 0 || y < 0 || z < 0) {
System.err.println("Bad local pos"); System.err.println("Bad local pos")
System.exit(1); System.exit(1)
} }
return config.height() * 16 * x + 16 * y + z return config.height() * 16 * x + 16 * y + z
} }
// This is basically just what NoiseChunkGenerator is doing // This is basically just what NoiseChunkGenerator is doing
private fun populate_noise(start_x: Int, start_z: Int, sampler: ChunkNoiseSampler, config: GenerationShapeConfig, settings: ChunkGeneratorSettings): IntArray? { private fun populate_noise(
start_x: Int,
start_z: Int,
sampler: ChunkNoiseSampler,
config: GenerationShapeConfig,
settings: ChunkGeneratorSettings
): IntArray? {
val result = IntArray(16 * 16 * config.height()) val result = IntArray(16 * 16 * config.height())
for (method: KFunction<*> in sampler::class.declaredFunctions) { for (method: KFunction<*> in sampler::class.declaredFunctions) {
@ -104,8 +94,8 @@ class Tests : Extractor.Extractor {
return result return result
} }
} }
System.err.println("No valid method found for block state sampler!"); System.err.println("No valid method found for block state sampler!")
return null; return null
} }
// Dumps a chunk to an array of block state ids // Dumps a chunk to an array of block state ids
@ -124,13 +114,18 @@ class Tests : Extractor.Extractor {
// Overworld shape config // Overworld shape config
val shape = GenerationShapeConfig(-64, 384, 1, 2) val shape = GenerationShapeConfig(-64, 384, 1, 2)
val test_sampler = ChunkNoiseSampler(16 / shape.horizontalCellBlockCount(), config, chunk_pos.startX, chunk_pos.startZ, val test_sampler =
ChunkNoiseSampler(
16 / shape.horizontalCellBlockCount(), config, chunk_pos.startX, chunk_pos.startZ,
shape, object : DensityFunctionTypes.Beardifying { shape, object : DensityFunctionTypes.Beardifying {
override fun maxValue(): Double = 0.0 override fun maxValue(): Double = 0.0
override fun minValue(): Double = 0.0 override fun minValue(): Double = 0.0
override fun sample(pos: NoisePos): Double = 0.0 override fun sample(pos: NoisePos): Double = 0.0
override fun fill(densities: DoubleArray, applier: EachApplier) {densities.fill(0.0)} override fun fill(densities: DoubleArray, applier: EachApplier) {
}, settings, createFluidLevelSampler(settings), Blender.getNoBlending()) densities.fill(0.0)
}
}, settings, createFluidLevelSampler(settings), Blender.getNoBlending()
)
val data = populate_noise(chunk_pos.startX, chunk_pos.startZ, test_sampler, shape, settings) val data = populate_noise(chunk_pos.startX, chunk_pos.startZ, test_sampler, shape, settings)
data?.forEach { state -> data?.forEach { state ->