added ender armour, need to polish thing and give the ingot an item model - disabled at eagerLoad for now

This commit is contained in:
2026-07-12 00:04:56 +01:00
parent fe04526040
commit e58470c0cc
23 changed files with 291 additions and 153 deletions
@@ -0,0 +1,32 @@
{
"parent": "minecraft:recipes/root",
"criteria": {
"has_addition": {
"conditions": {
"items": [
{
"items": "minecraft:wither_skeleton_skull"
}
]
},
"trigger": "minecraft:inventory_changed"
},
"has_the_recipe": {
"conditions": {
"recipe": "fantasysmp:witherite_shield"
},
"trigger": "minecraft:recipe_unlocked"
}
},
"requirements": [
[
"has_the_recipe",
"has_addition"
]
],
"rewards": {
"recipes": [
"fantasysmp:witherite_shield"
]
}
}
@@ -0,0 +1,37 @@
{
"parent": "minecraft:recipes/root",
"criteria": {
"has_ingredient": {
"conditions": {
"items": [
{
"items": [
"minecraft:shulker_shell",
"fantasysmp:dragon_scale",
"minecraft:dragon_breath",
"minecraft:chorus_fruit"
]
}
]
},
"trigger": "minecraft:inventory_changed"
},
"has_the_recipe": {
"conditions": {
"recipe": "fantasysmp:dragonite_ingot"
},
"trigger": "minecraft:recipe_unlocked"
}
},
"requirements": [
[
"has_the_recipe",
"has_ingredient"
]
],
"rewards": {
"recipes": [
"fantasysmp:dragonite_ingot"
]
}
}
@@ -0,0 +1,18 @@
{
"type": "minecraft:crafting_shaped",
"category": "misc",
"key": {
"B": "minecraft:dragon_breath",
"C": "minecraft:chorus_fruit",
"S": "minecraft:shulker_shell",
"X": "fantasysmp:dragon_scale"
},
"pattern": [
"SBS",
"CXC",
"SBS"
],
"result": {
"id": "fantasysmp:dragonite_ingot"
}
}
@@ -1,9 +1,9 @@
{ {
"type": "minecraft:smithing_transform", "type": "minecraft:smithing_transform",
"template": "minecraft:netherite_upgrade_smithing_template",
"base": "minecraft:shield",
"addition": "minecraft:wither_skeleton_skull", "addition": "minecraft:wither_skeleton_skull",
"base": "minecraft:shield",
"result": { "result": {
"id": "fantasysmp:witherite_shield" "id": "fantasysmp:witherite_shield"
} },
} "template": "minecraft:netherite_upgrade_smithing_template"
}
-16
View File
@@ -3,17 +3,13 @@ package dev.zxq5
import dev.zxq5.items.template.GenericItemSet import dev.zxq5.items.template.GenericItemSet
import dev.zxq5.items.template.ItemTagAdder import dev.zxq5.items.template.ItemTagAdder
import dev.zxq5.items.ModItems import dev.zxq5.items.ModItems
import dev.zxq5.items.sets.Witherite
//import dev.zxq5.items.sets.Witherite
import net.fabricmc.api.ModInitializer import net.fabricmc.api.ModInitializer
import net.fabricmc.fabric.api.datagen.v1.FabricPackOutput import net.fabricmc.fabric.api.datagen.v1.FabricPackOutput
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagsProvider import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagsProvider
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents
import net.minecraft.core.HolderLookup import net.minecraft.core.HolderLookup
import net.minecraft.data.recipes.RecipeOutput import net.minecraft.data.recipes.RecipeOutput
import net.minecraft.data.recipes.RecipeProvider import net.minecraft.data.recipes.RecipeProvider
import net.minecraft.world.effect.MobEffects
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletableFuture
@@ -25,18 +21,6 @@ object Fantasysmp : ModInitializer {
override fun onInitialize() { override fun onInitialize() {
logger.info("Hello Fabric world!") logger.info("Hello Fabric world!")
ModItems.onLoad(); ModItems.onLoad();
// Register the group.
registerItemEffects()
}
private fun registerItemEffects() {
ServerTickEvents.END_SERVER_TICK.register { server ->
for (player in server.playerList.players) {
if (Witherite.fullSetEquippedBy(player)) {
player.removeEffect(MobEffects.WITHER)
}
}
}
} }
} }
@@ -3,6 +3,7 @@ package dev.zxq5.items
import dev.zxq5.Fantasysmp import dev.zxq5.Fantasysmp
import dev.zxq5.items.template.GenericItemSet import dev.zxq5.items.template.GenericItemSet
import dev.zxq5.items.sets.Dragonite import dev.zxq5.items.sets.Dragonite
import dev.zxq5.items.sets.Ender
import dev.zxq5.items.sets.Witherite import dev.zxq5.items.sets.Witherite
import net.fabricmc.fabric.api.creativetab.v1.FabricCreativeModeTab import net.fabricmc.fabric.api.creativetab.v1.FabricCreativeModeTab
import net.minecraft.core.Registry import net.minecraft.core.Registry
@@ -44,6 +45,7 @@ object ModItems {
private val eagerLoad = listOf<GenericItemSet>( private val eagerLoad = listOf<GenericItemSet>(
Witherite, Witherite,
Dragonite, Dragonite,
// Ender // TODO: Enable for content drop #1
) )
fun onLoad() { fun onLoad() {
@@ -5,6 +5,7 @@ import dev.zxq5.items.template.GenericGearSet
import dev.zxq5.items.ModItems.register import dev.zxq5.items.ModItems.register
import dev.zxq5.items.template.registerItem import dev.zxq5.items.template.registerItem
import dev.zxq5.items.template.provideDelegate import dev.zxq5.items.template.provideDelegate
import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents
import net.minecraft.core.component.DataComponents import net.minecraft.core.component.DataComponents
import net.minecraft.core.particles.ParticleTypes import net.minecraft.core.particles.ParticleTypes
import net.minecraft.core.particles.PowerParticleOption import net.minecraft.core.particles.PowerParticleOption
@@ -15,6 +16,8 @@ import net.minecraft.util.Unit
import net.minecraft.world.InteractionHand import net.minecraft.world.InteractionHand
import net.minecraft.world.InteractionResult import net.minecraft.world.InteractionResult
import net.minecraft.world.damagesource.DamageSource import net.minecraft.world.damagesource.DamageSource
import net.minecraft.world.damagesource.DamageSources
import net.minecraft.world.damagesource.DamageTypes
import net.minecraft.world.entity.Entity import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.player.Player import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.Item import net.minecraft.world.item.Item
@@ -32,7 +35,7 @@ object Dragonite: GenericGearSet() {
get() = super.materialDefinition.copy(assetId = materialKey) get() = super.materialDefinition.copy(assetId = materialKey)
val SCALE by registerItem("dragon_scale", ::Item) val SCALE by registerItem("dragon_scale", ::Item)
val INGOT by registerItem("dragonite_ingot", ::Item) { val INGOT by registerItem("dragonite_ingot", ::Item) {
shapedRecipe("SBS", "CXC", "SBS", key=mapOf<Char, Item>( shapedRecipe("SBS", "CXC", "SBS", key=mapOf<Char, Item>(
'S' to Items.SHULKER_SHELL, 'S' to Items.SHULKER_SHELL,
@@ -83,7 +86,35 @@ object Dragonite: GenericGearSet() {
override val armorSet: ArmorSet = ArmorSet(HELMET, CHESTPLATE, LEGGINGS, BOOTS) override val armorSet: ArmorSet = ArmorSet(HELMET, CHESTPLATE, LEGGINGS, BOOTS)
override val items = listOf(SWORD, HELMET, CHESTPLATE, LEGGINGS, BOOTS, SCALE, INGOT) override val items = listOf(SWORD, HELMET, CHESTPLATE, LEGGINGS, BOOTS, SCALE, INGOT)
override fun onLoad() {}
private var reducingCollision: Boolean = false
private const val FALL_DAMAGE_REDUCTION = 0.5f
private const val COLLISION_DAMAGE_REDUCTION = 0.75f // 75% reduction; tune to taste
override fun onLoad() {
ServerLivingEntityEvents.ALLOW_DAMAGE.register { entity, damageSource, amount ->
if (reducingCollision) return@register true // let our own re-applied hit through untouched
if (entity !is Player) return@register true
if (!fullSetEquippedBy(entity)) return@register true
val reduced = when {
damageSource.`is`(DamageTypes.FLY_INTO_WALL) -> amount * (1f - COLLISION_DAMAGE_REDUCTION)
damageSource.`is`(DamageTypes.FALL) -> amount * (1f - COLLISION_DAMAGE_REDUCTION)
else -> return@register false
}
if (reduced > 0f) {
reducingCollision = true
try {
entity.hurtServer(entity.level() as ServerLevel, damageSource, reduced)
return@register false
} finally {
reducingCollision = false
}
}
false
}
}
} }
class DragoniteSword(properties: Properties) : Item(properties) { class DragoniteSword(properties: Properties) : Item(properties) {
@@ -111,7 +142,7 @@ class DragoniteSword(properties: Properties) : Item(properties) {
override fun getAttackDamageBonus(victim: Entity, damage: Float, damageSource: DamageSource): Float { override fun getAttackDamageBonus(victim: Entity, damage: Float, damageSource: DamageSource): Float {
val superBonus = super.getAttackDamageBonus(victim, damage, damageSource) // 0f from vanilla, but respect it anyway val superBonus = super.getAttackDamageBonus(victim, damage, damageSource) // 0f from vanilla, but respect it anyway
val attacker = damageSource.entity as? Player ?: return superBonus val attacker = damageSource.entity as? Player ?: return superBonus
if (Dragonite.fullSetEquippedBy(attacker)) return superBonus if (!Dragonite.fullSetEquippedBy(attacker)) return superBonus
if (attacker.level().isClientSide) return superBonus if (attacker.level().isClientSide) return superBonus
if (!attacker.isFallFlying) return superBonus if (!attacker.isFallFlying) return superBonus
@@ -0,0 +1,145 @@
package dev.zxq5.items.sets
import dev.zxq5.items.template.ArmorSet
import dev.zxq5.items.template.GearMaterialDef
import dev.zxq5.items.template.GenericGearSet
import dev.zxq5.items.template.provideDelegate
import dev.zxq5.items.template.registerItem
import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents
import net.minecraft.core.BlockPos
import net.minecraft.core.component.DataComponents
import net.minecraft.core.particles.ParticleTypes
import net.minecraft.server.level.ServerLevel
import net.minecraft.sounds.SoundEvents
import net.minecraft.sounds.SoundSource
import net.minecraft.world.InteractionHand
import net.minecraft.world.InteractionResult
import net.minecraft.world.damagesource.DamageTypes
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.Item
import net.minecraft.world.item.Items
import net.minecraft.world.item.ToolMaterial
import net.minecraft.world.item.component.UseCooldown
import net.minecraft.world.item.equipment.ArmorType
import net.minecraft.world.level.ClipContext
import net.minecraft.world.level.Level
import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.HitResult
import net.minecraft.world.phys.Vec3
object Ender: GenericGearSet() {
override val materialName = "ender"
override val materialDefinition
get() = GearMaterialDef.DIAMOND.copy(assetId = materialKey)
val ENDER_INGOT by registerItem("ender_ingot", ::Item) {
shapedRecipe("EDE", "DED", "EDE", key=mapOf(
'E' to Items.ENDER_EYE,
'D' to Items.DIAMOND,
))
}
val SWORD by registerItem("ender_sword", ::EnderSword) {
properties {
enchantable(armorMaterial.enchantmentValue)
.component(DataComponents.USE_COOLDOWN, UseCooldown(3f))
.sword(ToolMaterial.DIAMOND, 3F, -2.4F)
}
smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.DIAMOND_SWORD, ENDER_INGOT)
}
val HELMET by registerItem("ender_helmet", ::Item) {
properties {
humanoidArmor(armorMaterial, ArmorType.HELMET)
}
smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.DIAMOND_HELMET, ENDER_INGOT)
}
val CHESTPLATE by registerItem("ender_chestplate", ::Item) {
properties {
humanoidArmor(armorMaterial, ArmorType.CHESTPLATE)
}
smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.DIAMOND_CHESTPLATE, ENDER_INGOT)
}
val LEGGINGS by registerItem("ender_leggings", ::Item) {
properties {
humanoidArmor(armorMaterial, ArmorType.LEGGINGS)
}
smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.DIAMOND_LEGGINGS, ENDER_INGOT)
}
val BOOTS by registerItem("ender_boots", ::Item) {
properties {
humanoidArmor(armorMaterial, ArmorType.BOOTS)
}
smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.DIAMOND_BOOTS, ENDER_INGOT)
}
override val armorSet: ArmorSet = ArmorSet(HELMET, CHESTPLATE, LEGGINGS, BOOTS)
override val items = listOf(SWORD, HELMET, CHESTPLATE, LEGGINGS, BOOTS)
override fun onLoad() {
ServerLivingEntityEvents.ALLOW_DAMAGE.register { entity, damageSource, _ ->
if (entity !is Player) return@register true
if (!fullSetEquippedBy(entity)) return@register true
if (damageSource.`is`(DamageTypes.ENDER_PEARL)) return@register false
return@register true
}
}
}
class EnderSword(properties: Properties) : Item(properties) {
override fun use(level: Level, user: Player, hand: InteractionHand): InteractionResult {
if (level.isClientSide || !Ender.fullSetEquippedBy(user)) return InteractionResult.PASS
val serverLevel = level as ServerLevel
val hit = getTargetedBlock(user, 64.0)
if (hit.type != HitResult.Type.BLOCK) return InteractionResult.PASS
val state = serverLevel.getBlockState(hit.blockPos)
if (state.isAir) return InteractionResult.PASS
val landingPos = findSafeLanding(serverLevel, hit) ?: return InteractionResult.PASS // no clearance — cancel silently
val oldPos = user.position()
serverLevel.playSound(null, oldPos.x, oldPos.y, oldPos.z, SoundEvents.ENDERMAN_TELEPORT, SoundSource.PLAYERS, 1.0f, 1.0f)
serverLevel.sendParticles(ParticleTypes.PORTAL, oldPos.x, oldPos.y, oldPos.z, 100, 0.5, 1.0, 0.5, 0.0)
val destination = Vec3.atBottomCenterOf(landingPos)
user.setDeltaMovement(user.deltaMovement.x, 0.0, user.deltaMovement.z)
user.teleportTo(destination.x, destination.y, destination.z)
serverLevel.playSound(null, destination.x, destination.y, destination.z, SoundEvents.ENDERMAN_TELEPORT, SoundSource.PLAYERS, 1.0f, 1.0f)
serverLevel.sendParticles(ParticleTypes.PORTAL, destination.x, destination.y, destination.z, 100, 0.5, 1.0, 0.5, 0.0)
return InteractionResult.SUCCESS
}
}
fun getTargetedBlock(player: Player, maxDistance: Double): BlockHitResult {
val start = player.eyePosition
val end = start.add(player.lookAngle.scale(maxDistance))
return player.level().clip(ClipContext(start, end,
ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player))
}
private const val MAX_UPWARD_SEARCH = 256
fun findSafeLanding(level: Level, hit: BlockHitResult): BlockPos? {
var pos = hit.blockPos.above()
repeat(MAX_UPWARD_SEARCH) {
if (isPassable(level, pos) && isPassable(level, pos.above())) {
return pos
}
pos = pos.above()
}
return null // no safe gap found within range — caller should cancel the teleport
}
private fun isPassable(level: Level, pos: BlockPos): Boolean {
val state = level.getBlockState(pos)
return state.getCollisionShape(level, pos).isEmpty
}
@@ -4,6 +4,7 @@ import dev.zxq5.items.template.ArmorSet
import dev.zxq5.items.template.GenericGearSet import dev.zxq5.items.template.GenericGearSet
import dev.zxq5.items.template.registerItem import dev.zxq5.items.template.registerItem
import dev.zxq5.items.template.provideDelegate import dev.zxq5.items.template.provideDelegate
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents
import net.minecraft.core.component.DataComponents import net.minecraft.core.component.DataComponents
import net.minecraft.sounds.SoundEvents import net.minecraft.sounds.SoundEvents
import net.minecraft.world.InteractionHand import net.minecraft.world.InteractionHand
@@ -49,7 +50,7 @@ object Witherite: GenericGearSet() {
Optional.empty() // default disable sound Optional.empty() // default disable sound
)) ))
} }
smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.NETHERITE_SWORD, Items.WITHER_SKELETON_SKULL) smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.SHIELD, Items.WITHER_SKELETON_SKULL)
} }
val SWORD by registerItem("witherite_sword", ::WitheriteSword) { val SWORD by registerItem("witherite_sword", ::WitheriteSword) {
@@ -102,7 +103,13 @@ object Witherite: GenericGearSet() {
override val items = listOf(SWORD, AXE, SHIELD, HELMET, CHESTPLATE, LEGGINGS, BOOTS) override val items = listOf(SWORD, AXE, SHIELD, HELMET, CHESTPLATE, LEGGINGS, BOOTS)
override fun onLoad() { override fun onLoad() {
// empty function - this must be called to initialise the above properties ^ ServerTickEvents.END_SERVER_TICK.register { server ->
for (player in server.playerList.players) {
if (fullSetEquippedBy(player)) {
player.removeEffect(MobEffects.WITHER)
}
}
}
} }
} }
@@ -8,6 +8,7 @@ import net.minecraft.tags.TagKey
import net.minecraft.world.entity.EquipmentSlot import net.minecraft.world.entity.EquipmentSlot
import net.minecraft.world.entity.player.Player import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.Item import net.minecraft.world.item.Item
import net.minecraft.world.item.ToolMaterial
import net.minecraft.world.item.equipment.ArmorMaterial import net.minecraft.world.item.equipment.ArmorMaterial
import net.minecraft.world.item.equipment.ArmorMaterials import net.minecraft.world.item.equipment.ArmorMaterials
import net.minecraft.world.item.equipment.ArmorType import net.minecraft.world.item.equipment.ArmorType
@@ -24,6 +25,10 @@ abstract class GenericGearSet: GenericItemSet() {
open val materialDefinition: GearMaterialDef open val materialDefinition: GearMaterialDef
get() = GearMaterialDef.NETHERITE get() = GearMaterialDef.NETHERITE
val toolMaterial: ToolMaterial by lazy {
materialDefinition.toToolMaterial()
}
val armorMaterial: ArmorMaterial by lazy { val armorMaterial: ArmorMaterial by lazy {
materialDefinition.toArmorMaterial() materialDefinition.toArmorMaterial()
} }
@@ -89,3 +94,6 @@ fun GearMaterialDef.toArmorMaterial(): ArmorMaterial {
) )
} }
fun GearMaterialDef.toToolMaterial(): ToolMaterial {
TODO()
}
@@ -24,7 +24,7 @@ abstract class GenericItemSet {
// list of all items part of the class // list of all items part of the class
abstract val items: List<Item> abstract val items: List<Item>
abstract fun onLoad() open fun onLoad() {}
private val itemRecipes = mutableMapOf<Item, List<RecipeSpec>>() private val itemRecipes = mutableMapOf<Item, List<RecipeSpec>>()
private val itemTags = mutableMapOf<Item, List<TagKey<Item>>>() private val itemTags = mutableMapOf<Item, List<TagKey<Item>>>()
@@ -81,6 +81,7 @@ abstract class GenericItemSet {
fun register(impl: GenericItemSet) = _all.add(impl) fun register(impl: GenericItemSet) = _all.add(impl)
} }
} }
class CustomItemBuilder<T : Item>( class CustomItemBuilder<T : Item>(
-10
View File
@@ -1,10 +0,0 @@
{
"type": "minecraft:smithing_transform",
"template": "minecraft:crying_obsidian",
"base": "minecraft:netherite_boots",
"addition": "fantasysmp:dragonite_ingot",
"result": {
"id": "fantasysmp:dragonite_boots"
}
}
@@ -1,9 +0,0 @@
{
"type": "minecraft:smithing_transform",
"template": "minecraft:elytra",
"base": "minecraft:netherite_chestplate",
"addition": "fantasysmp:dragonite_ingot",
"result": {
"id": "fantasysmp:dragonite_chestplate"
}
}
-9
View File
@@ -1,9 +0,0 @@
{
"type": "minecraft:smithing_transform",
"template": "minecraft:dragon_head",
"base": "minecraft:netherite_helmet",
"addition": "fantasysmp:dragonite_ingot",
"result": {
"id": "fantasysmp:dragonite_helmet"
}
}
-27
View File
@@ -1,27 +0,0 @@
{
"type": "minecraft:crafting_shaped",
"ingredients": [
"minecraft:dragon_breath",
"fantasysmp:dragon_scale"
],
"pattern": [
"SBS",
"CXC",
"SBS"
],
"key": {
"S": [
"minecraft:shulker_shell"
],
"B": [
"minecraft:dragon_breath"
],
"C": [
"minecraft:chorus_fruit"
],
"X": [
"fantasysmp:dragon_scale"
]
},
"result": "fantasysmp:dragonite_ingot"
}
@@ -1,9 +0,0 @@
{
"type": "minecraft:smithing_transform",
"template": "minecraft:crying_obsidian",
"base": "minecraft:netherite_leggings",
"addition": "fantasysmp:dragonite_ingot",
"result": {
"id": "fantasysmp:dragonite_leggings"
}
}
-9
View File
@@ -1,9 +0,0 @@
{
"type": "minecraft:smithing_transform",
"template": "minecraft:end_crystal",
"base": "minecraft:netherite_sword",
"addition": "fantasysmp:dragonite_ingot",
"result": {
"id": "fantasysmp:dragonite_sword"
}
}
-9
View File
@@ -1,9 +0,0 @@
{
"type": "minecraft:smithing_transform",
"template": "minecraft:netherite_upgrade_smithing_template",
"base": "minecraft:netherite_axe",
"addition": "minecraft:wither_skeleton_skull",
"result": {
"id": "fantasysmp:witherite_axe"
}
}
-9
View File
@@ -1,9 +0,0 @@
{
"type": "minecraft:smithing_transform",
"template": "minecraft:netherite_upgrade_smithing_template",
"base": "minecraft:netherite_boots",
"addition": "minecraft:wither_skeleton_skull",
"result": {
"id": "fantasysmp:witherite_boots"
}
}
@@ -1,9 +0,0 @@
{
"type": "minecraft:smithing_transform",
"template": "minecraft:netherite_upgrade_smithing_template",
"base": "minecraft:netherite_chestplate",
"addition": "minecraft:wither_skeleton_skull",
"result": {
"id": "fantasysmp:witherite_chestplate"
}
}
-9
View File
@@ -1,9 +0,0 @@
{
"type": "minecraft:smithing_transform",
"template": "minecraft:netherite_upgrade_smithing_template",
"base": "minecraft:netherite_helmet",
"addition": "minecraft:wither_skeleton_skull",
"result": {
"id": "fantasysmp:witherite_helmet"
}
}
@@ -1,9 +0,0 @@
{
"type": "minecraft:smithing_transform",
"template": "minecraft:netherite_upgrade_smithing_template",
"base": "minecraft:netherite_leggings",
"addition": "minecraft:wither_skeleton_skull",
"result": {
"id": "fantasysmp:witherite_leggings"
}
}
-9
View File
@@ -1,9 +0,0 @@
{
"type": "minecraft:smithing_transform",
"template": "minecraft:netherite_upgrade_smithing_template",
"base": "minecraft:netherite_sword",
"addition": "minecraft:wither_skeleton_skull",
"result": {
"id": "fantasysmp:witherite_sword"
}
}