this might actually work
build / build (push) Has been cancelled

This commit is contained in:
2026-06-30 22:26:46 +01:00
parent dd42e078ac
commit 1c1362d6ea
30 changed files with 526 additions and 26 deletions
+42 -5
View File
@@ -1,12 +1,16 @@
package dev.zxq5
import dev.zxq5.items.ModItems
import dev.zxq5.items.ModItems.CUSTOM_CREATIVE_TAB
import dev.zxq5.items.ModItems.CUSTOM_CREATIVE_TAB_KEY
import dev.zxq5.items.Witherite
import dev.zxq5.items.isWearingFullSet
import net.fabricmc.api.ModInitializer
import net.minecraft.core.Registry
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.world.item.Item
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents
import net.fabricmc.fabric.api.event.player.AttackEntityCallback
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.LivingEntity
import org.slf4j.LoggerFactory
object Fantasysmp : ModInitializer {
@@ -22,5 +26,38 @@ object Fantasysmp : ModInitializer {
logger.info("Hello Fabric world!")
ModItems.init();
// Register the group.
registerItemEffects()
}
private fun registerItemEffects() {
ServerTickEvents.END_SERVER_TICK.register { server ->
for (player in server.playerList.players) {
if (player.isWearingFullSet(Witherite.ARMOUR_SET)) {
player.removeEffect(MobEffects.WITHER)
}
}
}
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.SWORD) return@register InteractionResult.PASS
if (entity is LivingEntity) {
entity.addEffect(MobEffectInstance(MobEffects.WITHER, 60, 1), player)
}
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
}
}
}
+142
View File
@@ -0,0 +1,142 @@
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)
.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 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
}
}
+20 -9
View File
@@ -1,23 +1,19 @@
package dev.zxq5.items
import dev.zxq5.Fantasysmp
import dev.zxq5.items.Witherite.WITHERITE_HELMET
import dev.zxq5.items.Witherite.WITHERITE_SWORD
import dev.zxq5.items.Witherite.SWORD
import net.fabricmc.fabric.api.creativetab.v1.FabricCreativeModeTab
import net.minecraft.core.Registry
import net.minecraft.core.component.DataComponents
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.entity.EquipmentSlot
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.*
import net.minecraft.world.item.CreativeModeTab.DisplayItemsGenerator
import net.minecraft.world.item.CreativeModeTab.ItemDisplayParameters
import net.minecraft.world.item.component.ItemLore
import net.minecraft.world.item.equipment.ArmorMaterials
import net.minecraft.world.item.equipment.ArmorType
import java.util.List
import java.util.function.Supplier
@@ -38,16 +34,31 @@ object ModItems {
)
val CUSTOM_CREATIVE_TAB: CreativeModeTab = FabricCreativeModeTab.builder()
.icon(Supplier { ItemStack(WITHERITE_SWORD) })
.icon(Supplier { ItemStack(SWORD) })
.title(Component.translatable("Fantasysmp"))
.displayItems(DisplayItemsGenerator { params: ItemDisplayParameters, output: CreativeModeTab.Output ->
Witherite.ITEMS.forEach { output.accept(it) }
Dragonite.ITEMS.forEach { output.accept(it) }
})
.build()
fun init() {
Witherite.init();
Dragonite.init();
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
}
+37 -10
View File
@@ -2,22 +2,23 @@ package dev.zxq5.items
import dev.zxq5.Fantasysmp
import dev.zxq5.items.ModItems.register
import net.minecraft.network.chat.Component
import net.minecraft.core.component.DataComponents
import net.minecraft.resources.Identifier
import net.minecraft.resources.ResourceKey
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.Entity
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 {
@@ -44,38 +45,62 @@ object Witherite {
witherite_material_key,
)
val WITHERITE_SWORD = register("witherite_sword", ::WitheriteSword,
Item.Properties().sword(ToolMaterial.NETHERITE, 3.0F, -2.4F)
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 WITHERITE_HELMET = register(
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 WITHERITE_CHESTPLATE = register(
val CHESTPLATE = register(
"witherite_chestplate",
::Item,
Item.Properties().humanoidArmor(armorMaterial , ArmorType.CHESTPLATE)
.durability(ArmorType.CHESTPLATE.getDurability(armorMaterial.durability))
)
val WITHERITE_LEGGINGS = register(
val LEGGINGS = register(
"witherite_leggings",
::Item,
Item.Properties().humanoidArmor(armorMaterial , ArmorType.LEGGINGS)
.durability(ArmorType.LEGGINGS.getDurability(armorMaterial.durability))
)
val WITHERITE_BOOTS = register(
val BOOTS = register(
"witherite_boots",
::Item,
Item.Properties().humanoidArmor(armorMaterial , ArmorType.BOOTS)
.durability(ArmorType.BOOTS.getDurability(armorMaterial.durability))
)
val ITEMS = listOf(WITHERITE_SWORD, WITHERITE_HELMET, WITHERITE_CHESTPLATE, WITHERITE_LEGGINGS, WITHERITE_BOOTS)
val ITEMS = listOf(SWORD, AXE, SHIELD, HELMET, CHESTPLATE, LEGGINGS, BOOTS)
val ARMOUR_SET = ArmorSet(HELMET, CHESTPLATE, LEGGINGS, BOOTS)
fun init() {}
}
@@ -86,6 +111,8 @@ class WitheriteSword(properties: Properties) : Item(properties) {
return InteractionResult.PASS;
}
if (!user.isCrouching) return InteractionResult.PASS
val skull = WitherSkull(EntityType.WITHER_SKULL, level)
skull.setPos(user.eyePosition)
skull.deltaMovement = user.lookAngle