Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3dc064fab6 | |||
| cad49095b4 | |||
| a1c4fe3edf | |||
| e7af04418b | |||
| e58470c0cc | |||
| fe04526040 | |||
| 5b57baafb1 | |||
| 5f6350943e | |||
| 08c1800cac | |||
| db1f6cc5ae | |||
| d392be38c5 |
@@ -8,7 +8,7 @@ on: [pull_request, push]
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-24.04
|
runs-on: zqsrv-builder
|
||||||
steps:
|
steps:
|
||||||
- name: checkout repository
|
- name: checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v6
|
||||||
@@ -38,3 +38,4 @@ hs_err_*.log
|
|||||||
replay_*.log
|
replay_*.log
|
||||||
*.hprof
|
*.hprof
|
||||||
*.jfr
|
*.jfr
|
||||||
|
/src/main/generated/
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
# fantasysmp
|
# FantasySMP
|
||||||
|
|
||||||
## Setup
|
custom items mod.
|
||||||
|
as of writing this readme, includes:
|
||||||
For setup instructions, please see the [Fabric Documentation page](https://docs.fabricmc.net/develop/getting-started/creating-a-project#setting-up) related to the IDE that you are using.
|
- Witherite Gear
|
||||||
|
- Dragonite Gear
|
||||||
## License
|
|
||||||
|
|
||||||
This template is available under the CC0 license. Feel free to learn from it and incorporate it in your own projects.
|
|
||||||
+5
-2
@@ -49,6 +49,7 @@ tasks.processResources {
|
|||||||
val version = version
|
val version = version
|
||||||
inputs.property("version", version)
|
inputs.property("version", version)
|
||||||
|
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.INCLUDE
|
||||||
filesMatching("fabric.mod.json") {
|
filesMatching("fabric.mod.json") {
|
||||||
expand("version" to version)
|
expand("version" to version)
|
||||||
}
|
}
|
||||||
@@ -78,13 +79,15 @@ tasks.jar {
|
|||||||
val projectName = project.name
|
val projectName = project.name
|
||||||
inputs.property("projectName", projectName)
|
inputs.property("projectName", projectName)
|
||||||
|
|
||||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
duplicatesStrategy = DuplicatesStrategy.INCLUDE
|
||||||
from("LICENSE") {
|
from("LICENSE") {
|
||||||
rename { "${it}_$projectName" }
|
rename { "${it}_$projectName" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.named<Jar>("sourcesJar") {
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
|
}
|
||||||
|
|
||||||
// configure the maven publication
|
// configure the maven publication
|
||||||
publishing {
|
publishing {
|
||||||
|
|||||||
@@ -10,6 +10,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
public class ExampleClientMixin {
|
public class ExampleClientMixin {
|
||||||
@Inject(at = @At("HEAD"), method = "run")
|
@Inject(at = @At("HEAD"), method = "run")
|
||||||
private void init(CallbackInfo info) {
|
private void init(CallbackInfo info) {
|
||||||
// This code is injected into the start of Minecraft.run()V
|
// This code is injected into the start of Minecraft.run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,92 @@
|
|||||||
package dev.zxq5.client
|
package dev.zxq5.client
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray
|
||||||
|
import com.google.gson.JsonObject
|
||||||
|
import dev.zxq5.Fantasysmp
|
||||||
|
import dev.zxq5.ModItemTagProvider
|
||||||
|
import dev.zxq5.ModLanguageProvider
|
||||||
|
import dev.zxq5.ModRecipeProvider
|
||||||
|
import dev.zxq5.items.template.CustomItemBuilder
|
||||||
|
import dev.zxq5.items.template.GenericGearSet
|
||||||
|
import dev.zxq5.items.template.GenericItemSet
|
||||||
|
import dev.zxq5.items.template.ModelSpec
|
||||||
|
import net.fabricmc.fabric.api.client.datagen.v1.provider.FabricModelProvider
|
||||||
import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint
|
import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint
|
||||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator
|
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator
|
||||||
|
import net.fabricmc.fabric.api.datagen.v1.FabricPackOutput
|
||||||
|
import net.minecraft.client.data.models.BlockModelGenerators
|
||||||
|
import net.minecraft.client.data.models.ItemModelGenerators
|
||||||
|
import net.minecraft.client.data.models.model.ModelTemplates
|
||||||
|
import net.minecraft.data.CachedOutput
|
||||||
|
import net.minecraft.data.DataProvider
|
||||||
|
import net.minecraft.data.PackOutput
|
||||||
|
import java.util.concurrent.CompletableFuture
|
||||||
|
|
||||||
object FantasysmpDataGenerator : DataGeneratorEntrypoint {
|
object FantasysmpDataGenerator : DataGeneratorEntrypoint {
|
||||||
override fun onInitializeDataGenerator(fabricDataGenerator: FabricDataGenerator) {
|
override fun onInitializeDataGenerator(fabricDataGenerator: FabricDataGenerator) {
|
||||||
|
val pack = fabricDataGenerator.createPack()
|
||||||
|
pack.addProvider(::ModRecipeProvider)
|
||||||
|
pack.addProvider(::ModItemTagProvider) // TODO! fix impl.
|
||||||
|
pack.addProvider(::ModLanguageProvider)
|
||||||
|
|
||||||
|
// runs only in the client as it requires client only libs!
|
||||||
|
pack.addProvider(::ModModelProvider)
|
||||||
|
pack.addProvider(::ModEquipmentAssetProvider)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// client sourceSet
|
||||||
|
class ModModelProvider(output: FabricPackOutput) : FabricModelProvider(output) {
|
||||||
|
override fun generateBlockStateModels(blockModels: BlockModelGenerators) {}
|
||||||
|
|
||||||
|
override fun generateItemModels(itemModels: ItemModelGenerators) {
|
||||||
|
println("Generating item models")
|
||||||
|
GenericItemSet.all.forEach {
|
||||||
|
println("doing $it")
|
||||||
|
it.generateModels(itemModels)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ModEquipmentAssetProvider(private val output: FabricPackOutput) : DataProvider {
|
||||||
|
override fun run(writer: CachedOutput): CompletableFuture<*> {
|
||||||
|
val futures = GenericItemSet.all
|
||||||
|
.filterIsInstance<GenericGearSet>()
|
||||||
|
.map { set -> writeAsset(writer, set) }
|
||||||
|
return CompletableFuture.allOf(*futures.toTypedArray())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun writeAsset(writer: CachedOutput, set: GenericGearSet): CompletableFuture<*> {
|
||||||
|
val json = JsonObject()
|
||||||
|
val layersJson = JsonObject()
|
||||||
|
set.equipmentAssetSpec.layers.forEach { (layerType, layers) ->
|
||||||
|
val arr = JsonArray()
|
||||||
|
layers.forEach { layer ->
|
||||||
|
val entry = JsonObject()
|
||||||
|
entry.addProperty("texture", layer.texture)
|
||||||
|
if (!layer.usePlayerTexture) entry.addProperty("use_player_texture", false)
|
||||||
|
arr.add(entry)
|
||||||
|
}
|
||||||
|
layersJson.add(layerType, arr)
|
||||||
|
}
|
||||||
|
json.add("layers", layersJson)
|
||||||
|
|
||||||
|
val path = output.outputFolder
|
||||||
|
.resolve("assets/${Fantasysmp.MOD_ID}/equipment/${set.materialName}.json")
|
||||||
|
|
||||||
|
return DataProvider.saveStable(writer, json, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getName() = "Fantasysmp Equipment Assets"
|
||||||
|
}
|
||||||
|
|
||||||
|
// client sourceSet
|
||||||
|
fun GenericItemSet.generateModels(itemModels: ItemModelGenerators) {
|
||||||
|
modelSpecs.forEach { (item, spec) ->
|
||||||
|
when (spec) {
|
||||||
|
ModelSpec.Generated -> itemModels.generateFlatItem(item, ModelTemplates.FLAT_ITEM)
|
||||||
|
ModelSpec.Handheld -> itemModels.generateFlatItem(item, ModelTemplates.FLAT_HANDHELD_ITEM)
|
||||||
|
ModelSpec.None -> {} // nothing to do — hand-authored JSON covers it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,63 +1,74 @@
|
|||||||
package dev.zxq5
|
package dev.zxq5
|
||||||
|
|
||||||
import dev.zxq5.items.ModItems
|
import dev.zxq5.items.ModItems
|
||||||
import dev.zxq5.items.Witherite
|
import dev.zxq5.items.template.GenericItemSet
|
||||||
import dev.zxq5.items.isWearingFullSet
|
|
||||||
import net.fabricmc.api.ModInitializer
|
import net.fabricmc.api.ModInitializer
|
||||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents
|
import net.fabricmc.fabric.api.datagen.v1.FabricPackOutput
|
||||||
import net.fabricmc.fabric.api.event.player.AttackEntityCallback
|
import net.fabricmc.fabric.api.datagen.v1.provider.FabricLanguageProvider
|
||||||
import net.minecraft.world.InteractionHand
|
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider
|
||||||
import net.minecraft.world.InteractionResult
|
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagsProvider
|
||||||
import net.minecraft.world.effect.MobEffectInstance
|
import net.minecraft.core.HolderLookup
|
||||||
import net.minecraft.world.effect.MobEffects
|
import net.minecraft.core.registries.BuiltInRegistries
|
||||||
import net.minecraft.world.entity.LivingEntity
|
import net.minecraft.core.registries.Registries
|
||||||
|
import net.minecraft.data.recipes.RecipeOutput
|
||||||
|
import net.minecraft.data.recipes.RecipeProvider
|
||||||
|
import net.minecraft.resources.ResourceKey
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
import java.util.concurrent.CompletableFuture
|
||||||
|
|
||||||
object Fantasysmp : ModInitializer {
|
object Fantasysmp : ModInitializer {
|
||||||
|
|
||||||
const val MOD_ID = "fantasysmp"
|
const val MOD_ID = "fantasysmp"
|
||||||
|
|
||||||
private val logger = LoggerFactory.getLogger("fantasysmp")
|
private val logger = LoggerFactory.getLogger("fantasysmp")
|
||||||
|
|
||||||
override fun onInitialize() {
|
override fun onInitialize() {
|
||||||
// This code runs as soon as Minecraft is in a mod-load-ready state.
|
|
||||||
// However, some things (like resources) may still be uninitialized.
|
|
||||||
// Proceed with mild caution.
|
|
||||||
logger.info("Hello Fabric world!")
|
logger.info("Hello Fabric world!")
|
||||||
ModItems.init();
|
ModItems.onLoad();
|
||||||
// Register the group.
|
|
||||||
registerItemEffects()
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun registerItemEffects() {
|
class ModRecipeProvider(
|
||||||
ServerTickEvents.END_SERVER_TICK.register { server ->
|
output: FabricPackOutput,
|
||||||
for (player in server.playerList.players) {
|
registriesFuture: CompletableFuture<HolderLookup.Provider>
|
||||||
if (player.isWearingFullSet(Witherite.ARMOUR_SET)) {
|
) : FabricRecipeProvider(output, registriesFuture) {
|
||||||
player.removeEffect(MobEffects.WITHER)
|
override fun createRecipeProvider(
|
||||||
|
registries: HolderLookup.Provider,
|
||||||
|
exporter: RecipeOutput
|
||||||
|
): RecipeProvider {
|
||||||
|
return object : RecipeProvider(registries, exporter) {
|
||||||
|
override fun buildRecipes() {
|
||||||
|
GenericItemSet.all.forEach {
|
||||||
|
it.generateRecipes(registries, exporter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AttackEntityCallback.EVENT.register { player, world, hand, entity, _ ->
|
override fun getName(): String = "Fantasysmp Recipes"
|
||||||
if (world.isClientSide) return@register InteractionResult.PASS
|
}
|
||||||
if (hand != InteractionHand.MAIN_HAND) return@register InteractionResult.PASS
|
|
||||||
if (player.getItemInHand(hand).item != Witherite.SWORD) return@register InteractionResult.PASS
|
class ModItemTagProvider(output: FabricPackOutput, registriesFuture: CompletableFuture<HolderLookup.Provider>) :
|
||||||
if (entity is LivingEntity) {
|
FabricTagsProvider.ItemTagsProvider(output, registriesFuture) {
|
||||||
entity.addEffect(MobEffectInstance(MobEffects.WITHER, 60, 1), player)
|
override fun addTags(provider: HolderLookup.Provider) {
|
||||||
|
GenericItemSet.all.forEach {
|
||||||
|
it.generateItemTags(provider).forEach { (item, keys) ->
|
||||||
|
keys.forEach { key ->
|
||||||
|
builder(key)
|
||||||
|
.add(ResourceKey.create(Registries.ITEM, BuiltInRegistries.ITEM.getKey(item)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InteractionResult.PASS
|
|
||||||
}
|
|
||||||
|
|
||||||
AttackEntityCallback.EVENT.register { player, world, hand, entity, _ ->
|
|
||||||
if (world.isClientSide) return@register InteractionResult.PASS
|
|
||||||
if (hand != InteractionHand.MAIN_HAND) return@register InteractionResult.PASS
|
|
||||||
if (player.getItemInHand(hand).item != Witherite.AXE) return@register InteractionResult.PASS
|
|
||||||
if (entity is LivingEntity) {
|
|
||||||
entity.addEffect(MobEffectInstance(MobEffects.WITHER, 60, 1), player)
|
|
||||||
}
|
|
||||||
|
|
||||||
InteractionResult.PASS
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ModLanguageProvider(
|
||||||
|
output: FabricPackOutput, registriesFuture: CompletableFuture<HolderLookup.Provider>) :
|
||||||
|
FabricLanguageProvider(output, registriesFuture) {
|
||||||
|
|
||||||
|
override fun generateTranslations(
|
||||||
|
registryLookup: HolderLookup.Provider,
|
||||||
|
translationBuilder: TranslationBuilder
|
||||||
|
) {
|
||||||
|
GenericItemSet.all.forEach { it.generateTranslations(translationBuilder) }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
package dev.zxq5.items
|
|
||||||
|
|
||||||
import dev.zxq5.Fantasysmp
|
|
||||||
import dev.zxq5.items.ModItems.register
|
|
||||||
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.SoundSource
|
|
||||||
import net.minecraft.tags.ItemTags
|
|
||||||
import net.minecraft.util.Unit
|
|
||||||
import net.minecraft.world.InteractionHand
|
|
||||||
import net.minecraft.world.InteractionResult
|
|
||||||
import net.minecraft.world.entity.player.Player
|
|
||||||
import net.minecraft.world.item.Item
|
|
||||||
import net.minecraft.world.item.ToolMaterial
|
|
||||||
import net.minecraft.world.item.component.BlocksAttacks
|
|
||||||
import net.minecraft.world.item.equipment.*
|
|
||||||
import net.minecraft.world.level.Level
|
|
||||||
import java.util.Optional
|
|
||||||
|
|
||||||
|
|
||||||
object Dragonite {
|
|
||||||
const val BASE_DURABILITY = 40;
|
|
||||||
val witherite_material_key: ResourceKey<EquipmentAsset> = ResourceKey.create<EquipmentAsset>(
|
|
||||||
EquipmentAssets.ROOT_ID,
|
|
||||||
Identifier.fromNamespaceAndPath(Fantasysmp.MOD_ID, "dragon")
|
|
||||||
)
|
|
||||||
|
|
||||||
val armorMaterial = ArmorMaterial(
|
|
||||||
BASE_DURABILITY,
|
|
||||||
mapOf(
|
|
||||||
ArmorType.HELMET to 3,
|
|
||||||
ArmorType.CHESTPLATE to 8,
|
|
||||||
ArmorType.LEGGINGS to 6,
|
|
||||||
ArmorType.BOOTS to 3,
|
|
||||||
ArmorType.BODY to 19,
|
|
||||||
),
|
|
||||||
5,
|
|
||||||
SoundEvents.ARMOR_EQUIP_NETHERITE,
|
|
||||||
3.0f,
|
|
||||||
0.1f,
|
|
||||||
ItemTags.REPAIRS_NETHERITE_ARMOR,
|
|
||||||
witherite_material_key,
|
|
||||||
)
|
|
||||||
|
|
||||||
val SWORD = register("dragon_sword", ::DragoniteSword,
|
|
||||||
Item.Properties()
|
|
||||||
.sword(ToolMaterial.NETHERITE, 3.0F, -2.4F)
|
|
||||||
)
|
|
||||||
val HELMET = register(
|
|
||||||
"dragon_helmet",
|
|
||||||
::Item,
|
|
||||||
Item.Properties().humanoidArmor(armorMaterial , ArmorType.HELMET)
|
|
||||||
.durability(ArmorType.HELMET.getDurability(armorMaterial.durability))
|
|
||||||
)
|
|
||||||
|
|
||||||
val CHESTPLATE = register(
|
|
||||||
"dragon_chestplate",
|
|
||||||
::Item,
|
|
||||||
Item.Properties().humanoidArmor(armorMaterial , ArmorType.CHESTPLATE)
|
|
||||||
.component(DataComponents.GLIDER, Unit.INSTANCE)
|
|
||||||
.durability(ArmorType.CHESTPLATE.getDurability(armorMaterial.durability))
|
|
||||||
)
|
|
||||||
|
|
||||||
val LEGGINGS = register(
|
|
||||||
"dragon_leggings",
|
|
||||||
::Item,
|
|
||||||
Item.Properties().humanoidArmor(armorMaterial , ArmorType.LEGGINGS)
|
|
||||||
.durability(ArmorType.LEGGINGS.getDurability(armorMaterial.durability))
|
|
||||||
)
|
|
||||||
|
|
||||||
val BOOTS = register(
|
|
||||||
"dragon_boots",
|
|
||||||
::Item,
|
|
||||||
Item.Properties().humanoidArmor(armorMaterial , ArmorType.BOOTS)
|
|
||||||
.durability(ArmorType.BOOTS.getDurability(armorMaterial.durability))
|
|
||||||
)
|
|
||||||
|
|
||||||
val INGOT = register(
|
|
||||||
"dragonite_ingot",
|
|
||||||
::Item,
|
|
||||||
Item.Properties()
|
|
||||||
)
|
|
||||||
|
|
||||||
val SCALE = register(
|
|
||||||
"dragon_scale",
|
|
||||||
::Item,
|
|
||||||
Item.Properties()
|
|
||||||
)
|
|
||||||
|
|
||||||
val ITEMS = listOf(SWORD, HELMET, CHESTPLATE, LEGGINGS, BOOTS, INGOT, SCALE)
|
|
||||||
val ARMOUR_SET = ArmorSet(HELMET, CHESTPLATE, LEGGINGS, BOOTS)
|
|
||||||
|
|
||||||
fun init() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
class DragoniteSword(properties: Properties) : Item(properties) {
|
|
||||||
override fun use(level: Level, user: Player, hand: InteractionHand): InteractionResult {
|
|
||||||
if (level.isClientSide) return InteractionResult.PASS
|
|
||||||
if (!user.isWearingFullSet(Dragonite.ARMOUR_SET)) return InteractionResult.PASS
|
|
||||||
|
|
||||||
val stack = user.getItemInHand(hand)
|
|
||||||
if (user.cooldowns.isOnCooldown(stack)) return InteractionResult.PASS
|
|
||||||
|
|
||||||
val dir = user.lookAngle
|
|
||||||
user.deltaMovement = dir.scale(2.0)
|
|
||||||
user.hurtMarked = true
|
|
||||||
|
|
||||||
level.playSound(null, user.x, user.y, user.z,
|
|
||||||
SoundEvents.ENDER_DRAGON_FLAP, SoundSource.PLAYERS, 1.0f, 1.0f)
|
|
||||||
|
|
||||||
(level as? ServerLevel)?.sendParticles(
|
|
||||||
ParticleTypes.DRAGON_BREATH as ParticleOptions,
|
|
||||||
user.x, user.y, user.z,
|
|
||||||
100, 0.5, 0.5, 0.5, 0.5
|
|
||||||
)
|
|
||||||
|
|
||||||
user.cooldowns.addCooldown(stack, 25)
|
|
||||||
|
|
||||||
return InteractionResult.SUCCESS
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+25
-32
@@ -1,7 +1,10 @@
|
|||||||
package dev.zxq5.items
|
package dev.zxq5.items
|
||||||
|
|
||||||
import dev.zxq5.Fantasysmp
|
import dev.zxq5.Fantasysmp
|
||||||
import dev.zxq5.items.Witherite.SWORD
|
import dev.zxq5.items.sets.Dragonite
|
||||||
|
import dev.zxq5.items.sets.Ender
|
||||||
|
import dev.zxq5.items.sets.Witherite
|
||||||
|
import dev.zxq5.items.template.GenericItemSet
|
||||||
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
|
||||||
import net.minecraft.core.registries.BuiltInRegistries
|
import net.minecraft.core.registries.BuiltInRegistries
|
||||||
@@ -9,19 +12,15 @@ import net.minecraft.core.registries.Registries
|
|||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.resources.Identifier
|
import net.minecraft.resources.Identifier
|
||||||
import net.minecraft.resources.ResourceKey
|
import net.minecraft.resources.ResourceKey
|
||||||
import net.minecraft.world.entity.EquipmentSlot
|
import net.minecraft.world.item.CreativeModeTab
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.item.Item
|
||||||
import net.minecraft.world.item.*
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.item.CreativeModeTab.DisplayItemsGenerator
|
|
||||||
import net.minecraft.world.item.CreativeModeTab.ItemDisplayParameters
|
|
||||||
import java.util.function.Supplier
|
|
||||||
|
|
||||||
|
|
||||||
object ModItems {
|
object ModItems {
|
||||||
fun <T : Item> register(
|
fun <T : Item> register(
|
||||||
name: String,
|
name: String,
|
||||||
itemFactory: (Item.Properties) -> T,
|
itemFactory: (Item.Properties) -> T,
|
||||||
settings: Item.Properties
|
settings: Item.Properties = Item.Properties(),
|
||||||
): T {
|
): T {
|
||||||
val itemKey = ResourceKey.create(Registries.ITEM, Identifier.fromNamespaceAndPath(Fantasysmp.MOD_ID, name))
|
val itemKey = ResourceKey.create(Registries.ITEM, Identifier.fromNamespaceAndPath(Fantasysmp.MOD_ID, name))
|
||||||
val item = itemFactory(settings.setId(itemKey))
|
val item = itemFactory(settings.setId(itemKey))
|
||||||
@@ -29,36 +28,30 @@ object ModItems {
|
|||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
|
|
||||||
val CUSTOM_CREATIVE_TAB_KEY: ResourceKey<CreativeModeTab> = ResourceKey.create<CreativeModeTab>(
|
val CUSTOM_CREATIVE_TAB_KEY: ResourceKey<CreativeModeTab> = ResourceKey.create(
|
||||||
BuiltInRegistries.CREATIVE_MODE_TAB.key(), Identifier.fromNamespaceAndPath(Fantasysmp.MOD_ID, "creative_tab")
|
BuiltInRegistries.CREATIVE_MODE_TAB.key(), Identifier.fromNamespaceAndPath(Fantasysmp.MOD_ID, "creative_tab")
|
||||||
)
|
)
|
||||||
|
|
||||||
val CUSTOM_CREATIVE_TAB: CreativeModeTab = FabricCreativeModeTab.builder()
|
val CUSTOM_CREATIVE_TAB: CreativeModeTab = FabricCreativeModeTab.builder()
|
||||||
.icon(Supplier { ItemStack(SWORD) })
|
.icon { ItemStack(Witherite.SWORD) }
|
||||||
.title(Component.translatable("Fantasysmp"))
|
.title(Component.translatable("Fantasysmp"))
|
||||||
.displayItems(DisplayItemsGenerator { params: ItemDisplayParameters, output: CreativeModeTab.Output ->
|
.displayItems { _, output ->
|
||||||
Witherite.ITEMS.forEach { output.accept(it) }
|
GenericItemSet.all.forEach {
|
||||||
Dragonite.ITEMS.forEach { output.accept(it) }
|
it.items.forEach(output::accept)
|
||||||
})
|
}
|
||||||
|
}
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
fun init() {
|
private val eagerLoad = listOf<GenericItemSet>(
|
||||||
Witherite.init();
|
Witherite,
|
||||||
Dragonite.init();
|
Dragonite,
|
||||||
|
// Ender // TODO: Enable for content drop #1
|
||||||
|
)
|
||||||
|
|
||||||
|
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);
|
Registry.register(BuiltInRegistries.CREATIVE_MODE_TAB, CUSTOM_CREATIVE_TAB_KEY, CUSTOM_CREATIVE_TAB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class ArmorSet(
|
|
||||||
val helmet: Item,
|
|
||||||
val chestplate: Item,
|
|
||||||
val leggings: Item,
|
|
||||||
val boots: Item,
|
|
||||||
)
|
|
||||||
|
|
||||||
fun Player.isWearingFullSet(set: ArmorSet): Boolean {
|
|
||||||
return getItemBySlot(EquipmentSlot.HEAD).item == set.helmet &&
|
|
||||||
getItemBySlot(EquipmentSlot.CHEST).item == set.chestplate &&
|
|
||||||
getItemBySlot(EquipmentSlot.LEGS).item == set.leggings &&
|
|
||||||
getItemBySlot(EquipmentSlot.FEET).item == set.boots
|
|
||||||
}
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
package dev.zxq5.items
|
|
||||||
|
|
||||||
import dev.zxq5.Fantasysmp
|
|
||||||
import dev.zxq5.items.ModItems.register
|
|
||||||
import net.minecraft.core.component.DataComponents
|
|
||||||
import net.minecraft.resources.Identifier
|
|
||||||
import net.minecraft.resources.ResourceKey
|
|
||||||
import net.minecraft.sounds.SoundEvents
|
|
||||||
import net.minecraft.tags.ItemTags
|
|
||||||
import net.minecraft.util.Unit
|
|
||||||
import net.minecraft.world.InteractionHand
|
|
||||||
import net.minecraft.world.InteractionResult
|
|
||||||
import net.minecraft.world.entity.EntityType
|
|
||||||
import net.minecraft.world.entity.player.Player
|
|
||||||
import net.minecraft.world.entity.projectile.hurtingprojectile.WitherSkull
|
|
||||||
import net.minecraft.world.item.Item
|
|
||||||
import net.minecraft.world.item.ToolMaterial
|
|
||||||
import net.minecraft.world.item.component.BlocksAttacks
|
|
||||||
import net.minecraft.world.item.equipment.*
|
|
||||||
import net.minecraft.world.level.Level
|
|
||||||
import java.util.Optional
|
|
||||||
|
|
||||||
|
|
||||||
object Witherite {
|
|
||||||
val base_durability = 40;
|
|
||||||
val witherite_material_key: ResourceKey<EquipmentAsset> = ResourceKey.create<EquipmentAsset>(
|
|
||||||
EquipmentAssets.ROOT_ID,
|
|
||||||
Identifier.fromNamespaceAndPath(Fantasysmp.MOD_ID, "witherite")
|
|
||||||
)
|
|
||||||
|
|
||||||
val armorMaterial = ArmorMaterial(
|
|
||||||
base_durability,
|
|
||||||
mapOf(
|
|
||||||
ArmorType.HELMET to 3,
|
|
||||||
ArmorType.CHESTPLATE to 8,
|
|
||||||
ArmorType.LEGGINGS to 6,
|
|
||||||
ArmorType.BOOTS to 3,
|
|
||||||
ArmorType.BODY to 19,
|
|
||||||
),
|
|
||||||
5,
|
|
||||||
SoundEvents.ARMOR_EQUIP_NETHERITE,
|
|
||||||
3.0f,
|
|
||||||
0.1f,
|
|
||||||
ItemTags.REPAIRS_NETHERITE_ARMOR,
|
|
||||||
witherite_material_key,
|
|
||||||
)
|
|
||||||
|
|
||||||
val SHIELD = register("witherite_shield", ::Item,
|
|
||||||
Item.Properties().component(DataComponents.BLOCKS_ATTACKS, BlocksAttacks(
|
|
||||||
0.25f, // 5 tick warmup
|
|
||||||
1.0f, // standard disable cooldown
|
|
||||||
listOf(
|
|
||||||
BlocksAttacks.DamageReduction(
|
|
||||||
90.0f, // horizontalBlockingAngle — 90° arc each side (180° total, same as vanilla)
|
|
||||||
Optional.empty(), // type — empty = blocks all damage types
|
|
||||||
0.0f, // base — flat damage reduction
|
|
||||||
1.0f // factor — multiplier (1.0 = block 100% of damage)
|
|
||||||
)
|
|
||||||
), // full block — check if this constant exists, else build the list manually
|
|
||||||
BlocksAttacks.ItemDamageFunction.DEFAULT, // check for this constant too
|
|
||||||
Optional.empty(), // no bypass
|
|
||||||
Optional.empty(), // default block sound
|
|
||||||
Optional.empty() // default disable sound
|
|
||||||
))
|
|
||||||
)
|
|
||||||
|
|
||||||
val SWORD = register("witherite_sword", ::WitheriteSword,
|
|
||||||
Item.Properties().sword(ToolMaterial.NETHERITE, 3F, -2.4F)
|
|
||||||
)
|
|
||||||
|
|
||||||
val AXE = register("witherite_axe", ::Item,
|
|
||||||
Item.Properties().axe(ToolMaterial.NETHERITE, 5F, -3F))
|
|
||||||
|
|
||||||
val HELMET = register(
|
|
||||||
"witherite_helmet",
|
|
||||||
::Item,
|
|
||||||
Item.Properties().humanoidArmor(armorMaterial , ArmorType.HELMET)
|
|
||||||
.durability(ArmorType.HELMET.getDurability(armorMaterial.durability))
|
|
||||||
)
|
|
||||||
|
|
||||||
val CHESTPLATE = register(
|
|
||||||
"witherite_chestplate",
|
|
||||||
::Item,
|
|
||||||
Item.Properties().humanoidArmor(armorMaterial , ArmorType.CHESTPLATE)
|
|
||||||
.durability(ArmorType.CHESTPLATE.getDurability(armorMaterial.durability))
|
|
||||||
)
|
|
||||||
|
|
||||||
val LEGGINGS = register(
|
|
||||||
"witherite_leggings",
|
|
||||||
::Item,
|
|
||||||
Item.Properties().humanoidArmor(armorMaterial , ArmorType.LEGGINGS)
|
|
||||||
.durability(ArmorType.LEGGINGS.getDurability(armorMaterial.durability))
|
|
||||||
)
|
|
||||||
|
|
||||||
val BOOTS = register(
|
|
||||||
"witherite_boots",
|
|
||||||
::Item,
|
|
||||||
Item.Properties().humanoidArmor(armorMaterial , ArmorType.BOOTS)
|
|
||||||
.durability(ArmorType.BOOTS.getDurability(armorMaterial.durability))
|
|
||||||
)
|
|
||||||
|
|
||||||
val ITEMS = listOf(SWORD, AXE, SHIELD, HELMET, CHESTPLATE, LEGGINGS, BOOTS)
|
|
||||||
val ARMOUR_SET = ArmorSet(HELMET, CHESTPLATE, LEGGINGS, BOOTS)
|
|
||||||
|
|
||||||
fun init() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
class WitheriteSword(properties: Properties) : Item(properties) {
|
|
||||||
override fun use(level: Level, user: Player, hand: InteractionHand): InteractionResult {
|
|
||||||
if (level.isClientSide) {
|
|
||||||
return InteractionResult.PASS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!user.isCrouching) return InteractionResult.PASS
|
|
||||||
|
|
||||||
val skull = WitherSkull(EntityType.WITHER_SKULL, level)
|
|
||||||
skull.setPos(user.eyePosition)
|
|
||||||
skull.deltaMovement = user.lookAngle
|
|
||||||
level.addFreshEntity(skull)
|
|
||||||
skull.playSound(SoundEvents.WITHER_SHOOT)
|
|
||||||
return InteractionResult.SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,200 @@
|
|||||||
|
package dev.zxq5.items.sets
|
||||||
|
|
||||||
|
import dev.zxq5.Fantasysmp
|
||||||
|
import dev.zxq5.items.template.ArmorSet
|
||||||
|
import dev.zxq5.items.template.EquipmentLayer
|
||||||
|
import dev.zxq5.items.template.GenericGearSet
|
||||||
|
import dev.zxq5.items.template.ModelSpec
|
||||||
|
import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents
|
||||||
|
import net.minecraft.ChatFormatting
|
||||||
|
import net.minecraft.core.component.DataComponents
|
||||||
|
import net.minecraft.core.particles.ParticleTypes
|
||||||
|
import net.minecraft.core.particles.PowerParticleOption
|
||||||
|
import net.minecraft.server.level.ServerLevel
|
||||||
|
import net.minecraft.sounds.SoundEvents
|
||||||
|
import net.minecraft.sounds.SoundSource
|
||||||
|
import net.minecraft.util.Unit
|
||||||
|
import net.minecraft.world.InteractionHand
|
||||||
|
import net.minecraft.world.InteractionResult
|
||||||
|
import net.minecraft.world.damagesource.DamageSource
|
||||||
|
import net.minecraft.world.damagesource.DamageTypes
|
||||||
|
import net.minecraft.world.entity.Entity
|
||||||
|
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.Level
|
||||||
|
|
||||||
|
|
||||||
|
object Dragonite: GenericGearSet() {
|
||||||
|
override val materialName = "dragonite"
|
||||||
|
override val materialDefinition
|
||||||
|
get() = super.materialDefinition.copy(assetId = materialKey)
|
||||||
|
|
||||||
|
override val equipmentAssetSpec = super.equipmentAssetSpec.copy(
|
||||||
|
layers = super.equipmentAssetSpec.layers + ("wings" to listOf(
|
||||||
|
EquipmentLayer(
|
||||||
|
"${Fantasysmp.MOD_ID}:dragonite",
|
||||||
|
usePlayerTexture = false
|
||||||
|
)
|
||||||
|
))
|
||||||
|
)
|
||||||
|
|
||||||
|
const val LORE = " forged from the essence of dragons"
|
||||||
|
override val lore_style = ChatFormatting.DARK_PURPLE
|
||||||
|
|
||||||
|
val SCALE by registerItem("dragon_scale", ::Item) {
|
||||||
|
name("Dragon Scale")
|
||||||
|
}
|
||||||
|
|
||||||
|
val INGOT by registerItem("dragonite_ingot", ::Item) {
|
||||||
|
name("Dragonite Ingot")
|
||||||
|
shapedRecipe("SBS", "CXC", "SBS", key=mapOf<Char, Item>(
|
||||||
|
'S' to Items.SHULKER_SHELL,
|
||||||
|
'X' to SCALE,
|
||||||
|
'B' to Items.DRAGON_BREATH,
|
||||||
|
'C' to Items.CHORUS_FRUIT
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
val SWORD by registerItem("dragonite_sword", ::DragoniteSword) {
|
||||||
|
name("Dragonite Sword")
|
||||||
|
lore("A sword$LORE")
|
||||||
|
model(ModelSpec.Handheld)
|
||||||
|
properties {
|
||||||
|
enchantable(armorMaterial.enchantmentValue)
|
||||||
|
.component(DataComponents.USE_COOLDOWN, UseCooldown(2f))
|
||||||
|
.sword(ToolMaterial.NETHERITE, 3F, -2.4F)
|
||||||
|
}
|
||||||
|
smithingUpgrade(Items.END_CRYSTAL, Items.NETHERITE_SWORD, INGOT)
|
||||||
|
tags("swords")
|
||||||
|
}
|
||||||
|
|
||||||
|
val HELMET by registerItem("dragonite_helmet", ::Item) {
|
||||||
|
name("Dragonite Helmet")
|
||||||
|
lore("A helmet$LORE")
|
||||||
|
properties {
|
||||||
|
humanoidArmor(armorMaterial, ArmorType.HELMET)
|
||||||
|
}
|
||||||
|
smithingUpgrade(Items.DRAGON_HEAD, Items.NETHERITE_HELMET, INGOT)
|
||||||
|
tags("head_armor")
|
||||||
|
}
|
||||||
|
|
||||||
|
val CHESTPLATE by registerItem("dragonite_chestplate", ::Item) {
|
||||||
|
name("Dragonite Chestplate")
|
||||||
|
lore("A chestplate$LORE")
|
||||||
|
properties {
|
||||||
|
humanoidArmor(armorMaterial, ArmorType.CHESTPLATE)
|
||||||
|
.component(DataComponents.GLIDER, Unit.INSTANCE)
|
||||||
|
.component(DataComponents.UNBREAKABLE, Unit.INSTANCE)
|
||||||
|
}
|
||||||
|
smithingUpgrade(Items.ELYTRA, Items.NETHERITE_CHESTPLATE, INGOT)
|
||||||
|
tags("chest_armor")
|
||||||
|
}
|
||||||
|
|
||||||
|
val LEGGINGS by registerItem("dragonite_leggings", ::Item) {
|
||||||
|
name("Dragonite Leggings")
|
||||||
|
lore("Leggings$LORE")
|
||||||
|
properties {
|
||||||
|
humanoidArmor(armorMaterial, ArmorType.LEGGINGS)
|
||||||
|
}
|
||||||
|
smithingUpgrade(Items.CRYING_OBSIDIAN, Items.NETHERITE_LEGGINGS, INGOT)
|
||||||
|
tags("leg_armor")
|
||||||
|
}
|
||||||
|
|
||||||
|
val BOOTS by registerItem("dragonite_boots", ::Item) {
|
||||||
|
name("Dragonite Boots")
|
||||||
|
lore("Boots$LORE")
|
||||||
|
properties {
|
||||||
|
humanoidArmor(armorMaterial, ArmorType.BOOTS)
|
||||||
|
}
|
||||||
|
smithingUpgrade(Items.CRYING_OBSIDIAN, Items.NETHERITE_BOOTS, INGOT)
|
||||||
|
tags("foot_armor")
|
||||||
|
}
|
||||||
|
|
||||||
|
override val armorSet: ArmorSet = ArmorSet(HELMET, CHESTPLATE, LEGGINGS, BOOTS)
|
||||||
|
override val items = listOf(SWORD, HELMET, CHESTPLATE, LEGGINGS, BOOTS, SCALE, INGOT)
|
||||||
|
|
||||||
|
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) {
|
||||||
|
override fun use(level: Level, user: Player, hand: InteractionHand): InteractionResult {
|
||||||
|
if (level.isClientSide || !Dragonite.fullSetEquippedBy(user)) return InteractionResult.PASS
|
||||||
|
|
||||||
|
val direction = user.lookAngle
|
||||||
|
|
||||||
|
val scale = if (user.isFallFlying) { 4.0 } else { 1.5 }
|
||||||
|
user.deltaMovement = direction.scale(scale)
|
||||||
|
user.hurtMarked = true
|
||||||
|
|
||||||
|
level.playSound(null, user.x, user.y, user.z,
|
||||||
|
SoundEvents.ENDER_DRAGON_FLAP, SoundSource.PLAYERS, 1.0f, 1.0f)
|
||||||
|
|
||||||
|
(level as? ServerLevel)?.sendParticles(
|
||||||
|
PowerParticleOption.create(ParticleTypes.DRAGON_BREATH, 1.0f),
|
||||||
|
user.x, user.y, user.z,
|
||||||
|
100, 0.5, 0.5, 0.5, 0.5
|
||||||
|
)
|
||||||
|
|
||||||
|
return InteractionResult.SUCCESS
|
||||||
|
}
|
||||||
|
|
||||||
|
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 attacker = damageSource.entity as? Player ?: return superBonus
|
||||||
|
if (!Dragonite.fullSetEquippedBy(attacker)) return superBonus
|
||||||
|
if (attacker.level().isClientSide) return superBonus
|
||||||
|
if (!attacker.isFallFlying) return superBonus
|
||||||
|
|
||||||
|
val speed = attacker.deltaMovement.length()
|
||||||
|
if (speed < MIN_DIVE_SPEED) return superBonus
|
||||||
|
|
||||||
|
val clampedSpeed = speed.coerceAtMost(MAX_DIVE_SPEED)
|
||||||
|
val t = (clampedSpeed - MIN_DIVE_SPEED) / (MAX_DIVE_SPEED - MIN_DIVE_SPEED)
|
||||||
|
val multiplier = 1.0f + (t * MAX_BONUS_MULTIPLIER).toFloat()
|
||||||
|
|
||||||
|
// damage is the current total (base + crit + whatever ran before this hook).
|
||||||
|
// We want final = damage * multiplier, and this method adds its return value on top of damage,
|
||||||
|
// so the bonus we need to return is exactly (damage * multiplier) - damage.
|
||||||
|
val extraBonus = damage * (multiplier - 1f)
|
||||||
|
|
||||||
|
println("base: $damage bonus: ${superBonus + extraBonus}")
|
||||||
|
return superBonus + extraBonus
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val MIN_DIVE_SPEED = 0.3
|
||||||
|
const val MAX_DIVE_SPEED = 1.1
|
||||||
|
const val MAX_BONUS_MULTIPLIER = 2.0f
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
package dev.zxq5.items.sets
|
||||||
|
|
||||||
|
import dev.zxq5.items.template.ArmorSet
|
||||||
|
import dev.zxq5.items.template.GearMaterialDef
|
||||||
|
import dev.zxq5.items.template.GenericGearSet
|
||||||
|
import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents
|
||||||
|
import net.minecraft.ChatFormatting
|
||||||
|
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)
|
||||||
|
|
||||||
|
const val LORE = "Crafted from the essence of endermen"
|
||||||
|
override val lore_style: ChatFormatting
|
||||||
|
get() = ChatFormatting.AQUA
|
||||||
|
|
||||||
|
val ENDER_INGOT by registerItem("ender_ingot", ::Item) {
|
||||||
|
name("Ender Ingot")
|
||||||
|
lore(LORE)
|
||||||
|
shapedRecipe("EDE", "DED", "EDE", key=mapOf(
|
||||||
|
'E' to Items.ENDER_EYE,
|
||||||
|
'D' to Items.DIAMOND,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
val SWORD by registerItem("ender_sword", ::EnderSword) {
|
||||||
|
name("Ender Sword")
|
||||||
|
lore(LORE)
|
||||||
|
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)
|
||||||
|
tags("swords")
|
||||||
|
}
|
||||||
|
|
||||||
|
val HELMET by registerItem("ender_helmet", ::Item) {
|
||||||
|
name("Ender Helmet")
|
||||||
|
lore(LORE)
|
||||||
|
properties {
|
||||||
|
humanoidArmor(armorMaterial, ArmorType.HELMET)
|
||||||
|
}
|
||||||
|
smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.DIAMOND_HELMET, ENDER_INGOT)
|
||||||
|
tags("head_armor")
|
||||||
|
}
|
||||||
|
|
||||||
|
val CHESTPLATE by registerItem("ender_chestplate", ::Item) {
|
||||||
|
name("Ender Chestplate")
|
||||||
|
lore(LORE)
|
||||||
|
properties {
|
||||||
|
humanoidArmor(armorMaterial, ArmorType.CHESTPLATE)
|
||||||
|
}
|
||||||
|
smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.DIAMOND_CHESTPLATE, ENDER_INGOT)
|
||||||
|
tags("chest_armor")
|
||||||
|
}
|
||||||
|
|
||||||
|
val LEGGINGS by registerItem("ender_leggings", ::Item) {
|
||||||
|
name("Ender Leggings")
|
||||||
|
lore(LORE)
|
||||||
|
properties {
|
||||||
|
humanoidArmor(armorMaterial, ArmorType.LEGGINGS)
|
||||||
|
}
|
||||||
|
smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.DIAMOND_LEGGINGS, ENDER_INGOT)
|
||||||
|
tags("leg_armor")
|
||||||
|
}
|
||||||
|
|
||||||
|
val BOOTS by registerItem("ender_boots", ::Item) {
|
||||||
|
name("Ender Boots")
|
||||||
|
lore(LORE)
|
||||||
|
properties {
|
||||||
|
humanoidArmor(armorMaterial, ArmorType.BOOTS)
|
||||||
|
}
|
||||||
|
smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.DIAMOND_BOOTS, ENDER_INGOT)
|
||||||
|
tags("foot_armor")
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
package dev.zxq5.items.sets
|
||||||
|
|
||||||
|
import dev.zxq5.items.template.ArmorSet
|
||||||
|
import dev.zxq5.items.template.GenericGearSet
|
||||||
|
import dev.zxq5.items.template.ModelSpec
|
||||||
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents
|
||||||
|
import net.minecraft.ChatFormatting
|
||||||
|
import net.minecraft.core.component.DataComponents
|
||||||
|
import net.minecraft.sounds.SoundEvents
|
||||||
|
import net.minecraft.world.InteractionHand
|
||||||
|
import net.minecraft.world.InteractionResult
|
||||||
|
import net.minecraft.world.effect.MobEffectInstance
|
||||||
|
import net.minecraft.world.effect.MobEffects
|
||||||
|
import net.minecraft.world.entity.EntityType
|
||||||
|
import net.minecraft.world.entity.LivingEntity
|
||||||
|
import net.minecraft.world.entity.player.Player
|
||||||
|
import net.minecraft.world.entity.projectile.hurtingprojectile.WitherSkull
|
||||||
|
import net.minecraft.world.item.Item
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import net.minecraft.world.item.Items
|
||||||
|
import net.minecraft.world.item.ToolMaterial
|
||||||
|
import net.minecraft.world.item.component.BlocksAttacks
|
||||||
|
import net.minecraft.world.item.component.UseCooldown
|
||||||
|
import net.minecraft.world.item.equipment.ArmorType
|
||||||
|
import net.minecraft.world.level.Level
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
|
object Witherite: GenericGearSet() {
|
||||||
|
override val materialName = "witherite"
|
||||||
|
override val materialDefinition
|
||||||
|
get() = super.materialDefinition.copy(assetId = materialKey)
|
||||||
|
|
||||||
|
const val LORE = " forged with the skulls of wither skeletons."
|
||||||
|
|
||||||
|
override val lore_style
|
||||||
|
get() = ChatFormatting.BLACK
|
||||||
|
|
||||||
|
val SHIELD by registerItem("witherite_shield", ::Item) {
|
||||||
|
name("Witherite Shield")
|
||||||
|
lore("A shield$LORE")
|
||||||
|
properties {
|
||||||
|
component(DataComponents.BLOCKS_ATTACKS, BlocksAttacks(
|
||||||
|
0.25f, // 5 tick warmup
|
||||||
|
1.0f, // standard disable cooldown
|
||||||
|
listOf(
|
||||||
|
BlocksAttacks.DamageReduction(
|
||||||
|
90.0f, // horizontalBlockingAngle — 90° arc each side (180° total, same as vanilla)
|
||||||
|
Optional.empty(), // type — empty = blocks all damage types
|
||||||
|
0.0f, // base — flat damage reduction
|
||||||
|
1.0f // factor — multiplier (1.0 = block 100% of damage)
|
||||||
|
)
|
||||||
|
), // full block — check if this constant exists, else build the list manually
|
||||||
|
BlocksAttacks.ItemDamageFunction.DEFAULT, // check for this constant too
|
||||||
|
Optional.empty(), // no bypass
|
||||||
|
Optional.empty(), // default block sound
|
||||||
|
Optional.empty() // default disable sound
|
||||||
|
))
|
||||||
|
}
|
||||||
|
smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.SHIELD, Items.WITHER_SKELETON_SKULL)
|
||||||
|
}
|
||||||
|
|
||||||
|
val SWORD by registerItem("witherite_sword", ::WitheriteSword) {
|
||||||
|
name("Witherite Sword")
|
||||||
|
lore("A sword$LORE")
|
||||||
|
model(ModelSpec.Handheld)
|
||||||
|
properties {
|
||||||
|
enchantable(armorMaterial.enchantmentValue)
|
||||||
|
.component(DataComponents.USE_COOLDOWN, UseCooldown(2f))
|
||||||
|
.sword(ToolMaterial.NETHERITE, 3F, -2.4F)
|
||||||
|
}
|
||||||
|
smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.NETHERITE_SWORD, Items.WITHER_SKELETON_SKULL)
|
||||||
|
tags("swords")
|
||||||
|
}
|
||||||
|
|
||||||
|
val AXE by registerItem("witherite_axe", ::WitheriteWeapon) {
|
||||||
|
name("Witherite Axe")
|
||||||
|
lore("An axe$LORE")
|
||||||
|
model(ModelSpec.Handheld)
|
||||||
|
properties {
|
||||||
|
enchantable(armorMaterial.enchantmentValue)
|
||||||
|
.component(DataComponents.USE_COOLDOWN, UseCooldown(2f))
|
||||||
|
.axe(ToolMaterial.NETHERITE, 3F, -3F)
|
||||||
|
}
|
||||||
|
smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.NETHERITE_AXE, Items.WITHER_SKELETON_SKULL)
|
||||||
|
tags("axes")
|
||||||
|
}
|
||||||
|
|
||||||
|
val HELMET by registerItem("witherite_helmet", ::Item) {
|
||||||
|
name("Witherite Helmet")
|
||||||
|
lore("A helmet$LORE")
|
||||||
|
properties {
|
||||||
|
humanoidArmor(armorMaterial, ArmorType.HELMET)
|
||||||
|
}
|
||||||
|
smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.NETHERITE_HELMET, Items.WITHER_SKELETON_SKULL)
|
||||||
|
tags("head_armor")
|
||||||
|
}
|
||||||
|
|
||||||
|
val CHESTPLATE by registerItem("witherite_chestplate", ::Item) {
|
||||||
|
name("Witherite Chestplate")
|
||||||
|
lore("A chestplate$LORE")
|
||||||
|
properties {
|
||||||
|
humanoidArmor(armorMaterial, ArmorType.CHESTPLATE)
|
||||||
|
}
|
||||||
|
smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.NETHERITE_CHESTPLATE, Items.WITHER_SKELETON_SKULL)
|
||||||
|
tags("chest_armor")
|
||||||
|
}
|
||||||
|
|
||||||
|
val LEGGINGS by registerItem("witherite_leggings", ::Item) {
|
||||||
|
name("Witherite Leggings")
|
||||||
|
lore("Leggings$LORE")
|
||||||
|
properties {
|
||||||
|
humanoidArmor(armorMaterial, ArmorType.LEGGINGS)
|
||||||
|
}
|
||||||
|
smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.NETHERITE_LEGGINGS, Items.WITHER_SKELETON_SKULL)
|
||||||
|
tags("leg_armor")
|
||||||
|
}
|
||||||
|
|
||||||
|
val BOOTS by registerItem("witherite_boots", ::Item) {
|
||||||
|
name("Witherite Boots")
|
||||||
|
lore("Boots$LORE")
|
||||||
|
properties {
|
||||||
|
humanoidArmor(armorMaterial, ArmorType.BOOTS)
|
||||||
|
}
|
||||||
|
smithingUpgrade(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items.NETHERITE_BOOTS, Items.WITHER_SKELETON_SKULL)
|
||||||
|
tags("foot_armor")
|
||||||
|
}
|
||||||
|
|
||||||
|
override val armorSet: ArmorSet = ArmorSet(HELMET, CHESTPLATE, LEGGINGS, BOOTS)
|
||||||
|
override val items = listOf(SWORD, AXE, SHIELD, HELMET, CHESTPLATE, LEGGINGS, BOOTS)
|
||||||
|
|
||||||
|
override fun onLoad() {
|
||||||
|
ServerTickEvents.END_SERVER_TICK.register { server ->
|
||||||
|
for (player in server.playerList.players) {
|
||||||
|
if (fullSetEquippedBy(player)) {
|
||||||
|
player.removeEffect(MobEffects.WITHER)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class WitheriteWeapon(properties: Properties): Item(properties) {
|
||||||
|
override fun hurtEnemy(itemStack: ItemStack, mob: LivingEntity, attacker: LivingEntity) {
|
||||||
|
super.hurtEnemy(itemStack, mob, attacker)
|
||||||
|
|
||||||
|
if (attacker.level().isClientSide) return
|
||||||
|
|
||||||
|
val amplifier = if (attacker is Player) { 0 } else { 2 }
|
||||||
|
mob.addEffect(MobEffectInstance(MobEffects.WITHER, 60, amplifier), attacker)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class WitheriteSword(properties: Properties) : WitheriteWeapon(properties) {
|
||||||
|
override fun use(level: Level, user: Player, hand: InteractionHand): InteractionResult {
|
||||||
|
if (level.isClientSide
|
||||||
|
|| !user.isCrouching
|
||||||
|
|| !Witherite.fullSetEquippedBy(user)
|
||||||
|
) return InteractionResult.PASS;
|
||||||
|
|
||||||
|
val skull = WitherSkull(EntityType.WITHER_SKULL, level)
|
||||||
|
skull.setPos(user.eyePosition)
|
||||||
|
skull.deltaMovement = user.lookAngle
|
||||||
|
level.addFreshEntity(skull)
|
||||||
|
skull.playSound(SoundEvents.WITHER_SHOOT)
|
||||||
|
|
||||||
|
return InteractionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
package dev.zxq5.items.template
|
||||||
|
|
||||||
|
import dev.zxq5.Fantasysmp
|
||||||
|
import dev.zxq5.util.resourceKey
|
||||||
|
import net.minecraft.core.Holder
|
||||||
|
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.Item
|
||||||
|
import net.minecraft.world.item.ToolMaterial
|
||||||
|
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
|
||||||
|
|
||||||
|
abstract class GenericGearSet: GenericItemSet() {
|
||||||
|
abstract val materialName: String
|
||||||
|
|
||||||
|
abstract val armorSet: ArmorSet
|
||||||
|
|
||||||
|
open val equipmentAssetSpec: EquipmentAssetSpec
|
||||||
|
get() = EquipmentAssetSpec(
|
||||||
|
layers = mapOf(
|
||||||
|
"humanoid" to listOf(EquipmentLayer("${Fantasysmp.MOD_ID}:$materialName")),
|
||||||
|
"humanoid_leggings" to listOf(EquipmentLayer("${Fantasysmp.MOD_ID}:$materialName")),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
open val materialKey: ResourceKey<EquipmentAsset>
|
||||||
|
get() = materialName.resourceKey()
|
||||||
|
|
||||||
|
open val materialDefinition: GearMaterialDef
|
||||||
|
get() = GearMaterialDef.NETHERITE
|
||||||
|
|
||||||
|
val toolMaterial: ToolMaterial by lazy {
|
||||||
|
materialDefinition.toToolMaterial()
|
||||||
|
}
|
||||||
|
|
||||||
|
val armorMaterial: ArmorMaterial by lazy {
|
||||||
|
materialDefinition.toArmorMaterial()
|
||||||
|
}
|
||||||
|
|
||||||
|
open 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,
|
||||||
|
)
|
||||||
|
|
||||||
|
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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun GearMaterialDef.toToolMaterial(): ToolMaterial {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
@@ -0,0 +1,198 @@
|
|||||||
|
package dev.zxq5.items.template
|
||||||
|
|
||||||
|
import dev.zxq5.Fantasysmp
|
||||||
|
import dev.zxq5.items.ModItems
|
||||||
|
import dev.zxq5.util.mcItemTag
|
||||||
|
import net.fabricmc.fabric.api.datagen.v1.provider.FabricLanguageProvider
|
||||||
|
import net.minecraft.ChatFormatting
|
||||||
|
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.component.DataComponents
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries
|
||||||
|
import net.minecraft.core.registries.Registries
|
||||||
|
import net.minecraft.data.recipes.*
|
||||||
|
import net.minecraft.network.chat.Component
|
||||||
|
import net.minecraft.tags.TagKey
|
||||||
|
import net.minecraft.world.item.Item
|
||||||
|
import net.minecraft.world.item.component.ItemLore
|
||||||
|
import net.minecraft.world.item.crafting.Ingredient
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
|
||||||
|
abstract class GenericItemSet {
|
||||||
|
// list of all items part of the class
|
||||||
|
open val lore_style = ChatFormatting.GRAY
|
||||||
|
abstract val items: List<Item>
|
||||||
|
|
||||||
|
open fun onLoad() {}
|
||||||
|
|
||||||
|
private val itemRecipes = mutableMapOf<Item, List<RecipeSpec>>()
|
||||||
|
private val itemTags = mutableMapOf<Item, List<TagKey<Item>>>()
|
||||||
|
private val itemModels = mutableMapOf<Item, ModelSpec>()
|
||||||
|
private val itemTranslations = mutableMapOf<String, String>()
|
||||||
|
|
||||||
|
val modelSpecs: Map<Item, ModelSpec> get() = itemModels
|
||||||
|
internal fun registerDatagen(
|
||||||
|
item: Item,
|
||||||
|
recipes: List<RecipeSpec>,
|
||||||
|
tags: List<TagKey<Item>>,
|
||||||
|
model: ModelSpec,
|
||||||
|
translations: Map<String, String>
|
||||||
|
) {
|
||||||
|
itemRecipes[item] = recipes
|
||||||
|
itemTags[item] = tags
|
||||||
|
itemModels[item] = model
|
||||||
|
itemTranslations.putAll(translations)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun generateItemTags(provider: HolderLookup.Provider): Map<Item, List<TagKey<Item>>> {
|
||||||
|
return itemTags
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun generateTranslations(builder: FabricLanguageProvider.TranslationBuilder) {
|
||||||
|
itemTranslations.forEach { (key, value) -> builder.add(key, value) }
|
||||||
|
}
|
||||||
|
|
||||||
|
open 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
init {
|
||||||
|
register(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T : Item> registerItem(
|
||||||
|
name: String,
|
||||||
|
itemFactory: (Item.Properties) -> T,
|
||||||
|
block: CustomItemBuilder<T>.() -> Unit = {},
|
||||||
|
): CustomItemBuilder<T> {
|
||||||
|
return CustomItemBuilder(this, name, itemFactory).apply(block)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val _all = mutableListOf<GenericItemSet>()
|
||||||
|
|
||||||
|
val all: List<GenericItemSet> get() = _all
|
||||||
|
|
||||||
|
fun register(impl: GenericItemSet) = _all.add(impl)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data class EquipmentLayer(val texture: String, val usePlayerTexture: Boolean = true)
|
||||||
|
|
||||||
|
data class EquipmentAssetSpec(
|
||||||
|
val layers: Map<String, List<EquipmentLayer>> // "humanoid", "humanoid_leggings", "wings", etc.
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CustomItemBuilder<T : Item>(
|
||||||
|
private val owner: GenericItemSet,
|
||||||
|
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 val translations = mutableMapOf<String, String>()
|
||||||
|
private var modelSpec: ModelSpec = ModelSpec.Generated
|
||||||
|
|
||||||
|
fun model(spec: ModelSpec) {
|
||||||
|
modelSpec = spec
|
||||||
|
}
|
||||||
|
|
||||||
|
fun name(displayName: String) {
|
||||||
|
translations["item.${Fantasysmp.MOD_ID}.$name"] = displayName
|
||||||
|
}
|
||||||
|
|
||||||
|
fun lore(vararg lines: String, style: ChatFormatting = owner.lore_style) {
|
||||||
|
val components = lines.mapIndexed { index, line ->
|
||||||
|
val key = "item.${Fantasysmp.MOD_ID}.$name.lore.line${index + 1}"
|
||||||
|
translations[key] = line
|
||||||
|
Component.translatable(key).withStyle(style)
|
||||||
|
}
|
||||||
|
properties = properties.component(DataComponents.LORE, ItemLore(components))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun lore(vararg lines: Pair<String, ChatFormatting>) {
|
||||||
|
val components = lines.mapIndexed { index, (line, style) ->
|
||||||
|
val key = "item.${Fantasysmp.MOD_ID}.$name.lore.line${index + 1}"
|
||||||
|
translations[key] = line
|
||||||
|
Component.translatable(key).withStyle(style)
|
||||||
|
}
|
||||||
|
properties = properties.component(DataComponents.LORE, ItemLore(components))
|
||||||
|
}
|
||||||
|
|
||||||
|
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: String) {
|
||||||
|
tag.forEach {
|
||||||
|
tags += mcItemTag(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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, translations)
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun provideDelegate(
|
||||||
|
thisRef: Any?, property: KProperty<*>
|
||||||
|
): Lazy<T> = lazy { build() }
|
||||||
|
}
|
||||||
|
|
||||||
|
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 // handwritten JSON already exists, skip auto-gen
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun <T : Item> Lazy<T>.getValue(thisRef: Any?, property: KProperty<*>): T = value
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package dev.zxq5.util
|
||||||
|
import dev.zxq5.Fantasysmp
|
||||||
|
import net.minecraft.core.registries.Registries
|
||||||
|
import net.minecraft.resources.Identifier
|
||||||
|
import net.minecraft.resources.ResourceKey
|
||||||
|
import net.minecraft.tags.TagKey
|
||||||
|
import net.minecraft.world.item.Item
|
||||||
|
import net.minecraft.world.item.equipment.EquipmentAsset
|
||||||
|
import net.minecraft.world.item.equipment.EquipmentAssets
|
||||||
|
|
||||||
|
fun id(path: String): Identifier = Identifier.fromNamespaceAndPath(Fantasysmp.MOD_ID, path)
|
||||||
|
fun String.resourceKey(): ResourceKey<EquipmentAsset> = ResourceKey.create(
|
||||||
|
EquipmentAssets.ROOT_ID,
|
||||||
|
Identifier.fromNamespaceAndPath(Fantasysmp.MOD_ID, this),
|
||||||
|
)
|
||||||
|
|
||||||
|
fun mcItemTag(path: String): TagKey<Item> = TagKey.create(
|
||||||
|
Registries.ITEM,
|
||||||
|
Identifier.withDefaultNamespace(path)
|
||||||
|
)
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"layers": {
|
|
||||||
"humanoid": [
|
|
||||||
{
|
|
||||||
"texture": "fantasysmp:alchemist"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"humanoid_leggings": [
|
|
||||||
{
|
|
||||||
"texture": "fantasysmp:alchemist"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"layers": {
|
|
||||||
"humanoid": [
|
|
||||||
{
|
|
||||||
"texture": "fantasysmp:blazing"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"humanoid_leggings": [
|
|
||||||
{
|
|
||||||
"texture": "fantasysmp:blazing"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"layers": {
|
|
||||||
"humanoid": [
|
|
||||||
{
|
|
||||||
"texture": "fantasysmp:crimson"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"humanoid_leggings": [
|
|
||||||
{
|
|
||||||
"texture": "fantasysmp:crimson"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"layers": {
|
|
||||||
"humanoid": [
|
|
||||||
{
|
|
||||||
"texture": "fantasysmp:dragon"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"humanoid_leggings": [
|
|
||||||
{
|
|
||||||
"texture": "fantasysmp:dragon"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"wings": [
|
|
||||||
{
|
|
||||||
"texture": "fantasysmp:dragon",
|
|
||||||
"use_player_texture": false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"layers": {
|
|
||||||
"humanoid": [
|
|
||||||
{
|
|
||||||
"texture": "fantasysmp:ender"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"humanoid_leggings": [
|
|
||||||
{
|
|
||||||
"texture": "fantasysmp:ender"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"layers": {
|
|
||||||
"humanoid": [
|
|
||||||
{
|
|
||||||
"texture": "fantasysmp:mechanist"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"humanoid_leggings": [
|
|
||||||
{
|
|
||||||
"texture": "fantasysmp:mechanist"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"layers": {
|
|
||||||
"humanoid": [
|
|
||||||
{
|
|
||||||
"texture": "fantasysmp:poseidon"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"humanoid_leggings": [
|
|
||||||
{
|
|
||||||
"texture": "fantasysmp:poseidon"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"layers": {
|
|
||||||
"humanoid": [
|
|
||||||
{
|
|
||||||
"texture": "fantasysmp:true_netherite"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"humanoid_leggings": [
|
|
||||||
{
|
|
||||||
"texture": "fantasysmp:true_netherite"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"layers": {
|
|
||||||
"humanoid": [
|
|
||||||
{
|
|
||||||
"texture": "fantasysmp:witherite"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"humanoid_leggings": [
|
|
||||||
{
|
|
||||||
"texture": "fantasysmp:witherite"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Regular → Executable
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 113 KiB |
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/alchemist_boots"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/alchemist_chestplate"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/alchemist_helmet"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/alchemist_leggings"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/alchemist_sword"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/blazing_boots"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/blazing_chestplate"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/blazing_helmet"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/blazing_leggings"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/blazing_sword"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/crimson_sword"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/dragon_boots"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/dragon_chestplate"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/dragon_helmet"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/dragon_leggings"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/dragon_scale"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/dragon_sword"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/dragonite_ingot"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/ender_boots"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/ender_chestplate"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/ender_helmet"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/ender_leggings"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/ender_sword"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/lightning_sword"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/poseidons_boots"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/poseidons_chestplate"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/poseidons_helmet"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/poseidons_leggings"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/poseidons_trident"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/stevens_wrath"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/true_netherite_boots"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/true_netherite_chestplate"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/true_netherite_helmet"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/true_netherite_leggings"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/true_netherite_sword"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/witherite_axe"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/witherite_boots"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/witherite_chestplate"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/witherite_helmet"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/witherite_leggings"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:condition",
|
|
||||||
"on_false": {
|
|
||||||
"type": "minecraft:special",
|
|
||||||
"base": "minecraft:item/shield",
|
|
||||||
"model": {
|
|
||||||
"type": "fantasysmp:witherite_shield"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"on_true": {
|
|
||||||
"type": "minecraft:special",
|
|
||||||
"base": "minecraft:item/shield_blocking",
|
|
||||||
"model": {
|
|
||||||
"type": "fantasysmp:witherite_shield"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"property": "minecraft:using_item",
|
|
||||||
"transformation": {
|
|
||||||
"left_rotation": [
|
|
||||||
0.0,
|
|
||||||
0.0,
|
|
||||||
0.0,
|
|
||||||
1.0
|
|
||||||
],
|
|
||||||
"right_rotation": [
|
|
||||||
0.0,
|
|
||||||
0.0,
|
|
||||||
0.0,
|
|
||||||
1.0
|
|
||||||
],
|
|
||||||
"scale": [
|
|
||||||
1.0,
|
|
||||||
-1.0,
|
|
||||||
-1.0
|
|
||||||
],
|
|
||||||
"translation": [
|
|
||||||
0.0,
|
|
||||||
0.0,
|
|
||||||
0.0
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"model": {
|
|
||||||
"type": "minecraft:model",
|
|
||||||
"model": "fantasysmp:item/witherite_sword"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"item.fantasysmp.witherite_sword": "Witherite Sword",
|
|
||||||
"item.fantasysmp.witherite_helmet": "Witherite Helmet",
|
|
||||||
"item.fantasysmp.witherite_chestplate": "Witherite Chestplate",
|
|
||||||
"item.fantasysmp.witherite_leggings": "Witherite Leggings",
|
|
||||||
"item.fantasysmp.witherite_boots": "Witherite Boots",
|
|
||||||
"item.fantasysmp.witherite_axe": "Witherite Axe",
|
|
||||||
"item.fantasysmp.witherite_shield": "Witherite Shield",
|
|
||||||
"item.fantasysmp.dragon_sword": "Dragon Sword",
|
|
||||||
"item.fantasysmp.dragon_helmet": "Dragon Helmet",
|
|
||||||
"item.fantasysmp.dragon_chestplate": "Dragon Chestplate",
|
|
||||||
"item.fantasysmp.dragon_leggings": "Dragon Leggings",
|
|
||||||
"item.fantasysmp.dragon_boots": "Dragon Boots"
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/diamond_boots",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/alchemist_boots"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/diamond_chestplate",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/alchemist_chestplate"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/diamond_helmet",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/alchemist_helmet"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/diamond_leggings",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/alchemist_leggings"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/diamond_sword",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/alchemist_sword"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/diamond_boots",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/blazing_boots"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/diamond_chestplate",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/blazing_chestplate"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/diamond_helmet",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/blazing_helmet"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/diamond_leggings",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/blazing_leggings"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/diamond_sword",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/blazing_sword"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/netherite_sword",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/crimson_sword"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/netherite_boots",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/dragon_boots"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/netherite_chestplate",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/dragon_chestplate"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/netherite_helmet",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/dragon_helmet"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/netherite_leggings",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/dragon_leggings"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/netherite_ingot",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/dragon_scale"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/netherite_sword",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/dragon_sword"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/netherite_ingot",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/dragonite_ingot"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/diamond_boots",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/ender_boots"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/diamond_chestplate",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/ender_chestplate"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/diamond_helmet",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/ender_helmet"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/diamond_leggings",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/ender_leggings"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/diamond_sword",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/ender_sword"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/netherite_sword",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/lightning_sword"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/netherite_boots",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/poseidons_boots"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/netherite_chestplate",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/poseidons_chestplate"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/netherite_helmet",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/poseidons_helmet"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/netherite_leggings",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/poseidons_leggings"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/trident",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/poseidons_trident"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/netherite_sword",
|
|
||||||
"display": {
|
|
||||||
"thirdperson_righthand": {
|
|
||||||
"rotation": [ 0, -90, 55 ],
|
|
||||||
"translation": [ 0, 12, -1 ],
|
|
||||||
"scale": [ 2.0, 2.0, 1.25 ]
|
|
||||||
},
|
|
||||||
"thirdperson_lefthand": {
|
|
||||||
"rotation": [ 0, 90, -55 ],
|
|
||||||
"translation": [ 0, 12, -1 ],
|
|
||||||
"scale": [ 2.0, 2.0, 1.25 ]
|
|
||||||
},
|
|
||||||
"firstperson_righthand": {
|
|
||||||
"rotation": [ 0, -90, 40 ],
|
|
||||||
"translation": [ 1.13, 3.2, 1.13 ],
|
|
||||||
"scale": [ 1.5, 1.5, 1.5 ]
|
|
||||||
},
|
|
||||||
"firstperson_lefthand": {
|
|
||||||
"rotation": [ 0, 90, -40 ],
|
|
||||||
"translation": [ 1.13, 3.2, 1.13 ],
|
|
||||||
"scale": [ 1.5, 1.5, 1.5 ]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/stevens_wrath"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "item/netherite_boots",
|
|
||||||
"textures": {
|
|
||||||
"layer0": "fantasysmp:item/true_netherite_boots"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user