custom items now use new builder DSL syntax, implementing first new set begins tmr
build / build (push) Failing after 3m16s
build / build (push) Failing after 3m16s
This commit is contained in:
@@ -0,0 +1,54 @@
|
|||||||
|
package dev.zxq5.items
|
||||||
|
|
||||||
|
import dev.zxq5.Fantasysmp
|
||||||
|
import dev.zxq5.items.core.GenericGearSet
|
||||||
|
import dev.zxq5.items.core.GenericItemSet
|
||||||
|
import net.fabricmc.fabric.api.creativetab.v1.FabricCreativeModeTab
|
||||||
|
import net.minecraft.core.Registry
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries
|
||||||
|
import net.minecraft.core.registries.Registries
|
||||||
|
import net.minecraft.network.chat.Component
|
||||||
|
import net.minecraft.resources.Identifier
|
||||||
|
import net.minecraft.resources.ResourceKey
|
||||||
|
import net.minecraft.world.item.CreativeModeTab
|
||||||
|
import net.minecraft.world.item.Item
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
|
||||||
|
object ModItems {
|
||||||
|
fun <T : Item> register(
|
||||||
|
name: String,
|
||||||
|
itemFactory: (Item.Properties) -> T,
|
||||||
|
settings: Item.Properties
|
||||||
|
): T {
|
||||||
|
val itemKey = ResourceKey.create(Registries.ITEM, Identifier.fromNamespaceAndPath(Fantasysmp.MOD_ID, name))
|
||||||
|
val item = itemFactory(settings.setId(itemKey))
|
||||||
|
Registry.register(BuiltInRegistries.ITEM, itemKey, item)
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
|
||||||
|
val CUSTOM_CREATIVE_TAB_KEY: ResourceKey<CreativeModeTab> = ResourceKey.create(
|
||||||
|
BuiltInRegistries.CREATIVE_MODE_TAB.key(), Identifier.fromNamespaceAndPath(Fantasysmp.MOD_ID, "creative_tab")
|
||||||
|
)
|
||||||
|
|
||||||
|
val CUSTOM_CREATIVE_TAB: CreativeModeTab = FabricCreativeModeTab.builder()
|
||||||
|
.icon { ItemStack(Witherite.SWORD) }
|
||||||
|
.title(Component.translatable("Fantasysmp"))
|
||||||
|
.displayItems { _, output ->
|
||||||
|
GenericItemSet.all.forEach {
|
||||||
|
it.items.forEach(output::accept)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.build()
|
||||||
|
|
||||||
|
private val eagerLoad = listOf<GenericGearSet>(
|
||||||
|
Witherite,
|
||||||
|
Dragonite,
|
||||||
|
)
|
||||||
|
|
||||||
|
fun onLoad() {
|
||||||
|
// ensure that implementations such as creative tab are loaded and initialised
|
||||||
|
eagerLoad
|
||||||
|
GenericItemSet.all.forEach { it.onLoad() }
|
||||||
|
Registry.register(BuiltInRegistries.CREATIVE_MODE_TAB, CUSTOM_CREATIVE_TAB_KEY, CUSTOM_CREATIVE_TAB);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,290 +0,0 @@
|
|||||||
package dev.zxq5.items
|
|
||||||
|
|
||||||
import dev.zxq5.Fantasysmp
|
|
||||||
import dev.zxq5.util.id
|
|
||||||
import dev.zxq5.util.resourceKey
|
|
||||||
import kotlinx.serialization.descriptors.StructureKind
|
|
||||||
import net.fabricmc.fabric.api.creativetab.v1.FabricCreativeModeTab
|
|
||||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagsProvider
|
|
||||||
import net.minecraft.advancements.criterion.InventoryChangeTrigger
|
|
||||||
import net.minecraft.advancements.criterion.ItemPredicate
|
|
||||||
import net.minecraft.core.Holder
|
|
||||||
import net.minecraft.core.HolderGetter
|
|
||||||
import net.minecraft.core.HolderLookup
|
|
||||||
import net.minecraft.core.Registry
|
|
||||||
import net.minecraft.core.registries.BuiltInRegistries
|
|
||||||
import net.minecraft.core.registries.Registries
|
|
||||||
import net.minecraft.data.recipes.RecipeCategory
|
|
||||||
import net.minecraft.data.recipes.RecipeOutput
|
|
||||||
import net.minecraft.data.recipes.RecipeProvider
|
|
||||||
import net.minecraft.data.recipes.ShapedRecipeBuilder
|
|
||||||
import net.minecraft.data.recipes.SmithingTransformRecipeBuilder
|
|
||||||
import net.minecraft.network.chat.Component
|
|
||||||
import net.minecraft.resources.Identifier
|
|
||||||
import net.minecraft.resources.ResourceKey
|
|
||||||
import net.minecraft.sounds.SoundEvent
|
|
||||||
import net.minecraft.tags.TagKey
|
|
||||||
import net.minecraft.world.entity.EquipmentSlot
|
|
||||||
import net.minecraft.world.entity.player.Player
|
|
||||||
import net.minecraft.world.item.*
|
|
||||||
import net.minecraft.world.item.crafting.Ingredient
|
|
||||||
import net.minecraft.world.item.equipment.ArmorMaterial
|
|
||||||
import net.minecraft.world.item.equipment.ArmorMaterials
|
|
||||||
import net.minecraft.world.item.equipment.ArmorType
|
|
||||||
import net.minecraft.world.item.equipment.EquipmentAsset
|
|
||||||
import kotlin.reflect.KProperty
|
|
||||||
|
|
||||||
abstract class ItemImplementation {
|
|
||||||
// list of all items part of the class
|
|
||||||
abstract val items: List<Item>
|
|
||||||
|
|
||||||
abstract fun onLoad()
|
|
||||||
|
|
||||||
open fun generateRecipes(registries: HolderLookup.Provider, exporter: RecipeOutput) {}
|
|
||||||
|
|
||||||
open fun generateItemTags(tags: ItemTagAdder) {}
|
|
||||||
// open fun generateItemModels(models: ItemModelGenerators) {}
|
|
||||||
|
|
||||||
init {
|
|
||||||
register(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val _all = mutableListOf<ItemImplementation>()
|
|
||||||
|
|
||||||
val all: List<ItemImplementation> get() = _all
|
|
||||||
|
|
||||||
fun register(impl: ItemImplementation) = _all.add(impl)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class GenericGearSet: ItemImplementation() {
|
|
||||||
abstract val materialName: String
|
|
||||||
|
|
||||||
abstract val armorSet: ArmorSet
|
|
||||||
|
|
||||||
open val materialKey: ResourceKey<EquipmentAsset>
|
|
||||||
get() = materialName.resourceKey()
|
|
||||||
|
|
||||||
open val materialDefinition: GearMaterialDef
|
|
||||||
get() = GearMaterialDef.NETHERITE
|
|
||||||
|
|
||||||
val armorMaterial: ArmorMaterial by lazy {
|
|
||||||
materialDefinition.toArmorMaterial()
|
|
||||||
}
|
|
||||||
|
|
||||||
private val itemRecipes = mutableMapOf<Item, List<RecipeSpec>>()
|
|
||||||
|
|
||||||
private val itemTags = mutableMapOf<Item, List<TagKey<Item>>>()
|
|
||||||
|
|
||||||
private val itemModels = mutableMapOf<Item, ModelSpec>()
|
|
||||||
|
|
||||||
internal fun registerDatagen(item: Item, recipes: List<RecipeSpec>, tags: List<TagKey<Item>>, model: ModelSpec) {
|
|
||||||
itemRecipes[item] = recipes
|
|
||||||
itemTags[item] = tags
|
|
||||||
itemModels[item] = model
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
val modelSpecs: Map<Item, ModelSpec> get() = itemModels
|
|
||||||
|
|
||||||
override fun generateRecipes(registries: HolderLookup.Provider, exporter: RecipeOutput) {
|
|
||||||
val itemLookup: HolderGetter<Item> = registries.lookupOrThrow(Registries.ITEM)
|
|
||||||
|
|
||||||
itemRecipes.forEach { (item, specs) ->
|
|
||||||
specs.forEach { spec ->
|
|
||||||
when (spec) {
|
|
||||||
is RecipeSpec.Smithing -> SmithingTransformRecipeBuilder.smithing(
|
|
||||||
Ingredient.of(spec.template), Ingredient.of(spec.base), Ingredient.of(spec.addition),
|
|
||||||
RecipeCategory.COMBAT, item
|
|
||||||
).unlocks("has_addition", InventoryChangeTrigger.TriggerInstance.hasItems(spec.addition))
|
|
||||||
.save(exporter, BuiltInRegistries.ITEM.getKey(item).path)
|
|
||||||
|
|
||||||
is RecipeSpec.Shaped -> {
|
|
||||||
val builder = ShapedRecipeBuilder.shaped(itemLookup, RecipeCategory.MISC, item)
|
|
||||||
spec.pattern.forEach { builder.pattern(it) }
|
|
||||||
spec.key.forEach { (char, ingredientItem) ->
|
|
||||||
builder.define(char, ingredientItem)
|
|
||||||
|
|
||||||
}
|
|
||||||
builder
|
|
||||||
.unlockedBy("has_ingredient", RecipeProvider.inventoryTrigger(
|
|
||||||
ItemPredicate.Builder().of(itemLookup, *spec.key.values.toTypedArray() )
|
|
||||||
))
|
|
||||||
.save(exporter)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun generateItemTags(tags: ItemTagAdder) {
|
|
||||||
itemTags.forEach { (item, tagList) -> tagList.forEach { tags.add(it, item) } }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun fullSetEquippedBy(p: Player) =
|
|
||||||
p.getItemBySlot(EquipmentSlot.HEAD).item == armorSet.helmet &&
|
|
||||||
p.getItemBySlot(EquipmentSlot.CHEST).item == armorSet.chestplate &&
|
|
||||||
p.getItemBySlot(EquipmentSlot.LEGS).item == armorSet.leggings &&
|
|
||||||
p.getItemBySlot(EquipmentSlot.FEET).item == armorSet.boots
|
|
||||||
}
|
|
||||||
|
|
||||||
data class ArmorSet(
|
|
||||||
val helmet: Item,
|
|
||||||
val chestplate: Item,
|
|
||||||
val leggings: Item,
|
|
||||||
val boots: Item,
|
|
||||||
)
|
|
||||||
|
|
||||||
object ModItems {
|
|
||||||
fun <T : Item> register(
|
|
||||||
name: String,
|
|
||||||
itemFactory: (Item.Properties) -> T,
|
|
||||||
settings: Item.Properties
|
|
||||||
): T {
|
|
||||||
val itemKey = ResourceKey.create(Registries.ITEM, Identifier.fromNamespaceAndPath(Fantasysmp.MOD_ID, name))
|
|
||||||
val item = itemFactory(settings.setId(itemKey))
|
|
||||||
Registry.register(BuiltInRegistries.ITEM, itemKey, item)
|
|
||||||
return item
|
|
||||||
}
|
|
||||||
|
|
||||||
val CUSTOM_CREATIVE_TAB_KEY: ResourceKey<CreativeModeTab> = ResourceKey.create(
|
|
||||||
BuiltInRegistries.CREATIVE_MODE_TAB.key(), Identifier.fromNamespaceAndPath(Fantasysmp.MOD_ID, "creative_tab")
|
|
||||||
)
|
|
||||||
|
|
||||||
val CUSTOM_CREATIVE_TAB: CreativeModeTab = FabricCreativeModeTab.builder()
|
|
||||||
.icon { ItemStack(Witherite.SWORD) }
|
|
||||||
.title(Component.translatable("Fantasysmp"))
|
|
||||||
.displayItems { _, output ->
|
|
||||||
ItemImplementation.all.forEach {
|
|
||||||
it.items.forEach(output::accept)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.build()
|
|
||||||
|
|
||||||
private val eagerLoad = listOf<GenericGearSet>(
|
|
||||||
Witherite,
|
|
||||||
Dragonite,
|
|
||||||
)
|
|
||||||
|
|
||||||
fun onLoad() {
|
|
||||||
// ensure that implementations such as creative tab are loaded and initialised
|
|
||||||
eagerLoad
|
|
||||||
ItemImplementation.all.forEach { it.onLoad() }
|
|
||||||
Registry.register(BuiltInRegistries.CREATIVE_MODE_TAB, CUSTOM_CREATIVE_TAB_KEY, CUSTOM_CREATIVE_TAB);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class GearMaterialDef(
|
|
||||||
val durability: Int = ArmorMaterials.NETHERITE.durability,
|
|
||||||
val defence: Map<ArmorType, Int> = ArmorMaterials.NETHERITE.defense,
|
|
||||||
val enchantability: Int = ArmorMaterials.NETHERITE.enchantmentValue,
|
|
||||||
val equipSound: Holder<SoundEvent> = ArmorMaterials.NETHERITE.equipSound,
|
|
||||||
val toughness: Float = ArmorMaterials.NETHERITE.toughness,
|
|
||||||
val knockbackResistance: Float = ArmorMaterials.NETHERITE.knockbackResistance,
|
|
||||||
val repairIngredient: TagKey<Item> = ArmorMaterials.NETHERITE.repairIngredient,
|
|
||||||
val assetId: ResourceKey<EquipmentAsset> = ArmorMaterials.NETHERITE.assetId,
|
|
||||||
) {
|
|
||||||
companion object {
|
|
||||||
val NETHERITE = GearMaterialDef(
|
|
||||||
durability = ArmorMaterials.NETHERITE.durability,
|
|
||||||
defence = ArmorMaterials.NETHERITE.defense,
|
|
||||||
enchantability = ArmorMaterials.NETHERITE.enchantmentValue,
|
|
||||||
equipSound = ArmorMaterials.NETHERITE.equipSound,
|
|
||||||
toughness = ArmorMaterials.NETHERITE.toughness,
|
|
||||||
knockbackResistance = ArmorMaterials.NETHERITE.knockbackResistance,
|
|
||||||
repairIngredient = ArmorMaterials.NETHERITE.repairIngredient,
|
|
||||||
assetId = ArmorMaterials.NETHERITE.assetId,
|
|
||||||
)
|
|
||||||
val DIAMOND = GearMaterialDef(
|
|
||||||
durability = ArmorMaterials.DIAMOND.durability,
|
|
||||||
defence = ArmorMaterials.DIAMOND.defense,
|
|
||||||
enchantability = ArmorMaterials.DIAMOND.enchantmentValue,
|
|
||||||
equipSound = ArmorMaterials.DIAMOND.equipSound,
|
|
||||||
toughness = ArmorMaterials.DIAMOND.toughness,
|
|
||||||
knockbackResistance = ArmorMaterials.DIAMOND.knockbackResistance,
|
|
||||||
repairIngredient = ArmorMaterials.DIAMOND.repairIngredient,
|
|
||||||
assetId = ArmorMaterials.DIAMOND.assetId,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun GearMaterialDef.toArmorMaterial(): ArmorMaterial {
|
|
||||||
return ArmorMaterial(
|
|
||||||
durability,
|
|
||||||
defence,
|
|
||||||
enchantability,
|
|
||||||
equipSound,
|
|
||||||
toughness,
|
|
||||||
knockbackResistance,
|
|
||||||
repairIngredient,
|
|
||||||
assetId,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
class ItemTagAdder(private val provider: FabricTagsProvider.ItemTagsProvider) {
|
|
||||||
fun add(tag: TagKey<Item>, vararg items: Item) {
|
|
||||||
provider.apply { items.forEach { add(tag, it) } }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed interface RecipeSpec {
|
|
||||||
data class Smithing(val template: Item, val base: Item, val addition: Item) : RecipeSpec
|
|
||||||
data class Shaped(val pattern: List<String>, val key: Map<Char, Item>) : RecipeSpec
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed interface ModelSpec {
|
|
||||||
data object Generated : ModelSpec // plain flat 2D item icon
|
|
||||||
data object Handheld : ModelSpec // flat icon, held like a tool
|
|
||||||
data object None : ModelSpec // hand-written JSON already exists, skip auto-gen
|
|
||||||
}
|
|
||||||
|
|
||||||
class GearItemBuilder<T : Item>(
|
|
||||||
private val owner: GenericGearSet,
|
|
||||||
val name: String,
|
|
||||||
private val itemFactory: (Item.Properties) -> T,
|
|
||||||
) {
|
|
||||||
private var properties = Item.Properties()
|
|
||||||
private val recipes = mutableListOf<RecipeSpec>()
|
|
||||||
private val tags = mutableListOf<TagKey<Item>>()
|
|
||||||
private var modelSpec: ModelSpec = ModelSpec.None
|
|
||||||
|
|
||||||
fun model(spec: ModelSpec) {
|
|
||||||
modelSpec = spec
|
|
||||||
}
|
|
||||||
|
|
||||||
fun properties(block: Item.Properties.() -> Item.Properties) {
|
|
||||||
properties = properties.block()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun smithingUpgrade(template: Item, base: Item, addition: Item) {
|
|
||||||
recipes += RecipeSpec.Smithing(template, base, addition)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun shapedRecipe(vararg pattern: String, key: Map<Char, Item>) {
|
|
||||||
recipes += RecipeSpec.Shaped(pattern.toList(), key)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun tags(vararg tag: TagKey<Item>) {
|
|
||||||
tags += tag
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun build(): T {
|
|
||||||
val item = ModItems.register(name, itemFactory, properties)
|
|
||||||
owner.registerDatagen(item, recipes, tags, modelSpec)
|
|
||||||
return item
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T : Item> GenericGearSet.gearItem(
|
|
||||||
name: String,
|
|
||||||
itemFactory: (Item.Properties) -> T,
|
|
||||||
block: GearItemBuilder<T>.() -> Unit = {},
|
|
||||||
): GearItemBuilder<T> = GearItemBuilder(this, name, itemFactory).apply(block)
|
|
||||||
|
|
||||||
operator fun <T : Item> GearItemBuilder<T>.provideDelegate(
|
|
||||||
thisRef: Any?, property: KProperty<*>
|
|
||||||
): Lazy<T> = lazy { build() }
|
|
||||||
|
|
||||||
operator fun <T : Item> Lazy<T>.getValue(thisRef: Any?, property: KProperty<*>): T = value
|
|
||||||
+3
-8
@@ -1,16 +1,11 @@
|
|||||||
package dev.zxq5.items
|
package dev.zxq5.items.sets
|
||||||
|
|
||||||
import dev.zxq5.Fantasysmp
|
import dev.zxq5.items.core.ArmorSet
|
||||||
|
import dev.zxq5.items.core.GenericGearSet
|
||||||
import dev.zxq5.items.ModItems.register
|
import dev.zxq5.items.ModItems.register
|
||||||
import net.minecraft.core.component.DataComponents
|
import net.minecraft.core.component.DataComponents
|
||||||
import net.minecraft.core.particles.ParticleOptions
|
|
||||||
import net.minecraft.core.particles.ParticleTypes
|
|
||||||
import net.minecraft.resources.Identifier
|
|
||||||
import net.minecraft.resources.ResourceKey
|
|
||||||
import net.minecraft.server.level.ServerLevel
|
|
||||||
import net.minecraft.sounds.SoundEvents
|
import net.minecraft.sounds.SoundEvents
|
||||||
import net.minecraft.sounds.SoundSource
|
import net.minecraft.sounds.SoundSource
|
||||||
import net.minecraft.tags.ItemTags
|
|
||||||
import net.minecraft.util.Unit
|
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
|
||||||
+13
-63
@@ -1,11 +1,10 @@
|
|||||||
package dev.zxq5.items
|
package dev.zxq5.items.sets
|
||||||
|
|
||||||
import dev.zxq5.items.ModItems.register
|
import dev.zxq5.items.core.ArmorSet
|
||||||
import dev.zxq5.util.mcItemTag
|
import dev.zxq5.items.core.GenericGearSet
|
||||||
|
import dev.zxq5.items.core.gearItem
|
||||||
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.tags.ItemTags
|
|
||||||
import net.minecraft.tags.TagKey
|
|
||||||
import net.minecraft.world.InteractionHand
|
import net.minecraft.world.InteractionHand
|
||||||
import net.minecraft.world.InteractionResult
|
import net.minecraft.world.InteractionResult
|
||||||
import net.minecraft.world.effect.MobEffectInstance
|
import net.minecraft.world.effect.MobEffectInstance
|
||||||
@@ -20,7 +19,6 @@ import net.minecraft.world.item.Items
|
|||||||
import net.minecraft.world.item.ToolMaterial
|
import net.minecraft.world.item.ToolMaterial
|
||||||
import net.minecraft.world.item.component.BlocksAttacks
|
import net.minecraft.world.item.component.BlocksAttacks
|
||||||
import net.minecraft.world.item.component.UseCooldown
|
import net.minecraft.world.item.component.UseCooldown
|
||||||
import net.minecraft.world.item.equipment.ArmorMaterial
|
|
||||||
import net.minecraft.world.item.equipment.ArmorType
|
import net.minecraft.world.item.equipment.ArmorType
|
||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -31,9 +29,9 @@ object Witherite: GenericGearSet() {
|
|||||||
override val materialDefinition
|
override val materialDefinition
|
||||||
get() = super.materialDefinition.copy(assetId = materialKey)
|
get() = super.materialDefinition.copy(assetId = materialKey)
|
||||||
|
|
||||||
val SHIELD = register("witherite_shield", ::Item,
|
val SHIELD by gearItem("witherite_shield", ::Item) {
|
||||||
Item.Properties()
|
properties {
|
||||||
.component(DataComponents.BLOCKS_ATTACKS, BlocksAttacks(
|
component(DataComponents.BLOCKS_ATTACKS, BlocksAttacks(
|
||||||
0.25f, // 5 tick warmup
|
0.25f, // 5 tick warmup
|
||||||
1.0f, // standard disable cooldown
|
1.0f, // standard disable cooldown
|
||||||
listOf(
|
listOf(
|
||||||
@@ -49,19 +47,8 @@ object Witherite: GenericGearSet() {
|
|||||||
Optional.empty(), // default block sound
|
Optional.empty(), // default block sound
|
||||||
Optional.empty() // default disable sound
|
Optional.empty() // default disable sound
|
||||||
))
|
))
|
||||||
)
|
}
|
||||||
|
}
|
||||||
// val SWORD = register("witherite_sword", ::WitheriteSword,
|
|
||||||
// Item.Properties()
|
|
||||||
// .enchantable(armorMaterial.enchantmentValue)
|
|
||||||
// .component(DataComponents.USE_COOLDOWN, UseCooldown(2f))
|
|
||||||
// .sword(ToolMaterial.NETHERITE, 3F, -2.4F)
|
|
||||||
// )
|
|
||||||
|
|
||||||
// val AXE = register("witherite_axe", ::WitheriteWeapon,
|
|
||||||
// Item.Properties()
|
|
||||||
// .enchantable(armorMaterial.enchantmentValue)
|
|
||||||
// .axe(ToolMaterial.NETHERITE, 5F, -3F))
|
|
||||||
|
|
||||||
val SWORD by gearItem("witherite_sword", ::WitheriteSword) {
|
val SWORD by gearItem("witherite_sword", ::WitheriteSword) {
|
||||||
properties {
|
properties {
|
||||||
@@ -79,9 +66,6 @@ object Witherite: GenericGearSet() {
|
|||||||
.axe(ToolMaterial.NETHERITE, 3F, -3F)
|
.axe(ToolMaterial.NETHERITE, 3F, -3F)
|
||||||
}
|
}
|
||||||
smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.NETHERITE_AXE, Items.WITHER_SKELETON_SKULL)
|
smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.NETHERITE_AXE, Items.WITHER_SKELETON_SKULL)
|
||||||
tags(
|
|
||||||
mcItemTag("axes")
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val HELMET by gearItem("witherite_helmet", ::Item) {
|
val HELMET by gearItem("witherite_helmet", ::Item) {
|
||||||
@@ -112,46 +96,12 @@ object Witherite: GenericGearSet() {
|
|||||||
smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.NETHERITE_BOOTS, Items.WITHER_SKELETON_SKULL)
|
smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.NETHERITE_BOOTS, Items.WITHER_SKELETON_SKULL)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// val HELMET = register(
|
|
||||||
// "witherite_helmet",
|
|
||||||
// ::Item,
|
|
||||||
// Item.Properties().humanoidArmor(armorMaterial , ArmorType.HELMET)
|
|
||||||
// .enchantable(armorMaterial.enchantmentValue)
|
|
||||||
// .durability(ArmorType.HELMET.getDurability(armorMaterial.durability))
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// val CHESTPLATE = register(
|
|
||||||
// "witherite_chestplate",
|
|
||||||
// ::Item,
|
|
||||||
//
|
|
||||||
// Item.Properties()
|
|
||||||
// .enchantable(armorMaterial.enchantmentValue)
|
|
||||||
// .humanoidArmor(armorMaterial , ArmorType.CHESTPLATE)
|
|
||||||
// .durability(ArmorType.CHESTPLATE.getDurability(armorMaterial.durability))
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// val LEGGINGS = register(
|
|
||||||
// "witherite_leggings",
|
|
||||||
// ::Item,
|
|
||||||
// Item.Properties()
|
|
||||||
// .enchantable(armorMaterial.enchantmentValue)
|
|
||||||
// .humanoidArmor(armorMaterial , ArmorType.LEGGINGS)
|
|
||||||
// .durability(ArmorType.LEGGINGS.getDurability(armorMaterial.durability))
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// val BOOTS = register(
|
|
||||||
// "witherite_boots",
|
|
||||||
// ::Item,
|
|
||||||
// Item.Properties()
|
|
||||||
// .enchantable(armorMaterial.enchantmentValue)
|
|
||||||
// .humanoidArmor(armorMaterial , ArmorType.BOOTS)
|
|
||||||
// .durability(ArmorType.BOOTS.getDurability(armorMaterial.durability))
|
|
||||||
// )
|
|
||||||
|
|
||||||
override val armorSet: ArmorSet = ArmorSet(HELMET, CHESTPLATE, LEGGINGS, BOOTS)
|
override val armorSet: ArmorSet = ArmorSet(HELMET, CHESTPLATE, LEGGINGS, BOOTS)
|
||||||
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 ^
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open class WitheriteWeapon(properties: Properties): Item(properties) {
|
open class WitheriteWeapon(properties: Properties): Item(properties) {
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
package dev.zxq5.items.core
|
||||||
|
|
||||||
|
import dev.zxq5.util.resourceKey
|
||||||
|
import net.minecraft.advancements.criterion.InventoryChangeTrigger
|
||||||
|
import net.minecraft.advancements.criterion.ItemPredicate
|
||||||
|
import net.minecraft.core.HolderGetter
|
||||||
|
import net.minecraft.core.HolderLookup
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries
|
||||||
|
import net.minecraft.core.registries.Registries
|
||||||
|
import net.minecraft.data.recipes.RecipeCategory
|
||||||
|
import net.minecraft.data.recipes.RecipeOutput
|
||||||
|
import net.minecraft.data.recipes.RecipeProvider
|
||||||
|
import net.minecraft.data.recipes.ShapedRecipeBuilder
|
||||||
|
import net.minecraft.data.recipes.SmithingTransformRecipeBuilder
|
||||||
|
import net.minecraft.resources.ResourceKey
|
||||||
|
import net.minecraft.tags.TagKey
|
||||||
|
import net.minecraft.world.entity.EquipmentSlot
|
||||||
|
import net.minecraft.world.entity.player.Player
|
||||||
|
import net.minecraft.world.item.Item
|
||||||
|
import net.minecraft.world.item.crafting.Ingredient
|
||||||
|
import net.minecraft.world.item.equipment.ArmorMaterial
|
||||||
|
import net.minecraft.world.item.equipment.EquipmentAsset
|
||||||
|
|
||||||
|
abstract class GenericGearSet: GenericItemSet() {
|
||||||
|
abstract val materialName: String
|
||||||
|
|
||||||
|
abstract val armorSet: ArmorSet
|
||||||
|
|
||||||
|
open val materialKey: ResourceKey<EquipmentAsset>
|
||||||
|
get() = materialName.resourceKey()
|
||||||
|
|
||||||
|
open val materialDefinition: GearMaterialDef
|
||||||
|
get() = GearMaterialDef.NETHERITE
|
||||||
|
|
||||||
|
val armorMaterial: ArmorMaterial by lazy {
|
||||||
|
materialDefinition.toArmorMaterial()
|
||||||
|
}
|
||||||
|
|
||||||
|
private val itemRecipes = mutableMapOf<Item, List<RecipeSpec>>()
|
||||||
|
|
||||||
|
private val itemTags = mutableMapOf<Item, List<TagKey<Item>>>()
|
||||||
|
|
||||||
|
private val itemModels = mutableMapOf<Item, ModelSpec>()
|
||||||
|
|
||||||
|
internal fun registerDatagen(item: Item, recipes: List<RecipeSpec>, tags: List<TagKey<Item>>, model: ModelSpec) {
|
||||||
|
itemRecipes[item] = recipes
|
||||||
|
itemTags[item] = tags
|
||||||
|
itemModels[item] = model
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val modelSpecs: Map<Item, ModelSpec> get() = itemModels
|
||||||
|
|
||||||
|
override fun generateRecipes(registries: HolderLookup.Provider, exporter: RecipeOutput) {
|
||||||
|
val itemLookup: HolderGetter<Item> = registries.lookupOrThrow(Registries.ITEM)
|
||||||
|
|
||||||
|
itemRecipes.forEach { (item, specs) ->
|
||||||
|
specs.forEach { spec ->
|
||||||
|
when (spec) {
|
||||||
|
is RecipeSpec.Smithing -> SmithingTransformRecipeBuilder.smithing(
|
||||||
|
Ingredient.of(spec.template), Ingredient.of(spec.base), Ingredient.of(spec.addition),
|
||||||
|
RecipeCategory.COMBAT, item
|
||||||
|
).unlocks("has_addition", InventoryChangeTrigger.TriggerInstance.hasItems(spec.addition))
|
||||||
|
.save(exporter, BuiltInRegistries.ITEM.getKey(item).path)
|
||||||
|
|
||||||
|
is RecipeSpec.Shaped -> {
|
||||||
|
val builder = ShapedRecipeBuilder.shaped(itemLookup, RecipeCategory.MISC, item)
|
||||||
|
spec.pattern.forEach { builder.pattern(it) }
|
||||||
|
spec.key.forEach { (char, ingredientItem) ->
|
||||||
|
builder.define(char, ingredientItem)
|
||||||
|
|
||||||
|
}
|
||||||
|
builder
|
||||||
|
.unlockedBy("has_ingredient", RecipeProvider.inventoryTrigger(
|
||||||
|
ItemPredicate.Builder().of(itemLookup, *spec.key.values.toTypedArray() )
|
||||||
|
))
|
||||||
|
.save(exporter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun generateItemTags(tags: ItemTagAdder) {
|
||||||
|
itemTags.forEach { (item, tagList) -> tagList.forEach { tags.add(it, item) } }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fullSetEquippedBy(p: Player) =
|
||||||
|
p.getItemBySlot(EquipmentSlot.HEAD).item == armorSet.helmet &&
|
||||||
|
p.getItemBySlot(EquipmentSlot.CHEST).item == armorSet.chestplate &&
|
||||||
|
p.getItemBySlot(EquipmentSlot.LEGS).item == armorSet.leggings &&
|
||||||
|
p.getItemBySlot(EquipmentSlot.FEET).item == armorSet.boots
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package dev.zxq5.items.core
|
||||||
|
|
||||||
|
import net.minecraft.core.HolderLookup
|
||||||
|
import net.minecraft.data.recipes.RecipeOutput
|
||||||
|
import net.minecraft.world.item.Item
|
||||||
|
|
||||||
|
abstract class GenericItemSet {
|
||||||
|
// list of all items part of the class
|
||||||
|
abstract val items: List<Item>
|
||||||
|
|
||||||
|
abstract fun onLoad()
|
||||||
|
|
||||||
|
open fun generateRecipes(registries: HolderLookup.Provider, exporter: RecipeOutput) {}
|
||||||
|
|
||||||
|
open fun generateItemTags(tags: ItemTagAdder) {}
|
||||||
|
// open fun generateItemModels(models: ItemModelGenerators) {}
|
||||||
|
|
||||||
|
init {
|
||||||
|
register(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val _all = mutableListOf<GenericItemSet>()
|
||||||
|
|
||||||
|
val all: List<GenericItemSet> get() = _all
|
||||||
|
|
||||||
|
fun register(impl: GenericItemSet) = _all.add(impl)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user