140 lines
5.4 KiB
Kotlin
140 lines
5.4 KiB
Kotlin
package dev.zxq5.items.sets
|
|
|
|
import dev.zxq5.items.template.ArmorSet
|
|
import dev.zxq5.items.template.GenericGearSet
|
|
import dev.zxq5.items.ModItems.register
|
|
import dev.zxq5.items.template.registerItem
|
|
import dev.zxq5.items.template.provideDelegate
|
|
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.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.*
|
|
import net.minecraft.world.level.Level
|
|
import kotlin.getValue
|
|
|
|
|
|
object Dragonite: GenericGearSet() {
|
|
override val materialName = "dragonite"
|
|
override val materialDefinition
|
|
get() = super.materialDefinition.copy(assetId = materialKey)
|
|
|
|
val SCALE by registerItem("dragon_scale", ::Item)
|
|
|
|
val INGOT by registerItem("dragonite_ingot", ::Item) {
|
|
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) {
|
|
properties {
|
|
enchantable(armorMaterial.enchantmentValue)
|
|
.component(DataComponents.USE_COOLDOWN, UseCooldown(2f))
|
|
.sword(ToolMaterial.NETHERITE, 3F, -2.4F)
|
|
}
|
|
smithingUpgrade(Items.END_CRYSTAL, Items.NETHERITE_SWORD, INGOT)
|
|
}
|
|
|
|
val HELMET by registerItem("dragonite_helmet", ::Item) {
|
|
properties {
|
|
humanoidArmor(armorMaterial, ArmorType.HELMET)
|
|
}
|
|
smithingUpgrade(Items.DRAGON_HEAD, Items.NETHERITE_HELMET, INGOT)
|
|
}
|
|
|
|
val CHESTPLATE by registerItem("dragonite_chestplate", ::Item) {
|
|
properties {
|
|
humanoidArmor(armorMaterial, ArmorType.CHESTPLATE)
|
|
.component(DataComponents.GLIDER, Unit.INSTANCE)
|
|
.component(DataComponents.UNBREAKABLE, Unit.INSTANCE)
|
|
}
|
|
smithingUpgrade(Items.ELYTRA, Items.NETHERITE_CHESTPLATE, INGOT)
|
|
}
|
|
|
|
val LEGGINGS by registerItem("dragonite_leggings", ::Item) {
|
|
properties {
|
|
humanoidArmor(armorMaterial, ArmorType.LEGGINGS)
|
|
}
|
|
smithingUpgrade(Items.CRYING_OBSIDIAN, Items.NETHERITE_LEGGINGS, INGOT)
|
|
}
|
|
|
|
val BOOTS by registerItem("dragonite_boots", ::Item) {
|
|
properties {
|
|
humanoidArmor(armorMaterial, ArmorType.BOOTS)
|
|
}
|
|
smithingUpgrade(Items.CRYING_OBSIDIAN, Items.NETHERITE_BOOTS, INGOT)
|
|
}
|
|
|
|
override val armorSet: ArmorSet = ArmorSet(HELMET, CHESTPLATE, LEGGINGS, BOOTS)
|
|
override val items = listOf(SWORD, HELMET, CHESTPLATE, LEGGINGS, BOOTS, SCALE, INGOT)
|
|
override fun onLoad() {}
|
|
}
|
|
|
|
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
|
|
}
|
|
}
|