From 543da47169cfd50b992ba9e0232445e292a91d9b Mon Sep 17 00:00:00 2001 From: MarkPLacer Date: Thu, 9 Apr 2026 02:15:52 +0200 Subject: [PATCH 1/2] fix(attributes): properly extract default attributes using vanilla DefaultAttributes --- .../snowii/extractor/extractors/Entities.kt | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/main/kotlin/de/snowii/extractor/extractors/Entities.kt b/src/main/kotlin/de/snowii/extractor/extractors/Entities.kt index e1b2971..9ae61d4 100644 --- a/src/main/kotlin/de/snowii/extractor/extractors/Entities.kt +++ b/src/main/kotlin/de/snowii/extractor/extractors/Entities.kt @@ -34,15 +34,11 @@ class Entities : Extractor.Extractor { val entity = entityType.create(server.overworld(), EntitySpawnReason.NATURAL) if (entity != null) { - if (entity is LivingEntity) { - entityJson.addProperty("max_health", entity.maxHealth) - - if (entityName in TARGET_HURT_SOUND_ENTITIES) { - val hurtSound = getHurtSound(entity, damageSource) - val hurtSoundId = hurtSound?.let(BuiltInRegistries.SOUND_EVENT::getKey)?.path - if (hurtSoundId != null) { - entityJson.addProperty("hurt_sound", hurtSoundId) - } + if (entity is LivingEntity && entityName in TARGET_HURT_SOUND_ENTITIES) { + val hurtSound = getHurtSound(entity, damageSource) + val hurtSoundId = hurtSound?.let(BuiltInRegistries.SOUND_EVENT::getKey)?.path + if (hurtSoundId != null) { + entityJson.addProperty("hurt_sound", hurtSoundId) } } entityJson.addProperty("attackable", entity.isAttackable) @@ -50,6 +46,24 @@ class Entities : Extractor.Extractor { entityJson.addProperty("limit_per_chunk", (entity as? Mob)?.maxSpawnClusterSize ?: 0) } + if (net.minecraft.world.entity.ai.attributes.DefaultAttributes.hasSupplier(entityType)) { + val supplier = net.minecraft.world.entity.ai.attributes.DefaultAttributes.getSupplier(entityType as net.minecraft.world.entity.EntityType) + val attributesArray = JsonArray() + + for (attribute in BuiltInRegistries.ATTRIBUTE) { + val holder = BuiltInRegistries.ATTRIBUTE.wrapAsHolder(attribute) + if (supplier.hasAttribute(holder)) { + val attrObj = JsonObject() + attrObj.addProperty( + BuiltInRegistries.ATTRIBUTE.getKey(attribute)!!.toString(), + supplier.getBaseValue(holder) + ) + attributesArray.add(attrObj) + } + } + entityJson.add("attributes", attributesArray) + } + entityJson.addProperty("summonable", entityType.canSummon()) entityJson.addProperty("saveable", entityType.canSerialize()) entityJson.addProperty("fire_immune", entityType.fireImmune()) From 456e63e4a31d079c2f57471a5532b22c1bc90242 Mon Sep 17 00:00:00 2001 From: MarkPLacer Date: Thu, 9 Apr 2026 15:27:29 +0200 Subject: [PATCH 2/2] fix(attributes): restore max_health top-level field for output compatibility --- .../kotlin/de/snowii/extractor/extractors/Entities.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/de/snowii/extractor/extractors/Entities.kt b/src/main/kotlin/de/snowii/extractor/extractors/Entities.kt index 9ae61d4..4527e99 100644 --- a/src/main/kotlin/de/snowii/extractor/extractors/Entities.kt +++ b/src/main/kotlin/de/snowii/extractor/extractors/Entities.kt @@ -48,8 +48,14 @@ class Entities : Extractor.Extractor { if (net.minecraft.world.entity.ai.attributes.DefaultAttributes.hasSupplier(entityType)) { val supplier = net.minecraft.world.entity.ai.attributes.DefaultAttributes.getSupplier(entityType as net.minecraft.world.entity.EntityType) - val attributesArray = JsonArray() + // Backwards compatibility for top-level max_health + val maxHealth = net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH + if (supplier.hasAttribute(maxHealth)) { + entityJson.addProperty("max_health", supplier.getBaseValue(maxHealth)) + } + + val attributesArray = JsonArray() for (attribute in BuiltInRegistries.ATTRIBUTE) { val holder = BuiltInRegistries.ATTRIBUTE.wrapAsHolder(attribute) if (supplier.hasAttribute(holder)) {