From 9bb327a937190fd3f4fc7d8630d80f9dfd40d403 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 3 Nov 2024 15:34:40 +0100 Subject: [PATCH 01/83] Simplify cake entity renderer --- .../api/entity/renderer/CakeEntityRenderer.kt | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/renderer/CakeEntityRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/renderer/CakeEntityRenderer.kt index 8f3241198..328dbedb3 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/renderer/CakeEntityRenderer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/renderer/CakeEntityRenderer.kt @@ -22,16 +22,13 @@ import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.minecraft.block.Blocks import net.minecraft.client.render.OverlayTexture -import net.minecraft.client.render.RenderLayers import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.render.entity.EntityRenderer import net.minecraft.client.render.entity.EntityRendererFactory import net.minecraft.client.texture.SpriteAtlasTexture import net.minecraft.client.util.math.MatrixStack import net.minecraft.util.Identifier -import net.minecraft.util.math.BlockPos import net.minecraft.util.math.MathHelper -import net.minecraft.util.math.random.Random import opekope2.avm_staff.api.entity.CakeEntity import opekope2.avm_staff.mixin.ICakeBlockAccessor import opekope2.avm_staff.util.push @@ -63,24 +60,11 @@ class CakeEntityRenderer(context: EntityRendererFactory.Context) : EntityRendere val cakePitch = MathHelper.atan2(horizontalSpeed, normalSpeed.y).toFloat() matrices.push { - matrices.translate(0f, cake.getDimensions(cake.pose).height / 2, 0f) - matrices.multiply(Quaternionf().rotationYXZ(cakeYaw, cakePitch, 0f)) - matrices.translate(-.5f, NEGATIVE_HALF_CAKE_HEIGHT, -.5f) + translate(0f, cake.getDimensions(cake.pose).height / 2, 0f) + multiply(Quaternionf().rotationYXZ(cakeYaw, cakePitch, 0f)) + translate(-.5f, NEGATIVE_HALF_CAKE_HEIGHT, -.5f) - blockRenderManager.modelRenderer.render( - cake.world, - blockRenderManager.getModel(CAKE_STATE), - CAKE_STATE, - BlockPos.ofFloored(cake.x, cake.boundingBox.maxY, cake.z), - matrices, - vertexConsumers.getBuffer( - RenderLayers.getMovingBlockLayer(CAKE_STATE) - ), - false, - Random.create(), - CAKE_STATE.getRenderingSeed(cake.startPos), - OverlayTexture.DEFAULT_UV - ) + blockRenderManager.renderBlockAsEntity(CAKE_STATE, this, vertexConsumers, light, OverlayTexture.DEFAULT_UV) } super.render(cake, yaw, tickDelta, matrices, vertexConsumers, light) From 671d2a238d65d0c6b58fdb1f7ae794a0045c1ed8 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 3 Nov 2024 16:29:00 +0100 Subject: [PATCH 02/83] Add interpolation to cake renderer --- .../avm_staff/api/entity/CakeEntity.kt | 20 +++++++++++++++++-- .../api/entity/renderer/CakeEntityRenderer.kt | 7 ++----- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt index affcd2f0d..4dd85ca91 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt @@ -38,12 +38,13 @@ import net.minecraft.predicate.entity.EntityPredicates import net.minecraft.server.network.EntityTrackerEntry import net.minecraft.sound.SoundCategory import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.MathHelper import net.minecraft.util.math.Vec3d import net.minecraft.util.math.random.Random import net.minecraft.world.World import opekope2.avm_staff.api.* -import opekope2.avm_staff.util.damageSource -import opekope2.avm_staff.util.times +import opekope2.avm_staff.util.* +import kotlin.math.sqrt /** * A flying cake entity, which splashes on collision damaging target(s). @@ -136,9 +137,11 @@ class CakeEntity(entityType: EntityType, world: World) : Entity(enti override fun getGravity() = 0.04 override fun tick() { + setPrevData() ++timeFalling applyGravity() move(MovementType.SELF, velocity) + setYawAndPitch() if (!world.isClient) { if (timeFalling > 100 && blockPos.y !in world.topY downTo (world.bottomY + 1) || timeFalling > 600) { discard() @@ -149,6 +152,19 @@ class CakeEntity(entityType: EntityType, world: World) : Entity(enti velocity *= 0.98 } + private fun setPrevData() { + prevYaw = yaw + prevPitch = pitch + prevHorizontalSpeed = horizontalSpeed + } + + private fun setYawAndPitch() { + val (vx, vy, vz) = velocity.normalize() + val horizontalSpeed = sqrt(vx * vx + vz * vz) + yaw = MathHelper.atan2(vx, vz).toFloat() + pitch = MathHelper.atan2(horizontalSpeed, vy).toFloat() + } + private fun splashOnImpact() { if (horizontalCollision || verticalCollision) { damageCollidingEntities() diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/renderer/CakeEntityRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/renderer/CakeEntityRenderer.kt index 328dbedb3..023c99e1c 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/renderer/CakeEntityRenderer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/renderer/CakeEntityRenderer.kt @@ -33,7 +33,6 @@ import opekope2.avm_staff.api.entity.CakeEntity import opekope2.avm_staff.mixin.ICakeBlockAccessor import opekope2.avm_staff.util.push import org.joml.Quaternionf -import kotlin.math.sqrt /** * Renderer of [CakeEntity]. @@ -54,10 +53,8 @@ class CakeEntityRenderer(context: EntityRendererFactory.Context) : EntityRendere vertexConsumers: VertexConsumerProvider, light: Int ) { - val normalSpeed = cake.velocity.normalize() - val horizontalSpeed = sqrt(normalSpeed.x * normalSpeed.x + normalSpeed.z * normalSpeed.z) - val cakeYaw = MathHelper.atan2(normalSpeed.x, normalSpeed.z).toFloat() - val cakePitch = MathHelper.atan2(horizontalSpeed, normalSpeed.y).toFloat() + val cakeYaw = MathHelper.lerpAngleDegrees(tickDelta, cake.prevYaw, cake.yaw) + val cakePitch = MathHelper.lerpAngleDegrees(tickDelta, cake.prevPitch, cake.pitch) matrices.push { translate(0f, cake.getDimensions(cake.pose).height / 2, 0f) From c898d2ced2c8f95185ef93392ba746fa0ee54383 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 3 Nov 2024 18:25:22 +0100 Subject: [PATCH 03/83] Rewrite cake entity data sync --- .../avm_staff/api/entity/CakeEntity.kt | 40 ++++++++++--------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt index 4dd85ca91..8fc679047 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt @@ -31,7 +31,6 @@ import net.minecraft.entity.LivingEntity import net.minecraft.entity.MovementType import net.minecraft.entity.damage.DamageSource import net.minecraft.entity.data.DataTracker -import net.minecraft.entity.data.TrackedDataHandlerRegistry import net.minecraft.nbt.NbtCompound import net.minecraft.network.packet.s2c.play.EntitySpawnS2CPacket import net.minecraft.predicate.entity.EntityPredicates @@ -55,12 +54,20 @@ class CakeEntity(entityType: EntityType, world: World) : Entity(enti constructor(world: World, position: Vec3d, velocity: Vec3d, thrower: LivingEntity?) : this(cakeEntityType.get(), world) { + val (x, y, z) = position + val (vx, vy, vz) = velocity + init(x, y, z, vx, vy, vz, thrower) + } + + private fun init(x: Double, y: Double, z: Double, vx: Double, vy: Double, vz: Double, thrower: LivingEntity?) { intersectionChecked = true - setPosition(position) - this.velocity = velocity - prevX = position.x - prevY = position.y - prevZ = position.z + setPosition(x, y, z) + setVelocity(vx, vy, vz) + prevX = x + prevY = y + prevZ = z + setYawAndPitch() + setPrevData() startPos = blockPos this.thrower = thrower } @@ -75,18 +82,14 @@ class CakeEntity(entityType: EntityType, world: World) : Entity(enti /** * The position, where the cake was spawned. */ - var startPos: BlockPos - get() = dataTracker[BLOCK_POS] - set(pos) { - dataTracker[BLOCK_POS] = pos - } + var startPos: BlockPos = BlockPos.ORIGIN + private set override fun getMoveEffect(): MoveEffect { return MoveEffect.NONE } override fun initDataTracker(builder: DataTracker.Builder) { - builder.add(BLOCK_POS, BlockPos.ORIGIN) } override fun onRemoved() { @@ -210,20 +213,19 @@ class CakeEntity(entityType: EntityType, world: World) : Entity(enti override fun entityDataRequiresOperator() = true override fun createSpawnPacket(entityTrackerEntry: EntityTrackerEntry) = - EntitySpawnS2CPacket(this, entityTrackerEntry) + EntitySpawnS2CPacket(this, entityTrackerEntry, thrower?.id ?: 0) override fun onSpawnPacket(packet: EntitySpawnS2CPacket) { super.onSpawnPacket(packet) - intersectionChecked = true - setPosition(packet.x, packet.y, packet.z) - startPos = blockPos + init( + packet.x, packet.y, packet.z, + packet.velocityX, packet.velocityY, packet.velocityZ, + world.getEntityById(packet.entityData) as? LivingEntity + ) } companion object { private val CAKE_STATE = Blocks.CAKE.defaultState - private val BLOCK_POS = DataTracker.registerData( - CakeEntity::class.java, TrackedDataHandlerRegistry.BLOCK_POS - ) private val particleManager by lazy { MinecraftClient.getInstance().particleManager } private val graphicsModeOption by lazy { MinecraftClient.getInstance().options.graphicsMode } private val particlePerSide: Int From a6635ef3cc272a31ab488480d7b9e0a51763cd66 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 3 Nov 2024 18:50:53 +0100 Subject: [PATCH 04/83] Move MinecraftClient calls to utility file --- .../neoforge/item/NeoForgeStaffItem.kt | 8 +-- .../avm_staff/api/entity/CakeEntity.kt | 9 +-- .../renderer/BlockStateStaffItemRenderer.kt | 15 ++-- .../api/item/renderer/StaffRenderer.kt | 31 +++++---- .../internal/staff/handler/CampfireHandler.kt | 9 +-- .../internal/staff/handler/FurnaceHandler.kt | 2 - .../avm_staff/util/MinecraftClientUtil.kt | 68 +++++++++++++++++++ 7 files changed, 106 insertions(+), 36 deletions(-) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/util/MinecraftClientUtil.kt diff --git a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/NeoForgeStaffItem.kt b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/NeoForgeStaffItem.kt index d2745625e..4d6f249d3 100644 --- a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/NeoForgeStaffItem.kt +++ b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/NeoForgeStaffItem.kt @@ -18,7 +18,6 @@ package opekope2.avm_staff.internal.neoforge.item -import net.minecraft.client.MinecraftClient import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.render.item.BuiltinModelItemRenderer import net.minecraft.client.render.model.json.ModelTransformationMode @@ -33,6 +32,8 @@ import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions import net.neoforged.neoforge.common.extensions.IItemExtension import opekope2.avm_staff.api.item.StaffItem import opekope2.avm_staff.api.item.renderer.StaffRenderer +import opekope2.avm_staff.util.blockEntityRenderDispatcher +import opekope2.avm_staff.util.entityModelLoader import opekope2.avm_staff.util.itemInStaff import opekope2.avm_staff.util.staffHandlerOrDefault import java.util.function.Consumer @@ -71,10 +72,7 @@ class NeoForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IItemExt }) } - object Renderer : BuiltinModelItemRenderer( - MinecraftClient.getInstance().blockEntityRenderDispatcher, - MinecraftClient.getInstance().entityModelLoader - ) { + object Renderer : BuiltinModelItemRenderer(blockEntityRenderDispatcher, entityModelLoader) { override fun render( stack: ItemStack, mode: ModelTransformationMode, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt index 8fc679047..3ca365dbd 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt @@ -21,7 +21,6 @@ package opekope2.avm_staff.api.entity import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.minecraft.block.Blocks -import net.minecraft.client.MinecraftClient import net.minecraft.client.option.GraphicsMode import net.minecraft.client.particle.BlockDustParticle import net.minecraft.client.world.ClientWorld @@ -226,14 +225,12 @@ class CakeEntity(entityType: EntityType, world: World) : Entity(enti companion object { private val CAKE_STATE = Blocks.CAKE.defaultState - private val particleManager by lazy { MinecraftClient.getInstance().particleManager } - private val graphicsModeOption by lazy { MinecraftClient.getInstance().options.graphicsMode } private val particlePerSide: Int @Environment(EnvType.CLIENT) - get() = when (graphicsModeOption.value!!) { - GraphicsMode.FAST -> 4 - GraphicsMode.FANCY -> 5 + get() = when (clientOptions.graphicsMode.value) { GraphicsMode.FABULOUS -> 6 + GraphicsMode.FANCY -> 5 + else -> 4 } /** diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/BlockStateStaffItemRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/BlockStateStaffItemRenderer.kt index 4932cdf4e..4bdee169e 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/BlockStateStaffItemRenderer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/BlockStateStaffItemRenderer.kt @@ -21,13 +21,14 @@ package opekope2.avm_staff.api.item.renderer import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.minecraft.block.BlockState -import net.minecraft.client.MinecraftClient import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.render.block.BlockModels import net.minecraft.client.render.model.json.ModelTransformationMode import net.minecraft.client.util.ModelIdentifier import net.minecraft.client.util.math.MatrixStack import net.minecraft.item.ItemStack +import opekope2.avm_staff.util.bakedModelManager +import opekope2.avm_staff.util.itemRenderer /** * A [IStaffItemRenderer], always which renders a single block state. @@ -90,11 +91,15 @@ class BlockStateStaffItemRenderer(blockState: BlockState) : IStaffItemRenderer { light: Int, overlay: Int ) { - val itemRenderer = MinecraftClient.getInstance().itemRenderer - val modelManager = MinecraftClient.getInstance().bakedModelManager - val model = modelManager.getModel(blockStateId) itemRenderer.renderItem( - blockStateItem, ModelTransformationMode.NONE, false, matrices, vertexConsumers, light, overlay, model + blockStateItem, + ModelTransformationMode.NONE, + false, + matrices, + vertexConsumers, + light, + overlay, + bakedModelManager.getModel(blockStateId) ) } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt index 6da562e53..e9dd015f8 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt @@ -20,7 +20,6 @@ package opekope2.avm_staff.api.item.renderer import net.fabricmc.api.EnvType import net.fabricmc.api.Environment -import net.minecraft.client.MinecraftClient import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.render.model.BakedModel import net.minecraft.client.render.model.json.ModelTransformationMode @@ -30,6 +29,8 @@ import net.minecraft.registry.Registries import opekope2.avm_staff.api.component.StaffRendererPartComponent import opekope2.avm_staff.api.staffRendererOverrideComponentType import opekope2.avm_staff.api.staffRendererPartComponentType +import opekope2.avm_staff.util.bakedModelManager +import opekope2.avm_staff.util.itemRenderer import opekope2.avm_staff.util.itemStackInStaff import opekope2.avm_staff.util.push import kotlin.jvm.optionals.getOrNull @@ -194,11 +195,15 @@ object StaffRenderer { if (staffItemRenderer != null) { staffItemRenderer.renderItemInStaff(staffStack, mode, matrices, vertexConsumers, light, overlay) } else { - val itemRenderer = MinecraftClient.getInstance().itemRenderer - val model = MinecraftClient.getInstance().bakedModelManager.missingModel - itemRenderer.renderItem( - itemStackInStaff, ModelTransformationMode.NONE, false, matrices, vertexConsumers, light, overlay, model + itemStackInStaff, + ModelTransformationMode.NONE, + false, + matrices, + vertexConsumers, + light, + overlay, + bakedModelManager.missingModel ) } } @@ -211,23 +216,25 @@ object StaffRenderer { overlay: Int, part: StaffRendererPartComponent ) { - val itemRenderer = MinecraftClient.getInstance().itemRenderer - val model = safeGetModel(staffStack, part) - itemRenderer.renderItem( - staffStack, ModelTransformationMode.NONE, false, matrices, vertexConsumers, light, overlay, model + staffStack, + ModelTransformationMode.NONE, + false, + matrices, + vertexConsumers, + light, + overlay, + safeGetModel(staffStack, part) ) } private fun safeGetModel(staffStack: ItemStack, part: StaffRendererPartComponent): BakedModel { - val itemRenderer = MinecraftClient.getInstance().itemRenderer - staffStack[staffRendererPartComponentType.get()] = part val model = itemRenderer.getModel(staffStack, null, null, 0) staffStack.remove(staffRendererPartComponentType.get()) // Prevent StackOverflowError if an override is missing return if (!model.isBuiltin) model - else MinecraftClient.getInstance().bakedModelManager.missingModel + else bakedModelManager.missingModel } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt index d72d5f272..aef6cf045 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt @@ -24,7 +24,6 @@ import dev.architectury.registry.registries.RegistrySupplier import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.minecraft.block.* -import net.minecraft.client.MinecraftClient import net.minecraft.client.option.GraphicsMode import net.minecraft.entity.Entity import net.minecraft.entity.LivingEntity @@ -115,8 +114,6 @@ internal class CampfireHandler( @Environment(EnvType.CLIENT) fun throwFlameParticles(user: LivingEntity, target: Vec3d, relativeRight: Vec3d, relativeUp: Vec3d) { val random = Random.create() - val particleManager = MinecraftClient.getInstance().particleManager - val origin = user.approximateStaffTipPosition for (i in 0..flameParticleCount) { @@ -257,10 +254,10 @@ internal class CampfireHandler( private val flameParticleCount: Int @Environment(EnvType.CLIENT) - get() = when (MinecraftClient.getInstance().options.graphicsMode.value!!) { - GraphicsMode.FAST -> 4 * 4 - GraphicsMode.FANCY -> 8 * 8 + get() = when (clientOptions.graphicsMode.value) { GraphicsMode.FABULOUS -> 16 * 16 + GraphicsMode.FANCY -> 8 * 8 + else -> 4 * 4 } private val firePellets = mutableListOf() diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt index 49142ed97..4456fc19c 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt @@ -23,7 +23,6 @@ import net.fabricmc.api.Environment import net.minecraft.block.AbstractFurnaceBlock import net.minecraft.block.Block import net.minecraft.block.BlockState -import net.minecraft.client.MinecraftClient import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.render.model.json.ModelTransformationMode import net.minecraft.client.util.math.MatrixStack @@ -129,7 +128,6 @@ internal class FurnaceHandler( val ry = Math.random() * 0.5 val rz = Math.random() * 0.25 - 0.25 / 2 - val particleManager = MinecraftClient.getInstance().particleManager particleManager.addParticle(ParticleTypes.FLAME, x + rx, y + ry, z + rz, 0.0, 0.0, 0.0) particleManager.addParticle(ParticleTypes.SMOKE, x + rx, y + ry, z + rz, 0.0, 0.0, 0.0) } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/MinecraftClientUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/MinecraftClientUtil.kt new file mode 100644 index 000000000..6ea2010c0 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/MinecraftClientUtil.kt @@ -0,0 +1,68 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +@file: JvmName("MinecraftClientUtil") +@file: Environment(EnvType.CLIENT) + +package opekope2.avm_staff.util + +import net.fabricmc.api.EnvType +import net.fabricmc.api.Environment +import net.minecraft.client.MinecraftClient +import net.minecraft.client.option.GameOptions +import net.minecraft.client.particle.ParticleManager +import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher +import net.minecraft.client.render.entity.model.EntityModelLoader +import net.minecraft.client.render.item.ItemRenderer +import net.minecraft.client.render.model.BakedModelManager + +/** + * @see MinecraftClient.bakedModelManager + */ +inline val bakedModelManager: BakedModelManager + get() = MinecraftClient.getInstance().bakedModelManager + +/** + * @see MinecraftClient.blockEntityRenderDispatcher + */ +inline val blockEntityRenderDispatcher: BlockEntityRenderDispatcher + get() = MinecraftClient.getInstance().blockEntityRenderDispatcher + +/** + * @see MinecraftClient.options + */ +inline val clientOptions: GameOptions + get() = MinecraftClient.getInstance().options + +/** + * @see MinecraftClient.entityModelLoader + */ +inline val entityModelLoader: EntityModelLoader + get() = MinecraftClient.getInstance().entityModelLoader + +/** + * @see MinecraftClient.itemRenderer + */ +inline val itemRenderer: ItemRenderer + get() = MinecraftClient.getInstance().itemRenderer + +/** + * @see MinecraftClient.particleManager + */ +inline val particleManager: ParticleManager + get() = MinecraftClient.getInstance().particleManager From ebb0166eb0634aed08267da49f4237548755b473 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 3 Nov 2024 19:11:16 +0100 Subject: [PATCH 05/83] Add staff item renderer for the missing model --- .../api/item/renderer/MissingModelRenderer.kt | 54 +++++++++++++++++++ .../api/item/renderer/StaffRenderer.kt | 30 ++--------- 2 files changed, 57 insertions(+), 27 deletions(-) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/MissingModelRenderer.kt diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/MissingModelRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/MissingModelRenderer.kt new file mode 100644 index 000000000..f101810f7 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/MissingModelRenderer.kt @@ -0,0 +1,54 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.api.item.renderer + +import net.minecraft.client.render.VertexConsumerProvider +import net.minecraft.client.render.model.json.ModelTransformationMode +import net.minecraft.client.util.math.MatrixStack +import net.minecraft.item.ItemStack +import opekope2.avm_staff.util.bakedModelManager +import opekope2.avm_staff.util.itemRenderer +import opekope2.avm_staff.util.itemStackInStaff + +/** + * A staff item renderer, which renders the missing model. + */ +object MissingModelRenderer : IStaffItemRenderer { + override fun renderItemInStaff( + staffStack: ItemStack, + mode: ModelTransformationMode, + matrices: MatrixStack, + vertexConsumers: VertexConsumerProvider, + light: Int, + overlay: Int + ) { + staffStack.itemStackInStaff?.let { itemInStaff -> + itemRenderer.renderItem( + itemInStaff, + ModelTransformationMode.NONE, + false, + matrices, + vertexConsumers, + light, + overlay, + bakedModelManager.missingModel + ) + } + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt index e9dd015f8..a97d8e337 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt @@ -176,38 +176,14 @@ object StaffRenderer { ) } else { staffStack.itemStackInStaff?.let { itemInStaff -> - renderItem(staffStack, itemInStaff, mode, matrices, light, overlay, vertexConsumers) + val staffItemRenderer = IStaffItemRenderer[Registries.ITEM.getId(itemInStaff.item)] + ?: MissingModelRenderer + staffItemRenderer.renderItemInStaff(staffStack, mode, matrices, vertexConsumers, light, overlay) } } } } - private fun renderItem( - staffStack: ItemStack, - itemStackInStaff: ItemStack, - mode: ModelTransformationMode, - matrices: MatrixStack, - light: Int, - overlay: Int, - vertexConsumers: VertexConsumerProvider - ) { - val staffItemRenderer = IStaffItemRenderer[Registries.ITEM.getId(itemStackInStaff.item)] - if (staffItemRenderer != null) { - staffItemRenderer.renderItemInStaff(staffStack, mode, matrices, vertexConsumers, light, overlay) - } else { - itemRenderer.renderItem( - itemStackInStaff, - ModelTransformationMode.NONE, - false, - matrices, - vertexConsumers, - light, - overlay, - bakedModelManager.missingModel - ) - } - } - private fun renderPart( staffStack: ItemStack, matrices: MatrixStack, From e89e89d8f9dcb6647c2032fe3c6709b50265f27d Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 3 Nov 2024 20:02:49 +0100 Subject: [PATCH 06/83] Remove staff renderer overrides --- .../mixin/BipedEntityModelMixin.java | 7 +- .../kotlin/opekope2/avm_staff/api/StaffMod.kt | 13 --- .../StaffRendererOverrideComponent.kt | 83 ------------------- .../renderer/BlockStateStaffItemRenderer.kt | 67 +++------------ .../api/item/renderer/StaffRenderer.kt | 27 ++---- .../internal/model/ModelPredicates.kt | 11 +-- 6 files changed, 22 insertions(+), 186 deletions(-) delete mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/StaffRendererOverrideComponent.kt diff --git a/StaffMod/src/main/java/opekope2/avm_staff/mixin/BipedEntityModelMixin.java b/StaffMod/src/main/java/opekope2/avm_staff/mixin/BipedEntityModelMixin.java index 87a9f0e56..e0ee5c45f 100644 --- a/StaffMod/src/main/java/opekope2/avm_staff/mixin/BipedEntityModelMixin.java +++ b/StaffMod/src/main/java/opekope2/avm_staff/mixin/BipedEntityModelMixin.java @@ -21,8 +21,6 @@ import net.minecraft.client.model.ModelPart; import net.minecraft.client.render.entity.model.BipedEntityModel; import net.minecraft.entity.LivingEntity; -import opekope2.avm_staff.api.StaffMod; -import opekope2.avm_staff.api.component.StaffRendererOverrideComponent; import opekope2.avm_staff.util.ItemStackUtil; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -71,9 +69,6 @@ private void positionRightArm(LivingEntity entity, CallbackInfo ci) { @Unique private boolean staffMod$pointForward(BipedEntityModel.ArmPose armPose, LivingEntity entity) { if (armPose != BipedEntityModel.ArmPose.ITEM) return false; - if (!ItemStackUtil.isStaff(entity.getActiveItem())) return false; - - StaffRendererOverrideComponent rendererOverride = entity.getActiveItem().get(StaffMod.getStaffRendererOverrideComponentType().get()); - return rendererOverride == null || rendererOverride.isActive().orElse(true); + return ItemStackUtil.isStaff(entity.getActiveItem()); } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt index b589a8171..83fe9facc 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -50,7 +50,6 @@ import opekope2.avm_staff.api.block.CrownBlock import opekope2.avm_staff.api.block.WallCrownBlock import opekope2.avm_staff.api.component.StaffFurnaceDataComponent import opekope2.avm_staff.api.component.StaffItemComponent -import opekope2.avm_staff.api.component.StaffRendererOverrideComponent import opekope2.avm_staff.api.component.StaffRendererPartComponent import opekope2.avm_staff.api.entity.CakeEntity import opekope2.avm_staff.api.entity.ImpactTntEntity @@ -246,18 +245,6 @@ val staffFurnaceDataComponentType: RegistrySupplier> = - DATA_COMPONENT_TYPES.register("staff_renderer_override") { - ComponentType.builder() - .codec(StaffRendererOverrideComponent.CODEC) - .packetCodec(StaffRendererOverrideComponent.PACKET_CODEC) - .build() - } - /** * Data component registered as `avm_staff:staff_renderer_part`. Only used for rendering. */ diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/StaffRendererOverrideComponent.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/StaffRendererOverrideComponent.kt deleted file mode 100644 index 1abeca086..000000000 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/StaffRendererOverrideComponent.kt +++ /dev/null @@ -1,83 +0,0 @@ -/* - * AvM Staff Mod - * Copyright (c) 2024 opekope2 - * - * This mod is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This mod is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this mod. If not, see . - */ - -package opekope2.avm_staff.api.component - -import com.mojang.serialization.Codec -import com.mojang.serialization.codecs.RecordCodecBuilder -import net.minecraft.block.BlockState -import net.minecraft.client.render.model.json.ModelTransformationMode -import net.minecraft.entity.LivingEntity -import net.minecraft.network.PacketByteBuf -import net.minecraft.network.RegistryByteBuf -import net.minecraft.network.codec.PacketCodec -import opekope2.avm_staff.api.item.renderer.StaffRenderer -import java.util.* - -/** - * Data component to override the behavior of a [StaffRenderer]. - * - * @param renderMode The display transform of the model to use - * @param isActive The item should be treated as if it was [LivingEntity.getActiveItem] - * @param blockState The blocks state to render in the staff - */ -data class StaffRendererOverrideComponent( - val renderMode: Optional, - val isActive: Optional, - val blockState: Optional -) { - private constructor(buf: RegistryByteBuf) : this( - buf.readOptional { - it.readEnumConstant(ModelTransformationMode::class.java) - }, - buf.readOptional(PacketByteBuf::readBoolean), - buf.readOptional { - it.decodeAsJson(BlockState.CODEC) - } - ) - - private fun encode(buf: RegistryByteBuf) { - buf.writeOptional(renderMode, PacketByteBuf::writeEnumConstant) - buf.writeOptional(isActive, PacketByteBuf::writeBoolean) - buf.writeOptional(blockState) { buffer, state -> - buffer.encodeAsJson(BlockState.CODEC, state) - } - } - - companion object { - /** - * [Codec] for [StaffRendererOverrideComponent]. - */ - @JvmField - val CODEC: Codec = RecordCodecBuilder.create { instance -> - instance.group( - ModelTransformationMode.CODEC.optionalFieldOf("renderMode") - .forGetter(StaffRendererOverrideComponent::renderMode), - Codec.BOOL.optionalFieldOf("pointForward").forGetter(StaffRendererOverrideComponent::isActive), - BlockState.CODEC.optionalFieldOf("blockState").forGetter(StaffRendererOverrideComponent::blockState) - ).apply(instance, ::StaffRendererOverrideComponent) - } - - /** - * [PacketCodec] for [StaffRendererOverrideComponent]. - */ - @JvmField - val PACKET_CODEC: PacketCodec = - PacketCodec.of(StaffRendererOverrideComponent::encode, ::StaffRendererOverrideComponent) - } -} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/BlockStateStaffItemRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/BlockStateStaffItemRenderer.kt index 4bdee169e..2b72965b5 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/BlockStateStaffItemRenderer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/BlockStateStaffItemRenderer.kt @@ -24,7 +24,6 @@ import net.minecraft.block.BlockState import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.render.block.BlockModels import net.minecraft.client.render.model.json.ModelTransformationMode -import net.minecraft.client.util.ModelIdentifier import net.minecraft.client.util.math.MatrixStack import net.minecraft.item.ItemStack import opekope2.avm_staff.util.bakedModelManager @@ -47,60 +46,16 @@ class BlockStateStaffItemRenderer(blockState: BlockState) : IStaffItemRenderer { vertexConsumers: VertexConsumerProvider, light: Int, overlay: Int - ) = renderBlockState(blockStateId, blockItem, matrices, vertexConsumers, light, overlay) - - companion object { - /** - * Renders a [BlockState]. - * - * @param blockState The block state to render - * @param matrices The render transformation matrix - * @param vertexConsumers The render output - * @param light Light parameter from the game - * @param overlay Overlay parameter from the game - */ - @JvmStatic - fun renderBlockState( - blockState: BlockState, - matrices: MatrixStack, - vertexConsumers: VertexConsumerProvider, - light: Int, - overlay: Int - ) { - val blockStateId = BlockModels.getModelId(blockState) - val blockStateItem = blockState.block.asItem().defaultStack - renderBlockState(blockStateId, blockStateItem, matrices, vertexConsumers, light, overlay) - } - - /** - * Renders a [BlockState]. - * - * @param blockStateId The ID of the block state - * @param blockStateItem The item form of the block state - * @param matrices The render transformation matrix - * @param vertexConsumers The render output - * @param light Light parameter from the game - * @param overlay Overlay parameter from the game - */ - @JvmStatic - fun renderBlockState( - blockStateId: ModelIdentifier, - blockStateItem: ItemStack, - matrices: MatrixStack, - vertexConsumers: VertexConsumerProvider, - light: Int, - overlay: Int - ) { - itemRenderer.renderItem( - blockStateItem, - ModelTransformationMode.NONE, - false, - matrices, - vertexConsumers, - light, - overlay, - bakedModelManager.getModel(blockStateId) - ) - } + ) { + itemRenderer.renderItem( + blockItem, + ModelTransformationMode.NONE, + false, + matrices, + vertexConsumers, + light, + overlay, + bakedModelManager.getModel(blockStateId) + ) } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt index a97d8e337..3ef8c4707 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt @@ -27,13 +27,11 @@ import net.minecraft.client.util.math.MatrixStack import net.minecraft.item.ItemStack import net.minecraft.registry.Registries import opekope2.avm_staff.api.component.StaffRendererPartComponent -import opekope2.avm_staff.api.staffRendererOverrideComponentType import opekope2.avm_staff.api.staffRendererPartComponentType import opekope2.avm_staff.util.bakedModelManager import opekope2.avm_staff.util.itemRenderer import opekope2.avm_staff.util.itemStackInStaff import opekope2.avm_staff.util.push -import kotlin.jvm.optionals.getOrNull /** * Builtin model item renderer for staffs. @@ -58,19 +56,17 @@ object StaffRenderer { light: Int, overlay: Int ) { - val renderMode = staffStack[staffRendererOverrideComponentType.get()]?.renderMode?.getOrNull() ?: mode - - when (renderMode) { + when (mode) { ModelTransformationMode.GUI -> renderInventoryStaff( - staffStack, renderMode, matrices, vertexConsumers, light, overlay + staffStack, mode, matrices, vertexConsumers, light, overlay ) ModelTransformationMode.FIXED -> renderItemFrameStaff( - staffStack, renderMode, matrices, vertexConsumers, light, overlay + staffStack, mode, matrices, vertexConsumers, light, overlay ) else -> renderFullStaff( - staffStack, renderMode, matrices, vertexConsumers, light, overlay + staffStack, mode, matrices, vertexConsumers, light, overlay ) } } @@ -169,17 +165,10 @@ object StaffRenderer { matrices.push { safeGetModel(staffStack, StaffRendererPartComponent.ITEM).transformation.fixed.apply(false, this) - val blockStateOverride = staffStack[staffRendererOverrideComponentType.get()]?.blockState?.getOrNull() - if (blockStateOverride != null) { - BlockStateStaffItemRenderer.renderBlockState( - blockStateOverride, matrices, vertexConsumers, light, overlay - ) - } else { - staffStack.itemStackInStaff?.let { itemInStaff -> - val staffItemRenderer = IStaffItemRenderer[Registries.ITEM.getId(itemInStaff.item)] - ?: MissingModelRenderer - staffItemRenderer.renderItemInStaff(staffStack, mode, matrices, vertexConsumers, light, overlay) - } + staffStack.itemStackInStaff?.let { itemInStaff -> + val staffItemRenderer = IStaffItemRenderer[Registries.ITEM.getId(itemInStaff.item)] + ?: MissingModelRenderer + staffItemRenderer.renderItemInStaff(staffStack, mode, matrices, vertexConsumers, light, overlay) } } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt index dbcf9b30f..c58bab535 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt @@ -24,22 +24,15 @@ import net.minecraft.client.item.ClampedModelPredicateProvider import net.minecraft.item.ItemStack import net.minecraft.util.Identifier import opekope2.avm_staff.api.component.StaffRendererPartComponent -import opekope2.avm_staff.api.staffRendererOverrideComponentType import opekope2.avm_staff.api.staffRendererPartComponentType import opekope2.avm_staff.util.MOD_ID -import kotlin.jvm.optionals.getOrNull // ModelPredicateProviderRegistry.register is private in common project @Environment(EnvType.CLIENT) fun registerModelPredicateProviders(register: (Identifier, ClampedModelPredicateProvider) -> Unit) { register(Identifier.of(MOD_ID, "using_item")) { stack, _, entity, _ -> - val isActiveOverride = stack[staffRendererOverrideComponentType.get()]?.isActive?.getOrNull() - when { - isActiveOverride == true -> 1f - isActiveOverride == false -> 0f - entity != null && entity.isUsingItem && ItemStack.areEqual(entity.activeItem, stack) -> 1f - else -> 0f - } + if (entity != null && entity.isUsingItem && ItemStack.areEqual(entity.activeItem, stack)) 1f + else 0f } register(Identifier.of(MOD_ID, "head"), matchStaffRendererPart(StaffRendererPartComponent.HEAD)) register(Identifier.of(MOD_ID, "item"), matchStaffRendererPart(StaffRendererPartComponent.ITEM)) From d159f091236a95789eaede443d7cf67a120cacb0 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 3 Nov 2024 21:55:54 +0100 Subject: [PATCH 07/83] Inline model predicate provider registration --- .../opekope2/avm_staff/internal/model/ModelPredicates.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt index c58bab535..8b64c835e 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt @@ -29,7 +29,7 @@ import opekope2.avm_staff.util.MOD_ID // ModelPredicateProviderRegistry.register is private in common project @Environment(EnvType.CLIENT) -fun registerModelPredicateProviders(register: (Identifier, ClampedModelPredicateProvider) -> Unit) { +inline fun registerModelPredicateProviders(register: (Identifier, ClampedModelPredicateProvider) -> Unit) { register(Identifier.of(MOD_ID, "using_item")) { stack, _, entity, _ -> if (entity != null && entity.isUsingItem && ItemStack.areEqual(entity.activeItem, stack)) 1f else 0f @@ -40,7 +40,7 @@ fun registerModelPredicateProviders(register: (Identifier, ClampedModelPredicate register(Identifier.of(MOD_ID, "rod_bottom"), matchStaffRendererPart(StaffRendererPartComponent.ROD_BOTTOM)) } -private fun matchStaffRendererPart(part: StaffRendererPartComponent) = ClampedModelPredicateProvider { stack, _, _, _ -> +fun matchStaffRendererPart(part: StaffRendererPartComponent) = ClampedModelPredicateProvider { stack, _, _, _ -> if (stack[staffRendererPartComponentType.get()] == part) 1f else 0f } From 7e9021464f842234a6d1e09f9e3fc2ab56fa1955 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 3 Nov 2024 21:57:23 +0100 Subject: [PATCH 08/83] Format StaffMod.kt --- .../kotlin/opekope2/avm_staff/api/StaffMod.kt | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt index 83fe9facc..f0e951184 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -186,17 +186,16 @@ val impactTntEntityType: RegistrySupplier> = ENTITY_ /** * Entity registered as `avm_staff:cake` */ -val cakeEntityType: RegistrySupplier> = - ENTITY_TYPES.register("cake") { - val cakeBox = ICakeBlockAccessor.bitesToShape()[0].boundingBox - val cakeSize = max(cakeBox.lengthX, max(cakeBox.lengthY, cakeBox.lengthZ)) +val cakeEntityType: RegistrySupplier> = ENTITY_TYPES.register("cake") { + val cakeBox = ICakeBlockAccessor.bitesToShape()[0].boundingBox + val cakeSize = max(cakeBox.lengthX, max(cakeBox.lengthY, cakeBox.lengthZ)) - EntityType.Builder.create(::CakeEntity, SpawnGroup.MISC) - .dimensions(cakeSize.toFloat(), cakeSize.toFloat()) - .maxTrackingRange(EntityType.FALLING_BLOCK.maxTrackDistance) - .trackingTickInterval(EntityType.FALLING_BLOCK.trackTickInterval) - .build(Identifier.of(MOD_ID, "cake").toString()) - } + EntityType.Builder.create(::CakeEntity, SpawnGroup.MISC) + .dimensions(cakeSize.toFloat(), cakeSize.toFloat()) + .maxTrackingRange(EntityType.FALLING_BLOCK.maxTrackDistance) + .trackingTickInterval(EntityType.FALLING_BLOCK.trackTickInterval) + .build(Identifier.of(MOD_ID, "cake").toString()) +} /** * Particle registered as `avm_staff:flame`. From 02d8d7e3a1c5fbbfee71f3e0dbf5f8f1382ec2a3 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 9 Nov 2024 17:13:38 +0100 Subject: [PATCH 09/83] Change CampfireHandler parameters --- .../internal/staff/handler/CampfireHandler.kt | 14 ++++++-------- .../internal/staff/handler/VanillaStaffHandlers.kt | 6 ++---- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt index aef6cf045..cbd7c7c61 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt @@ -49,10 +49,7 @@ import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.internal.MinecraftUnit import opekope2.avm_staff.util.* -internal class CampfireHandler( - private val particleEffectSupplier: RegistrySupplier, - private val properties: Properties -) : StaffHandler() { +internal class CampfireHandler(private val parameters: Parameters) : StaffHandler() { override val maxUseTime: Int get() = 72000 @@ -150,16 +147,17 @@ internal class CampfireHandler( target: Entity, hand: Hand ): EventResult { - target.setOnFireFor(properties.attackFireSeconds) + target.setOnFireFor(parameters.attackFireSeconds) return EventResult.pass() } - data class Properties( - val nonFlammableBlockFireChance: Double, + data class Parameters( val flammableBlockFireChance: Double, + val nonFlammableBlockFireChance: Double, val attackFireSeconds: Float, val flameFireTicks: Int, - val rocketThrust: Double + val rocketThrust: Double, + val particleEffectSupplier: RegistrySupplier ) private inner class FirePellet( diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt index d11b22e67..731f2338a 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt @@ -51,14 +51,12 @@ fun registerVanillaStaffHandlers() { CAMPFIRE.registerHandler( CampfireHandler( - flamethrowerParticleType, - CampfireHandler.Properties(1 / 20.0, 5 / 20.0, 4f, 1, 0.1) + CampfireHandler.Parameters(5 / 20.0, 1 / 20.0, 4f, 1, 0.1, flamethrowerParticleType) ) ) SOUL_CAMPFIRE.registerHandler( CampfireHandler( - soulFlamethrowerParticleType, - CampfireHandler.Properties(2 / 20.0, 10 / 20.0, 6f, 2, 0.12) + CampfireHandler.Parameters(10 / 20.0, 2 / 20.0, 6f, 2, 0.12, soulFlamethrowerParticleType) ) ) From e3ccee4586956fa613a8658039d8f4b4a4e83090 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 9 Nov 2024 22:54:01 +0100 Subject: [PATCH 10/83] Rework campfire staff flamethrower --- .../kotlin/opekope2/avm_staff/api/StaffMod.kt | 15 + .../api/entity/CampfireFlameEntity.kt | 402 ++++++++++++++++++ .../avm_staff/internal/Initializer.kt | 7 +- .../internal/staff/handler/CampfireHandler.kt | 218 ++-------- .../opekope2/avm_staff/util/EntityUtil.kt | 12 + 5 files changed, 465 insertions(+), 189 deletions(-) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CampfireFlameEntity.kt diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt index f0e951184..ae0d523d0 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -52,6 +52,7 @@ import opekope2.avm_staff.api.component.StaffFurnaceDataComponent import opekope2.avm_staff.api.component.StaffItemComponent import opekope2.avm_staff.api.component.StaffRendererPartComponent import opekope2.avm_staff.api.entity.CakeEntity +import opekope2.avm_staff.api.entity.CampfireFlameEntity import opekope2.avm_staff.api.entity.ImpactTntEntity import opekope2.avm_staff.api.item.CrownItem import opekope2.avm_staff.api.item.StaffItem @@ -197,6 +198,20 @@ val cakeEntityType: RegistrySupplier> = ENTITY_TYPES.regi .build(Identifier.of(MOD_ID, "cake").toString()) } +val campfireFlameEntityType: RegistrySupplier> = + ENTITY_TYPES.register("campfire_flame") { + EntityType.Builder.create(::CampfireFlameEntity, SpawnGroup.MISC) + .dimensions(0f, 0f) + .maxTrackingRange(EntityType.AREA_EFFECT_CLOUD.maxTrackDistance) + // Don't send existing entities (the ones entering tracking distance) to the client + // The tracking distance is high enough compared to the max age of the flame + .trackingTickInterval(Int.MAX_VALUE) + .disableSaving() + .disableSummon() + .makeFireImmune() + .build(Identifier.of(MOD_ID, "campfire_flame").toString()) + } + /** * Particle registered as `avm_staff:flame`. * diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CampfireFlameEntity.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CampfireFlameEntity.kt new file mode 100644 index 000000000..71f5ba043 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CampfireFlameEntity.kt @@ -0,0 +1,402 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.api.entity + +import dev.architectury.extensions.network.EntitySpawnExtension +import dev.architectury.networking.NetworkManager +import net.fabricmc.api.EnvType +import net.fabricmc.api.Environment +import net.minecraft.block.* +import net.minecraft.block.piston.PistonBehavior +import net.minecraft.client.option.GraphicsMode +import net.minecraft.entity.Entity +import net.minecraft.entity.EntityType +import net.minecraft.entity.LivingEntity +import net.minecraft.entity.data.DataTracker +import net.minecraft.entity.projectile.ProjectileUtil +import net.minecraft.nbt.NbtCompound +import net.minecraft.network.PacketByteBuf +import net.minecraft.network.listener.ClientPlayPacketListener +import net.minecraft.network.packet.Packet +import net.minecraft.particle.ParticleEffect +import net.minecraft.particle.ParticleType +import net.minecraft.registry.Registries +import net.minecraft.registry.RegistryKey +import net.minecraft.registry.RegistryKeys +import net.minecraft.server.network.EntityTrackerEntry +import net.minecraft.state.property.Properties.LIT +import net.minecraft.util.hit.BlockHitResult +import net.minecraft.util.hit.HitResult +import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Box +import net.minecraft.util.math.Vec3d +import net.minecraft.world.RaycastContext +import net.minecraft.world.World +import net.minecraft.world.event.GameEvent +import opekope2.avm_staff.api.campfireFlameEntityType +import opekope2.avm_staff.api.flamethrowerParticleType +import opekope2.avm_staff.util.* +import java.util.* + +/** + * Technical entity representing a part of a flame of a campfire staff. + */ +class CampfireFlameEntity : Entity, EntitySpawnExtension { + private var currentRelativeRight: Vec3d = Vec3d.ZERO + private var currentRelativeUp: Vec3d = Vec3d.ZERO + + private lateinit var parameters: Parameters + + private lateinit var shooter: LivingEntity + + private var rays: BitSet + private inline val rayResolution: Int + get() = (parameters as? ServerParameters)?.rayResolution ?: flameParticleRayResolution + + @Deprecated("This constructor is not supported on the server") + internal constructor(type: EntityType<*>, world: World) : super(type, world) { + require(world.isClient) { "This constructor is not supported on the server" } + // Leave edges unset for accurate visuals + rays = BitSet(flameParticleRayResolution * flameParticleRayResolution).apply { + for (i in 1 until flameParticleRayResolution - 1) { + for (j in 1 until flameParticleRayResolution - 1) { + this.set(i * flameParticleRayResolution + j) + } + } + } + } + + /** + * Creates a new [CampfireFlameEntity]. + * + * @param world The world to create the flame entity in + * @param parameters Parameters for the flame + * @param shooter The entity shooting the flame + */ + constructor(world: World, parameters: ServerParameters, shooter: LivingEntity) : + super(campfireFlameEntityType.get(), world) { + this.setPosition(parameters.origin) + this.velocity = shooter.velocity + parameters.relativeTarget * (1.0 / parameters.stepResolution) + + this.parameters = parameters + + this.shooter = shooter + + val rayCount = rayResolution * rayResolution + this.rays = BitSet(rayCount).apply { set(0, rayCount) } + } + + override fun initDataTracker(builder: DataTracker.Builder) { + } + + override fun readCustomDataFromNbt(nbt: NbtCompound?) { + } + + override fun writeCustomDataToNbt(nbt: NbtCompound?) { + } + + override fun tick() { + super.tick() + + val nextPos = pos + velocity + val nextRelativeRight = parameters.flameConeWidth * (age.toDouble() / parameters.stepResolution) + val nextRelativeUp = parameters.flameConeHeight * (age.toDouble() / parameters.stepResolution) + + if (world.isClient) { + @Suppress("UNCHECKED_CAST") + val particleType = Registries.PARTICLE_TYPE[parameters.particleType as RegistryKey>] + val particleEffect = particleType as? ParticleEffect ?: flamethrowerParticleType.get() + + tickRays(nextPos, nextRelativeRight, nextRelativeUp) { start, end -> + val result = tickRayClient(start, end) + if (!result.stopsRay) spawnParticle(particleEffect, start, end) + result + } + } else { + val parameters = parameters as ServerParameters + val entitiesToBurn = mutableSetOf() + val blocksToLight = mutableSetOf() + val blocksToSetOnFire = mutableSetOf() + + tickRays(nextPos, nextRelativeRight, nextRelativeUp) { start, end -> + tickRayServer(start, end, parameters, entitiesToBurn, blocksToLight, blocksToSetOnFire) + } + + burnEntities(entitiesToBurn, parameters.flameFireTicks) + lightBlocks(blocksToLight) + setBlocksOnFire(blocksToSetOnFire) + } + + currentRelativeRight = nextRelativeRight + currentRelativeUp = nextRelativeUp + setPosition(nextPos) + lookForward() + + if (!world.isClient && age >= parameters.stepResolution) discard() + } + + @Environment(EnvType.CLIENT) + private fun spawnParticle(particleEffect: ParticleEffect, start: Vec3d, end: Vec3d) { + val particleOffset = (end - start) * random.nextDouble() + + currentRelativeRight * ((random.nextDouble() * 2 - 1) / rayResolution) + + currentRelativeUp * ((random.nextDouble() * 2 - 1) / rayResolution) + val (x, y, z) = start + particleOffset + particleManager.addParticle(particleEffect, x, y, z, 0.0, 0.0, 0.0)!!.apply { + scale(random.nextFloat() - random.nextFloat() + 1f) + maxAge = (0.25 * FLAME_MAX_AGE / (Math.random() * 0.8 + 0.2) - 0.05 * FLAME_MAX_AGE).toInt() + } + } + + private inline fun tickRays( + nextPos: Vec3d, + nextRelativeRight: Vec3d, + nextRelativeUp: Vec3d, + tickRay: (start: Vec3d, end: Vec3d) -> HitResult.Type + ) { + for (offsetX in 0 until rayResolution) { + for (offsetY in 0 until rayResolution) { + val index = offsetX * rayResolution + offsetY + if (!rays[index]) continue + + val scaleX = offsetX / (rayResolution - 1.0) - 0.5 + val scaleY = offsetY / (rayResolution - 1.0) - 0.5 + val start = pos + currentRelativeRight * scaleX + currentRelativeUp * scaleY + val end = nextPos + nextRelativeRight * scaleX + nextRelativeUp * scaleY + + rays[index] = !tickRay(start, end).stopsRay + } + } + } + + @Environment(EnvType.CLIENT) + private fun tickRayClient(start: Vec3d, end: Vec3d): HitResult.Type { + val blockHit = raycastBlock(start, end) + val entityHit = raycastEntity(start, end, false) + + return when { + entityHit != null && entityHit.pos.squaredDistanceTo(start) < blockHit.pos.squaredDistanceTo(start) -> HitResult.Type.ENTITY + blockHit.type == HitResult.Type.BLOCK -> HitResult.Type.BLOCK + else -> HitResult.Type.MISS + } + } + + private fun tickRayServer( + start: Vec3d, + end: Vec3d, + parameters: ServerParameters, + entitiesToBurn: MutableSet, + blocksToLight: MutableSet, + blocksToSetOnFire: MutableSet + ): HitResult.Type { + val blockHit = raycastBlock(start, end) + val entityHit = raycastEntity(start, end, parameters.damageShooter) + + return when { + entityHit != null && entityHit.pos.squaredDistanceTo(start) < blockHit.pos.squaredDistanceTo(start) -> { + entitiesToBurn += entityHit.entity + HitResult.Type.ENTITY + } + + blockHit.type == HitResult.Type.BLOCK -> { + collectBlockToLight( + blockHit, + blocksToLight, + blocksToSetOnFire, + parameters.flammableBlockFireChance, + parameters.nonFlammableBlockFireChance + ) + HitResult.Type.BLOCK + } + + else -> HitResult.Type.MISS + } + } + + private fun raycastBlock(start: Vec3d, end: Vec3d) = world.raycast( + RaycastContext( + start, + end, + RaycastContext.ShapeType.COLLIDER, + RaycastContext.FluidHandling.ANY, + ShapeContext.absent() + ) + ) + + private fun raycastEntity(start: Vec3d, end: Vec3d, includeShooter: Boolean) = ProjectileUtil.raycast( + this, + start, + end, + Box(start, end), + { it != shooter || includeShooter }, + velocity.lengthSquared() + ) + + private fun collectBlockToLight( + blockHit: BlockHitResult, + blocksToLight: MutableSet, + blocksToSetOnFire: MutableSet, + flammableBlockFireChance: Double, + nonFlammableBlockFireChance: Double + ) { + val firePos = blockHit.blockPos.offset(blockHit.side) + val blockToLight = world.getBlockState(blockHit.blockPos) + if (CampfireBlock.canBeLit(blockToLight) || + CandleBlock.canBeLit(blockToLight) || + CandleCakeBlock.canBeLit(blockToLight) + ) { + blocksToLight += blockHit.blockPos + return + } + + if (!world.canSetBlock(firePos)) return + if (!AbstractFireBlock.canPlaceAt(world, firePos, horizontalFacing)) return + + var fireCauseChance = + if (world.getBlockState(blockHit.blockPos).isBurnable) flammableBlockFireChance + else nonFlammableBlockFireChance + fireCauseChance /= rayResolution * rayResolution + + if (Math.random() < fireCauseChance) { + blocksToSetOnFire += firePos + } + } + + private fun burnEntities(entities: Set, flameFireTicks: Int) { + for (target in entities) { + if (target.isOnFire) { + // Technically inFire, but use onFire, because it has a more fitting death message + target.damage(target.damageSources.onFire(), flameFireTicks.toFloat()) + } + target.fireTicks = target.fireTicks.coerceAtLeast(0) + flameFireTicks + 1 + (target as? LivingEntity)?.attacker = shooter + } + } + + private fun lightBlocks(blocksToLight: MutableSet) { + for (pos in blocksToLight) { + world.setBlockState(pos, world.getBlockState(pos).with(LIT, true), Block.NOTIFY_ALL_AND_REDRAW) + world.emitGameEvent(this, GameEvent.BLOCK_CHANGE, pos) + } + } + + private fun setBlocksOnFire(blocksToSetOnFire: MutableSet) { + for (pos in blocksToSetOnFire) { + world.setBlockState(pos, AbstractFireBlock.getState(world, pos), Block.NOTIFY_ALL_AND_REDRAW) + world.emitGameEvent(this, GameEvent.BLOCK_PLACE, pos) + } + } + + override fun canUsePortals(allowVehicles: Boolean) = false + + override fun getPistonBehavior() = PistonBehavior.IGNORE + + override fun createSpawnPacket(entityTrackerEntry: EntityTrackerEntry): Packet = + NetworkManager.createAddEntityPacket(this, entityTrackerEntry) + + override fun saveAdditionalSpawnData(buf: PacketByteBuf) { + parameters.write(buf) + buf.writeVarInt(shooter.id) + } + + override fun loadAdditionalSpawnData(buf: PacketByteBuf) { + parameters = Parameters(buf) + shooter = world.getEntityById(buf.readVarInt()) as LivingEntity + } + + /** + * Parameters of a [CampfireFlameEntity]. + * + * @param origin Starting position of the entity + * @param relativeTarget The position towards the fire goes relative to [origin] + * @param flameConeWidth The width of the fire cone, points right relative to the shooter's POV + * @param flameConeHeight The height of the fire cone, points up relative to the shooter's POV + * @param stepResolution How many ticks to divide the distance between [origin] and [relativeTarget] + * @param particleType The registry key of the flame particle type in [Registries.PARTICLE_TYPE] + */ + open class Parameters( + val origin: Vec3d, + val relativeTarget: Vec3d, + val flameConeWidth: Vec3d, + val flameConeHeight: Vec3d, + val stepResolution: Int, + val particleType: RegistryKey>, + ) { + constructor(buf: PacketByteBuf) : this( + buf.readVec3d(), + buf.readVec3d(), + buf.readVec3d(), + buf.readVec3d(), + buf.readVarInt(), + buf.readRegistryKey(RegistryKeys.PARTICLE_TYPE) + ) + + fun write(buf: PacketByteBuf) { + buf.writeVec3d(origin) + buf.writeVec3d(relativeTarget) + buf.writeVec3d(flameConeWidth) + buf.writeVec3d(flameConeHeight) + buf.writeVarInt(stepResolution) + buf.writeRegistryKey(particleType) + } + } + + /** + * Server-side parameters of a [CampfireFlameEntity]. + * + * @param origin Starting position of the entity + * @param relativeTarget The position towards the fire goes relative to [origin] + * @param flameConeWidth The width of the fire cone, points right relative to the shooter's POV + * @param flameConeHeight The height of the fire cone, points up relative to the shooter's POV + * @param stepResolution How many ticks to divide the distance between [origin] and [relativeTarget] + * @param rayResolution The resolution to divide the fire cone both horizontally and vertically + * @param particleType The registry key of the flame particle type in [Registries.PARTICLE_TYPE] + * @param flammableBlockFireChance The chance a [flammable][BlockState.isBurnable] block is set on fire + * @param nonFlammableBlockFireChance The chance a [non-flammable][BlockState.isBurnable] block is set on fire + * @param flameFireTicks The number of ticks an entity is additionally set on fire for + * @param damageShooter Whether the flame should damage the shooter + */ + class ServerParameters( + origin: Vec3d, + relativeTarget: Vec3d, + flameConeWidth: Vec3d, + flameConeHeight: Vec3d, + stepResolution: Int, + particleType: RegistryKey>, + val rayResolution: Int, + val flammableBlockFireChance: Double, + val nonFlammableBlockFireChance: Double, + val flameFireTicks: Int, + val damageShooter: Boolean + ) : Parameters(origin, relativeTarget, flameConeWidth, flameConeHeight, stepResolution, particleType) + + private companion object { + private const val FLAME_MAX_AGE = 16 + + private val HitResult.Type.stopsRay: Boolean + get() = this == HitResult.Type.BLOCK + + private val flameParticleRayResolution: Int + @Environment(EnvType.CLIENT) + get() = when (clientOptions.graphicsMode.value) { + GraphicsMode.FABULOUS -> 6 + GraphicsMode.FANCY -> 5 + else -> 4 + } + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt index c3ab8db5a..737c5cc2f 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -26,6 +26,7 @@ import dev.architectury.registry.client.level.entity.EntityRendererRegistry import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.minecraft.block.DispenserBlock +import net.minecraft.client.render.entity.EmptyEntityRenderer import net.minecraft.client.render.entity.TntEntityRenderer import net.minecraft.entity.Entity import net.minecraft.entity.ItemEntity @@ -48,15 +49,12 @@ import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Box import net.minecraft.util.math.Direction import net.minecraft.world.World +import opekope2.avm_staff.api.* import opekope2.avm_staff.api.block.dispenser.CakeDispenserBehavior -import opekope2.avm_staff.api.cakeEntityType -import opekope2.avm_staff.api.crownOfKingOrangeItem import opekope2.avm_staff.api.entity.CakeEntity import opekope2.avm_staff.api.entity.renderer.CakeEntityRenderer -import opekope2.avm_staff.api.impactTntEntityType import opekope2.avm_staff.api.item.StaffItem import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures -import opekope2.avm_staff.api.throwableCakesGameRule import opekope2.avm_staff.internal.event_handler.handleKeyBindings import opekope2.avm_staff.internal.event_handler.registerKeyBindings import opekope2.avm_staff.internal.networking.c2s.play.AttackC2SPacket @@ -188,6 +186,7 @@ fun registerClientContent() { registerKeyBindings() EntityRendererRegistry.register(impactTntEntityType, ::TntEntityRenderer) EntityRendererRegistry.register(cakeEntityType, ::CakeEntityRenderer) + EntityRendererRegistry.register(campfireFlameEntityType, ::EmptyEntityRenderer) } @Environment(EnvType.CLIENT) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt index cbd7c7c61..0c8c1b9c6 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt @@ -19,35 +19,23 @@ package opekope2.avm_staff.internal.staff.handler import dev.architectury.event.EventResult -import dev.architectury.event.events.common.TickEvent import dev.architectury.registry.registries.RegistrySupplier -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment -import net.minecraft.block.* -import net.minecraft.client.option.GraphicsMode import net.minecraft.entity.Entity import net.minecraft.entity.LivingEntity import net.minecraft.entity.player.PlayerEntity -import net.minecraft.entity.projectile.ProjectileUtil import net.minecraft.item.ItemStack import net.minecraft.particle.SimpleParticleType -import net.minecraft.server.MinecraftServer -import net.minecraft.state.property.Properties.LIT import net.minecraft.util.Hand import net.minecraft.util.TypedActionResult -import net.minecraft.util.hit.BlockHitResult -import net.minecraft.util.hit.HitResult -import net.minecraft.util.math.Box import net.minecraft.util.math.MathHelper -import net.minecraft.util.math.Vec3d -import net.minecraft.util.math.random.Random -import net.minecraft.world.RaycastContext import net.minecraft.world.World -import net.minecraft.world.event.GameEvent +import opekope2.avm_staff.api.entity.CampfireFlameEntity import opekope2.avm_staff.api.rocketModeComponentType import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.internal.MinecraftUnit -import opekope2.avm_staff.util.* +import opekope2.avm_staff.util.approximateStaffTipPosition +import opekope2.avm_staff.util.canUseStaff +import opekope2.avm_staff.util.times internal class CampfireHandler(private val parameters: Parameters) : StaffHandler() { override val maxUseTime: Int @@ -72,63 +60,36 @@ internal class CampfireHandler(private val parameters: Parameters) : StaffHandle val forward = user.rotationVector val origin = user.approximateStaffTipPosition - val target = origin + forward * FLAME_MAX_DISTANCE val relativeRight = user.getRotationVector(0f, MathHelper.wrapDegrees(user.yaw + 90f)).normalize() val relativeUp = relativeRight.crossProduct(forward).normalize() + val rocketMode = rocketModeComponentType.get() in staffStack - if (rocketModeComponentType.get() in staffStack) { - user.addVelocity(forward * -properties.rocketThrust) + if (rocketMode) { + user.addVelocity(forward * -parameters.rocketThrust) user.limitFallDistance() } - if (world.isClient) { - throwFlameParticles(user, target, relativeRight, relativeUp) - return - } - - for (i in 0 until FLAMETHROWER_CONE_RAYS) { - for (j in 0 until FLAMETHROWER_CONE_RAYS) { - val xScale = i / (FLAMETHROWER_CONE_RAYS - 1.0) - 0.5 - val yScale = j / (FLAMETHROWER_CONE_RAYS - 1.0) - 0.5 - - val offsetTarget = target + - relativeRight * (xScale * FLAMETHROWER_CONE_END_WIDTH) + - relativeUp * (yScale * FLAMETHROWER_CONE_END_HEIGHT) - - shootFire( - FirePellet( - user, - world, - origin, - (offsetTarget - origin).normalize() * FLAME_SPEED, - FLAME_MAX_AGE - ) - ) - } - } - } - - @Environment(EnvType.CLIENT) - fun throwFlameParticles(user: LivingEntity, target: Vec3d, relativeRight: Vec3d, relativeUp: Vec3d) { - val random = Random.create() - val origin = user.approximateStaffTipPosition - - for (i in 0..flameParticleCount) { - val xScale = random.nextDouble() - 0.5 - val yScale = random.nextDouble() - 0.5 - - val offsetTarget = target + - relativeRight * (xScale * FLAMETHROWER_CONE_END_WIDTH) + - relativeUp * (yScale * FLAMETHROWER_CONE_END_HEIGHT) - val targetDirection = (offsetTarget - origin).normalize() - val particleSpeed = targetDirection.normalize() * FLAME_SPEED * (0.9 + Math.random() * 0.2) - - particleManager.addParticle( - particleEffectSupplier.get(), - origin.x, origin.y, origin.z, - particleSpeed.x, particleSpeed.y, particleSpeed.z - )!!.maxAge = (0.25 * FLAME_MAX_AGE / (Math.random() * 0.8 + 0.2) - 0.05 * FLAME_MAX_AGE).toInt() - } + if (world.isClient) return + + world.spawnEntity( + CampfireFlameEntity( + world, + CampfireFlameEntity.ServerParameters( + origin, + forward * FLAMETHROWER_STEP_RESOLUTION.toDouble(), + relativeRight * FLAMETHROWER_CONE_END_WIDTH, + relativeUp * FLAMETHROWER_CONE_END_HEIGHT, + 16, + parameters.particleEffectSupplier.key, + FLAMETHROWER_CONE_RAY_RESOLUTION, + parameters.flammableBlockFireChance, + parameters.nonFlammableBlockFireChance, + parameters.flameFireTicks, + !rocketMode + ), + user + ) + ) } override fun onStoppedUsing(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { @@ -160,123 +121,10 @@ internal class CampfireHandler(private val parameters: Parameters) : StaffHandle val particleEffectSupplier: RegistrySupplier ) - private inner class FirePellet( - private val shooter: LivingEntity, - private val world: World, - private var position: Vec3d, - private val velocity: Vec3d, - private val maxAge: Int - ) { - private var age = 0 - - fun tick(attackedEntities: MutableSet): Boolean { - val newPosition = position + velocity - val blockHit = world.raycast( - RaycastContext( - position, - newPosition, - RaycastContext.ShapeType.COLLIDER, - RaycastContext.FluidHandling.ANY, - ShapeContext.absent() - ) - ) - val entityHit = ProjectileUtil.raycast( - shooter, - position, - newPosition, - Box(position, newPosition), - { true }, - velocity.lengthSquared() - ) - - val blockDistance = blockHit.pos.squaredDistanceTo(position) - val entityDistance = entityHit?.pos?.squaredDistanceTo(position) - if (entityHit != null && entityDistance!! < blockDistance) { - tryBurnEntity(entityHit.entity, attackedEntities) - } else if (blockHit.type == HitResult.Type.BLOCK) { - tryCauseFire(blockHit) - return false - } - - position = newPosition - return ++age < maxAge - } - - private fun tryBurnEntity(target: Entity, ignoredEntities: MutableSet) { - if (target in ignoredEntities) return - - if (target.isOnFire) { - // Technically inFire, but use onFire, because it has a more fitting death message - target.damage(target.damageSources.onFire(), properties.flameFireTicks.toFloat()) - } - target.fireTicks = target.fireTicks.coerceAtLeast(0) + properties.flameFireTicks + 1 - (target as? LivingEntity)?.attacker = shooter - ignoredEntities += target - } - - private fun tryCauseFire(blockHit: BlockHitResult) { - val firePos = blockHit.blockPos.offset(blockHit.side) - val blockToLight = world.getBlockState(blockHit.blockPos) - if (CampfireBlock.canBeLit(blockToLight) || - CandleBlock.canBeLit(blockToLight) || - CandleCakeBlock.canBeLit(blockToLight) - ) { - world.setBlockState(blockHit.blockPos, blockToLight.with(LIT, true), Block.NOTIFY_ALL_AND_REDRAW) - world.emitGameEvent(shooter, GameEvent.BLOCK_CHANGE, firePos) - return - } - - if (!world.canSetBlock(firePos)) return - if (!AbstractFireBlock.canPlaceAt(world, firePos, shooter.horizontalFacing)) return - - var fireCauseChance = - if (world.getBlockState(blockHit.blockPos).isBurnable) properties.flammableBlockFireChance - else properties.nonFlammableBlockFireChance - fireCauseChance /= FLAMETHROWER_CONE_RAYS_TOTAL - if (Math.random() >= fireCauseChance) return - - world.setBlockState(firePos, AbstractFireBlock.getState(world, firePos), Block.NOTIFY_ALL_AND_REDRAW) - world.emitGameEvent(shooter, GameEvent.BLOCK_PLACE, firePos) - } - } - - private companion object : TickEvent.Server { - private const val FLAME_SPEED = 1.0 - private const val FLAME_MAX_AGE = 16 - private const val FLAME_MAX_DISTANCE = FLAME_SPEED * FLAME_MAX_AGE - - private const val FLAMETHROWER_CONE_END_WIDTH = 0.25 * FLAME_MAX_DISTANCE - private const val FLAMETHROWER_CONE_END_HEIGHT = 0.25 * FLAME_MAX_DISTANCE - private const val FLAMETHROWER_CONE_RAYS = 16 - private const val FLAMETHROWER_CONE_RAYS_TOTAL = FLAMETHROWER_CONE_RAYS * FLAMETHROWER_CONE_RAYS - - private val flameParticleCount: Int - @Environment(EnvType.CLIENT) - get() = when (clientOptions.graphicsMode.value) { - GraphicsMode.FABULOUS -> 16 * 16 - GraphicsMode.FANCY -> 8 * 8 - else -> 4 * 4 - } - private val firePellets = mutableListOf() - - init { - TickEvent.SERVER_PRE.register(this) - } - - private fun shootFire(firePellet: FirePellet) { - firePellets += firePellet - } - - override fun tick(server: MinecraftServer) { - if (!server.tickManager.shouldTick()) return - val damagedEntities = mutableSetOf() - val iterator = firePellets.iterator() - while (iterator.hasNext()) { - val pellet = iterator.next() - if (!pellet.tick(damagedEntities)) { - iterator.remove() - } - } - } + private companion object { + private const val FLAMETHROWER_STEP_RESOLUTION = 16 + private const val FLAMETHROWER_CONE_END_WIDTH = 0.25 * FLAMETHROWER_STEP_RESOLUTION + private const val FLAMETHROWER_CONE_END_HEIGHT = 0.25 * FLAMETHROWER_STEP_RESOLUTION + private const val FLAMETHROWER_CONE_RAY_RESOLUTION = 16 } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/EntityUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/EntityUtil.kt index c92f0f17c..31c3f9187 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/EntityUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/EntityUtil.kt @@ -23,8 +23,10 @@ package opekope2.avm_staff.util import net.minecraft.entity.Entity import net.minecraft.entity.EntityType import net.minecraft.util.math.Direction +import net.minecraft.util.math.MathHelper import net.minecraft.util.math.Vec3d import net.minecraft.world.World +import kotlin.math.sqrt /** * Calculates the camera's upward direction based on [Entity.getFacing] and [Entity.getHorizontalFacing]. @@ -48,3 +50,13 @@ fun EntityType.getSpawnPosition(world: World, center: Vec3d): Vec3d? return if (world.isSpaceEmpty(getSpawnBox(spawnPos.x, spawnPos.y, spawnPos.z))) spawnPos else null } + +/** + * Sets the [yaw][Entity.yaw] and [pitch][Entity.pitch] of the entity to look [forward][Entity.velocity]. + */ +fun Entity.lookForward() { + val (vx, vy, vz) = velocity.normalize() + val horizontalSpeed = sqrt(vx * vx + vz * vz) + yaw = MathHelper.atan2(vx, vz).toFloat() + pitch = MathHelper.atan2(horizontalSpeed, vy).toFloat() +} From 9e56ca2bd6918129102b509583e22c884018f840 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 9 Nov 2024 23:33:39 +0100 Subject: [PATCH 11/83] Optimize player death handler --- .../kotlin/opekope2/avm_staff/internal/Initializer.kt | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt index 737c5cc2f..98f290463 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -34,7 +34,6 @@ import net.minecraft.entity.LivingEntity import net.minecraft.entity.damage.DamageSource import net.minecraft.entity.mob.AbstractPiglinEntity import net.minecraft.entity.player.PlayerEntity -import net.minecraft.entity.player.PlayerInventory import net.minecraft.item.ItemStack import net.minecraft.item.Items import net.minecraft.loot.LootPool @@ -96,13 +95,8 @@ fun subscribeToEvents() { private fun stopUsingStaffOnPlayerDeath(entity: LivingEntity, damageSource: DamageSource): EventResult { if (entity !is PlayerEntity) return EventResult.pass() - iterator { - yieldAll(0 until PlayerInventory.MAIN_SIZE) - yield(PlayerInventory.OFF_HAND_SLOT) - }.forEach { slot -> - if (entity.inventory.getStack(slot).isStaff) { - entity.stopUsingItem() - } + if (entity.activeItem.isStaff) { + entity.stopUsingItem() } return EventResult.pass() From 5273a0c0721937907e4c8258ec517730c7f411d8 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 9 Nov 2024 23:35:02 +0100 Subject: [PATCH 12/83] Activate sculk shriekers with thrown cakes --- .../mixin/SculkShriekerBlockEntityMixin.java | 41 +++++++++++++++++++ .../avm_staff/api/entity/CakeEntity.kt | 30 +++++++------- .../src/main/resources/avm_staff.mixins.json | 1 + 3 files changed, 56 insertions(+), 16 deletions(-) create mode 100644 StaffMod/src/main/java/opekope2/avm_staff/mixin/SculkShriekerBlockEntityMixin.java diff --git a/StaffMod/src/main/java/opekope2/avm_staff/mixin/SculkShriekerBlockEntityMixin.java b/StaffMod/src/main/java/opekope2/avm_staff/mixin/SculkShriekerBlockEntityMixin.java new file mode 100644 index 000000000..277137e8d --- /dev/null +++ b/StaffMod/src/main/java/opekope2/avm_staff/mixin/SculkShriekerBlockEntityMixin.java @@ -0,0 +1,41 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.mixin; + +import net.minecraft.block.entity.SculkShriekerBlockEntity; +import net.minecraft.entity.Entity; +import net.minecraft.server.network.ServerPlayerEntity; +import opekope2.avm_staff.api.entity.CakeEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(SculkShriekerBlockEntity.class) +public abstract class SculkShriekerBlockEntityMixin { + @Inject(method = "findResponsiblePlayerFromEntity", at = @At("TAIL"), cancellable = true) + private static void findResponsiblePlayerFromCake(Entity entity, CallbackInfoReturnable cir) { + if (entity instanceof CakeEntity cake) { + Entity owner = cake.getOwner(); + if (owner instanceof ServerPlayerEntity player) { + cir.setReturnValue(player); + } + } + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt index 3ca365dbd..b9403ec8c 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt @@ -24,10 +24,7 @@ import net.minecraft.block.Blocks import net.minecraft.client.option.GraphicsMode import net.minecraft.client.particle.BlockDustParticle import net.minecraft.client.world.ClientWorld -import net.minecraft.entity.Entity -import net.minecraft.entity.EntityType -import net.minecraft.entity.LivingEntity -import net.minecraft.entity.MovementType +import net.minecraft.entity.* import net.minecraft.entity.damage.DamageSource import net.minecraft.entity.data.DataTracker import net.minecraft.nbt.NbtCompound @@ -36,21 +33,27 @@ import net.minecraft.predicate.entity.EntityPredicates import net.minecraft.server.network.EntityTrackerEntry import net.minecraft.sound.SoundCategory import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.MathHelper import net.minecraft.util.math.Vec3d import net.minecraft.util.math.random.Random import net.minecraft.world.World import opekope2.avm_staff.api.* import opekope2.avm_staff.util.* -import kotlin.math.sqrt /** * A flying cake entity, which splashes on collision damaging target(s). */ -class CakeEntity(entityType: EntityType, world: World) : Entity(entityType, world) { +class CakeEntity(entityType: EntityType, world: World) : Entity(entityType, world), Ownable { private var thrower: LivingEntity? = null private var timeFalling = 0 + /** + * Creates a new [CakeEntity]. + * + * @param world The world to create the cake in + * @param position The position of the cake to spawn at + * @param velocity The velocity of the spawned cake + * @param thrower The entity that threw the cake + */ constructor(world: World, position: Vec3d, velocity: Vec3d, thrower: LivingEntity?) : this(cakeEntityType.get(), world) { val (x, y, z) = position @@ -65,7 +68,7 @@ class CakeEntity(entityType: EntityType, world: World) : Entity(enti prevX = x prevY = y prevZ = z - setYawAndPitch() + lookForward() setPrevData() startPos = blockPos this.thrower = thrower @@ -143,7 +146,7 @@ class CakeEntity(entityType: EntityType, world: World) : Entity(enti ++timeFalling applyGravity() move(MovementType.SELF, velocity) - setYawAndPitch() + lookForward() if (!world.isClient) { if (timeFalling > 100 && blockPos.y !in world.topY downTo (world.bottomY + 1) || timeFalling > 600) { discard() @@ -160,13 +163,6 @@ class CakeEntity(entityType: EntityType, world: World) : Entity(enti prevHorizontalSpeed = horizontalSpeed } - private fun setYawAndPitch() { - val (vx, vy, vz) = velocity.normalize() - val horizontalSpeed = sqrt(vx * vx + vz * vz) - yaw = MathHelper.atan2(vx, vz).toFloat() - pitch = MathHelper.atan2(horizontalSpeed, vy).toFloat() - } - private fun splashOnImpact() { if (horizontalCollision || verticalCollision) { damageCollidingEntities() @@ -223,6 +219,8 @@ class CakeEntity(entityType: EntityType, world: World) : Entity(enti ) } + override fun getOwner() = thrower + companion object { private val CAKE_STATE = Blocks.CAKE.defaultState private val particlePerSide: Int diff --git a/StaffMod/src/main/resources/avm_staff.mixins.json b/StaffMod/src/main/resources/avm_staff.mixins.json index 536daea1b..ba3e2dbb3 100644 --- a/StaffMod/src/main/resources/avm_staff.mixins.json +++ b/StaffMod/src/main/resources/avm_staff.mixins.json @@ -20,6 +20,7 @@ "ICakeBlockAccessor", "IPiglinBrainAccessor", "ISmithingTemplateItemAccessor", + "SculkShriekerBlockEntityMixin", "TurtleEggBlockMixin" ] } From 102871a618f0e95791892d3a99bcd506e468ed51 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 9 Nov 2024 23:35:18 +0100 Subject: [PATCH 13/83] Make TurtleEggBlockMixin abstract --- .../main/java/opekope2/avm_staff/mixin/TurtleEggBlockMixin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/StaffMod/src/main/java/opekope2/avm_staff/mixin/TurtleEggBlockMixin.java b/StaffMod/src/main/java/opekope2/avm_staff/mixin/TurtleEggBlockMixin.java index 65fe7c0cc..8a359b6a2 100644 --- a/StaffMod/src/main/java/opekope2/avm_staff/mixin/TurtleEggBlockMixin.java +++ b/StaffMod/src/main/java/opekope2/avm_staff/mixin/TurtleEggBlockMixin.java @@ -35,7 +35,7 @@ import org.spongepowered.asm.mixin.Shadow; @Mixin(TurtleEggBlock.class) -public class TurtleEggBlockMixin implements IBlockAfterDestroyHandler { +public abstract class TurtleEggBlockMixin implements IBlockAfterDestroyHandler { @Shadow @Final public static IntProperty EGGS; From dfacde1af62b60739346836406ff3deeef2459fc Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 10 Nov 2024 15:54:13 +0100 Subject: [PATCH 14/83] Translate campfire flame entity --- StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json | 1 + 1 file changed, 1 insertion(+) diff --git a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json index 56aa2936d..2f1542b84 100644 --- a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json +++ b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json @@ -4,6 +4,7 @@ "death.attack.avm_staff.pranked.player": "%s was pranked by %s", "death.attack.avm_staff.pranked.player.item": "%s was pranked by %s using %s", "entity.avm_staff.cake": "Cake", + "entity.avm_staff.campfire_flame": "Campfire flame", "entity.avm_staff.impact_tnt": "Impact TNT", "gamerule.throwableCakes": "Throwable cakes", "gamerule.throwableCakes.description": "Enable throwing cakes by players and dispensers", From 78a6c94aedc822a8edfd6ffceef57710a6f259f1 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 10 Nov 2024 21:52:24 +0100 Subject: [PATCH 15/83] Add avm_staff:get_hurt_while_using_item criterion --- .../kotlin/opekope2/avm_staff/api/StaffMod.kt | 10 ++ .../TakeDamageWhileUsingItemCriterion.kt | 95 +++++++++++++++++++ .../avm_staff/internal/Initializer.kt | 10 ++ 3 files changed, 115 insertions(+) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/advancement/criterion/TakeDamageWhileUsingItemCriterion.kt diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt index ae0d523d0..ac5af4151 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -24,6 +24,7 @@ package opekope2.avm_staff.api import dev.architectury.registry.CreativeTabRegistry import dev.architectury.registry.registries.DeferredRegister import dev.architectury.registry.registries.RegistrySupplier +import net.minecraft.advancement.criterion.Criteria import net.minecraft.block.AbstractBlock import net.minecraft.block.enums.NoteBlockInstrument import net.minecraft.block.piston.PistonBehavior @@ -46,6 +47,7 @@ import net.minecraft.text.Text import net.minecraft.util.Identifier import net.minecraft.util.Rarity import net.minecraft.world.GameRules +import opekope2.avm_staff.api.advancement.criterion.TakeDamageWhileUsingItemCriterion import opekope2.avm_staff.api.block.CrownBlock import opekope2.avm_staff.api.block.WallCrownBlock import opekope2.avm_staff.api.component.StaffFurnaceDataComponent @@ -302,6 +304,14 @@ val playerCakeDamageType: RegistryKey = val throwableCakesGameRule: GameRules.Key = GameRules.register("throwableCakes", GameRules.Category.MISC, GameRules.BooleanRule.create(false)) +/** + * Criterion registered as `avm_staff:get_hurt_while_using_item`. + */ +val takeDamageWhileUsingItemCriterion: TakeDamageWhileUsingItemCriterion = Criteria.register( + Identifier.of(MOD_ID, "get_hurt_while_using_item").toString(), + TakeDamageWhileUsingItemCriterion() +) + /** * @suppress */ diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/advancement/criterion/TakeDamageWhileUsingItemCriterion.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/advancement/criterion/TakeDamageWhileUsingItemCriterion.kt new file mode 100644 index 000000000..60d3fb5ae --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/advancement/criterion/TakeDamageWhileUsingItemCriterion.kt @@ -0,0 +1,95 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.api.advancement.criterion + +import com.mojang.serialization.Codec +import com.mojang.serialization.codecs.RecordCodecBuilder +import net.minecraft.advancement.criterion.AbstractCriterion +import net.minecraft.advancement.criterion.EntityHurtPlayerCriterion +import net.minecraft.advancement.criterion.UsingItemCriterion +import net.minecraft.entity.damage.DamageSource +import net.minecraft.item.ItemStack +import net.minecraft.predicate.entity.DamageSourcePredicate +import net.minecraft.predicate.entity.EntityPredicate +import net.minecraft.predicate.entity.LootContextPredicate +import net.minecraft.predicate.item.ItemPredicate +import net.minecraft.server.network.ServerPlayerEntity +import java.util.* + +/** + * A fusion criterion between [UsingItemCriterion] and [EntityHurtPlayerCriterion]. + */ +class TakeDamageWhileUsingItemCriterion : AbstractCriterion() { + override fun getConditionsCodec() = Conditions.CODEC + + /** + * Triggers the criterion. + * + * @param player The player triggering the criterion + * @param stack The item stack the player is using + * @param damageSource The damage the player took + */ + fun trigger(player: ServerPlayerEntity, stack: ItemStack, damageSource: DamageSource) { + trigger(player) { conditions -> conditions.test(player, stack, damageSource) } + } + + /** + * Conditions of [TakeDamageWhileUsingItemCriterion]. + * + * @param player Predicate matching the player + * @param item Predicate matching the item the player is using + * @param damageType Predicate matching the damage the player took + */ + data class Conditions( + val player: Optional, + val item: Optional, + val damageType: Optional + ) : AbstractCriterion.Conditions { + override fun player() = player + + /** + * Tests the given parameters against the datapack-specified conditions. + * + * @param player The player triggering the criterion + * @param stack The item stack the player is using + * @param damageSource The damage the player took + */ + fun test(player: ServerPlayerEntity, stack: ItemStack, damageSource: DamageSource): Boolean { + if (item.isPresent && !item.get().test(stack)) return false + if (damageType.isPresent && !damageType.get().test(player, damageSource)) return false + + return true + } + + companion object { + /** + * [Codec] for [Conditions]. + */ + @JvmField + val CODEC: Codec = RecordCodecBuilder.create { instance -> + instance.group( + EntityPredicate.LOOT_CONTEXT_PREDICATE_CODEC.optionalFieldOf("player") + .forGetter(AbstractCriterion.Conditions::player), + ItemPredicate.CODEC.optionalFieldOf("item").forGetter(Conditions::item), + DamageSourcePredicate.CODEC.optionalFieldOf("damage_type").forGetter(Conditions::damageType) + ).apply(instance, ::Conditions) + } + } + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt index 98f290463..61c1df832 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -41,6 +41,7 @@ import net.minecraft.loot.LootTable import net.minecraft.loot.entry.LootTableEntry import net.minecraft.registry.RegistryKey import net.minecraft.registry.RegistryKeys +import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.util.Hand import net.minecraft.util.Identifier import net.minecraft.util.hit.EntityHitResult @@ -89,6 +90,7 @@ fun subscribeToEvents() { LootEvent.MODIFY_LOOT_TABLE.register(::modifyLootTables) PlayerEvent.ATTACK_ENTITY.register(::tryAngerPiglins) PlayerEvent.DROP_ITEM.register(::stopUsingStaffWhenDropped) + EntityEvent.LIVING_HURT.register(::triggerDamageWhileUsingItemCriterion) } @Suppress("UNUSED_PARAMETER") @@ -175,6 +177,14 @@ fun stopUsingStaffWhenDropped(entity: LivingEntity, item: ItemEntity): EventResu return EventResult.pass() } +@Suppress("UNUSED_PARAMETER") +fun triggerDamageWhileUsingItemCriterion(entity: LivingEntity, damage: DamageSource, amount: Float): EventResult { + if (entity is ServerPlayerEntity && entity.isUsingItem) { + takeDamageWhileUsingItemCriterion.trigger(entity, entity.activeItem, damage) + } + return EventResult.pass() +} + @Environment(EnvType.CLIENT) fun registerClientContent() { registerKeyBindings() From bfd740b825bc5e2d8839fef2fd52919c21279a8c Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 11 Nov 2024 00:53:51 +0100 Subject: [PATCH 16/83] Add avm_staff:break_block_with_staff criterion --- .../kotlin/opekope2/avm_staff/api/StaffMod.kt | 9 ++ .../criterion/BreakBlockWithStaffCriterion.kt | 87 +++++++++++++++++++ .../avm_staff/api/staff/StaffHandler.kt | 2 + .../staff/handler/DiamondBlockHandler.kt | 4 + .../staff/handler/NetheriteBlockHandler.kt | 4 + 5 files changed, 106 insertions(+) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/advancement/criterion/BreakBlockWithStaffCriterion.kt diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt index ac5af4151..8f44159c7 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -47,6 +47,7 @@ import net.minecraft.text.Text import net.minecraft.util.Identifier import net.minecraft.util.Rarity import net.minecraft.world.GameRules +import opekope2.avm_staff.api.advancement.criterion.BreakBlockWithStaffCriterion import opekope2.avm_staff.api.advancement.criterion.TakeDamageWhileUsingItemCriterion import opekope2.avm_staff.api.block.CrownBlock import opekope2.avm_staff.api.block.WallCrownBlock @@ -312,6 +313,14 @@ val takeDamageWhileUsingItemCriterion: TakeDamageWhileUsingItemCriterion = Crite TakeDamageWhileUsingItemCriterion() ) +/** + * Criterion registered as `avm_staff:break_block_with_staff`. Triggers before a block is broken by a staff. + */ +val breakBlockWithStaffCriterion: BreakBlockWithStaffCriterion = Criteria.register( + Identifier.of(MOD_ID, "break_block_with_staff").toString(), + BreakBlockWithStaffCriterion() +) + /** * @suppress */ diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/advancement/criterion/BreakBlockWithStaffCriterion.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/advancement/criterion/BreakBlockWithStaffCriterion.kt new file mode 100644 index 000000000..652560ea8 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/advancement/criterion/BreakBlockWithStaffCriterion.kt @@ -0,0 +1,87 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.api.advancement.criterion + +import com.mojang.serialization.Codec +import com.mojang.serialization.codecs.RecordCodecBuilder +import net.minecraft.advancement.criterion.AbstractCriterion +import net.minecraft.predicate.entity.EntityPredicate +import net.minecraft.predicate.entity.LocationPredicate +import net.minecraft.predicate.entity.LootContextPredicate +import net.minecraft.server.network.ServerPlayerEntity +import net.minecraft.server.world.ServerWorld +import net.minecraft.util.math.BlockPos +import opekope2.avm_staff.util.component1 +import opekope2.avm_staff.util.component2 +import opekope2.avm_staff.util.component3 +import java.util.* + +/** + * A criterion, which triggers when a player breaks a block using a staff. + */ +class BreakBlockWithStaffCriterion : AbstractCriterion() { + override fun getConditionsCodec() = Conditions.CODEC + + /** + * Triggers the criterion. + * + * @param player The player triggering the criterion + * @param world The world where the player broke the block + * @param pos The position of the broken block + */ + fun trigger(player: ServerPlayerEntity, world: ServerWorld, pos: BlockPos) { + trigger(player) { conditions -> conditions.test(world, pos) } + } + + /** + * Conditions of [BreakBlockWithStaffCriterion]. + * + * @param player Predicate matching the player + * @param location Predicate matching the location of the broken block + */ + data class Conditions(val player: Optional, val location: Optional) : + AbstractCriterion.Conditions { + override fun player() = player + + /** + * Tests the given parameters against the datapack-specified conditions. + * + * @param world The world where the player broke the block + * @param pos The position of the broken block + */ + fun test(world: ServerWorld, pos: BlockPos): Boolean { + val (x, y, z) = pos.toCenterPos() + return location.isEmpty || location.get().test(world, x, y, z) + } + + companion object { + /** + * [Codec] for [Conditions]. + */ + @JvmField + val CODEC: Codec = RecordCodecBuilder.create { instance -> + instance.group( + EntityPredicate.LOOT_CONTEXT_PREDICATE_CODEC.optionalFieldOf("player") + .forGetter(AbstractCriterion.Conditions::player), + LocationPredicate.CODEC.optionalFieldOf("location").forGetter(Conditions::location) + ).apply(instance, ::Conditions) + } + } + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt index 6736b7d45..622c8ee21 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt @@ -35,6 +35,7 @@ import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction import net.minecraft.world.World import net.minecraft.world.event.GameEvent +import opekope2.avm_staff.api.breakBlockWithStaffCriterion /** * Provides functionality for a staff, when an item is inserted into it. @@ -230,6 +231,7 @@ abstract class StaffHandler { * @param target The block the [attacker] attacked * @param side The side of the [block][target], which was attacked * @param hand The hand of the [attacker], in which the [staff][staffStack] is + * @see breakBlockWithStaffCriterion */ open fun attackBlock( staffStack: ItemStack, world: World, attacker: LivingEntity, target: BlockPos, side: Direction, hand: Hand diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/DiamondBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/DiamondBlockHandler.kt index d4257738f..b22b3576f 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/DiamondBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/DiamondBlockHandler.kt @@ -25,11 +25,13 @@ import net.minecraft.entity.LivingEntity import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack +import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.server.world.ServerWorld import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction import net.minecraft.world.World +import opekope2.avm_staff.api.breakBlockWithStaffCriterion import opekope2.avm_staff.api.staff.StaffAttributeModifiersComponentBuilder import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.attackDamage @@ -69,6 +71,8 @@ class DiamondBlockHandler : StaffHandler() { if (attacker is PlayerEntity && attacker.abilities.creativeMode) NoOpBlockDropCollector() else ChunkedBlockDropCollector(shapePredicate.volume, MAX_CHUNK_SIZE) + if (attacker is ServerPlayerEntity) breakBlockWithStaffCriterion.trigger(attacker, world, target) + destroyBox( world, shapePredicate.volume, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/NetheriteBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/NetheriteBlockHandler.kt index 81ad923a3..2653d2bfe 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/NetheriteBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/NetheriteBlockHandler.kt @@ -26,6 +26,7 @@ import net.minecraft.entity.LivingEntity import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack +import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.server.world.ServerWorld import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos @@ -34,6 +35,7 @@ import net.minecraft.util.math.MathHelper import net.minecraft.util.math.Vec2f import net.minecraft.world.World import net.minecraft.world.WorldEvents +import opekope2.avm_staff.api.breakBlockWithStaffCriterion import opekope2.avm_staff.api.staff.StaffAttributeModifiersComponentBuilder import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.* @@ -121,6 +123,8 @@ class NetheriteBlockHandler : StaffHandler() { if (attacker is PlayerEntity && attacker.abilities.creativeMode) NoOpBlockDropCollector() else ChunkedBlockDropCollector(shapePredicate.volume, MAX_CHUNK_SIZE) + if (attacker is ServerPlayerEntity) breakBlockWithStaffCriterion.trigger(attacker, world, target) + destroyBox( world, shapePredicate.volume, From b65890f3484a9cc86ccbd5664669e777b37c8773 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 11 Nov 2024 01:37:09 +0100 Subject: [PATCH 17/83] Re-add avm_staff:staffs tag --- StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt | 6 ++++++ .../src/main/resources/data/avm_staff/tags/item/staffs.json | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 StaffMod/src/main/resources/data/avm_staff/tags/item/staffs.json diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt index 8f44159c7..747b52238 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -41,6 +41,7 @@ import net.minecraft.network.codec.PacketCodec import net.minecraft.particle.SimpleParticleType import net.minecraft.registry.RegistryKey import net.minecraft.registry.RegistryKeys +import net.minecraft.registry.tag.TagKey import net.minecraft.sound.BlockSoundGroup import net.minecraft.sound.SoundEvent import net.minecraft.text.Text @@ -163,6 +164,11 @@ val staffInfusionSmithingTemplateItem: RegistrySupplier = ITEMS.register(" ) } +/** + * Tag registered as `avm_staff:staffs`. + */ +val staffsTag: TagKey = TagKey.of(RegistryKeys.ITEM, Identifier.of(MOD_ID, "staffs")) + /** * Item group containing items added by Staff Mod. */ diff --git a/StaffMod/src/main/resources/data/avm_staff/tags/item/staffs.json b/StaffMod/src/main/resources/data/avm_staff/tags/item/staffs.json new file mode 100644 index 000000000..d252465a6 --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/tags/item/staffs.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "avm_staff:royal_staff" + ] +} From f6aff6366a6e63a38b4e40c1f5dd396cd867e8e3 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 18 Nov 2024 14:27:13 +0100 Subject: [PATCH 18/83] Remove unused fabric-loader from libs.versions.toml --- gradle/libs.versions.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 797f5da88..30da438fe 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,6 @@ architectury-loom = "1.7-SNAPSHOT" yarn = "1.21+build.9" shadow = "8.1.1" minecraft = "1.21" -fabric-loader = "0.15.11" forge = "1.21-51.0.33" kotlinforforge = "5.4.0" mixin-extras = "0.4.0" @@ -17,7 +16,6 @@ dokka = "1.9.20" minecraft = { group = "com.mojang", name = "minecraft", version.ref = "minecraft" } yarn = { group = "net.fabricmc", name = "yarn", version.ref = "yarn" } kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" } -fabric-loader = { group = "net.fabricmc", name = "fabric-loader", version.ref = "fabric-loader" } forge = { group = "net.minecraftforge", name = "forge", version.ref = "forge" } kotlinforforge = { group = "thedarkcolour", name = "kotlinforforge", version.ref = "kotlinforforge" } mixinextras-common = { group = "io.github.llamalad7", name = "mixinextras-common", version.ref = "mixin-extras" } From abdde3452fcd11add60630c7111b63357a414261 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 11 Nov 2024 01:43:11 +0100 Subject: [PATCH 19/83] Add advancements --- .../kotlin/opekope2/avm_staff/api/StaffMod.kt | 1 + .../avm_staff/api/entity/CakeEntity.kt | 18 +++- .../assets/avm_staff/lang/en_us.json | 26 ++++++ .../data/avm_staff/advancement/bazeboze.json | 58 ++++++++++++ .../data/avm_staff/advancement/bulldozer.json | 67 ++++++++++++++ .../avm_staff/advancement/coming_down.json | 68 ++++++++++++++ .../avm_staff/advancement/coronavirus.json | 65 ++++++++++++++ .../flying_into_space_like_a_rocket.json | 89 +++++++++++++++++++ .../advancement/get_pranked_lol.json | 39 ++++++++ .../avm_staff/advancement/infinite_power.json | 34 +++++++ .../advancement/learning_to_fly.json | 85 ++++++++++++++++++ .../advancement/meet_the_engineer.json | 44 +++++++++ .../data/avm_staff/advancement/meteor.json | 28 ++++++ .../data/avm_staff/advancement/prankster.json | 42 +++++++++ .../advancement/trust_me_im_an_engineer.json | 51 +++++++++++ .../avm_staff/tags/damage_type/is_prank.json | 7 ++ 16 files changed, 720 insertions(+), 2 deletions(-) create mode 100644 StaffMod/src/main/resources/data/avm_staff/advancement/bazeboze.json create mode 100644 StaffMod/src/main/resources/data/avm_staff/advancement/bulldozer.json create mode 100644 StaffMod/src/main/resources/data/avm_staff/advancement/coming_down.json create mode 100644 StaffMod/src/main/resources/data/avm_staff/advancement/coronavirus.json create mode 100644 StaffMod/src/main/resources/data/avm_staff/advancement/flying_into_space_like_a_rocket.json create mode 100644 StaffMod/src/main/resources/data/avm_staff/advancement/get_pranked_lol.json create mode 100644 StaffMod/src/main/resources/data/avm_staff/advancement/infinite_power.json create mode 100644 StaffMod/src/main/resources/data/avm_staff/advancement/learning_to_fly.json create mode 100644 StaffMod/src/main/resources/data/avm_staff/advancement/meet_the_engineer.json create mode 100644 StaffMod/src/main/resources/data/avm_staff/advancement/meteor.json create mode 100644 StaffMod/src/main/resources/data/avm_staff/advancement/prankster.json create mode 100644 StaffMod/src/main/resources/data/avm_staff/advancement/trust_me_im_an_engineer.json create mode 100644 StaffMod/src/main/resources/data/avm_staff/tags/damage_type/is_prank.json diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt index 747b52238..7d3f211e9 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -254,6 +254,7 @@ val staffItemComponentType: RegistrySupplier> val rocketModeComponentType: RegistrySupplier> = DATA_COMPONENT_TYPES.register("rocket_mode") { ComponentType.builder() + .codec(MinecraftUnit.CODEC) .packetCodec(PacketCodec.unit(MinecraftUnit.INSTANCE)) .build() } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt index b9403ec8c..64fc7a5ad 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt @@ -45,6 +45,7 @@ import opekope2.avm_staff.util.* class CakeEntity(entityType: EntityType, world: World) : Entity(entityType, world), Ownable { private var thrower: LivingEntity? = null private var timeFalling = 0 + private var redirectedByImpactTnt = false /** * Creates a new [CakeEntity]. @@ -195,12 +196,23 @@ class CakeEntity(entityType: EntityType, world: World) : Entity(enti override fun handleFallDamage(fallDistance: Float, damageMultiplier: Float, damageSource: DamageSource) = false + override fun damage(source: DamageSource, amount: Float): Boolean { + val causer = source.source + if (causer is ImpactTntEntity && causer.owner != null) { + thrower = causer.owner + redirectedByImpactTnt = true + } + return super.damage(source, amount) + } + override fun writeCustomDataToNbt(nbt: NbtCompound) { - nbt.putInt("Time", timeFalling) + nbt.putInt(TIME_KEY, timeFalling) + nbt.putBoolean(REDIRECTED_BY_IMPACT_TNT_KEY, redirectedByImpactTnt) } override fun readCustomDataFromNbt(nbt: NbtCompound) { - timeFalling = nbt.getInt("Time") + timeFalling = nbt.getInt(TIME_KEY) + redirectedByImpactTnt = nbt.getBoolean(REDIRECTED_BY_IMPACT_TNT_KEY) } override fun doesRenderOnFire() = false @@ -222,6 +234,8 @@ class CakeEntity(entityType: EntityType, world: World) : Entity(enti override fun getOwner() = thrower companion object { + private const val TIME_KEY = "Time" + private const val REDIRECTED_BY_IMPACT_TNT_KEY = "EngineeredAttack" private val CAKE_STATE = Blocks.CAKE.defaultState private val particlePerSide: Int @Environment(EnvType.CLIENT) diff --git a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json index 2f1542b84..e882c03a8 100644 --- a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json +++ b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json @@ -1,4 +1,28 @@ { + "advancements.avm_staff.bazeboze.description": "Hit a %s using a %s", + "advancements.avm_staff.bazeboze.title": "Bazeboze", + "advancements.avm_staff.bulldozer.description": "Cause mass destruction using a staff", + "advancements.avm_staff.bulldozer.title": "Bulldozer", + "advancements.avm_staff.coming_down.description": "...is the hardest thing", + "advancements.avm_staff.coming_down.title": "Coming down", + "advancements.avm_staff.coronavirus.description": "Die while wearing a %s cursed with %s", + "advancements.avm_staff.coronavirus.title": "Coronavirus", + "advancements.avm_staff.engineered_attack.description": "Use an %s to launch a %s at someone", + "advancements.avm_staff.engineered_attack.title": "Trust me, I'm an engineer!", + "advancements.avm_staff.flying_into_space_like_a_rocket.description": "Use a %s to fly above build limit", + "advancements.avm_staff.flying_into_space_like_a_rocket.title": "Flying into space like a rocket", + "advancements.avm_staff.get_pranked_lol.description": "Get thrown with a %s", + "advancements.avm_staff.get_pranked_lol.title": "Get pranked LOL", + "advancements.avm_staff.infinite_power.description": "Obtain a staff", + "advancements.avm_staff.infinite_power.title": "Infinite Power!", + "advancements.avm_staff.learning_to_fly.description": "Use a %s to fly", + "advancements.avm_staff.learning_to_fly.title": "Learning to fly", + "advancements.avm_staff.meet_the_engineer.description": "Get thrown with a %s launched by an %s", + "advancements.avm_staff.meet_the_engineer.title": "Meet the Engineer", + "advancements.avm_staff.meteor.description": "Reach Mach 0.5 falling down", + "advancements.avm_staff.meteor.title": "Meteor", + "advancements.avm_staff.prankster.description": "Throw a %s at someone", + "advancements.avm_staff.prankster.title": "Prankster", "block.avm_staff.crown_of_king_orange": "Crown of King Orange", "death.attack.avm_staff.pranked": "%s was pranked", "death.attack.avm_staff.pranked.player": "%s was pranked by %s", @@ -18,6 +42,8 @@ "item.avm_staff.staff_infusion_smithing_template.applies_to": "Faint staffs", "item.avm_staff.staff_infusion_smithing_template.base_slot_description": "Add faint staff", "item.avm_staff.staff_infusion_smithing_template.title": "Staff Infusion Template", + "item.avm_staff.staff_template": "Staff", + "item.avm_staff.staff_template.with_item": "Staff with %s", "itemGroup.avm_staff_items": "Staff Mod", "key.avm_staff.add_remove_staff_item": "Add/remove staff item", "key.categories.avm_staff": "Staff Mod", diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/bazeboze.json b/StaffMod/src/main/resources/data/avm_staff/advancement/bazeboze.json new file mode 100644 index 000000000..cd2e36b58 --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/bazeboze.json @@ -0,0 +1,58 @@ +{ + "parent": "avm_staff:infinite_power", + "display": { + "icon": { + "id": "avm_staff:royal_staff", + "components": { + "avm_staff:staff_item": { + "item": { + "id": "minecraft:netherite_block" + } + } + } + }, + "title": { + "translate": "advancements.avm_staff.bazeboze.title" + }, + "description": { + "translate": "advancements.avm_staff.bazeboze.description", + "with": [ + { + "translate": "entity.minecraft.bat" + }, + { + "translate": "item.avm_staff.staff_template.with_item", + "with": [ + { + "translate": "block.minecraft.netherite_block" + } + ] + } + ] + } + }, + "criteria": { + "hit_bat": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { + "player": { + "equipment": { + "mainhand": { + "items": "#avm_staff:staffs", + "components": { + "avm_staff:staff_item": { + "item": { + "id": "minecraft:netherite_block" + } + } + } + } + } + }, + "entity": { + "type": "minecraft:bat" + } + } + } + } +} diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/bulldozer.json b/StaffMod/src/main/resources/data/avm_staff/advancement/bulldozer.json new file mode 100644 index 000000000..65ecb0dd0 --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/bulldozer.json @@ -0,0 +1,67 @@ +{ + "parent": "avm_staff:infinite_power", + "display": { + "icon": { + "id": "avm_staff:royal_staff", + "components": { + "avm_staff:staff_item": { + "item": { + "id": "minecraft:netherite_block" + } + } + } + }, + "title": { + "translate": "advancements.avm_staff.bulldozer.title" + }, + "description": { + "translate": "advancements.avm_staff.bulldozer.description" + } + }, + "criteria": { + "use_diamond_block_staff": { + "trigger": "avm_staff:break_block_with_staff", + "conditions": { + "player": { + "equipment": { + "mainhand": { + "items": "#avm_staff:staffs", + "components": { + "avm_staff:staff_item": { + "item": { + "id": "minecraft:diamond_block" + } + } + } + } + } + } + } + }, + "use_netherite_block_staff": { + "trigger": "avm_staff:break_block_with_staff", + "conditions": { + "player": { + "equipment": { + "mainhand": { + "items": "#avm_staff:staffs", + "components": { + "avm_staff:staff_item": { + "item": { + "id": "minecraft:netherite_block" + } + } + } + } + } + } + } + } + }, + "requirements": [ + [ + "use_diamond_block_staff", + "use_netherite_block_staff" + ] + ] +} diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/coming_down.json b/StaffMod/src/main/resources/data/avm_staff/advancement/coming_down.json new file mode 100644 index 000000000..bace7c38c --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/coming_down.json @@ -0,0 +1,68 @@ +{ + "parent": "avm_staff:learning_to_fly", + "display": { + "icon": { + "id": "minecraft:anvil" + }, + "title": { + "translate": "advancements.avm_staff.coming_down.title" + }, + "description": { + "translate": "advancements.avm_staff.coming_down.description" + } + }, + "criteria": { + "using_campfire_staff": { + "trigger": "avm_staff:get_hurt_while_using_item", + "conditions": { + "item": { + "items": "#avm_staff:staffs", + "components": { + "avm_staff:staff_item": { + "item": { + "id": "minecraft:campfire" + } + } + } + }, + "damage_type": { + "tags": [ + { + "id": "minecraft:is_fall", + "expected": true + } + ] + } + } + }, + "using_soul_campfire_staff": { + "trigger": "avm_staff:get_hurt_while_using_item", + "conditions": { + "item": { + "items": "#avm_staff:staffs", + "components": { + "avm_staff:staff_item": { + "item": { + "id": "minecraft:soul_campfire" + } + } + } + }, + "damage_type": { + "tags": [ + { + "id": "minecraft:is_fall", + "expected": true + } + ] + } + } + } + }, + "requirements": [ + [ + "using_campfire_staff", + "using_soul_campfire_staff" + ] + ] +} diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/coronavirus.json b/StaffMod/src/main/resources/data/avm_staff/advancement/coronavirus.json new file mode 100644 index 000000000..52578c5f1 --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/coronavirus.json @@ -0,0 +1,65 @@ +{ + "parent": "avm_staff:infinite_power", + "display": { + "icon": { + "id": "avm_staff:crown_of_king_orange" + }, + "title": { + "translate": "advancements.avm_staff.coronavirus.title" + }, + "description": { + "translate": "advancements.avm_staff.coronavirus.description", + "with": [ + { + "translate": "block.avm_staff.crown_of_king_orange" + }, + { + "translate": "enchantment.minecraft.binding_curse" + } + ] + } + }, + "criteria": { + "die": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { + "player": { + "nbt": "{Health:0f}", + "equipment": { + "head": { + "items": "avm_staff:crown_of_king_orange", + "components": { + "minecraft:enchantments": { + "minecraft:binding_curse": 1 + } + } + } + } + } + } + }, + "survive_with_totem": { + "trigger": "minecraft:used_totem", + "conditions": { + "player": { + "equipment": { + "head": { + "items": "avm_staff:crown_of_king_orange", + "components": { + "minecraft:enchantments": { + "minecraft:binding_curse": 1 + } + } + } + } + } + } + } + }, + "requirements": [ + [ + "die", + "survive_with_totem" + ] + ] +} diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/flying_into_space_like_a_rocket.json b/StaffMod/src/main/resources/data/avm_staff/advancement/flying_into_space_like_a_rocket.json new file mode 100644 index 000000000..40368876b --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/flying_into_space_like_a_rocket.json @@ -0,0 +1,89 @@ +{ + "parent": "avm_staff:learning_to_fly", + "display": { + "icon": { + "id": "avm_staff:royal_staff", + "components": { + "avm_staff:staff_item": { + "item": { + "id": "minecraft:soul_campfire" + } + } + } + }, + "title": { + "translate": "advancements.avm_staff.flying_into_space_like_a_rocket.title" + }, + "description": { + "translate": "advancements.avm_staff.flying_into_space_like_a_rocket.description", + "with": [ + { + "translate": "item.avm_staff.staff_template.with_item", + "with": [ + { + "translate": "block.minecraft.campfire" + } + ] + } + ] + } + }, + "criteria": { + "flying_above_build_limit_using_campfire_staff": { + "trigger": "minecraft:using_item", + "conditions": { + "player": { + "location": { + "position": { + "y": { + "min": 320 + } + } + } + }, + "item": { + "items": "#avm_staff:staffs", + "components": { + "avm_staff:rocket_mode": {}, + "avm_staff:staff_item": { + "item": { + "id": "minecraft:campfire" + } + } + } + } + } + }, + "flying_above_build_limit_using_soul_campfire_staff": { + "trigger": "minecraft:using_item", + "conditions": { + "player": { + "location": { + "position": { + "y": { + "min": 320 + } + } + } + }, + "item": { + "items": "#avm_staff:staffs", + "components": { + "avm_staff:rocket_mode": {}, + "avm_staff:staff_item": { + "item": { + "id": "minecraft:soul_campfire" + } + } + } + } + } + } + }, + "requirements": [ + [ + "flying_above_build_limit_using_campfire_staff", + "flying_above_build_limit_using_soul_campfire_staff" + ] + ] +} diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/get_pranked_lol.json b/StaffMod/src/main/resources/data/avm_staff/advancement/get_pranked_lol.json new file mode 100644 index 000000000..2b8fd8472 --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/get_pranked_lol.json @@ -0,0 +1,39 @@ +{ + "parent": "avm_staff:infinite_power", + "display": { + "icon": { + "id": "minecraft:cake" + }, + "title": { + "translate": "advancements.avm_staff.get_pranked_lol.title" + }, + "description": { + "translate": "advancements.avm_staff.get_pranked_lol.description", + "with": [ + { + "translate": "block.minecraft.cake" + } + ] + } + }, + "criteria": { + "get_pranked": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { + "damage": { + "type": { + "tags": [ + { + "id": "avm_staff:is_prank", + "expected": true + } + ], + "direct_entity": { + "type": "avm_staff:cake" + } + } + } + } + } + } +} diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/infinite_power.json b/StaffMod/src/main/resources/data/avm_staff/advancement/infinite_power.json new file mode 100644 index 000000000..00489979c --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/infinite_power.json @@ -0,0 +1,34 @@ +{ + "display": { + "icon": { + "id": "avm_staff:royal_staff", + "components": { + "avm_staff:staff_item": { + "item": { + "id": "minecraft:command_block" + } + } + } + }, + "title": { + "translate": "advancements.avm_staff.infinite_power.title" + }, + "description": { + "translate": "advancements.avm_staff.infinite_power.description" + }, + "frame": "goal", + "background": "minecraft:textures/block/smithing_table_top.png" + }, + "criteria": { + "obtain_staff": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "items": "#avm_staff:staffs" + } + ] + } + } + } +} diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/learning_to_fly.json b/StaffMod/src/main/resources/data/avm_staff/advancement/learning_to_fly.json new file mode 100644 index 000000000..0883fd8d2 --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/learning_to_fly.json @@ -0,0 +1,85 @@ +{ + "parent": "avm_staff:infinite_power", + "display": { + "icon": { + "id": "avm_staff:royal_staff", + "components": { + "avm_staff:staff_item": { + "item": { + "id": "minecraft:campfire" + } + } + } + }, + "title": { + "translate": "advancements.avm_staff.learning_to_fly.title" + }, + "description": { + "translate": "advancements.avm_staff.learning_to_fly.description", + "with": [ + { + "translate": "item.avm_staff.staff_template.with_item", + "with": [ + { + "translate": "block.minecraft.campfire" + } + ] + } + ] + } + }, + "criteria": { + "flying_using_campfire_staff": { + "trigger": "minecraft:using_item", + "conditions": { + "player": { + "movement": { + "y": { + "min": 5 + } + } + }, + "item": { + "items": "#avm_staff:staffs", + "components": { + "avm_staff:rocket_mode": {}, + "avm_staff:staff_item": { + "item": { + "id": "minecraft:campfire" + } + } + } + } + } + }, + "flying_using_soul_campfire_staff": { + "trigger": "minecraft:using_item", + "conditions": { + "player": { + "movement": { + "y": { + "min": 5 + } + } + }, + "item": { + "items": "#avm_staff:staffs", + "components": { + "avm_staff:rocket_mode": {}, + "avm_staff:staff_item": { + "item": { + "id": "minecraft:soul_campfire" + } + } + } + } + } + } + }, + "requirements": [ + [ + "flying_using_campfire_staff", + "flying_using_soul_campfire_staff" + ] + ] +} diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/meet_the_engineer.json b/StaffMod/src/main/resources/data/avm_staff/advancement/meet_the_engineer.json new file mode 100644 index 000000000..fdf35141f --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/meet_the_engineer.json @@ -0,0 +1,44 @@ +{ + "parent": "avm_staff:get_pranked_lol", + "display": { + "icon": { + "id": "minecraft:cake" + }, + "title": { + "translate": "advancements.avm_staff.meet_the_engineer.title" + }, + "description": { + "translate": "advancements.avm_staff.meet_the_engineer.description", + "with": [ + { + "translate": "block.minecraft.cake" + }, + { + "translate": "entity.avm_staff.impact_tnt" + } + ] + }, + "hidden": true + }, + "criteria": { + "meet_the_engineer": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { + "damage": { + "type": { + "tags": [ + { + "id": "avm_staff:is_prank", + "expected": true + } + ], + "direct_entity": { + "type": "avm_staff:cake", + "nbt": "{EngineeredAttack:1b}" + } + } + } + } + } + } +} diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/meteor.json b/StaffMod/src/main/resources/data/avm_staff/advancement/meteor.json new file mode 100644 index 000000000..33effd62f --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/meteor.json @@ -0,0 +1,28 @@ +{ + "parent": "avm_staff:flying_into_space_like_a_rocket", + "display": { + "icon": { + "id": "minecraft:fire_charge" + }, + "title": { + "translate": "advancements.avm_staff.meteor.title" + }, + "description": { + "translate": "advancements.avm_staff.meteor.description" + } + }, + "criteria": { + "half_mach": { + "trigger": "minecraft:tick", + "conditions": { + "player": { + "movement": { + "y": { + "max": -171.5 + } + } + } + } + } + } +} diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/prankster.json b/StaffMod/src/main/resources/data/avm_staff/advancement/prankster.json new file mode 100644 index 000000000..70b9d4437 --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/prankster.json @@ -0,0 +1,42 @@ +{ + "parent": "avm_staff:infinite_power", + "display": { + "icon": { + "id": "minecraft:cake" + }, + "title": { + "translate": "advancements.avm_staff.prankster.title" + }, + "description": { + "translate": "advancements.avm_staff.prankster.description", + "with": [ + { + "translate": "block.minecraft.cake" + } + ] + } + }, + "criteria": { + "prankster": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { + "entity": { + "type": "player" + }, + "damage": { + "type": { + "tags": [ + { + "id": "avm_staff:is_prank", + "expected": true + } + ], + "direct_entity": { + "type": "avm_staff:cake" + } + } + } + } + } + } +} diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/trust_me_im_an_engineer.json b/StaffMod/src/main/resources/data/avm_staff/advancement/trust_me_im_an_engineer.json new file mode 100644 index 000000000..0f4a95212 --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/trust_me_im_an_engineer.json @@ -0,0 +1,51 @@ +{ + "parent": "avm_staff:prankster", + "display": { + "icon": { + "id": "minecraft:cake" + }, + "title": { + "translate": "advancements.avm_staff.engineered_attack.title" + }, + "description": { + "translate": "advancements.avm_staff.engineered_attack.description", + "with": [ + { + "translate": "entity.avm_staff.impact_tnt" + }, + { + "translate": "block.minecraft.cake" + } + ] + }, + "frame": "challenge", + "hidden": true + }, + "criteria": { + "engineered_attack": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { + "entity": { + "type": "player" + }, + "damage": { + "type": { + "tags": [ + { + "id": "avm_staff:is_prank", + "expected": true + } + ], + "direct_entity": { + "type": "avm_staff:cake", + "nbt": "{EngineeredAttack:1b}" + } + } + } + } + } + }, + "rewards": { + "experience": 50 + } +} diff --git a/StaffMod/src/main/resources/data/avm_staff/tags/damage_type/is_prank.json b/StaffMod/src/main/resources/data/avm_staff/tags/damage_type/is_prank.json new file mode 100644 index 000000000..cdcf70815 --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/tags/damage_type/is_prank.json @@ -0,0 +1,7 @@ +{ + "replace": false, + "values": [ + "avm_staff:pranked", + "avm_staff:pranked_by_player" + ] +} From 20a0dc987c0ecd67db43473cb77af8858614392c Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 15 Nov 2024 17:17:44 +0100 Subject: [PATCH 20/83] Extend StaffItem.maxUseTime API --- .../opekope2/avm_staff/api/item/StaffItem.kt | 2 +- .../avm_staff/api/staff/StaffHandler.kt | 26 +++++++++++-------- .../internal/staff/handler/CakeHandler.kt | 3 +-- .../internal/staff/handler/CampfireHandler.kt | 3 +-- .../internal/staff/handler/FurnaceHandler.kt | 2 +- .../staff/handler/MagmaBlockHandler.kt | 2 +- .../staff/handler/SnowBlockHandler.kt | 2 +- .../handler/WitherSkeletonSkullHandler.kt | 7 +++-- 8 files changed, 26 insertions(+), 21 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt index a8474cdf8..addf66153 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt @@ -54,7 +54,7 @@ abstract class StaffItem(settings: Settings) : Item(settings) { } override fun getMaxUseTime(stack: ItemStack, user: LivingEntity): Int { - return stack.itemInStaff.staffHandlerOrDefault.maxUseTime // TODO extend API + return stack.itemInStaff.staffHandlerOrDefault.getMaxUseTime(stack, user.entityWorld, user) } override fun use(world: World, user: PlayerEntity, hand: Hand): TypedActionResult { diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt index 622c8ee21..6f316b910 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt @@ -41,22 +41,26 @@ import opekope2.avm_staff.api.breakBlockWithStaffCriterion * Provides functionality for a staff, when an item is inserted into it. */ abstract class StaffHandler { - /** - * The number of ticks the staff can be used for using the current item. - */ - open val maxUseTime: Int - get() = 0 - /** * Gets the attribute modifiers (damage, attack speed, etc.) of the staff when held. */ open val attributeModifiers: AttributeModifiersComponent get() = Default.ATTRIBUTE_MODIFIERS + /** + * Called on both the client and the server my Minecraft to get the number of ticks the staff can be used for using + * the current item. + * + * @param staffStack The item stack used to perform the action + * @param world The world the [user] is in + * @param user The player, which uses the staff + */ + open fun getMaxUseTime(staffStack: ItemStack, world: World, user: LivingEntity): Int = 0 + /** * Called on both the client and the server by Minecraft when the player uses the staff. * - * If the staff can be used for multiple ticks, override [maxUseTime] to return a positive number, and call + * If the staff can be used for multiple ticks, override [getMaxUseTime] to return a positive number, and call * [PlayerEntity.setCurrentHand] on [user] with [hand] as the argument. * * @return @@ -92,7 +96,7 @@ abstract class StaffHandler { * @param world The world [user] is in * @param user The entity, which uses the staff * @param remainingUseTicks The number of ticks remaining before an entity finishes using the staff counting down - * from [maxUseTime] to 0 + * from [getMaxUseTime] to 0 * @see Item.usageTick */ open fun usageTick(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { @@ -100,12 +104,12 @@ abstract class StaffHandler { /** * Called on both the client and the server by Minecraft, when an entity stops using the staff before being used for - * [maxUseTime]. If that time is reached, [finishUsing] will be called. + * [getMaxUseTime]. If that time is reached, [finishUsing] will be called. * * @param staffStack The item stack used to perform the action * @param world The world the [user] is in * @param user The entity, which used the staff - * @param remainingUseTicks The number of ticks left until reaching [maxUseTime] + * @param remainingUseTicks The number of ticks left until reaching [getMaxUseTime] * @see Item.onStoppedUsing */ open fun onStoppedUsing(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { @@ -113,7 +117,7 @@ abstract class StaffHandler { /** * Called on both the client and the server by Minecraft, when an entity finishes using the staff - * (usage ticks reach [maxUseTime]). + * (usage ticks reach [getMaxUseTime]). * * @param staffStack The item stack used to perform the action * @param world The world the [user] is in diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CakeHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CakeHandler.kt index 103ea5e60..c6aee1115 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CakeHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CakeHandler.kt @@ -30,8 +30,7 @@ import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.* internal class CakeHandler : StaffHandler() { - override val maxUseTime: Int - get() = 72000 + override fun getMaxUseTime(staffStack: ItemStack, world: World, user: LivingEntity) = 72000 override fun use( staffStack: ItemStack, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt index 0c8c1b9c6..df766c0bd 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt @@ -38,8 +38,7 @@ import opekope2.avm_staff.util.canUseStaff import opekope2.avm_staff.util.times internal class CampfireHandler(private val parameters: Parameters) : StaffHandler() { - override val maxUseTime: Int - get() = 72000 + override fun getMaxUseTime(staffStack: ItemStack, world: World, user: LivingEntity) = 72000 override fun use( staffStack: ItemStack, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt index 4456fc19c..69abb94d3 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt @@ -59,7 +59,7 @@ internal class FurnaceHandler( private val recipeType: RecipeType, private val smeltSound: SoundEvent ) : StaffHandler() { - override val maxUseTime = 72000 + override fun getMaxUseTime(staffStack: ItemStack, world: World, user: LivingEntity) = 72000 override val attributeModifiers = StaffAttributeModifiersComponentBuilder() .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(10.0), AttributeModifierSlot.MAINHAND) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/MagmaBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/MagmaBlockHandler.kt index f818dc0c5..32bcfce74 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/MagmaBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/MagmaBlockHandler.kt @@ -36,7 +36,7 @@ import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.* internal class MagmaBlockHandler : StaffHandler() { - override val maxUseTime = 72000 + override fun getMaxUseTime(staffStack: ItemStack, world: World, user: LivingEntity) = 72000 override val attributeModifiers = StaffAttributeModifiersComponentBuilder() .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(10.0), AttributeModifierSlot.MAINHAND) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/SnowBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/SnowBlockHandler.kt index 97756fc75..c01ecf624 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/SnowBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/SnowBlockHandler.kt @@ -31,7 +31,7 @@ import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.* internal class SnowBlockHandler : StaffHandler() { - override val maxUseTime = 72000 + override fun getMaxUseTime(staffStack: ItemStack, world: World, user: LivingEntity) = 72000 override fun use( staffStack: ItemStack, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt index f37b40b53..1ef919027 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt @@ -46,7 +46,7 @@ import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.* internal class WitherSkeletonSkullHandler : StaffHandler() { - override val maxUseTime = 20 + override fun getMaxUseTime(staffStack: ItemStack, world: World, user: LivingEntity) = 20 override fun use( staffStack: ItemStack, @@ -102,7 +102,10 @@ internal class WitherSkeletonSkullHandler : StaffHandler() { } override fun onStoppedUsing(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - (user as? PlayerEntity)?.itemCooldownManager?.set(staffStack.item, 4 * (maxUseTime - remainingUseTicks)) + (user as? PlayerEntity)?.itemCooldownManager?.set( + staffStack.item, + 4 * (getMaxUseTime(staffStack, world, user) - remainingUseTicks) + ) } override fun finishUsing(staffStack: ItemStack, world: World, user: LivingEntity): ItemStack { From 401b6fa8d70f45436431d65e4dd5302f25831000 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 15 Nov 2024 18:09:52 +0100 Subject: [PATCH 21/83] Register criteria the Architectury way because NeoForge cries --- .../kotlin/opekope2/avm_staff/api/StaffMod.kt | 19 ++++++++++--------- .../avm_staff/internal/Initializer.kt | 2 +- .../staff/handler/DiamondBlockHandler.kt | 2 +- .../staff/handler/NetheriteBlockHandler.kt | 2 +- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt index 7d3f211e9..7ab3db88c 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -24,7 +24,6 @@ package opekope2.avm_staff.api import dev.architectury.registry.CreativeTabRegistry import dev.architectury.registry.registries.DeferredRegister import dev.architectury.registry.registries.RegistrySupplier -import net.minecraft.advancement.criterion.Criteria import net.minecraft.block.AbstractBlock import net.minecraft.block.enums.NoteBlockInstrument import net.minecraft.block.piston.PistonBehavior @@ -76,6 +75,7 @@ private val ENTITY_TYPES = DeferredRegister.create(MOD_ID, RegistryKeys.ENTITY_T private val PARTICLE_TYPES = DeferredRegister.create(MOD_ID, RegistryKeys.PARTICLE_TYPE) private val DATA_COMPONENT_TYPES = DeferredRegister.create(MOD_ID, RegistryKeys.DATA_COMPONENT_TYPE) private val SOUND_EVENTS = DeferredRegister.create(MOD_ID, RegistryKeys.SOUND_EVENT) +private val CRITERIA = DeferredRegister.create(MOD_ID, RegistryKeys.CRITERION) /** * Block registered as `avm_staff:crown_of_king_orange`. @@ -315,18 +315,18 @@ val throwableCakesGameRule: GameRules.Key = /** * Criterion registered as `avm_staff:get_hurt_while_using_item`. */ -val takeDamageWhileUsingItemCriterion: TakeDamageWhileUsingItemCriterion = Criteria.register( - Identifier.of(MOD_ID, "get_hurt_while_using_item").toString(), - TakeDamageWhileUsingItemCriterion() -) +val takeDamageWhileUsingItemCriterion: RegistrySupplier = + CRITERIA.register(Identifier.of(MOD_ID, "get_hurt_while_using_item")) { + TakeDamageWhileUsingItemCriterion() + } /** * Criterion registered as `avm_staff:break_block_with_staff`. Triggers before a block is broken by a staff. */ -val breakBlockWithStaffCriterion: BreakBlockWithStaffCriterion = Criteria.register( - Identifier.of(MOD_ID, "break_block_with_staff").toString(), - BreakBlockWithStaffCriterion() -) +val breakBlockWithStaffCriterion: RegistrySupplier = + CRITERIA.register(Identifier.of(MOD_ID, "break_block_with_staff")) { + BreakBlockWithStaffCriterion() + } /** * @suppress @@ -340,6 +340,7 @@ internal fun registerContent() { PARTICLE_TYPES.register() DATA_COMPONENT_TYPES.register() SOUND_EVENTS.register() + CRITERIA.register() // Because SmithingTemplateItem doesn't take Item.Settings in its constructor CreativeTabRegistry.append(staffModItemGroup, staffInfusionSmithingTemplateItem) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt index 61c1df832..f1eea62d5 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -180,7 +180,7 @@ fun stopUsingStaffWhenDropped(entity: LivingEntity, item: ItemEntity): EventResu @Suppress("UNUSED_PARAMETER") fun triggerDamageWhileUsingItemCriterion(entity: LivingEntity, damage: DamageSource, amount: Float): EventResult { if (entity is ServerPlayerEntity && entity.isUsingItem) { - takeDamageWhileUsingItemCriterion.trigger(entity, entity.activeItem, damage) + takeDamageWhileUsingItemCriterion.get().trigger(entity, entity.activeItem, damage) } return EventResult.pass() } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/DiamondBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/DiamondBlockHandler.kt index b22b3576f..f8fcf063d 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/DiamondBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/DiamondBlockHandler.kt @@ -71,7 +71,7 @@ class DiamondBlockHandler : StaffHandler() { if (attacker is PlayerEntity && attacker.abilities.creativeMode) NoOpBlockDropCollector() else ChunkedBlockDropCollector(shapePredicate.volume, MAX_CHUNK_SIZE) - if (attacker is ServerPlayerEntity) breakBlockWithStaffCriterion.trigger(attacker, world, target) + if (attacker is ServerPlayerEntity) breakBlockWithStaffCriterion.get().trigger(attacker, world, target) destroyBox( world, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/NetheriteBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/NetheriteBlockHandler.kt index 2653d2bfe..210a647c3 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/NetheriteBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/NetheriteBlockHandler.kt @@ -123,7 +123,7 @@ class NetheriteBlockHandler : StaffHandler() { if (attacker is PlayerEntity && attacker.abilities.creativeMode) NoOpBlockDropCollector() else ChunkedBlockDropCollector(shapePredicate.volume, MAX_CHUNK_SIZE) - if (attacker is ServerPlayerEntity) breakBlockWithStaffCriterion.trigger(attacker, world, target) + if (attacker is ServerPlayerEntity) breakBlockWithStaffCriterion.get().trigger(attacker, world, target) destroyBox( world, From 86b6c62930b47ff32a4ead7a726823e7e5203c2f Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 15 Nov 2024 18:35:18 +0100 Subject: [PATCH 22/83] Bump Arcitectury API to fix a bug on NeoForge --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b6a998ec8..d66560bd1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ architectury-loom = "1.7-SNAPSHOT" yarn = "1.21+build.9" shadow = "8.1.1" minecraft = "1.21" -architectury-api = "13.0.6" +architectury-api = "13.0.8" fabric-loader = "0.15.11" neoforge = "21.0.164" fabric-api = "0.102.0+1.21" From b5693d2a8c46753944f15b922f4e2bd8ee5ac28e Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 15 Nov 2024 18:41:47 +0100 Subject: [PATCH 23/83] Make staffs repairable --- .../kotlin/opekope2/avm_staff/internal/fabric/StaffMod.kt | 4 +++- .../avm_staff/internal/fabric/item/FabricStaffItem.kt | 4 +++- .../opekope2/avm_staff/internal/neoforge/StaffMod.kt | 4 +++- .../avm_staff/internal/neoforge/item/NeoForgeStaffItem.kt | 6 ++++-- .../kotlin/opekope2/avm_staff/api/IStaffModPlatform.kt | 3 ++- .../src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt | 3 ++- .../main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt | 7 ++++++- 7 files changed, 23 insertions(+), 8 deletions(-) diff --git a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffMod.kt b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffMod.kt index 055fbab65..b01eee09a 100644 --- a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffMod.kt +++ b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffMod.kt @@ -18,6 +18,7 @@ package opekope2.avm_staff.internal.fabric +import dev.architectury.registry.registries.RegistrySupplier import net.fabricmc.api.EnvType import net.fabricmc.api.ModInitializer import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry @@ -63,7 +64,8 @@ object StaffMod : ModInitializer, IStaffModPlatform { else ActionResult.PASS } - override fun staffItem(settings: Item.Settings) = FabricStaffItem(settings) + override fun staffItem(settings: Item.Settings, repairIngredient: RegistrySupplier?) = + FabricStaffItem(settings, repairIngredient) override fun itemWithStaffRenderer(settings: Item.Settings) = Item(settings).also { item -> if (FabricLoader.getInstance().environmentType == EnvType.CLIENT) { diff --git a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/FabricStaffItem.kt b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/FabricStaffItem.kt index db0f4a948..e285471be 100644 --- a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/FabricStaffItem.kt +++ b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/FabricStaffItem.kt @@ -18,6 +18,7 @@ package opekope2.avm_staff.internal.fabric.item +import dev.architectury.registry.registries.RegistrySupplier import net.fabricmc.api.EnvType import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry import net.fabricmc.fabric.api.item.v1.FabricItem @@ -31,7 +32,8 @@ import opekope2.avm_staff.api.item.renderer.StaffRenderer import opekope2.avm_staff.util.itemInStaff import opekope2.avm_staff.util.staffHandlerOrDefault -class FabricStaffItem(settings: Item.Settings) : StaffItem(settings), FabricItem { +class FabricStaffItem(settings: Item.Settings, repairIngredient: RegistrySupplier?) : + StaffItem(settings, repairIngredient), FabricItem { init { if (FabricLoader.getInstance().environmentType == EnvType.CLIENT) { BuiltinItemRendererRegistry.INSTANCE.register(this, StaffRenderer::renderStaff) diff --git a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffMod.kt b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffMod.kt index 6230d333b..b34dac936 100644 --- a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffMod.kt +++ b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffMod.kt @@ -18,6 +18,7 @@ package opekope2.avm_staff.internal.neoforge +import dev.architectury.registry.registries.RegistrySupplier import net.minecraft.block.Block import net.minecraft.item.Item import net.minecraft.particle.SimpleParticleType @@ -58,7 +59,8 @@ object StaffMod : IStaffModPlatform { } } - override fun staffItem(settings: Item.Settings) = NeoForgeStaffItem(settings) + override fun staffItem(settings: Item.Settings, repairIngredient: RegistrySupplier?) = + NeoForgeStaffItem(settings, repairIngredient) override fun itemWithStaffRenderer(settings: Item.Settings) = NeoForgeStaffRendererItem(settings) diff --git a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/NeoForgeStaffItem.kt b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/NeoForgeStaffItem.kt index 4d6f249d3..a3dabebfc 100644 --- a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/NeoForgeStaffItem.kt +++ b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/NeoForgeStaffItem.kt @@ -18,6 +18,7 @@ package opekope2.avm_staff.internal.neoforge.item +import dev.architectury.registry.registries.RegistrySupplier import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.render.item.BuiltinModelItemRenderer import net.minecraft.client.render.model.json.ModelTransformationMode @@ -38,13 +39,14 @@ import opekope2.avm_staff.util.itemInStaff import opekope2.avm_staff.util.staffHandlerOrDefault import java.util.function.Consumer -class NeoForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IItemExtension { +class NeoForgeStaffItem(settings: Item.Settings, repairIngredientSupplier: RegistrySupplier?) : + StaffItem(settings, repairIngredientSupplier), IItemExtension { @Suppress("RemoveExplicitSuperQualifier") // Required because StaffItem apparently also has canDisableShield override fun canDisableShield(stack: ItemStack, shield: ItemStack, entity: LivingEntity, attacker: LivingEntity) = disablesShield(stack, attacker.entityWorld, attacker, Hand.MAIN_HAND) || super.canDisableShield(stack, shield, entity, attacker) - override fun isRepairable(arg: ItemStack) = false + override fun isRepairable(arg: ItemStack) = true override fun onEntitySwing(stack: ItemStack, entity: LivingEntity) = !canSwingHand( stack, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/IStaffModPlatform.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/IStaffModPlatform.kt index c5d3d279c..e065b103f 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/IStaffModPlatform.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/IStaffModPlatform.kt @@ -18,6 +18,7 @@ package opekope2.avm_staff.api +import dev.architectury.registry.registries.RegistrySupplier import net.minecraft.block.Block import net.minecraft.item.Item import net.minecraft.particle.SimpleParticleType @@ -37,7 +38,7 @@ interface IStaffModPlatform { * * @param settings The item settings to pass to the constructor */ - fun staffItem(settings: Item.Settings): StaffItem + fun staffItem(settings: Item.Settings, repairIngredient: RegistrySupplier?): StaffItem /** * Creates an item, which is rendered like a staff. diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt index 7ab3db88c..fb808395c 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -125,7 +125,8 @@ val faintRoyalStaffItem: RegistrySupplier = ITEMS.register("faint_royal_st val royalStaffItem: RegistrySupplier = ITEMS.register("royal_staff") { IStaffModPlatform.staffItem( Item.Settings().maxCount(1).rarity(Rarity.EPIC).attributeModifiers(StaffHandler.Default.ATTRIBUTE_MODIFIERS) - .`arch$tab`(staffModItemGroup) + .maxDamage(5179).`arch$tab`(staffModItemGroup), + royalStaffIngredientItem ) } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt index addf66153..4e2a45f95 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt @@ -18,6 +18,7 @@ package opekope2.avm_staff.api.item +import dev.architectury.registry.registries.RegistrySupplier import net.minecraft.component.DataComponentTypes import net.minecraft.entity.Entity import net.minecraft.entity.ItemEntity @@ -42,7 +43,11 @@ import opekope2.avm_staff.util.* * Implementing loader-specific interfaces is highly recommended when extending the class to pass loader-specific * functionality to [StaffHandler]. */ -abstract class StaffItem(settings: Settings) : Item(settings) { +abstract class StaffItem(settings: Settings, private val repairIngredientSupplier: RegistrySupplier?) : + Item(settings) { + override fun canRepair(stack: ItemStack, ingredient: ItemStack) = + repairIngredientSupplier != null && ingredient.isOf(repairIngredientSupplier.get()) + override fun onItemEntityDestroyed(entity: ItemEntity) { val staffStack = entity.stack val staffItem = staffStack.mutableItemStackInStaff ?: return From 6e0e6c31cafa5ce9b3da70f9ed4392ea23e00544 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 15 Nov 2024 19:29:22 +0100 Subject: [PATCH 24/83] Refactor and organize staff handler and renderer registration code --- .../renderer/BlockStateStaffItemRenderer.kt | 12 +- ...er.kt => MissingModelStaffItemRenderer.kt} | 2 +- ...ffItemRenderer.kt => StaffItemRenderer.kt} | 43 ++--- .../api/item/renderer/StaffRenderer.kt | 6 +- .../avm_staff/api/registry/RegistryBase.kt | 69 +++++++ .../avm_staff/api/staff/StaffHandler.kt | 39 ++-- .../staff/handler/BellBlockHandler.kt | 40 ---- .../internal/staff/handler/FurnaceHandler.kt | 34 ---- .../staff/handler/LightningRodHandler.kt | 30 --- .../staff/handler/VanillaStaffHandlers.kt | 172 +++++++++--------- .../handler/WitherSkeletonSkullHandler.kt | 45 +---- .../item_renderer/BellStaffItemRenderer.kt | 61 +++++++ .../item_renderer/FurnaceStaffItemRenderer.kt | 58 ++++++ .../LightningRodStaffItemRenderer.kt | 51 ++++++ .../WitherSkeletonSkullStaffItemRenderer.kt | 62 +++++++ .../opekope2/avm_staff/util/StaffUtil.kt | 12 +- 16 files changed, 437 insertions(+), 299 deletions(-) rename StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/{MissingModelRenderer.kt => MissingModelStaffItemRenderer.kt} (96%) rename StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/{IStaffItemRenderer.kt => StaffItemRenderer.kt} (60%) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/registry/RegistryBase.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/BellStaffItemRenderer.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/FurnaceStaffItemRenderer.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/LightningRodStaffItemRenderer.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/WitherSkeletonSkullStaffItemRenderer.kt diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/BlockStateStaffItemRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/BlockStateStaffItemRenderer.kt index 2b72965b5..f96f2b4c6 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/BlockStateStaffItemRenderer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/BlockStateStaffItemRenderer.kt @@ -20,6 +20,7 @@ package opekope2.avm_staff.api.item.renderer import net.fabricmc.api.EnvType import net.fabricmc.api.Environment +import net.minecraft.block.Block import net.minecraft.block.BlockState import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.render.block.BlockModels @@ -30,15 +31,22 @@ import opekope2.avm_staff.util.bakedModelManager import opekope2.avm_staff.util.itemRenderer /** - * A [IStaffItemRenderer], always which renders a single block state. + * A [StaffItemRenderer], always which renders a single block state. * * @param blockState The block state to render */ @Environment(EnvType.CLIENT) -class BlockStateStaffItemRenderer(blockState: BlockState) : IStaffItemRenderer { +class BlockStateStaffItemRenderer(blockState: BlockState) : StaffItemRenderer() { private val blockStateId = BlockModels.getModelId(blockState) private val blockItem = blockState.block.asItem().defaultStack + /** + * Creates a new [BlockStateStaffItemRenderer] with the [default state][Block.defaultState] of the given block. + * + * @param block The block to render its default state + */ + constructor(block: Block) : this(block.defaultState) + override fun renderItemInStaff( staffStack: ItemStack, mode: ModelTransformationMode, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/MissingModelRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/MissingModelStaffItemRenderer.kt similarity index 96% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/MissingModelRenderer.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/MissingModelStaffItemRenderer.kt index f101810f7..64ea00fc7 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/MissingModelRenderer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/MissingModelStaffItemRenderer.kt @@ -29,7 +29,7 @@ import opekope2.avm_staff.util.itemStackInStaff /** * A staff item renderer, which renders the missing model. */ -object MissingModelRenderer : IStaffItemRenderer { +object MissingModelStaffItemRenderer : StaffItemRenderer() { override fun renderItemInStaff( staffStack: ItemStack, mode: ModelTransformationMode, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/IStaffItemRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffItemRenderer.kt similarity index 60% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/IStaffItemRenderer.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffItemRenderer.kt index 14738ccdb..07f05d511 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/IStaffItemRenderer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffItemRenderer.kt @@ -23,16 +23,19 @@ import net.fabricmc.api.Environment import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.render.model.json.ModelTransformationMode import net.minecraft.client.util.math.MatrixStack +import net.minecraft.item.Item import net.minecraft.item.ItemStack +import net.minecraft.registry.Registries import net.minecraft.util.Identifier +import opekope2.avm_staff.api.registry.RegistryBase /** * A renderer for an item, which can be placed into a staff. * - * @see IStaffItemRenderer.register + * @see StaffItemRenderer.register */ @Environment(EnvType.CLIENT) -fun interface IStaffItemRenderer { +abstract class StaffItemRenderer { /** * Renders an item. * @@ -44,7 +47,7 @@ fun interface IStaffItemRenderer { * @param light Light component for rendering calls * @param overlay Overlay component for rendering calls */ - fun renderItemInStaff( + abstract fun renderItemInStaff( staffStack: ItemStack, mode: ModelTransformationMode, matrices: MatrixStack, @@ -54,38 +57,30 @@ fun interface IStaffItemRenderer { ) @Environment(EnvType.CLIENT) - companion object { - private val staffItemRenderers = mutableMapOf() + companion object Registry : RegistryBase() { + private inline val Item.registryId: Identifier + get() = Registries.ITEM.getId(this) /** - * Registers a renderer for a given [item ID][staffItem]. + * Registers an entry to this registry. * - * @param staffItem The item ID to register a renderer for - * @param renderer The item's renderer - * @return `true`, if the registration was successful, `false`, if a renderer for the item was already registered + * @param key The key to associate a value with + * @param value The value to register */ - @JvmStatic - fun register(staffItem: Identifier, renderer: IStaffItemRenderer): Boolean { - if (staffItem in staffItemRenderers) return false - - staffItemRenderers[staffItem] = renderer - return true - } + fun register(key: Item, value: StaffItemRenderer) = register(key.registryId, value) /** - * Checks if a renderer for the [given item][staffItem] is registered. + * Checks if the given key is present in the registry * - * @param staffItem The item ID, which can be inserted into the staff + * @param key The key to check */ - @JvmStatic - operator fun contains(staffItem: Identifier): Boolean = staffItem in staffItemRenderers + operator fun contains(key: Item) = key.registryId in this /** - * Gets the registered renderer for the [given item][staffItem] or `null`, if no renderer was registered. + * Gets the value associated with the given key or throws an exception, if the key is not present in this registry. * - * @param staffItem The item ID, which can be inserted into the staff + * @param key The key to check */ - @JvmStatic - operator fun get(staffItem: Identifier): IStaffItemRenderer? = staffItemRenderers[staffItem] + operator fun get(key: Item) = this[key.registryId] } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt index 3ef8c4707..d15ef5da6 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt @@ -25,7 +25,6 @@ import net.minecraft.client.render.model.BakedModel import net.minecraft.client.render.model.json.ModelTransformationMode import net.minecraft.client.util.math.MatrixStack import net.minecraft.item.ItemStack -import net.minecraft.registry.Registries import opekope2.avm_staff.api.component.StaffRendererPartComponent import opekope2.avm_staff.api.staffRendererPartComponentType import opekope2.avm_staff.util.bakedModelManager @@ -166,8 +165,9 @@ object StaffRenderer { safeGetModel(staffStack, StaffRendererPartComponent.ITEM).transformation.fixed.apply(false, this) staffStack.itemStackInStaff?.let { itemInStaff -> - val staffItemRenderer = IStaffItemRenderer[Registries.ITEM.getId(itemInStaff.item)] - ?: MissingModelRenderer + val staffItemRenderer = + if (itemInStaff.item !in StaffItemRenderer.Registry) MissingModelStaffItemRenderer + else StaffItemRenderer.Registry[itemInStaff.item] staffItemRenderer.renderItemInStaff(staffStack, mode, matrices, vertexConsumers, light, overlay) } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/registry/RegistryBase.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/registry/RegistryBase.kt new file mode 100644 index 000000000..008f61037 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/registry/RegistryBase.kt @@ -0,0 +1,69 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.api.registry + +/** + * AvM Staff mod base registration utility. + * This is not to be confused with Minecraft registries. + */ +abstract class RegistryBase : Iterable> { + private val entries = mutableMapOf() + + /** + * Gets all the registered keys in this registry. + */ + val keys: Set + get() = entries.keys + + /** + * Validates an entry to be registered. Throws an exception, if the entry is invalid. + * + * Implementors must call the super method to check if the key is not already registered. + */ + open fun validateEntry(key: TKey, value: TValue) { + require(key !in entries) { "Key `$key` is already registered" } + } + + /** + * Registers an entry to this registry. + * + * @param key The key to associate a value with + * @param value The value to register + */ + open fun register(key: TKey, value: TValue) { + validateEntry(key, value) + entries[key] = value + } + + /** + * Checks if the given key is present in the registry + * + * @param key The key to check + */ + operator fun contains(key: TKey) = key in entries + + /** + * Gets the value associated with the given key or throws an exception, if the key is not present in this registry. + * + * @param key The key to check + */ + operator fun get(key: TKey) = entries.getValue(key) + + override fun iterator(): Iterator> = entries.iterator() +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt index 6f316b910..e4d29b4ac 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt @@ -26,6 +26,7 @@ import net.minecraft.entity.LivingEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.Item import net.minecraft.item.ItemStack +import net.minecraft.registry.Registries import net.minecraft.stat.Stats import net.minecraft.util.ActionResult import net.minecraft.util.Hand @@ -36,6 +37,7 @@ import net.minecraft.util.math.Direction import net.minecraft.world.World import net.minecraft.world.event.GameEvent import opekope2.avm_staff.api.breakBlockWithStaffCriterion +import opekope2.avm_staff.api.registry.RegistryBase /** * Provides functionality for a staff, when an item is inserted into it. @@ -318,41 +320,30 @@ abstract class StaffHandler { val ATTRIBUTE_MODIFIERS = StaffAttributeModifiersComponentBuilder.default() } - companion object { - private val staffItemsHandlers = mutableMapOf() + companion object Registry : RegistryBase() { + private inline val Item.registryId: Identifier + get() = Registries.ITEM.getId(this) /** - * Registers a [StaffHandler] for the given [item ID][staffItem]. Call this from your common mod initializer. + * Registers an entry to this registry. * - * @param staffItem The item ID to register a handler for. This is the item, which can be - * inserted into the staff - * @param handler The staff item handler, which processes staff interactions, while the - * [registered item][staffItem] is inserted into it - * @return `true`, if the registration was successful, `false`, if the item was already registered + * @param key The key to associate a value with + * @param value The value to register */ - @JvmStatic - fun register(staffItem: Identifier, handler: StaffHandler): Boolean { - if (staffItem in staffItemsHandlers) return false - - staffItemsHandlers[staffItem] = handler - return true - } + fun register(key: Item, value: StaffHandler) = register(key.registryId, value) /** - * Checks, if a staff item handler for the [given item][staffItem] is registered. + * Checks if the given key is present in the registry * - * @param staffItem The item ID, which can be inserted into the staff + * @param key The key to check */ - @JvmStatic - operator fun contains(staffItem: Identifier): Boolean = staffItem in staffItemsHandlers + operator fun contains(key: Item) = key.registryId in this /** - * Gets the registered staff item handler for the [given item][staffItem] or `null`, if no staff item handler was - * registered. + * Gets the value associated with the given key or throws an exception, if the key is not present in this registry. * - * @param staffItem The item ID, which can be inserted into the staff + * @param key The key to check */ - @JvmStatic - operator fun get(staffItem: Identifier): StaffHandler? = staffItemsHandlers[staffItem] + operator fun get(key: Item) = this[key.registryId] } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellBlockHandler.kt index 5719ecb78..19450b295 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellBlockHandler.kt @@ -19,13 +19,6 @@ package opekope2.avm_staff.internal.staff.handler import dev.architectury.event.EventResult -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment -import net.minecraft.client.render.RenderLayer -import net.minecraft.client.render.VertexConsumerProvider -import net.minecraft.client.render.block.entity.BellBlockEntityRenderer -import net.minecraft.client.render.model.json.ModelTransformationMode -import net.minecraft.client.util.math.MatrixStack import net.minecraft.component.type.AttributeModifierSlot import net.minecraft.entity.Entity import net.minecraft.entity.LivingEntity @@ -37,12 +30,10 @@ import net.minecraft.sound.SoundEvents import net.minecraft.util.Hand import net.minecraft.util.TypedActionResult import net.minecraft.world.World -import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer import opekope2.avm_staff.api.staff.StaffAttributeModifiersComponentBuilder import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.attackSpeed -import opekope2.avm_staff.util.push internal class BellBlockHandler : StaffHandler() { override val attributeModifiers = StaffAttributeModifiersComponentBuilder() @@ -81,35 +72,4 @@ internal class BellBlockHandler : StaffHandler() { return EventResult.pass() } - - @Environment(EnvType.CLIENT) - class BellStaffItemRenderer : IStaffItemRenderer { - private val bellModel = BellBlockEntityRenderer.getTexturedModelData().createModel().apply { - setPivot(-8f, -12f, -8f) - } - - override fun renderItemInStaff( - staffStack: ItemStack, - mode: ModelTransformationMode, - matrices: MatrixStack, - vertexConsumers: VertexConsumerProvider, - light: Int, - overlay: Int - ) { - matrices.push { - scale(16f / 9f, 16f / 9f, 16f / 9f) - translate(0f, 2f / 9f, 0f) - - bellModel.render( - matrices, - BellBlockEntityRenderer.BELL_BODY_TEXTURE.getVertexConsumer( - vertexConsumers, - RenderLayer::getEntitySolid - ), - light, - overlay - ) - } - } - } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt index 69abb94d3..dd2708db8 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt @@ -20,12 +20,6 @@ package opekope2.avm_staff.internal.staff.handler import net.fabricmc.api.EnvType import net.fabricmc.api.Environment -import net.minecraft.block.AbstractFurnaceBlock -import net.minecraft.block.Block -import net.minecraft.block.BlockState -import net.minecraft.client.render.VertexConsumerProvider -import net.minecraft.client.render.model.json.ModelTransformationMode -import net.minecraft.client.util.math.MatrixStack import net.minecraft.component.type.AttributeModifierSlot import net.minecraft.entity.EntityType import net.minecraft.entity.ItemEntity @@ -46,8 +40,6 @@ import net.minecraft.util.math.Box import net.minecraft.util.math.Vec3d import net.minecraft.world.World import opekope2.avm_staff.api.component.StaffFurnaceDataComponent -import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer -import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer import opekope2.avm_staff.api.staff.StaffAttributeModifiersComponentBuilder import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.api.staffFurnaceDataComponentType @@ -141,32 +133,6 @@ internal class FurnaceHandler( return staffStack } - @Environment(EnvType.CLIENT) - class FurnaceStaffItemRenderer(unlitState: BlockState, litState: BlockState) : IStaffItemRenderer { - constructor(furnaceBlock: Block) : this( - furnaceBlock.defaultState, - furnaceBlock.defaultState.with(AbstractFurnaceBlock.LIT, true) - ) - - private val unlitRenderer = BlockStateStaffItemRenderer(unlitState) - private val litRenderer = BlockStateStaffItemRenderer(litState) - - override fun renderItemInStaff( - staffStack: ItemStack, - mode: ModelTransformationMode, - matrices: MatrixStack, - vertexConsumers: VertexConsumerProvider, - light: Int, - overlay: Int - ) { - val renderer = - if (staffFurnaceDataComponentType.get() in staffStack) litRenderer - else unlitRenderer - - renderer.renderItemInStaff(staffStack, mode, matrices, vertexConsumers, light, overlay) - } - } - private companion object { private val ITEM_DIMENSIONS = EntityType.ITEM.dimensions private val SMELTING_VOLUME = Box(-0.5, -0.5, -0.5, 0.5, 0.5, 0.5).contract( diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/LightningRodHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/LightningRodHandler.kt index 708281349..a7eacd03f 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/LightningRodHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/LightningRodHandler.kt @@ -19,12 +19,6 @@ package opekope2.avm_staff.internal.staff.handler import dev.architectury.event.EventResult -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment -import net.minecraft.block.Blocks -import net.minecraft.client.render.VertexConsumerProvider -import net.minecraft.client.render.model.json.ModelTransformationMode -import net.minecraft.client.util.math.MatrixStack import net.minecraft.component.type.AttributeModifierSlot import net.minecraft.entity.Entity import net.minecraft.entity.EntityType @@ -39,13 +33,10 @@ import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction import net.minecraft.util.math.Vec3d import net.minecraft.world.World -import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer -import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer import opekope2.avm_staff.api.staff.StaffAttributeModifiersComponentBuilder import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.interactionRange import opekope2.avm_staff.util.isItemCoolingDown -import opekope2.avm_staff.util.push internal class LightningRodHandler : StaffHandler() { override val attributeModifiers = StaffAttributeModifiersComponentBuilder() @@ -114,25 +105,4 @@ internal class LightningRodHandler : StaffHandler() { return true } - - @Environment(EnvType.CLIENT) - class LightningRodStaffItemRenderer : IStaffItemRenderer { - private val lightningRodRenderer = BlockStateStaffItemRenderer(Blocks.LIGHTNING_ROD.defaultState) - - override fun renderItemInStaff( - staffStack: ItemStack, - mode: ModelTransformationMode, - matrices: MatrixStack, - vertexConsumers: VertexConsumerProvider, - light: Int, - overlay: Int - ) { - matrices.push { - if (mode != ModelTransformationMode.GUI && mode != ModelTransformationMode.FIXED) { - translate(0f, 22f / 16f, 0f) - } - lightningRodRenderer.renderItemInStaff(staffStack, mode, matrices, vertexConsumers, light, overlay) - } - } - } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt index 731f2338a..6316acbfc 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt @@ -20,41 +20,40 @@ package opekope2.avm_staff.internal.staff.handler import net.fabricmc.api.EnvType import net.fabricmc.api.Environment -import net.minecraft.block.Block import net.minecraft.block.Blocks import net.minecraft.item.BlockItem -import net.minecraft.item.Item import net.minecraft.item.Items.* import net.minecraft.recipe.RecipeType -import net.minecraft.registry.Registries import net.minecraft.sound.SoundEvents import opekope2.avm_staff.api.flamethrowerParticleType import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer -import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer +import opekope2.avm_staff.api.item.renderer.StaffItemRenderer import opekope2.avm_staff.api.soulFlamethrowerParticleType import opekope2.avm_staff.api.staff.StaffHandler - -private fun Item.registerHandler(handler: StaffHandler) { - StaffHandler.register(Registries.ITEM.getId(this), handler) -} +import opekope2.avm_staff.internal.staff.item_renderer.BellStaffItemRenderer +import opekope2.avm_staff.internal.staff.item_renderer.FurnaceStaffItemRenderer +import opekope2.avm_staff.internal.staff.item_renderer.LightningRodStaffItemRenderer +import opekope2.avm_staff.internal.staff.item_renderer.WitherSkeletonSkullStaffItemRenderer fun registerVanillaStaffHandlers() { - ANVIL.registerHandler(AnvilHandler(CHIPPED_ANVIL)) - CHIPPED_ANVIL.registerHandler(AnvilHandler(DAMAGED_ANVIL)) - DAMAGED_ANVIL.registerHandler(AnvilHandler(null)) + StaffHandler.register(ANVIL, AnvilHandler(CHIPPED_ANVIL)) + StaffHandler.register(CHIPPED_ANVIL, AnvilHandler(DAMAGED_ANVIL)) + StaffHandler.register(DAMAGED_ANVIL, AnvilHandler(null)) - BELL.registerHandler(BellBlockHandler()) + StaffHandler.register(BELL, BellBlockHandler()) - BONE_BLOCK.registerHandler(BoneBlockHandler()) + StaffHandler.register(BONE_BLOCK, BoneBlockHandler()) - CAKE.registerHandler(CakeHandler()) + StaffHandler.register(CAKE, CakeHandler()) - CAMPFIRE.registerHandler( + StaffHandler.register( + CAMPFIRE, CampfireHandler( CampfireHandler.Parameters(5 / 20.0, 1 / 20.0, 4f, 1, 0.1, flamethrowerParticleType) ) ) - SOUL_CAMPFIRE.registerHandler( + StaffHandler.register( + SOUL_CAMPFIRE, CampfireHandler( CampfireHandler.Parameters(10 / 20.0, 2 / 20.0, 6f, 2, 0.12, soulFlamethrowerParticleType) ) @@ -62,113 +61,104 @@ fun registerVanillaStaffHandlers() { // TODO command block - DIAMOND_BLOCK.registerHandler(DiamondBlockHandler()) + StaffHandler.register(DIAMOND_BLOCK, DiamondBlockHandler()) - FURNACE.registerHandler( + StaffHandler.register( + FURNACE, FurnaceHandler(RecipeType.SMELTING, SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE) ) - BLAST_FURNACE.registerHandler( + StaffHandler.register( + BLAST_FURNACE, FurnaceHandler(RecipeType.BLASTING, SoundEvents.BLOCK_BLASTFURNACE_FIRE_CRACKLE) ) - SMOKER.registerHandler( + StaffHandler.register( + SMOKER, FurnaceHandler(RecipeType.SMOKING, SoundEvents.BLOCK_SMOKER_SMOKE) ) - GOLD_BLOCK.registerHandler(GoldBlockHandler()) + StaffHandler.register(GOLD_BLOCK, GoldBlockHandler()) - LIGHTNING_ROD.registerHandler(LightningRodHandler()) + StaffHandler.register(LIGHTNING_ROD, LightningRodHandler()) - MAGMA_BLOCK.registerHandler(MagmaBlockHandler()) + StaffHandler.register(MAGMA_BLOCK, MagmaBlockHandler()) - NETHERITE_BLOCK.registerHandler(NetheriteBlockHandler()) + StaffHandler.register(NETHERITE_BLOCK, NetheriteBlockHandler()) - SNOW_BLOCK.registerHandler(SnowBlockHandler()) + StaffHandler.register(SNOW_BLOCK, SnowBlockHandler()) - TNT.registerHandler(TntHandler()) + StaffHandler.register(TNT, TntHandler()) - WITHER_SKELETON_SKULL.registerHandler( - WitherSkeletonSkullHandler() - ) - - WHITE_WOOL.registerHandler(WoolHandler(WHITE_WOOL as BlockItem, WHITE_CARPET as BlockItem)) - ORANGE_WOOL.registerHandler(WoolHandler(ORANGE_WOOL as BlockItem, ORANGE_CARPET as BlockItem)) - MAGENTA_WOOL.registerHandler(WoolHandler(MAGENTA_WOOL as BlockItem, MAGENTA_CARPET as BlockItem)) - LIGHT_BLUE_WOOL.registerHandler(WoolHandler(LIGHT_BLUE_WOOL as BlockItem, LIGHT_BLUE_CARPET as BlockItem)) - YELLOW_WOOL.registerHandler(WoolHandler(YELLOW_WOOL as BlockItem, YELLOW_CARPET as BlockItem)) - LIME_WOOL.registerHandler(WoolHandler(LIME_WOOL as BlockItem, LIME_CARPET as BlockItem)) - PINK_WOOL.registerHandler(WoolHandler(PINK_WOOL as BlockItem, PINK_CARPET as BlockItem)) - GRAY_WOOL.registerHandler(WoolHandler(GRAY_WOOL as BlockItem, GRAY_CARPET as BlockItem)) - LIGHT_GRAY_WOOL.registerHandler(WoolHandler(LIGHT_GRAY_WOOL as BlockItem, LIGHT_GRAY_CARPET as BlockItem)) - CYAN_WOOL.registerHandler(WoolHandler(CYAN_WOOL as BlockItem, CYAN_CARPET as BlockItem)) - PURPLE_WOOL.registerHandler(WoolHandler(PURPLE_WOOL as BlockItem, PURPLE_CARPET as BlockItem)) - BLUE_WOOL.registerHandler(WoolHandler(BLUE_WOOL as BlockItem, BLUE_CARPET as BlockItem)) - BROWN_WOOL.registerHandler(WoolHandler(BROWN_WOOL as BlockItem, BROWN_CARPET as BlockItem)) - GREEN_WOOL.registerHandler(WoolHandler(GREEN_WOOL as BlockItem, GREEN_CARPET as BlockItem)) - RED_WOOL.registerHandler(WoolHandler(RED_WOOL as BlockItem, RED_CARPET as BlockItem)) - BLACK_WOOL.registerHandler(WoolHandler(BLACK_WOOL as BlockItem, BLACK_CARPET as BlockItem)) -} + StaffHandler.register(WITHER_SKELETON_SKULL, WitherSkeletonSkullHandler()) -@Environment(EnvType.CLIENT) -private fun Item.registerStaffItemRenderer(renderer: IStaffItemRenderer) { - IStaffItemRenderer.register(Registries.ITEM.getId(this), renderer) -} - -@Environment(EnvType.CLIENT) -private fun Item.registerStaffItemRenderer(staffItem: Block) { - registerStaffItemRenderer(BlockStateStaffItemRenderer(staffItem.defaultState)) + StaffHandler.register(WHITE_WOOL, WoolHandler(WHITE_WOOL as BlockItem, WHITE_CARPET as BlockItem)) + StaffHandler.register(ORANGE_WOOL, WoolHandler(ORANGE_WOOL as BlockItem, ORANGE_CARPET as BlockItem)) + StaffHandler.register(MAGENTA_WOOL, WoolHandler(MAGENTA_WOOL as BlockItem, MAGENTA_CARPET as BlockItem)) + StaffHandler.register(LIGHT_BLUE_WOOL, WoolHandler(LIGHT_BLUE_WOOL as BlockItem, LIGHT_BLUE_CARPET as BlockItem)) + StaffHandler.register(YELLOW_WOOL, WoolHandler(YELLOW_WOOL as BlockItem, YELLOW_CARPET as BlockItem)) + StaffHandler.register(LIME_WOOL, WoolHandler(LIME_WOOL as BlockItem, LIME_CARPET as BlockItem)) + StaffHandler.register(PINK_WOOL, WoolHandler(PINK_WOOL as BlockItem, PINK_CARPET as BlockItem)) + StaffHandler.register(GRAY_WOOL, WoolHandler(GRAY_WOOL as BlockItem, GRAY_CARPET as BlockItem)) + StaffHandler.register(LIGHT_GRAY_WOOL, WoolHandler(LIGHT_GRAY_WOOL as BlockItem, LIGHT_GRAY_CARPET as BlockItem)) + StaffHandler.register(CYAN_WOOL, WoolHandler(CYAN_WOOL as BlockItem, CYAN_CARPET as BlockItem)) + StaffHandler.register(PURPLE_WOOL, WoolHandler(PURPLE_WOOL as BlockItem, PURPLE_CARPET as BlockItem)) + StaffHandler.register(BLUE_WOOL, WoolHandler(BLUE_WOOL as BlockItem, BLUE_CARPET as BlockItem)) + StaffHandler.register(BROWN_WOOL, WoolHandler(BROWN_WOOL as BlockItem, BROWN_CARPET as BlockItem)) + StaffHandler.register(GREEN_WOOL, WoolHandler(GREEN_WOOL as BlockItem, GREEN_CARPET as BlockItem)) + StaffHandler.register(RED_WOOL, WoolHandler(RED_WOOL as BlockItem, RED_CARPET as BlockItem)) + StaffHandler.register(BLACK_WOOL, WoolHandler(BLACK_WOOL as BlockItem, BLACK_CARPET as BlockItem)) } @Environment(EnvType.CLIENT) fun registerVanillaStaffItemRenderers() { - ANVIL.registerStaffItemRenderer(Blocks.ANVIL) - CHIPPED_ANVIL.registerStaffItemRenderer(Blocks.CHIPPED_ANVIL) - DAMAGED_ANVIL.registerStaffItemRenderer(Blocks.DAMAGED_ANVIL) + StaffItemRenderer.register(ANVIL, BlockStateStaffItemRenderer(Blocks.ANVIL)) + StaffItemRenderer.register(CHIPPED_ANVIL, BlockStateStaffItemRenderer(Blocks.CHIPPED_ANVIL)) + StaffItemRenderer.register(DAMAGED_ANVIL, BlockStateStaffItemRenderer(Blocks.DAMAGED_ANVIL)) - BELL.registerStaffItemRenderer(BellBlockHandler.BellStaffItemRenderer()) + StaffItemRenderer.register(BELL, BellStaffItemRenderer()) - BONE_BLOCK.registerStaffItemRenderer(Blocks.BONE_BLOCK) + StaffItemRenderer.register(BONE_BLOCK, BlockStateStaffItemRenderer(Blocks.BONE_BLOCK)) - CAKE.registerStaffItemRenderer(Blocks.CAKE) + StaffItemRenderer.register(CAKE, BlockStateStaffItemRenderer(Blocks.CAKE)) - CAMPFIRE.registerStaffItemRenderer(Blocks.CAMPFIRE) - SOUL_CAMPFIRE.registerStaffItemRenderer(Blocks.SOUL_CAMPFIRE) + StaffItemRenderer.register(CAMPFIRE, BlockStateStaffItemRenderer(Blocks.CAMPFIRE)) + StaffItemRenderer.register(SOUL_CAMPFIRE, BlockStateStaffItemRenderer(Blocks.SOUL_CAMPFIRE)) - COMMAND_BLOCK.registerStaffItemRenderer(Blocks.COMMAND_BLOCK) + StaffItemRenderer.register(COMMAND_BLOCK, BlockStateStaffItemRenderer(Blocks.COMMAND_BLOCK)) - DIAMOND_BLOCK.registerStaffItemRenderer(Blocks.DIAMOND_BLOCK) + StaffItemRenderer.register(DIAMOND_BLOCK, BlockStateStaffItemRenderer(Blocks.DIAMOND_BLOCK)) - FURNACE.registerStaffItemRenderer(FurnaceHandler.FurnaceStaffItemRenderer(Blocks.FURNACE)) - BLAST_FURNACE.registerStaffItemRenderer(FurnaceHandler.FurnaceStaffItemRenderer(Blocks.BLAST_FURNACE)) - SMOKER.registerStaffItemRenderer(FurnaceHandler.FurnaceStaffItemRenderer(Blocks.SMOKER)) + StaffItemRenderer.register(FURNACE, FurnaceStaffItemRenderer(Blocks.FURNACE)) + StaffItemRenderer.register(BLAST_FURNACE, FurnaceStaffItemRenderer(Blocks.BLAST_FURNACE)) + StaffItemRenderer.register(SMOKER, FurnaceStaffItemRenderer(Blocks.SMOKER)) - GOLD_BLOCK.registerStaffItemRenderer(Blocks.GOLD_BLOCK) + StaffItemRenderer.register(GOLD_BLOCK, BlockStateStaffItemRenderer(Blocks.GOLD_BLOCK)) - LIGHTNING_ROD.registerStaffItemRenderer(LightningRodHandler.LightningRodStaffItemRenderer()) + StaffItemRenderer.register(LIGHTNING_ROD, LightningRodStaffItemRenderer()) - MAGMA_BLOCK.registerStaffItemRenderer(Blocks.MAGMA_BLOCK) + StaffItemRenderer.register(MAGMA_BLOCK, BlockStateStaffItemRenderer(Blocks.MAGMA_BLOCK)) - NETHERITE_BLOCK.registerStaffItemRenderer(Blocks.NETHERITE_BLOCK) + StaffItemRenderer.register(NETHERITE_BLOCK, BlockStateStaffItemRenderer(Blocks.NETHERITE_BLOCK)) - SNOW_BLOCK.registerStaffItemRenderer(Blocks.SNOW_BLOCK) + StaffItemRenderer.register(SNOW_BLOCK, BlockStateStaffItemRenderer(Blocks.SNOW_BLOCK)) - TNT.registerStaffItemRenderer(Blocks.TNT) + StaffItemRenderer.register(TNT, BlockStateStaffItemRenderer(Blocks.TNT)) - WITHER_SKELETON_SKULL.registerStaffItemRenderer(WitherSkeletonSkullHandler.WitherSkeletonSkullStaffItemRenderer()) + StaffItemRenderer.register(WITHER_SKELETON_SKULL, WitherSkeletonSkullStaffItemRenderer()) - WHITE_WOOL.registerStaffItemRenderer(Blocks.WHITE_WOOL) - ORANGE_WOOL.registerStaffItemRenderer(Blocks.ORANGE_WOOL) - MAGENTA_WOOL.registerStaffItemRenderer(Blocks.MAGENTA_WOOL) - LIGHT_BLUE_WOOL.registerStaffItemRenderer(Blocks.LIGHT_BLUE_WOOL) - YELLOW_WOOL.registerStaffItemRenderer(Blocks.YELLOW_WOOL) - LIME_WOOL.registerStaffItemRenderer(Blocks.LIME_WOOL) - PINK_WOOL.registerStaffItemRenderer(Blocks.PINK_WOOL) - GRAY_WOOL.registerStaffItemRenderer(Blocks.GRAY_WOOL) - LIGHT_GRAY_WOOL.registerStaffItemRenderer(Blocks.LIGHT_GRAY_WOOL) - CYAN_WOOL.registerStaffItemRenderer(Blocks.CYAN_WOOL) - PURPLE_WOOL.registerStaffItemRenderer(Blocks.PURPLE_WOOL) - BLUE_WOOL.registerStaffItemRenderer(Blocks.BLUE_WOOL) - BROWN_WOOL.registerStaffItemRenderer(Blocks.BROWN_WOOL) - GREEN_WOOL.registerStaffItemRenderer(Blocks.GREEN_WOOL) - RED_WOOL.registerStaffItemRenderer(Blocks.RED_WOOL) - BLACK_WOOL.registerStaffItemRenderer(Blocks.BLACK_WOOL) + StaffItemRenderer.register(WHITE_WOOL, BlockStateStaffItemRenderer(Blocks.WHITE_WOOL)) + StaffItemRenderer.register(ORANGE_WOOL, BlockStateStaffItemRenderer(Blocks.ORANGE_WOOL)) + StaffItemRenderer.register(MAGENTA_WOOL, BlockStateStaffItemRenderer(Blocks.MAGENTA_WOOL)) + StaffItemRenderer.register(LIGHT_BLUE_WOOL, BlockStateStaffItemRenderer(Blocks.LIGHT_BLUE_WOOL)) + StaffItemRenderer.register(YELLOW_WOOL, BlockStateStaffItemRenderer(Blocks.YELLOW_WOOL)) + StaffItemRenderer.register(LIME_WOOL, BlockStateStaffItemRenderer(Blocks.LIME_WOOL)) + StaffItemRenderer.register(PINK_WOOL, BlockStateStaffItemRenderer(Blocks.PINK_WOOL)) + StaffItemRenderer.register(GRAY_WOOL, BlockStateStaffItemRenderer(Blocks.GRAY_WOOL)) + StaffItemRenderer.register(LIGHT_GRAY_WOOL, BlockStateStaffItemRenderer(Blocks.LIGHT_GRAY_WOOL)) + StaffItemRenderer.register(CYAN_WOOL, BlockStateStaffItemRenderer(Blocks.CYAN_WOOL)) + StaffItemRenderer.register(PURPLE_WOOL, BlockStateStaffItemRenderer(Blocks.PURPLE_WOOL)) + StaffItemRenderer.register(BLUE_WOOL, BlockStateStaffItemRenderer(Blocks.BLUE_WOOL)) + StaffItemRenderer.register(BROWN_WOOL, BlockStateStaffItemRenderer(Blocks.BROWN_WOOL)) + StaffItemRenderer.register(GREEN_WOOL, BlockStateStaffItemRenderer(Blocks.GREEN_WOOL)) + StaffItemRenderer.register(RED_WOOL, BlockStateStaffItemRenderer(Blocks.RED_WOOL)) + StaffItemRenderer.register(BLACK_WOOL, BlockStateStaffItemRenderer(Blocks.BLACK_WOOL)) } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt index 1ef919027..a1d384fd5 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt @@ -19,15 +19,6 @@ package opekope2.avm_staff.internal.staff.handler import dev.architectury.event.EventResult -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment -import net.minecraft.block.AbstractSkullBlock -import net.minecraft.block.Blocks -import net.minecraft.client.render.VertexConsumerProvider -import net.minecraft.client.render.block.entity.SkullBlockEntityRenderer -import net.minecraft.client.render.entity.model.SkullEntityModel -import net.minecraft.client.render.model.json.ModelTransformationMode -import net.minecraft.client.util.math.MatrixStack import net.minecraft.entity.Entity import net.minecraft.entity.EntityType import net.minecraft.entity.LivingEntity @@ -41,9 +32,11 @@ import net.minecraft.util.TypedActionResult import net.minecraft.world.Difficulty import net.minecraft.world.World import net.minecraft.world.WorldEvents -import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer import opekope2.avm_staff.api.staff.StaffHandler -import opekope2.avm_staff.util.* +import opekope2.avm_staff.util.approximateStaffTipPosition +import opekope2.avm_staff.util.canUseStaff +import opekope2.avm_staff.util.getSpawnPosition +import opekope2.avm_staff.util.isAttackCoolingDown internal class WitherSkeletonSkullHandler : StaffHandler() { override fun getMaxUseTime(staffStack: ItemStack, world: World, user: LivingEntity) = 20 @@ -112,34 +105,4 @@ internal class WitherSkeletonSkullHandler : StaffHandler() { onStoppedUsing(staffStack, world, user, 0) return staffStack } - - @Environment(EnvType.CLIENT) - class WitherSkeletonSkullStaffItemRenderer : IStaffItemRenderer { - private val skullModel = SkullEntityModel.getSkullTexturedModelData().createModel() - - override fun renderItemInStaff( - staffStack: ItemStack, - mode: ModelTransformationMode, - matrices: MatrixStack, - vertexConsumers: VertexConsumerProvider, - light: Int, - overlay: Int - ) { - matrices.push { - scale(-1f, -1f, 1f) - translate(0f, 8f / 16f, 0f) - scale(2f, 2f, 2f) - skullModel.render( - matrices, - vertexConsumers.getBuffer( - SkullBlockEntityRenderer.getRenderLayer( - (Blocks.WITHER_SKELETON_SKULL as AbstractSkullBlock).skullType, null - ) - ), - light, - overlay - ) - } - } - } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/BellStaffItemRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/BellStaffItemRenderer.kt new file mode 100644 index 000000000..f3d36edaf --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/BellStaffItemRenderer.kt @@ -0,0 +1,61 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.internal.staff.item_renderer + +import net.fabricmc.api.EnvType +import net.fabricmc.api.Environment +import net.minecraft.client.render.RenderLayer +import net.minecraft.client.render.VertexConsumerProvider +import net.minecraft.client.render.block.entity.BellBlockEntityRenderer +import net.minecraft.client.render.model.json.ModelTransformationMode +import net.minecraft.client.util.math.MatrixStack +import net.minecraft.item.ItemStack +import opekope2.avm_staff.api.item.renderer.StaffItemRenderer +import opekope2.avm_staff.util.push + +@Environment(EnvType.CLIENT) +class BellStaffItemRenderer : StaffItemRenderer() { + private val bellModel = BellBlockEntityRenderer.getTexturedModelData().createModel().apply { + setPivot(-8f, -12f, -8f) + } + + override fun renderItemInStaff( + staffStack: ItemStack, + mode: ModelTransformationMode, + matrices: MatrixStack, + vertexConsumers: VertexConsumerProvider, + light: Int, + overlay: Int + ) { + matrices.push { + scale(16f / 9f, 16f / 9f, 16f / 9f) + translate(0f, 2f / 9f, 0f) + + bellModel.render( + matrices, + BellBlockEntityRenderer.BELL_BODY_TEXTURE.getVertexConsumer( + vertexConsumers, + RenderLayer::getEntitySolid + ), + light, + overlay + ) + } + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/FurnaceStaffItemRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/FurnaceStaffItemRenderer.kt new file mode 100644 index 000000000..10c80390b --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/FurnaceStaffItemRenderer.kt @@ -0,0 +1,58 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.internal.staff.item_renderer + +import net.fabricmc.api.EnvType +import net.fabricmc.api.Environment +import net.minecraft.block.AbstractFurnaceBlock +import net.minecraft.block.Block +import net.minecraft.block.BlockState +import net.minecraft.client.render.VertexConsumerProvider +import net.minecraft.client.render.model.json.ModelTransformationMode +import net.minecraft.client.util.math.MatrixStack +import net.minecraft.item.ItemStack +import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer +import opekope2.avm_staff.api.item.renderer.StaffItemRenderer +import opekope2.avm_staff.api.staffFurnaceDataComponentType + +@Environment(EnvType.CLIENT) +class FurnaceStaffItemRenderer(unlitState: BlockState, litState: BlockState) : StaffItemRenderer() { + constructor(furnaceBlock: Block) : this( + furnaceBlock.defaultState, + furnaceBlock.defaultState.with(AbstractFurnaceBlock.LIT, true) + ) + + private val unlitRenderer = BlockStateStaffItemRenderer(unlitState) + private val litRenderer = BlockStateStaffItemRenderer(litState) + + override fun renderItemInStaff( + staffStack: ItemStack, + mode: ModelTransformationMode, + matrices: MatrixStack, + vertexConsumers: VertexConsumerProvider, + light: Int, + overlay: Int + ) { + val renderer = + if (staffFurnaceDataComponentType.get() in staffStack) litRenderer + else unlitRenderer + + renderer.renderItemInStaff(staffStack, mode, matrices, vertexConsumers, light, overlay) + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/LightningRodStaffItemRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/LightningRodStaffItemRenderer.kt new file mode 100644 index 000000000..06b1110c3 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/LightningRodStaffItemRenderer.kt @@ -0,0 +1,51 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.internal.staff.item_renderer + +import net.fabricmc.api.EnvType +import net.fabricmc.api.Environment +import net.minecraft.block.Blocks +import net.minecraft.client.render.VertexConsumerProvider +import net.minecraft.client.render.model.json.ModelTransformationMode +import net.minecraft.client.util.math.MatrixStack +import net.minecraft.item.ItemStack +import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer +import opekope2.avm_staff.api.item.renderer.StaffItemRenderer +import opekope2.avm_staff.util.push + +@Environment(EnvType.CLIENT) +class LightningRodStaffItemRenderer : StaffItemRenderer() { + private val lightningRodRenderer = BlockStateStaffItemRenderer(Blocks.LIGHTNING_ROD.defaultState) + + override fun renderItemInStaff( + staffStack: ItemStack, + mode: ModelTransformationMode, + matrices: MatrixStack, + vertexConsumers: VertexConsumerProvider, + light: Int, + overlay: Int + ) { + matrices.push { + if (mode != ModelTransformationMode.GUI && mode != ModelTransformationMode.FIXED) { + translate(0f, 22f / 16f, 0f) + } + lightningRodRenderer.renderItemInStaff(staffStack, mode, matrices, vertexConsumers, light, overlay) + } + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/WitherSkeletonSkullStaffItemRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/WitherSkeletonSkullStaffItemRenderer.kt new file mode 100644 index 000000000..22c0e7666 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/WitherSkeletonSkullStaffItemRenderer.kt @@ -0,0 +1,62 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.internal.staff.item_renderer + +import net.fabricmc.api.EnvType +import net.fabricmc.api.Environment +import net.minecraft.block.AbstractSkullBlock +import net.minecraft.block.Blocks +import net.minecraft.client.render.VertexConsumerProvider +import net.minecraft.client.render.block.entity.SkullBlockEntityRenderer +import net.minecraft.client.render.entity.model.SkullEntityModel +import net.minecraft.client.render.model.json.ModelTransformationMode +import net.minecraft.client.util.math.MatrixStack +import net.minecraft.item.ItemStack +import opekope2.avm_staff.api.item.renderer.StaffItemRenderer +import opekope2.avm_staff.util.push + +@Environment(EnvType.CLIENT) +class WitherSkeletonSkullStaffItemRenderer : StaffItemRenderer() { + private val skullModel = SkullEntityModel.getSkullTexturedModelData().createModel() + + override fun renderItemInStaff( + staffStack: ItemStack, + mode: ModelTransformationMode, + matrices: MatrixStack, + vertexConsumers: VertexConsumerProvider, + light: Int, + overlay: Int + ) { + matrices.push { + scale(-1f, -1f, 1f) + translate(0f, 8f / 16f, 0f) + scale(2f, 2f, 2f) + skullModel.render( + matrices, + vertexConsumers.getBuffer( + SkullBlockEntityRenderer.getRenderLayer( + (Blocks.WITHER_SKELETON_SKULL as AbstractSkullBlock).skullType, null + ) + ), + light, + overlay + ) + } + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt index 4af883e34..c8eb33076 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt @@ -24,7 +24,6 @@ import net.minecraft.component.ComponentChanges import net.minecraft.entity.Entity import net.minecraft.item.Item import net.minecraft.item.ItemStack -import net.minecraft.registry.Registries import net.minecraft.util.hit.HitResult import net.minecraft.util.math.Vec3d import net.minecraft.world.RaycastContext @@ -79,19 +78,14 @@ var ItemStack.mutableItemStackInStaff: ItemStack? */ val Item.hasStaffHandler: Boolean @JvmName("hasStaffHandler") - get() { - val itemId = Registries.ITEM.getId(this) - return itemId in StaffHandler - } + get() = this in StaffHandler.Registry /** * Returns the registered staff handler of the given item if available. */ val Item.staffHandler: StaffHandler? - get() { - val itemId = Registries.ITEM.getId(this) - return StaffHandler[itemId] - } + get() = if (!hasStaffHandler) null + else StaffHandler.Registry[this] /** * Returns the registered staff handler of the given item if available, [StaffHandler.Default] otherwise. From 82263a0756f1883af973215efbd69b6e9e5f2ff1 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 15 Nov 2024 19:37:44 +0100 Subject: [PATCH 25/83] Refactor StaffInfusionSmithingRecipeTextures --- .../StaffInfusionSmithingRecipeTextures.kt | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffInfusionSmithingRecipeTextures.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffInfusionSmithingRecipeTextures.kt index e0233501e..d283b8de9 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffInfusionSmithingRecipeTextures.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffInfusionSmithingRecipeTextures.kt @@ -26,28 +26,31 @@ import opekope2.avm_staff.api.staffInfusionSmithingTemplateItem * [staff infusion smithing template][staffInfusionSmithingTemplateItem]. */ object StaffInfusionSmithingRecipeTextures { + private val registeredBaseSlotTextures = mutableListOf() + private val registeredAdditionsSlotTextures = mutableListOf() + /** - * @suppress + * Gets a copy of the registered background textures of the 2nd slot of the smithing table. */ - @JvmSynthetic - internal val baseSlotTextures = mutableListOf() + val baseSlotTextures: List + get() = registeredBaseSlotTextures.toList() /** - * @suppress + * Gets a copy of the registered background textures of the 3rd slot of the smithing table. */ - @JvmSynthetic - internal val additionsSlotTextures = mutableListOf() + val additionsSlotTextures: List + get() = registeredAdditionsSlotTextures.toList() /** * Registers a pair of staff texture and an ingredient texture to be displayed in a smithing table, when using a * [staff infusion smithing template][staffInfusionSmithingTemplateItem]. This method should be called for every * `minecraft:smithing_transform` recipe in the mod's data pack, which infuses an ingredient into a faint staff. * - * @param baseSlotTexture The background texture of the 2nd slot of the smithing table. - * @param additionsSlotTexture The background texture of the 3rd slot of the smithing table. + * @param baseSlotTexture The background texture of the 2nd slot of the smithing table + * @param additionsSlotTexture The background texture of the 3rd slot of the smithing table */ fun register(baseSlotTexture: Identifier, additionsSlotTexture: Identifier) { - baseSlotTextures += baseSlotTexture - additionsSlotTextures += additionsSlotTexture + registeredBaseSlotTextures += baseSlotTexture + registeredAdditionsSlotTextures += additionsSlotTexture } } From eedae5a7f8392c3e1f1200c2f26c9fef66619382 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 15 Nov 2024 19:43:50 +0100 Subject: [PATCH 26/83] Add flint and steel sound to TNT staff --- .../opekope2/avm_staff/internal/staff/handler/TntHandler.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt index c65c9c870..8785733b5 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt @@ -46,6 +46,12 @@ internal class TntHandler : StaffHandler() { val (x, y, z) = spawnPos world.spawnEntity(ImpactTntEntity(world, x, y, z, shooter.rotationVector + shooter.velocity, shooter)) + world.playSound( + null, + x, y, z, + SoundEvents.ITEM_FLINTANDSTEEL_USE, SoundCategory.BLOCKS, + 1f, world.random.nextFloat() * 0.4f + 0.8f + ) world.playSound(null, x, y, z, SoundEvents.ENTITY_TNT_PRIMED, SoundCategory.BLOCKS, 1f, 1f) world.emitGameEvent(shooter, GameEvent.PRIME_FUSE, spawnPos) } From e69edf129c6ad6f2a7f33d956ecc2deb8d1e7d92 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 16 Nov 2024 00:33:47 +0100 Subject: [PATCH 27/83] Refactor content registration in preparation for Minecraft 1.21.2+ --- .../internal/fabric/StaffModClient.kt | 14 +- .../internal/neoforge/StaffModClient.kt | 7 +- .../kotlin/opekope2/avm_staff/api/StaffMod.kt | 348 ------------------ .../block/dispenser/CakeDispenserBehavior.kt | 13 +- .../avm_staff/api/entity/CakeEntity.kt | 14 +- .../api/entity/CampfireFlameEntity.kt | 8 +- .../avm_staff/api/entity/ImpactTntEntity.kt | 4 +- .../api/item/renderer/StaffRenderer.kt | 6 +- .../api/particle/FlamethrowerParticle.kt | 7 +- .../avm_staff/api/staff/StaffHandler.kt | 3 +- .../StaffInfusionSmithingRecipeTextures.kt | 6 +- .../opekope2/avm_staff/content/Blocks.kt | 72 ++++ .../avm_staff/content/ComponentTypes.kt | 104 ++++++ .../opekope2/avm_staff/content/Criteria.kt | 61 +++ .../opekope2/avm_staff/content/DamageTypes.kt | 41 +++ .../opekope2/avm_staff/content/EntityTypes.kt | 103 ++++++ .../opekope2/avm_staff/content/GameRules.kt | 34 ++ .../opekope2/avm_staff/content/ItemGroups.kt | 52 +++ .../opekope2/avm_staff/content/ItemTags.kt | 36 ++ .../opekope2/avm_staff/content/Items.kt | 172 +++++++++ .../avm_staff/content/ParticleTypes.kt | 62 ++++ .../opekope2/avm_staff/content/SoundEvents.kt | 59 +++ .../avm_staff/internal/Initializer.kt | 47 ++- .../internal/model/ModelPredicates.kt | 4 +- .../internal/staff/handler/CakeHandler.kt | 4 +- .../internal/staff/handler/CampfireHandler.kt | 8 +- .../staff/handler/DiamondBlockHandler.kt | 4 +- .../internal/staff/handler/FurnaceHandler.kt | 8 +- .../staff/handler/NetheriteBlockHandler.kt | 4 +- .../internal/staff/handler/TntHandler.kt | 4 +- .../staff/handler/VanillaStaffHandlers.kt | 7 +- .../item_renderer/FurnaceStaffItemRenderer.kt | 4 +- .../avm_staff/util/RegistryKeyUtil.kt | 54 +++ .../opekope2/avm_staff/util/RegistryUtil.kt | 52 +++ .../opekope2/avm_staff/util/StaffUtil.kt | 12 +- 35 files changed, 998 insertions(+), 440 deletions(-) delete mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/content/Blocks.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/content/Criteria.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/content/DamageTypes.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/content/EntityTypes.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/content/GameRules.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/content/ItemGroups.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/content/ItemTags.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/content/ParticleTypes.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/content/SoundEvents.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/util/RegistryKeyUtil.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/util/RegistryUtil.kt diff --git a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModClient.kt b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModClient.kt index f80a7ba15..5c1134b36 100644 --- a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModClient.kt +++ b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModClient.kt @@ -25,11 +25,9 @@ import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry import net.minecraft.client.item.ModelPredicateProviderRegistry import net.minecraft.client.render.RenderLayer -import opekope2.avm_staff.api.crownOfKingOrangeBlock -import opekope2.avm_staff.api.flamethrowerParticleType import opekope2.avm_staff.api.particle.FlamethrowerParticle -import opekope2.avm_staff.api.soulFlamethrowerParticleType -import opekope2.avm_staff.api.wallCrownOfKingOrangeBlock +import opekope2.avm_staff.content.Blocks +import opekope2.avm_staff.content.ParticleTypes import opekope2.avm_staff.internal.model.registerModelPredicateProviders @Suppress("unused") @@ -37,14 +35,14 @@ import opekope2.avm_staff.internal.model.registerModelPredicateProviders object StaffModClient : ClientModInitializer { override fun onInitializeClient() { ParticleFactoryRegistry.getInstance().apply { - register(flamethrowerParticleType.get(), FlamethrowerParticle::Factory) - register(soulFlamethrowerParticleType.get(), FlamethrowerParticle::Factory) + register(ParticleTypes.flame, FlamethrowerParticle::Factory) + register(ParticleTypes.soulFireFlame, FlamethrowerParticle::Factory) } BlockRenderLayerMap.INSTANCE.putBlocks( RenderLayer.getCutout(), - crownOfKingOrangeBlock.get(), - wallCrownOfKingOrangeBlock.get() + Blocks.crownOfKingOrange, + Blocks.wallCrownOfKingOrange ) registerModelPredicateProviders(ModelPredicateProviderRegistry::register) diff --git a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModClient.kt b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModClient.kt index 233742b9a..faea9726a 100644 --- a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModClient.kt +++ b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModClient.kt @@ -24,9 +24,8 @@ import net.neoforged.api.distmarker.OnlyIn import net.neoforged.bus.api.SubscribeEvent import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent import net.neoforged.neoforge.client.event.RegisterParticleProvidersEvent -import opekope2.avm_staff.api.flamethrowerParticleType import opekope2.avm_staff.api.particle.FlamethrowerParticle -import opekope2.avm_staff.api.soulFlamethrowerParticleType +import opekope2.avm_staff.content.ParticleTypes import opekope2.avm_staff.internal.model.registerModelPredicateProviders import opekope2.avm_staff.internal.registerClientContent import opekope2.avm_staff.internal.registerSmithingTableTextures @@ -53,7 +52,7 @@ object StaffModClient { @SubscribeEvent fun registerParticleProviders(event: RegisterParticleProvidersEvent) { - event.registerSpriteSet(flamethrowerParticleType.get(), FlamethrowerParticle::Factory) - event.registerSpriteSet(soulFlamethrowerParticleType.get(), FlamethrowerParticle::Factory) + event.registerSpriteSet(ParticleTypes.flame, FlamethrowerParticle::Factory) + event.registerSpriteSet(ParticleTypes.soulFireFlame, FlamethrowerParticle::Factory) } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt deleted file mode 100644 index fb808395c..000000000 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ /dev/null @@ -1,348 +0,0 @@ -/* - * AvM Staff Mod - * Copyright (c) 2024 opekope2 - * - * This mod is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This mod is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this mod. If not, see . - */ - -@file: JvmName("StaffMod") -@file: Suppress("unused") - -package opekope2.avm_staff.api - -import dev.architectury.registry.CreativeTabRegistry -import dev.architectury.registry.registries.DeferredRegister -import dev.architectury.registry.registries.RegistrySupplier -import net.minecraft.block.AbstractBlock -import net.minecraft.block.enums.NoteBlockInstrument -import net.minecraft.block.piston.PistonBehavior -import net.minecraft.client.particle.ParticleManager -import net.minecraft.component.ComponentType -import net.minecraft.entity.EntityType -import net.minecraft.entity.SpawnGroup -import net.minecraft.entity.damage.DamageType -import net.minecraft.item.Item -import net.minecraft.item.ItemGroup -import net.minecraft.item.Items -import net.minecraft.item.SmithingTemplateItem -import net.minecraft.network.codec.PacketCodec -import net.minecraft.particle.SimpleParticleType -import net.minecraft.registry.RegistryKey -import net.minecraft.registry.RegistryKeys -import net.minecraft.registry.tag.TagKey -import net.minecraft.sound.BlockSoundGroup -import net.minecraft.sound.SoundEvent -import net.minecraft.text.Text -import net.minecraft.util.Identifier -import net.minecraft.util.Rarity -import net.minecraft.world.GameRules -import opekope2.avm_staff.api.advancement.criterion.BreakBlockWithStaffCriterion -import opekope2.avm_staff.api.advancement.criterion.TakeDamageWhileUsingItemCriterion -import opekope2.avm_staff.api.block.CrownBlock -import opekope2.avm_staff.api.block.WallCrownBlock -import opekope2.avm_staff.api.component.StaffFurnaceDataComponent -import opekope2.avm_staff.api.component.StaffItemComponent -import opekope2.avm_staff.api.component.StaffRendererPartComponent -import opekope2.avm_staff.api.entity.CakeEntity -import opekope2.avm_staff.api.entity.CampfireFlameEntity -import opekope2.avm_staff.api.entity.ImpactTntEntity -import opekope2.avm_staff.api.item.CrownItem -import opekope2.avm_staff.api.item.StaffItem -import opekope2.avm_staff.api.staff.StaffHandler -import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures -import opekope2.avm_staff.internal.MinecraftUnit -import opekope2.avm_staff.mixin.ICakeBlockAccessor -import opekope2.avm_staff.mixin.ISmithingTemplateItemAccessor -import opekope2.avm_staff.util.MOD_ID -import opekope2.avm_staff.util.mutableItemStackInStaff -import kotlin.math.max - -private val BLOCKS = DeferredRegister.create(MOD_ID, RegistryKeys.BLOCK) -private val ITEMS = DeferredRegister.create(MOD_ID, RegistryKeys.ITEM) -private val ITEM_GROUPS = DeferredRegister.create(MOD_ID, RegistryKeys.ITEM_GROUP) -private val ENTITY_TYPES = DeferredRegister.create(MOD_ID, RegistryKeys.ENTITY_TYPE) -private val PARTICLE_TYPES = DeferredRegister.create(MOD_ID, RegistryKeys.PARTICLE_TYPE) -private val DATA_COMPONENT_TYPES = DeferredRegister.create(MOD_ID, RegistryKeys.DATA_COMPONENT_TYPE) -private val SOUND_EVENTS = DeferredRegister.create(MOD_ID, RegistryKeys.SOUND_EVENT) -private val CRITERIA = DeferredRegister.create(MOD_ID, RegistryKeys.CRITERION) - -/** - * Block registered as `avm_staff:crown_of_king_orange`. - */ -val crownOfKingOrangeBlock: RegistrySupplier = BLOCKS.register("crown_of_king_orange") { - CrownBlock( - AbstractBlock.Settings.create().instrument(NoteBlockInstrument.BELL).strength(1.0f) - .pistonBehavior(PistonBehavior.DESTROY).sounds(BlockSoundGroup.COPPER_GRATE).nonOpaque() - ) -} - -/** - * Block registered as `avm_staff:wall_crown_of_king_orange`. - */ -val wallCrownOfKingOrangeBlock: RegistrySupplier = BLOCKS.register("wall_crown_of_king_orange") { - WallCrownBlock(AbstractBlock.Settings.copy(crownOfKingOrangeBlock.get())) -} - -/** - * Item registered as `avm_staff:faint_staff_rod`. - */ -val faintStaffRodItem: RegistrySupplier = ITEMS.register("faint_staff_rod") { - Item(Item.Settings().`arch$tab`(staffModItemGroup)) -} - -/** - * Item registered as `avm_staff:faint_royal_staff_head`. - */ -val faintRoyalStaffHeadItem: RegistrySupplier = ITEMS.register("faint_royal_staff_head") { - Item( - Item.Settings().maxCount(16).rarity(Rarity.RARE).`arch$tab`(staffModItemGroup) - ) -} - -/** - * Item registered as `avm_staff:faint_royal_staff`. - */ -val faintRoyalStaffItem: RegistrySupplier = ITEMS.register("faint_royal_staff") { - IStaffModPlatform.itemWithStaffRenderer( - Item.Settings().maxCount(1).rarity(Rarity.RARE).`arch$tab`(staffModItemGroup) - ) -} - -/** - * Item registered as `avm_staff:royal_staff`. - */ -val royalStaffItem: RegistrySupplier = ITEMS.register("royal_staff") { - IStaffModPlatform.staffItem( - Item.Settings().maxCount(1).rarity(Rarity.EPIC).attributeModifiers(StaffHandler.Default.ATTRIBUTE_MODIFIERS) - .maxDamage(5179).`arch$tab`(staffModItemGroup), - royalStaffIngredientItem - ) -} - -/** - * Item registered as `avm_staff:royal_staff_ingredient`. - */ -val royalStaffIngredientItem: RegistrySupplier = ITEMS.register("royal_staff_ingredient") { - Item(Item.Settings().`arch$tab`(staffModItemGroup)) -} - -/** - * Item registered as `avm_staff:crown_of_king_orange`. - */ -val crownOfKingOrangeItem: RegistrySupplier = ITEMS.register("crown_of_king_orange") { - IStaffModPlatform.crownItem( - crownOfKingOrangeBlock.get(), - wallCrownOfKingOrangeBlock.get(), - Item.Settings().maxCount(1).rarity(Rarity.UNCOMMON).`arch$tab`(staffModItemGroup) - ) -} - -/** - * Item registered as `avm_staff:staff_infusion_smithing_template`. - */ -val staffInfusionSmithingTemplateItem: RegistrySupplier = ITEMS.register("staff_infusion_smithing_template") { - SmithingTemplateItem( - Text.translatable("item.$MOD_ID.staff_infusion_smithing_template.applies_to") - .formatted(ISmithingTemplateItemAccessor.descriptionFormatting()), - ISmithingTemplateItemAccessor.armorTrimIngredientsText(), - Text.translatable("item.$MOD_ID.staff_infusion_smithing_template.title") - .formatted(ISmithingTemplateItemAccessor.titleFormatting()), - Text.translatable("item.$MOD_ID.staff_infusion_smithing_template.base_slot_description"), - ISmithingTemplateItemAccessor.armorTrimAdditionsSlotDescriptionText(), - StaffInfusionSmithingRecipeTextures.baseSlotTextures, - StaffInfusionSmithingRecipeTextures.additionsSlotTextures - ) -} - -/** - * Tag registered as `avm_staff:staffs`. - */ -val staffsTag: TagKey = TagKey.of(RegistryKeys.ITEM, Identifier.of(MOD_ID, "staffs")) - -/** - * Item group containing items added by Staff Mod. - */ -val staffModItemGroup: RegistrySupplier = ITEM_GROUPS.register("${MOD_ID}_items") { - CreativeTabRegistry.create(Text.translatable("itemGroup.${MOD_ID}_items")) { - royalStaffItem.get().defaultStack.apply { - mutableItemStackInStaff = Items.COMMAND_BLOCK.defaultStack - } - } -} - -/** - * Entity registered as `avm_staff:impact_tnt`. - */ -val impactTntEntityType: RegistrySupplier> = ENTITY_TYPES.register("impact_tnt") { - EntityType.Builder.create(::ImpactTntEntity, SpawnGroup.MISC) - .makeFireImmune() - .dimensions(EntityType.TNT.dimensions.width, EntityType.TNT.dimensions.height) - .eyeHeight(EntityType.TNT.dimensions.eyeHeight) - .maxTrackingRange(EntityType.TNT.maxTrackDistance) - .trackingTickInterval(EntityType.TNT.trackTickInterval) - .build(Identifier.of(MOD_ID, "impact_tnt").toString()) -} - -/** - * Entity registered as `avm_staff:cake` - */ -val cakeEntityType: RegistrySupplier> = ENTITY_TYPES.register("cake") { - val cakeBox = ICakeBlockAccessor.bitesToShape()[0].boundingBox - val cakeSize = max(cakeBox.lengthX, max(cakeBox.lengthY, cakeBox.lengthZ)) - - EntityType.Builder.create(::CakeEntity, SpawnGroup.MISC) - .dimensions(cakeSize.toFloat(), cakeSize.toFloat()) - .maxTrackingRange(EntityType.FALLING_BLOCK.maxTrackDistance) - .trackingTickInterval(EntityType.FALLING_BLOCK.trackTickInterval) - .build(Identifier.of(MOD_ID, "cake").toString()) -} - -val campfireFlameEntityType: RegistrySupplier> = - ENTITY_TYPES.register("campfire_flame") { - EntityType.Builder.create(::CampfireFlameEntity, SpawnGroup.MISC) - .dimensions(0f, 0f) - .maxTrackingRange(EntityType.AREA_EFFECT_CLOUD.maxTrackDistance) - // Don't send existing entities (the ones entering tracking distance) to the client - // The tracking distance is high enough compared to the max age of the flame - .trackingTickInterval(Int.MAX_VALUE) - .disableSaving() - .disableSummon() - .makeFireImmune() - .build(Identifier.of(MOD_ID, "campfire_flame").toString()) - } - -/** - * Particle registered as `avm_staff:flame`. - * - * @see ParticleManager.addParticle - */ -val flamethrowerParticleType: RegistrySupplier = - PARTICLE_TYPES.register("flame") { IStaffModPlatform.simpleParticleType(false) } - -/** - * Particle registered as `avm_staff:soul_fire_flame`. - * - * @see ParticleManager.addParticle - */ -val soulFlamethrowerParticleType: RegistrySupplier = - PARTICLE_TYPES.register("soul_fire_flame") { IStaffModPlatform.simpleParticleType(false) } - -/** - * Data component registered as `avm_staff:staff_item`. Stores the item inserted into the staff. - */ -val staffItemComponentType: RegistrySupplier> = - DATA_COMPONENT_TYPES.register("staff_item") { - ComponentType.builder() - .codec(StaffItemComponent.CODEC) - .packetCodec(StaffItemComponent.PACKET_CODEC) - .build() - } - -/** - * Data component registered as `avm_staff:rocket_mode`. Stores if a campfire staff should propel its user. - */ -val rocketModeComponentType: RegistrySupplier> = - DATA_COMPONENT_TYPES.register("rocket_mode") { - ComponentType.builder() - .codec(MinecraftUnit.CODEC) - .packetCodec(PacketCodec.unit(MinecraftUnit.INSTANCE)) - .build() - } - -/** - * Data component registered as `avm_staff:furnace_data`. If this is present, the furnace is lit. - */ -val staffFurnaceDataComponentType: RegistrySupplier> = - DATA_COMPONENT_TYPES.register("furnace_data") { - ComponentType.builder() - .packetCodec(StaffFurnaceDataComponent.PACKET_CODEC) - .build() - } - -/** - * Data component registered as `avm_staff:staff_renderer_part`. Only used for rendering. - */ -val staffRendererPartComponentType: RegistrySupplier> = - DATA_COMPONENT_TYPES.register("staff_renderer_part") { - ComponentType.builder() - .packetCodec(StaffRendererPartComponent.PACKET_CODEC) - .build() - } - -/** - * Sound event registered as `avm_staff:entity.cake.splash`. - */ -val cakeSplashSoundEvent: RegistrySupplier = SOUND_EVENTS.register("entity.cake.splash") { - SoundEvent.of(Identifier.of(MOD_ID, "entity.cake.splash")) -} - -/** - * Sound event registered as `avm_staff:entity.cake.throw`. - */ -val cakeThrowSoundEvent: RegistrySupplier = SOUND_EVENTS.register("entity.cake.throw") { - SoundEvent.of(Identifier.of(MOD_ID, "entity.cake.throw")) -} - -/** - * `avm_staff:pranked` damage type. - */ -val cakeDamageType: RegistryKey = - RegistryKey.of(RegistryKeys.DAMAGE_TYPE, Identifier.of(MOD_ID, "pranked")) - -/** - * `avm_staff:pranked_by_player` damage type. - */ -val playerCakeDamageType: RegistryKey = - RegistryKey.of(RegistryKeys.DAMAGE_TYPE, Identifier.of(MOD_ID, "pranked_by_player")) - -/** - * Throwable cakes game rule. When set to true, cakes can be thrown by right clicking, and dispensers will shoot cakes - * instead of dropping them as item. - */ -val throwableCakesGameRule: GameRules.Key = - GameRules.register("throwableCakes", GameRules.Category.MISC, GameRules.BooleanRule.create(false)) - -/** - * Criterion registered as `avm_staff:get_hurt_while_using_item`. - */ -val takeDamageWhileUsingItemCriterion: RegistrySupplier = - CRITERIA.register(Identifier.of(MOD_ID, "get_hurt_while_using_item")) { - TakeDamageWhileUsingItemCriterion() - } - -/** - * Criterion registered as `avm_staff:break_block_with_staff`. Triggers before a block is broken by a staff. - */ -val breakBlockWithStaffCriterion: RegistrySupplier = - CRITERIA.register(Identifier.of(MOD_ID, "break_block_with_staff")) { - BreakBlockWithStaffCriterion() - } - -/** - * @suppress - */ -@JvmSynthetic -internal fun registerContent() { - BLOCKS.register() - ITEMS.register() - ITEM_GROUPS.register() - ENTITY_TYPES.register() - PARTICLE_TYPES.register() - DATA_COMPONENT_TYPES.register() - SOUND_EVENTS.register() - CRITERIA.register() - - // Because SmithingTemplateItem doesn't take Item.Settings in its constructor - CreativeTabRegistry.append(staffModItemGroup, staffInfusionSmithingTemplateItem) -} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/block/dispenser/CakeDispenserBehavior.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/block/dispenser/CakeDispenserBehavior.kt index a81bba9ae..bf66256e3 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/block/dispenser/CakeDispenserBehavior.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/block/dispenser/CakeDispenserBehavior.kt @@ -24,17 +24,18 @@ import net.minecraft.item.ItemStack import net.minecraft.util.math.BlockPointer import net.minecraft.util.math.Vec3d import net.minecraft.world.WorldEvents -import opekope2.avm_staff.api.cakeEntityType import opekope2.avm_staff.api.entity.CakeEntity -import opekope2.avm_staff.api.throwableCakesGameRule +import opekope2.avm_staff.content.EntityTypes +import opekope2.avm_staff.content.GameRules /** - * Dispenser behavior, which throws [cakes][CakeEntity], if [throwableCakes][throwableCakesGameRule] game rule is + * Dispenser behavior, which throws [cakes][CakeEntity], if [throwableCakes][GameRules.THROWABLE_CAKES] game rule is * enabled. */ class CakeDispenserBehavior : ItemDispenserBehavior() { override fun dispenseSilently(pointer: BlockPointer, stack: ItemStack): ItemStack { - if (!pointer.world.gameRules.getBoolean(throwableCakesGameRule)) return super.dispenseSilently(pointer, stack) + if (!pointer.world.gameRules.getBoolean(GameRules.THROWABLE_CAKES)) + return super.dispenseSilently(pointer, stack) var spawnPos = DispenserBlock.getOutputLocation(pointer, 1.0, Vec3d.ZERO) spawnPos = Vec3d(spawnPos.x, spawnPos.y, spawnPos.z).add(0.0, NEGATIVE_HALF_CAKE_HEIGHT, 0.0) @@ -54,12 +55,12 @@ class CakeDispenserBehavior : ItemDispenserBehavior() { } override fun playSound(pointer: BlockPointer) { - if (!pointer.world.gameRules.getBoolean(throwableCakesGameRule)) return super.playSound(pointer) + if (!pointer.world.gameRules.getBoolean(GameRules.THROWABLE_CAKES)) return super.playSound(pointer) pointer.world().syncWorldEvent(WorldEvents.DISPENSER_LAUNCHES_PROJECTILE, pointer.pos(), 0) } private companion object { - private val NEGATIVE_HALF_CAKE_HEIGHT = cakeEntityType.get().dimensions.height / -2.0 + private val NEGATIVE_HALF_CAKE_HEIGHT = EntityTypes.cake.dimensions.height / -2.0 } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt index 64fc7a5ad..c71b1e73b 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt @@ -36,7 +36,9 @@ import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Vec3d import net.minecraft.util.math.random.Random import net.minecraft.world.World -import opekope2.avm_staff.api.* +import opekope2.avm_staff.content.DamageTypes +import opekope2.avm_staff.content.EntityTypes +import opekope2.avm_staff.content.SoundEvents import opekope2.avm_staff.util.* /** @@ -56,7 +58,7 @@ class CakeEntity(entityType: EntityType, world: World) : Entity(enti * @param thrower The entity that threw the cake */ constructor(world: World, position: Vec3d, velocity: Vec3d, thrower: LivingEntity?) : - this(cakeEntityType.get(), world) { + this(EntityTypes.cake, world) { val (x, y, z) = position val (vx, vy, vz) = velocity init(x, y, z, vx, vy, vz, thrower) @@ -98,7 +100,7 @@ class CakeEntity(entityType: EntityType, world: World) : Entity(enti override fun onRemoved() { world.playSound( x, y, z, - cakeSplashSoundEvent.get(), SoundCategory.BLOCKS, + SoundEvents.cakeSplash, SoundCategory.BLOCKS, (CAKE_STATE.soundGroup.volume + 1f) / 2f, CAKE_STATE.soundGroup.pitch * .8f, false ) @@ -186,8 +188,8 @@ class CakeEntity(entityType: EntityType, world: World) : Entity(enti val damageables = EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR.and(EntityPredicates.VALID_LIVING_ENTITY) val thrower = thrower val damageSource = - if (thrower == null) world.damageSource(cakeDamageType) - else world.damageSource(playerCakeDamageType, this, thrower) + if (thrower == null) world.damageSource(DamageTypes.PRANKED) + else world.damageSource(DamageTypes.PRANKED_BY_PLAYER, this, thrower) world.getOtherEntities(this, boundingBox, damageables).forEach { it.damage(damageSource, 1f) @@ -259,7 +261,7 @@ class CakeEntity(entityType: EntityType, world: World) : Entity(enti world.playSound( null, position.x, position.y, position.z, - cakeThrowSoundEvent.get(), thrower?.soundCategory ?: return, + SoundEvents.cakeThrow, thrower?.soundCategory ?: return, 0.5f, 0.4f / (world.getRandom().nextFloat() * 0.4f + 0.8f) ) } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CampfireFlameEntity.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CampfireFlameEntity.kt index 71f5ba043..0425d5a4a 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CampfireFlameEntity.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CampfireFlameEntity.kt @@ -49,8 +49,8 @@ import net.minecraft.util.math.Vec3d import net.minecraft.world.RaycastContext import net.minecraft.world.World import net.minecraft.world.event.GameEvent -import opekope2.avm_staff.api.campfireFlameEntityType -import opekope2.avm_staff.api.flamethrowerParticleType +import opekope2.avm_staff.content.EntityTypes +import opekope2.avm_staff.content.ParticleTypes import opekope2.avm_staff.util.* import java.util.* @@ -90,7 +90,7 @@ class CampfireFlameEntity : Entity, EntitySpawnExtension { * @param shooter The entity shooting the flame */ constructor(world: World, parameters: ServerParameters, shooter: LivingEntity) : - super(campfireFlameEntityType.get(), world) { + super(EntityTypes.campfireFlame, world) { this.setPosition(parameters.origin) this.velocity = shooter.velocity + parameters.relativeTarget * (1.0 / parameters.stepResolution) @@ -121,7 +121,7 @@ class CampfireFlameEntity : Entity, EntitySpawnExtension { if (world.isClient) { @Suppress("UNCHECKED_CAST") val particleType = Registries.PARTICLE_TYPE[parameters.particleType as RegistryKey>] - val particleEffect = particleType as? ParticleEffect ?: flamethrowerParticleType.get() + val particleEffect = particleType as? ParticleEffect ?: ParticleTypes.flame tickRays(nextPos, nextRelativeRight, nextRelativeUp) { start, end -> val result = tickRayClient(start, end) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntEntity.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntEntity.kt index 4c65015e0..f2c1cb03e 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntEntity.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntEntity.kt @@ -22,7 +22,7 @@ import net.minecraft.entity.* import net.minecraft.predicate.entity.EntityPredicates import net.minecraft.util.math.Vec3d import net.minecraft.world.World -import opekope2.avm_staff.api.impactTntEntityType +import opekope2.avm_staff.content.EntityTypes /** * A TNT entity, which explodes on collision. @@ -42,7 +42,7 @@ class ImpactTntEntity(entityType: EntityType, world: World) : T * */ constructor(world: World, x: Double, y: Double, z: Double, velocity: Vec3d, owner: LivingEntity?) : - this(impactTntEntityType.get(), world) { + this(EntityTypes.impactTnt, world) { setPosition(x, y, z) this.velocity = velocity fuse = 80 diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt index d15ef5da6..f67937d92 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt @@ -26,7 +26,7 @@ import net.minecraft.client.render.model.json.ModelTransformationMode import net.minecraft.client.util.math.MatrixStack import net.minecraft.item.ItemStack import opekope2.avm_staff.api.component.StaffRendererPartComponent -import opekope2.avm_staff.api.staffRendererPartComponentType +import opekope2.avm_staff.content.ComponentTypes import opekope2.avm_staff.util.bakedModelManager import opekope2.avm_staff.util.itemRenderer import opekope2.avm_staff.util.itemStackInStaff @@ -194,9 +194,9 @@ object StaffRenderer { } private fun safeGetModel(staffStack: ItemStack, part: StaffRendererPartComponent): BakedModel { - staffStack[staffRendererPartComponentType.get()] = part + staffStack[ComponentTypes.staffRendererPart] = part val model = itemRenderer.getModel(staffStack, null, null, 0) - staffStack.remove(staffRendererPartComponentType.get()) + staffStack.remove(ComponentTypes.staffRendererPart) // Prevent StackOverflowError if an override is missing return if (!model.isBuiltin) model diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/particle/FlamethrowerParticle.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/particle/FlamethrowerParticle.kt index 3955dfb61..005a4e360 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/particle/FlamethrowerParticle.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/particle/FlamethrowerParticle.kt @@ -24,8 +24,7 @@ import net.minecraft.client.particle.* import net.minecraft.client.world.ClientWorld import net.minecraft.particle.SimpleParticleType import net.minecraft.util.math.BlockPos -import opekope2.avm_staff.api.flamethrowerParticleType -import opekope2.avm_staff.api.soulFlamethrowerParticleType +import opekope2.avm_staff.content.ParticleTypes import opekope2.avm_staff.mixin.IParticleMixin /** @@ -107,8 +106,8 @@ class FlamethrowerParticle( * Factory class for [FlamethrowerParticle], intended to register in Minecraft instead of direct consumption. * * @param spriteProvider Flame sprite provider - * @see flamethrowerParticleType - * @see soulFlamethrowerParticleType + * @see ParticleTypes.flame + * @see ParticleTypes.soulFireFlame * @see ParticleManager.addParticle */ class Factory(private val spriteProvider: SpriteProvider) : ParticleFactory { diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt index e4d29b4ac..6433a4531 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt @@ -36,7 +36,6 @@ import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction import net.minecraft.world.World import net.minecraft.world.event.GameEvent -import opekope2.avm_staff.api.breakBlockWithStaffCriterion import opekope2.avm_staff.api.registry.RegistryBase /** @@ -237,7 +236,7 @@ abstract class StaffHandler { * @param target The block the [attacker] attacked * @param side The side of the [block][target], which was attacked * @param hand The hand of the [attacker], in which the [staff][staffStack] is - * @see breakBlockWithStaffCriterion + * @see opekope2.avm_staff.content.Criteria.breakBlockWithStaff */ open fun attackBlock( staffStack: ItemStack, world: World, attacker: LivingEntity, target: BlockPos, side: Direction, hand: Hand diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffInfusionSmithingRecipeTextures.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffInfusionSmithingRecipeTextures.kt index d283b8de9..ff7d8bb43 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffInfusionSmithingRecipeTextures.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffInfusionSmithingRecipeTextures.kt @@ -19,11 +19,11 @@ package opekope2.avm_staff.api.staff import net.minecraft.util.Identifier -import opekope2.avm_staff.api.staffInfusionSmithingTemplateItem +import opekope2.avm_staff.content.Items /** * Object holding textures to be displayed in a smithing table, when using a - * [staff infusion smithing template][staffInfusionSmithingTemplateItem]. + * [staff infusion smithing template][Items.STAFF_INFUSION_SMITHING_TEMPLATE]. */ object StaffInfusionSmithingRecipeTextures { private val registeredBaseSlotTextures = mutableListOf() @@ -43,7 +43,7 @@ object StaffInfusionSmithingRecipeTextures { /** * Registers a pair of staff texture and an ingredient texture to be displayed in a smithing table, when using a - * [staff infusion smithing template][staffInfusionSmithingTemplateItem]. This method should be called for every + * [staff infusion smithing template][Items.STAFF_INFUSION_SMITHING_TEMPLATE]. This method should be called for every * `minecraft:smithing_transform` recipe in the mod's data pack, which infuses an ingredient into a faint staff. * * @param baseSlotTexture The background texture of the 2nd slot of the smithing table diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Blocks.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Blocks.kt new file mode 100644 index 000000000..cd1e10393 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Blocks.kt @@ -0,0 +1,72 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.content + +import dev.architectury.registry.registries.RegistrySupplier +import net.minecraft.block.AbstractBlock +import net.minecraft.block.Block +import net.minecraft.block.enums.NoteBlockInstrument +import net.minecraft.block.piston.PistonBehavior +import net.minecraft.registry.RegistryKeys +import net.minecraft.sound.BlockSoundGroup +import opekope2.avm_staff.api.block.CrownBlock +import opekope2.avm_staff.api.block.WallCrownBlock +import opekope2.avm_staff.util.MOD_ID +import opekope2.avm_staff.util.RegistryUtil + +/** + * Blocks added by AVM Staffs mod. + */ +object Blocks : RegistryUtil(MOD_ID, RegistryKeys.BLOCK) { + private fun settings() = AbstractBlock.Settings.create() + private fun settings(block: RegistrySupplier) = AbstractBlock.Settings.copy(block.get()) + + /** + * Block registered as `avm_staff:crown_of_king_orange`. + */ + @JvmField + val CROWN_OF_KING_ORANGE = register("crown_of_king_orange") { + CrownBlock( + settings().instrument(NoteBlockInstrument.BELL).strength(1.0f).pistonBehavior(PistonBehavior.DESTROY) + .sounds(BlockSoundGroup.COPPER_GRATE).nonOpaque() + ) + } + + /** + * @see CROWN_OF_KING_ORANGE + */ + val crownOfKingOrange: CrownBlock + @JvmName("crownOfKingOrange") + get() = CROWN_OF_KING_ORANGE.get() + + /** + * Block registered as `avm_staff:wall_crown_of_king_orange`. + */ + @JvmField + val WALL_CROWN_OF_KING_ORANGE = register("wall_crown_of_king_orange") { + WallCrownBlock(settings(CROWN_OF_KING_ORANGE)) + } + + /** + * @see WALL_CROWN_OF_KING_ORANGE + */ + val wallCrownOfKingOrange: WallCrownBlock + @JvmName("wallCrownOfKingOrange") + get() = WALL_CROWN_OF_KING_ORANGE.get() +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt new file mode 100644 index 000000000..39e935dca --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt @@ -0,0 +1,104 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.content + +import net.minecraft.component.ComponentType +import net.minecraft.network.codec.PacketCodec +import net.minecraft.registry.RegistryKeys +import opekope2.avm_staff.api.component.StaffFurnaceDataComponent +import opekope2.avm_staff.api.component.StaffItemComponent +import opekope2.avm_staff.api.component.StaffRendererPartComponent +import opekope2.avm_staff.internal.MinecraftUnit +import opekope2.avm_staff.util.MOD_ID +import opekope2.avm_staff.util.RegistryUtil + +/** + * Component types added by AVM Staffs mod. + */ +object ComponentTypes : RegistryUtil>(MOD_ID, RegistryKeys.DATA_COMPONENT_TYPE) { + /** + * Data component registered as `avm_staff:staff_item`. Stores the item inserted into the staff. + */ + @JvmField + val STAFF_ITEM = register("staff_item") { + ComponentType.builder() + .codec(StaffItemComponent.CODEC) + .packetCodec(StaffItemComponent.PACKET_CODEC) + .build() + } + + /** + * @see STAFF_ITEM + */ + val staffItem: ComponentType + @JvmName("staffItem") + get() = STAFF_ITEM.get() + + /** + * Data component registered as `avm_staff:rocket_mode`. Stores if a campfire staff should propel its user. + */ + @JvmField + val ROCKET_MODE = register("rocket_mode") { + ComponentType.builder() + .codec(MinecraftUnit.CODEC) + .packetCodec(PacketCodec.unit(MinecraftUnit.INSTANCE)) + .build() + } + + /** + * @see ROCKET_MODE + */ + val rocketMode: ComponentType + @JvmName("rocketMode") + get() = ROCKET_MODE.get() + + /** + * Data component registered as `avm_staff:furnace_data`. If this is present, the furnace is lit. + */ + @JvmField + val FURNACE_DATA = register("furnace_data") { + ComponentType.builder() + .packetCodec(StaffFurnaceDataComponent.PACKET_CODEC) + .build() + } + + /** + * @see FURNACE_DATA + */ + val furnaceData: ComponentType + @JvmName("furnaceData") + get() = FURNACE_DATA.get() + + /** + * Data component registered as `avm_staff:staff_renderer_part`. Only used for rendering. + */ + @JvmField + val STAFF_RENDERER_PART = register("staff_renderer_part") { + ComponentType.builder() + .packetCodec(StaffRendererPartComponent.PACKET_CODEC) + .build() + } + + /** + * @see STAFF_RENDERER_PART + */ + val staffRendererPart: ComponentType + @JvmName("staffRendererPart") + get() = STAFF_RENDERER_PART.get() +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Criteria.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Criteria.kt new file mode 100644 index 000000000..f54ddfbc1 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Criteria.kt @@ -0,0 +1,61 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.content + +import net.minecraft.advancement.criterion.Criterion +import net.minecraft.registry.RegistryKeys +import opekope2.avm_staff.api.advancement.criterion.BreakBlockWithStaffCriterion +import opekope2.avm_staff.api.advancement.criterion.TakeDamageWhileUsingItemCriterion +import opekope2.avm_staff.util.MOD_ID +import opekope2.avm_staff.util.RegistryUtil + +/** + * Criteria added by AVM Staffs mod. + */ +object Criteria : RegistryUtil>(MOD_ID, RegistryKeys.CRITERION) { + /** + * Criterion registered as `avm_staff:get_hurt_while_using_item`. + */ + @JvmField + val TAKE_DAMAGE_WHILE_USING_ITEM = register("get_hurt_while_using_item") { + TakeDamageWhileUsingItemCriterion() + } + + /** + * @see TAKE_DAMAGE_WHILE_USING_ITEM + */ + val takeDamageWhileUsingItem: TakeDamageWhileUsingItemCriterion + @JvmName("takeDamageWhileUsingItem") + get() = TAKE_DAMAGE_WHILE_USING_ITEM.get() + + /** + * Criterion registered as `avm_staff:break_block_with_staff`. Triggers before a block is broken by a staff. + */ + @JvmField + val BREAK_BLOCK_WITH_STAFF = register("break_block_with_staff") { + BreakBlockWithStaffCriterion() + } + + /** + * @see BREAK_BLOCK_WITH_STAFF + */ + val breakBlockWithStaff: BreakBlockWithStaffCriterion + @JvmName("breakBlockWithStaff") + get() = BREAK_BLOCK_WITH_STAFF.get() +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/DamageTypes.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/DamageTypes.kt new file mode 100644 index 000000000..3ded0f8d2 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/DamageTypes.kt @@ -0,0 +1,41 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.content + +import net.minecraft.entity.damage.DamageType +import net.minecraft.registry.RegistryKeys +import opekope2.avm_staff.util.MOD_ID +import opekope2.avm_staff.util.RegistryKeyUtil + +/** + * Damage types added by AVM Staffs mod. + */ +object DamageTypes : RegistryKeyUtil(MOD_ID, RegistryKeys.DAMAGE_TYPE) { + /** + * `avm_staff:pranked` damage type. + */ + @JvmField + val PRANKED = registryKey("pranked") + + /** + * `avm_staff:pranked_by_player` damage type. + */ + @JvmField + val PRANKED_BY_PLAYER = registryKey("pranked_by_player") +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/EntityTypes.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/EntityTypes.kt new file mode 100644 index 000000000..79daea2ee --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/EntityTypes.kt @@ -0,0 +1,103 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.content + +import net.minecraft.entity.EntityType +import net.minecraft.entity.SpawnGroup +import net.minecraft.registry.RegistryKeys +import net.minecraft.util.Identifier +import opekope2.avm_staff.api.entity.CakeEntity +import opekope2.avm_staff.api.entity.CampfireFlameEntity +import opekope2.avm_staff.api.entity.ImpactTntEntity +import opekope2.avm_staff.mixin.ICakeBlockAccessor +import opekope2.avm_staff.util.MOD_ID +import opekope2.avm_staff.util.RegistryUtil +import kotlin.math.max + +/** + * Entity types added by AVM Staffs mod. + */ +object EntityTypes : RegistryUtil>(MOD_ID, RegistryKeys.ENTITY_TYPE) { + /** + * Entity registered as `avm_staff:impact_tnt`. + */ + @JvmField + val IMPACT_TNT = register("impact_tnt") { + EntityType.Builder.create(::ImpactTntEntity, SpawnGroup.MISC) + .makeFireImmune() + .dimensions(EntityType.TNT.dimensions.width, EntityType.TNT.dimensions.height) + .eyeHeight(EntityType.TNT.dimensions.eyeHeight) + .maxTrackingRange(EntityType.TNT.maxTrackDistance) + .trackingTickInterval(EntityType.TNT.trackTickInterval) + .build(Identifier.of(MOD_ID, "impact_tnt").toString()) + } + + /** + * @see IMPACT_TNT + */ + val impactTnt: EntityType + @JvmName("impactTnt") + get() = IMPACT_TNT.get() + + /** + * Entity registered as `avm_staff:cake` + */ + @JvmField + val CAKE = register("cake") { + val cakeBox = ICakeBlockAccessor.bitesToShape()[0].boundingBox + val cakeSize = max(cakeBox.lengthX, max(cakeBox.lengthY, cakeBox.lengthZ)) + + EntityType.Builder.create(::CakeEntity, SpawnGroup.MISC) + .dimensions(cakeSize.toFloat(), cakeSize.toFloat()) + .maxTrackingRange(EntityType.FALLING_BLOCK.maxTrackDistance) + .trackingTickInterval(EntityType.FALLING_BLOCK.trackTickInterval) + .build(Identifier.of(MOD_ID, "cake").toString()) + } + + /** + * @see CAKE + */ + val cake: EntityType + @JvmName("cake") + get() = CAKE.get() + + /** + * Technical entity registered as `avm_staff:campfire_flame` + */ + @JvmField + val CAMPFIRE_FLAME = register("campfire_flame") { + EntityType.Builder.create(::CampfireFlameEntity, SpawnGroup.MISC) + .dimensions(0f, 0f) + .maxTrackingRange(EntityType.AREA_EFFECT_CLOUD.maxTrackDistance) + // Don't send existing entities (the ones entering tracking distance) to the client + // The tracking distance is high enough compared to the max age of the flame + .trackingTickInterval(Int.MAX_VALUE) + .disableSaving() + .disableSummon() + .makeFireImmune() + .build(Identifier.of(MOD_ID, "campfire_flame").toString()) + } + + /** + * @see CAMPFIRE_FLAME + */ + val campfireFlame: EntityType + @JvmName("campfireFlame") + get() = CAMPFIRE_FLAME.get() +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/GameRules.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/GameRules.kt new file mode 100644 index 000000000..ee9af9b34 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/GameRules.kt @@ -0,0 +1,34 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.content + +import net.minecraft.world.GameRules + +/** + * Game rules added by AVM Staffs mod. + */ +object GameRules { + /** + * Throwable cakes game rule. When set to true, cakes can be thrown by right clicking, and dispensers will shoot cakes + * instead of dropping them as item. + */ + @JvmField + val THROWABLE_CAKES: GameRules.Key = + GameRules.register("throwableCakes", GameRules.Category.MISC, GameRules.BooleanRule.create(false)) +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ItemGroups.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ItemGroups.kt new file mode 100644 index 000000000..46d48cf2b --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ItemGroups.kt @@ -0,0 +1,52 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.content + +import dev.architectury.registry.CreativeTabRegistry +import dev.architectury.registry.registries.RegistrySupplier +import net.minecraft.item.ItemGroup +import net.minecraft.registry.RegistryKeys +import net.minecraft.text.Text +import opekope2.avm_staff.util.MOD_ID +import opekope2.avm_staff.util.RegistryUtil +import opekope2.avm_staff.util.mutableItemStackInStaff + +/** + * Item groups added by AVM Staffs mod. + */ +object ItemGroups : RegistryUtil(MOD_ID, RegistryKeys.ITEM_GROUP) { + /** + * Item group containing items added by Staff Mod. + */ + @JvmField + val AVM_STAFF_MOD_ITEMS: RegistrySupplier = ItemGroups.register("${MOD_ID}_items") { + CreativeTabRegistry.create(Text.translatable("itemGroup.${MOD_ID}_items")) { + Items.royalStaff.defaultStack.apply { + mutableItemStackInStaff = net.minecraft.item.Items.COMMAND_BLOCK.defaultStack + } + } + } + + /** + * @see AVM_STAFF_MOD_ITEMS + */ + val avmStaffModItems: ItemGroup + @JvmName("avmStaffModItems") + get() = AVM_STAFF_MOD_ITEMS.get() +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ItemTags.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ItemTags.kt new file mode 100644 index 000000000..874b0912f --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ItemTags.kt @@ -0,0 +1,36 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.content + +import net.minecraft.item.Item +import net.minecraft.registry.RegistryKeys +import net.minecraft.registry.tag.TagKey +import net.minecraft.util.Identifier +import opekope2.avm_staff.util.MOD_ID + +/** + * Item tags added by AVM Staffs mod. + */ +object ItemTags { + /** + * Item tag registered as `avm_staff:staffs`. + */ + @JvmField + val STAFFS: TagKey = TagKey.of(RegistryKeys.ITEM, Identifier.of(MOD_ID, "staffs")) +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt new file mode 100644 index 000000000..96075f93c --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt @@ -0,0 +1,172 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.content + +import dev.architectury.registry.CreativeTabRegistry +import net.minecraft.item.Item +import net.minecraft.item.SmithingTemplateItem +import net.minecraft.registry.RegistryKeys +import net.minecraft.text.Text +import net.minecraft.util.Rarity +import opekope2.avm_staff.api.IStaffModPlatform +import opekope2.avm_staff.api.item.CrownItem +import opekope2.avm_staff.api.item.StaffItem +import opekope2.avm_staff.api.staff.StaffHandler +import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures +import opekope2.avm_staff.mixin.ISmithingTemplateItemAccessor +import opekope2.avm_staff.util.MOD_ID +import opekope2.avm_staff.util.RegistryUtil + +/** + * Items added by AVM Staffs mod. + */ +object Items : RegistryUtil(MOD_ID, RegistryKeys.ITEM) { + private fun settings() = Item.Settings() + + /** + * Item registered as `avm_staff:faint_staff_rod`. + */ + @JvmField + val FAINT_STAFF_ROD = register("faint_staff_rod") { + Item(settings().`arch$tab`(ItemGroups.AVM_STAFF_MOD_ITEMS)) + } + + /** + * @see FAINT_STAFF_ROD + */ + val faintStaffRod: Item + @JvmName("faintStaffRod") + get() = FAINT_STAFF_ROD.get() + + /** + * Item registered as `avm_staff:faint_royal_staff_head`. + */ + @JvmField + val FAINT_ROYAL_STAFF_HEAD = register("faint_royal_staff_head") { + Item(settings().maxCount(16).rarity(Rarity.RARE).`arch$tab`(ItemGroups.AVM_STAFF_MOD_ITEMS)) + } + + /** + * @see FAINT_ROYAL_STAFF_HEAD + */ + val faintRoyalStaffHead: Item + @JvmName("faintRoyalStaffHead") + get() = FAINT_ROYAL_STAFF_HEAD.get() + + /** + * Item registered as `avm_staff:faint_royal_staff`. + */ + @JvmField + val FAINT_ROYAL_STAFF = register("faint_royal_staff") { + IStaffModPlatform.itemWithStaffRenderer( + settings().maxCount(1).rarity(Rarity.RARE).`arch$tab`(ItemGroups.AVM_STAFF_MOD_ITEMS) + ) + } + + /** + * @see FAINT_ROYAL_STAFF + */ + val faintRoyalStaff: Item + @JvmName("faintRoyalStaff") + get() = FAINT_ROYAL_STAFF.get() + + /** + * Item registered as `avm_staff:royal_staff`. + */ + @JvmField + val ROYAL_STAFF = register("royal_staff") { + IStaffModPlatform.staffItem( + settings().maxCount(1).rarity(Rarity.EPIC).attributeModifiers(StaffHandler.Default.ATTRIBUTE_MODIFIERS) + .maxDamage(5179).`arch$tab`(ItemGroups.AVM_STAFF_MOD_ITEMS), + ROYAL_STAFF_INGREDIENT + ) + } + + /** + * @see ROYAL_STAFF + */ + val royalStaff: StaffItem + @JvmName("royalStaff") + get() = ROYAL_STAFF.get() + + /** + * Item registered as `avm_staff:royal_staff_ingredient`. + */ + @JvmField + val ROYAL_STAFF_INGREDIENT = register("royal_staff_ingredient") { + Item(settings().`arch$tab`(ItemGroups.AVM_STAFF_MOD_ITEMS)) + } + + /** + * @see ROYAL_STAFF_INGREDIENT + */ + val royalStaffIngredient: Item + @JvmName("royalStaffIngredient") + get() = ROYAL_STAFF_INGREDIENT.get() + + /** + * Item registered as `avm_staff:crown_of_king_orange`. + */ + @JvmField + val CROWN_OF_KING_ORANGE = register("crown_of_king_orange") { + IStaffModPlatform.crownItem( + Blocks.CROWN_OF_KING_ORANGE.get(), + Blocks.WALL_CROWN_OF_KING_ORANGE.get(), + settings().maxCount(1).rarity(Rarity.UNCOMMON).`arch$tab`(ItemGroups.AVM_STAFF_MOD_ITEMS) + ) + } + + /** + * @see CROWN_OF_KING_ORANGE + */ + val crownOfKingOrange: CrownItem + @JvmName("crownOfKingOrange") + get() = CROWN_OF_KING_ORANGE.get() + + /** + * Item registered as `avm_staff:staff_infusion_smithing_template`. + */ + @JvmField + val STAFF_INFUSION_SMITHING_TEMPLATE = register("staff_infusion_smithing_template") { + SmithingTemplateItem( + Text.translatable("item.$MOD_ID.staff_infusion_smithing_template.applies_to") + .formatted(ISmithingTemplateItemAccessor.descriptionFormatting()), + ISmithingTemplateItemAccessor.armorTrimIngredientsText(), + Text.translatable("item.$MOD_ID.staff_infusion_smithing_template.title") + .formatted(ISmithingTemplateItemAccessor.titleFormatting()), + Text.translatable("item.$MOD_ID.staff_infusion_smithing_template.base_slot_description"), + ISmithingTemplateItemAccessor.armorTrimAdditionsSlotDescriptionText(), + StaffInfusionSmithingRecipeTextures.baseSlotTextures, + StaffInfusionSmithingRecipeTextures.additionsSlotTextures + ) + } + + /** + * @see STAFF_INFUSION_SMITHING_TEMPLATE + */ + val staffInfusionSmithingTemplate: SmithingTemplateItem + @JvmName("staffInfusionSmithingTemplate") + get() = STAFF_INFUSION_SMITHING_TEMPLATE.get() + + override fun register() { + super.register() + // Because SmithingTemplateItem doesn't take Item.Settings in its constructor + CreativeTabRegistry.append(ItemGroups.AVM_STAFF_MOD_ITEMS, STAFF_INFUSION_SMITHING_TEMPLATE) + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ParticleTypes.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ParticleTypes.kt new file mode 100644 index 000000000..1dbf0ef7b --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ParticleTypes.kt @@ -0,0 +1,62 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.content + +import net.minecraft.client.particle.ParticleManager +import net.minecraft.particle.ParticleType +import net.minecraft.particle.SimpleParticleType +import net.minecraft.registry.RegistryKeys +import opekope2.avm_staff.api.IStaffModPlatform +import opekope2.avm_staff.util.MOD_ID +import opekope2.avm_staff.util.RegistryUtil + +/** + * Particle types added by AVM Staffs mod. + */ +object ParticleTypes : RegistryUtil>(MOD_ID, RegistryKeys.PARTICLE_TYPE) { + /** + * Particle registered as `avm_staff:flame`. + * + * @see ParticleManager.addParticle + */ + @JvmField + val FLAME = register("flame") { IStaffModPlatform.simpleParticleType(false) } + + /** + * @see FLAME + */ + val flame: SimpleParticleType + @JvmName("flame") + get() = FLAME.get() + + /** + * Particle registered as `avm_staff:soul_fire_flame`. + * + * @see ParticleManager.addParticle + */ + @JvmField + val SOUL_FIRE_FLAME = register("soul_fire_flame") { IStaffModPlatform.simpleParticleType(false) } + + /** + * @see SOUL_FIRE_FLAME + */ + val soulFireFlame: SimpleParticleType + @JvmName("soulFireFlame") + get() = SOUL_FIRE_FLAME.get() +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/SoundEvents.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/SoundEvents.kt new file mode 100644 index 000000000..e0eea898e --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/SoundEvents.kt @@ -0,0 +1,59 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.content + +import net.minecraft.registry.RegistryKeys +import net.minecraft.sound.SoundEvent +import opekope2.avm_staff.util.MOD_ID +import opekope2.avm_staff.util.RegistryUtil + +/** + * Sound events added by AVM Staffs mod. + */ +object SoundEvents : RegistryUtil(MOD_ID, RegistryKeys.SOUND_EVENT) { + /** + * Sound event registered as `avm_staff:entity.cake.splash`. + */ + @JvmField + val CAKE_SPLASH = register("entity.cake.splash") { + SoundEvent.of(id("entity.cake.splash")) + } + + /** + * @see CAKE_SPLASH + */ + val cakeSplash: SoundEvent + @JvmName("cakeSplash") + get() = CAKE_SPLASH.get() + + /** + * Sound event registered as `avm_staff:entity.cake.throw`. + */ + @JvmField + val CAKE_THROW = register("entity.cake.throw") { + SoundEvent.of(id("entity.cake.throw")) + } + + /** + * @see CAKE_THROW + */ + val cakeThrow: SoundEvent + @JvmName("cakeThrow") + get() = CAKE_THROW.get() +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt index f1eea62d5..4f579ebe5 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -35,7 +35,6 @@ import net.minecraft.entity.damage.DamageSource import net.minecraft.entity.mob.AbstractPiglinEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.item.Items import net.minecraft.loot.LootPool import net.minecraft.loot.LootTable import net.minecraft.loot.entry.LootTableEntry @@ -49,12 +48,12 @@ import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Box import net.minecraft.util.math.Direction import net.minecraft.world.World -import opekope2.avm_staff.api.* import opekope2.avm_staff.api.block.dispenser.CakeDispenserBehavior import opekope2.avm_staff.api.entity.CakeEntity import opekope2.avm_staff.api.entity.renderer.CakeEntityRenderer import opekope2.avm_staff.api.item.StaffItem import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures +import opekope2.avm_staff.content.* import opekope2.avm_staff.internal.event_handler.handleKeyBindings import opekope2.avm_staff.internal.event_handler.registerKeyBindings import opekope2.avm_staff.internal.networking.c2s.play.AttackC2SPacket @@ -64,9 +63,17 @@ import opekope2.avm_staff.internal.networking.s2c.play.MassDestructionS2CPacket import opekope2.avm_staff.mixin.IPiglinBrainAccessor import opekope2.avm_staff.mixin.ISmithingTemplateItemAccessor import opekope2.avm_staff.util.* +import net.minecraft.item.Items as MinecraftItems fun registerContent() { - opekope2.avm_staff.api.registerContent() + Blocks.register() + ComponentTypes.register() + Criteria.register() + EntityTypes.register() + ItemGroups.register() + Items.register() + ParticleTypes.register() + SoundEvents.register() } fun initializeNetworking() { @@ -77,11 +84,6 @@ fun initializeNetworking() { MassDestructionS2CPacket.registerReceiver() } -private val MODIFIABLE_LOOT_TABLES = setOf( - Identifier.ofVanilla("chests/bastion_treasure"), - Identifier.ofVanilla("chests/trial_chambers/reward_unique") -) - fun subscribeToEvents() { EntityEvent.LIVING_DEATH.register(::stopUsingStaffOnPlayerDeath) InteractionEvent.LEFT_CLICK_BLOCK.register(::dispatchStaffBlockAttack) @@ -116,12 +118,12 @@ private fun dispatchStaffBlockAttack( private fun tryThrowCake(player: PlayerEntity, hand: Hand): CompoundEventResult { val world = player.entityWorld val cake = player.getStackInHand(hand) - val spawnPos = cakeEntityType.get().getSpawnPosition(world, player.approximateStaffTipPosition) + val spawnPos = EntityTypes.cake.getSpawnPosition(world, player.approximateStaffTipPosition) - if (!cake.isOf(Items.CAKE)) return CompoundEventResult.pass() + if (!cake.isOf(MinecraftItems.CAKE)) return CompoundEventResult.pass() if (spawnPos == null) return CompoundEventResult.pass() if (world.isClient) return CompoundEventResult.interruptTrue(cake) - if (!world.gameRules.getBoolean(throwableCakesGameRule)) return CompoundEventResult.pass() + if (!world.gameRules.getBoolean(GameRules.THROWABLE_CAKES)) return CompoundEventResult.pass() CakeEntity.throwCake(world, spawnPos, player.rotationVector * .5 + player.velocity, player) cake.decrementUnlessCreative(1, player) @@ -130,9 +132,14 @@ private fun tryThrowCake(player: PlayerEntity, hand: Hand): CompoundEventResult< } private fun setup() { - DispenserBlock.registerBehavior(Items.CAKE, CakeDispenserBehavior()) + DispenserBlock.registerBehavior(MinecraftItems.CAKE, CakeDispenserBehavior()) } +private val MODIFIABLE_LOOT_TABLES = setOf( + Identifier.ofVanilla("chests/bastion_treasure"), + Identifier.ofVanilla("chests/trial_chambers/reward_unique") +) + private fun modifyLootTables( lootTable: RegistryKey, context: LootEvent.LootTableModificationContext, @@ -150,7 +157,7 @@ private fun modifyLootTables( ) } -private const val maxAngerDistance = 16.0 +private const val MAX_ANGER_DISTANCE = 16.0 @Suppress("UNUSED_PARAMETER") private fun tryAngerPiglins( @@ -159,11 +166,11 @@ private fun tryAngerPiglins( if (world.isClient) return EventResult.pass() if (target !is LivingEntity) return EventResult.pass() if (!player.getStackInHand(hand).isStaff) return EventResult.pass() - if (!player.armorItems.any { it.isOf(crownOfKingOrangeItem.get()) }) return EventResult.pass() + if (!player.armorItems.any { it.isOf(Items.crownOfKingOrange) }) return EventResult.pass() - val box = Box.of(player.pos, 2 * maxAngerDistance, 2 * maxAngerDistance, 2 * maxAngerDistance) + val box = Box.of(player.pos, 2 * MAX_ANGER_DISTANCE, 2 * MAX_ANGER_DISTANCE, 2 * MAX_ANGER_DISTANCE) world.getEntitiesByClass(AbstractPiglinEntity::class.java, box) { - it !== target && it.squaredDistanceTo(player) <= maxAngerDistance * maxAngerDistance + it !== target && it.squaredDistanceTo(player) <= MAX_ANGER_DISTANCE * MAX_ANGER_DISTANCE }.forEach { IPiglinBrainAccessor.callBecomeAngryWith(it, target) } @@ -180,7 +187,7 @@ fun stopUsingStaffWhenDropped(entity: LivingEntity, item: ItemEntity): EventResu @Suppress("UNUSED_PARAMETER") fun triggerDamageWhileUsingItemCriterion(entity: LivingEntity, damage: DamageSource, amount: Float): EventResult { if (entity is ServerPlayerEntity && entity.isUsingItem) { - takeDamageWhileUsingItemCriterion.get().trigger(entity, entity.activeItem, damage) + Criteria.takeDamageWhileUsingItem.trigger(entity, entity.activeItem, damage) } return EventResult.pass() } @@ -188,9 +195,9 @@ fun triggerDamageWhileUsingItemCriterion(entity: LivingEntity, damage: DamageSou @Environment(EnvType.CLIENT) fun registerClientContent() { registerKeyBindings() - EntityRendererRegistry.register(impactTntEntityType, ::TntEntityRenderer) - EntityRendererRegistry.register(cakeEntityType, ::CakeEntityRenderer) - EntityRendererRegistry.register(campfireFlameEntityType, ::EmptyEntityRenderer) + EntityRendererRegistry.register(EntityTypes.IMPACT_TNT, ::TntEntityRenderer) + EntityRendererRegistry.register(EntityTypes.CAKE, ::CakeEntityRenderer) + EntityRendererRegistry.register(EntityTypes.CAMPFIRE_FLAME, ::EmptyEntityRenderer) } @Environment(EnvType.CLIENT) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt index 8b64c835e..fd9dd7e75 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt @@ -24,7 +24,7 @@ import net.minecraft.client.item.ClampedModelPredicateProvider import net.minecraft.item.ItemStack import net.minecraft.util.Identifier import opekope2.avm_staff.api.component.StaffRendererPartComponent -import opekope2.avm_staff.api.staffRendererPartComponentType +import opekope2.avm_staff.content.ComponentTypes import opekope2.avm_staff.util.MOD_ID // ModelPredicateProviderRegistry.register is private in common project @@ -41,6 +41,6 @@ inline fun registerModelPredicateProviders(register: (Identifier, ClampedModelPr } fun matchStaffRendererPart(part: StaffRendererPartComponent) = ClampedModelPredicateProvider { stack, _, _, _ -> - if (stack[staffRendererPartComponentType.get()] == part) 1f + if (stack[ComponentTypes.staffRendererPart] == part) 1f else 0f } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CakeHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CakeHandler.kt index c6aee1115..65f62c751 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CakeHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CakeHandler.kt @@ -24,9 +24,9 @@ import net.minecraft.item.ItemStack import net.minecraft.util.Hand import net.minecraft.util.TypedActionResult import net.minecraft.world.World -import opekope2.avm_staff.api.cakeEntityType import opekope2.avm_staff.api.entity.CakeEntity import opekope2.avm_staff.api.staff.StaffHandler +import opekope2.avm_staff.content.EntityTypes import opekope2.avm_staff.util.* internal class CakeHandler : StaffHandler() { @@ -56,7 +56,7 @@ internal class CakeHandler : StaffHandler() { if (!user.canUseStaff) return if (user is PlayerEntity && user.isAttackCoolingDown) return - val spawnPos = cakeEntityType.get().getSpawnPosition(world, user.approximateStaffTipPosition) ?: return + val spawnPos = EntityTypes.cake.getSpawnPosition(world, user.approximateStaffTipPosition) ?: return CakeEntity.throwCake(world, spawnPos, user.rotationVector * velocityMultiplier + user.velocity, user) } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt index df766c0bd..79455d001 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt @@ -30,8 +30,8 @@ import net.minecraft.util.TypedActionResult import net.minecraft.util.math.MathHelper import net.minecraft.world.World import opekope2.avm_staff.api.entity.CampfireFlameEntity -import opekope2.avm_staff.api.rocketModeComponentType import opekope2.avm_staff.api.staff.StaffHandler +import opekope2.avm_staff.content.ComponentTypes import opekope2.avm_staff.internal.MinecraftUnit import opekope2.avm_staff.util.approximateStaffTipPosition import opekope2.avm_staff.util.canUseStaff @@ -47,7 +47,7 @@ internal class CampfireHandler(private val parameters: Parameters) : StaffHandle hand: Hand ): TypedActionResult { if (user.isSneaking && !user.isOnGround) { - staffStack[rocketModeComponentType.get()] = MinecraftUnit.INSTANCE + staffStack[ComponentTypes.rocketMode] = MinecraftUnit.INSTANCE } user.setCurrentHand(hand) @@ -61,7 +61,7 @@ internal class CampfireHandler(private val parameters: Parameters) : StaffHandle val origin = user.approximateStaffTipPosition val relativeRight = user.getRotationVector(0f, MathHelper.wrapDegrees(user.yaw + 90f)).normalize() val relativeUp = relativeRight.crossProduct(forward).normalize() - val rocketMode = rocketModeComponentType.get() in staffStack + val rocketMode = ComponentTypes.rocketMode in staffStack if (rocketMode) { user.addVelocity(forward * -parameters.rocketThrust) @@ -92,7 +92,7 @@ internal class CampfireHandler(private val parameters: Parameters) : StaffHandle } override fun onStoppedUsing(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - staffStack.remove(rocketModeComponentType.get()) + staffStack.remove(ComponentTypes.rocketMode) } override fun finishUsing(staffStack: ItemStack, world: World, user: LivingEntity): ItemStack { diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/DiamondBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/DiamondBlockHandler.kt index f8fcf063d..4adcbb254 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/DiamondBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/DiamondBlockHandler.kt @@ -31,9 +31,9 @@ import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction import net.minecraft.world.World -import opekope2.avm_staff.api.breakBlockWithStaffCriterion import opekope2.avm_staff.api.staff.StaffAttributeModifiersComponentBuilder import opekope2.avm_staff.api.staff.StaffHandler +import opekope2.avm_staff.content.Criteria import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.attackSpeed import opekope2.avm_staff.util.cameraUp @@ -71,7 +71,7 @@ class DiamondBlockHandler : StaffHandler() { if (attacker is PlayerEntity && attacker.abilities.creativeMode) NoOpBlockDropCollector() else ChunkedBlockDropCollector(shapePredicate.volume, MAX_CHUNK_SIZE) - if (attacker is ServerPlayerEntity) breakBlockWithStaffCriterion.get().trigger(attacker, world, target) + if (attacker is ServerPlayerEntity) Criteria.breakBlockWithStaff.trigger(attacker, world, target) destroyBox( world, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt index dd2708db8..736767524 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt @@ -42,7 +42,7 @@ import net.minecraft.world.World import opekope2.avm_staff.api.component.StaffFurnaceDataComponent import opekope2.avm_staff.api.staff.StaffAttributeModifiersComponentBuilder import opekope2.avm_staff.api.staff.StaffHandler -import opekope2.avm_staff.api.staffFurnaceDataComponentType +import opekope2.avm_staff.content.ComponentTypes import opekope2.avm_staff.mixin.IAbstractFurnaceBlockEntityAccessor import opekope2.avm_staff.util.* import kotlin.jvm.optionals.getOrNull @@ -66,7 +66,7 @@ internal class FurnaceHandler( user: PlayerEntity, hand: Hand ): TypedActionResult { - staffStack[staffFurnaceDataComponentType.get()] = StaffFurnaceDataComponent(0) + staffStack[ComponentTypes.furnaceData] = StaffFurnaceDataComponent(0) user.setCurrentHand(hand) return TypedActionResult.consume(staffStack) @@ -83,7 +83,7 @@ internal class FurnaceHandler( return } - val furnaceData = staffStack[staffFurnaceDataComponentType.get()]!! + val furnaceData = staffStack[ComponentTypes.furnaceData]!! furnaceData.serverBurnTicks++ val stackToSmelt = itemToSmelt?.stack ?: return @@ -125,7 +125,7 @@ internal class FurnaceHandler( } override fun onStoppedUsing(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - staffStack.remove(staffFurnaceDataComponentType.get()) + staffStack.remove(ComponentTypes.furnaceData) } override fun finishUsing(staffStack: ItemStack, world: World, user: LivingEntity): ItemStack { diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/NetheriteBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/NetheriteBlockHandler.kt index 210a647c3..8f7675154 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/NetheriteBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/NetheriteBlockHandler.kt @@ -35,9 +35,9 @@ import net.minecraft.util.math.MathHelper import net.minecraft.util.math.Vec2f import net.minecraft.world.World import net.minecraft.world.WorldEvents -import opekope2.avm_staff.api.breakBlockWithStaffCriterion import opekope2.avm_staff.api.staff.StaffAttributeModifiersComponentBuilder import opekope2.avm_staff.api.staff.StaffHandler +import opekope2.avm_staff.content.Criteria import opekope2.avm_staff.util.* import opekope2.avm_staff.util.destruction.InTruncatedPyramidPredicate import opekope2.avm_staff.util.destruction.MaxHardnessPredicate @@ -123,7 +123,7 @@ class NetheriteBlockHandler : StaffHandler() { if (attacker is PlayerEntity && attacker.abilities.creativeMode) NoOpBlockDropCollector() else ChunkedBlockDropCollector(shapePredicate.volume, MAX_CHUNK_SIZE) - if (attacker is ServerPlayerEntity) breakBlockWithStaffCriterion.get().trigger(attacker, world, target) + if (attacker is ServerPlayerEntity) Criteria.breakBlockWithStaff.trigger(attacker, world, target) destroyBox( world, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt index 8785733b5..672ec4a49 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt @@ -27,8 +27,8 @@ import net.minecraft.util.Hand import net.minecraft.world.World import net.minecraft.world.event.GameEvent import opekope2.avm_staff.api.entity.ImpactTntEntity -import opekope2.avm_staff.api.impactTntEntityType import opekope2.avm_staff.api.staff.StaffHandler +import opekope2.avm_staff.content.EntityTypes import opekope2.avm_staff.util.* internal class TntHandler : StaffHandler() { @@ -42,7 +42,7 @@ internal class TntHandler : StaffHandler() { if (!shooter.canUseStaff) return if (shooter is PlayerEntity && shooter.isAttackCoolingDown) return - val spawnPos = impactTntEntityType.get().getSpawnPosition(world, shooter.approximateStaffTipPosition) ?: return + val spawnPos = EntityTypes.impactTnt.getSpawnPosition(world, shooter.approximateStaffTipPosition) ?: return val (x, y, z) = spawnPos world.spawnEntity(ImpactTntEntity(world, x, y, z, shooter.rotationVector + shooter.velocity, shooter)) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt index 6316acbfc..8bbb6b004 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt @@ -25,11 +25,10 @@ import net.minecraft.item.BlockItem import net.minecraft.item.Items.* import net.minecraft.recipe.RecipeType import net.minecraft.sound.SoundEvents -import opekope2.avm_staff.api.flamethrowerParticleType import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer import opekope2.avm_staff.api.item.renderer.StaffItemRenderer -import opekope2.avm_staff.api.soulFlamethrowerParticleType import opekope2.avm_staff.api.staff.StaffHandler +import opekope2.avm_staff.content.ParticleTypes import opekope2.avm_staff.internal.staff.item_renderer.BellStaffItemRenderer import opekope2.avm_staff.internal.staff.item_renderer.FurnaceStaffItemRenderer import opekope2.avm_staff.internal.staff.item_renderer.LightningRodStaffItemRenderer @@ -49,13 +48,13 @@ fun registerVanillaStaffHandlers() { StaffHandler.register( CAMPFIRE, CampfireHandler( - CampfireHandler.Parameters(5 / 20.0, 1 / 20.0, 4f, 1, 0.1, flamethrowerParticleType) + CampfireHandler.Parameters(5 / 20.0, 1 / 20.0, 4f, 1, 0.1, ParticleTypes.FLAME) ) ) StaffHandler.register( SOUL_CAMPFIRE, CampfireHandler( - CampfireHandler.Parameters(10 / 20.0, 2 / 20.0, 6f, 2, 0.12, soulFlamethrowerParticleType) + CampfireHandler.Parameters(10 / 20.0, 2 / 20.0, 6f, 2, 0.12, ParticleTypes.SOUL_FIRE_FLAME) ) ) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/FurnaceStaffItemRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/FurnaceStaffItemRenderer.kt index 10c80390b..a42496106 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/FurnaceStaffItemRenderer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/FurnaceStaffItemRenderer.kt @@ -29,7 +29,7 @@ import net.minecraft.client.util.math.MatrixStack import net.minecraft.item.ItemStack import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer import opekope2.avm_staff.api.item.renderer.StaffItemRenderer -import opekope2.avm_staff.api.staffFurnaceDataComponentType +import opekope2.avm_staff.content.ComponentTypes @Environment(EnvType.CLIENT) class FurnaceStaffItemRenderer(unlitState: BlockState, litState: BlockState) : StaffItemRenderer() { @@ -50,7 +50,7 @@ class FurnaceStaffItemRenderer(unlitState: BlockState, litState: BlockState) : S overlay: Int ) { val renderer = - if (staffFurnaceDataComponentType.get() in staffStack) litRenderer + if (ComponentTypes.furnaceData in staffStack) litRenderer else unlitRenderer renderer.renderItemInStaff(staffStack, mode, matrices, vertexConsumers, light, overlay) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/RegistryKeyUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/RegistryKeyUtil.kt new file mode 100644 index 000000000..1d528e993 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/RegistryKeyUtil.kt @@ -0,0 +1,54 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.util + +import net.minecraft.registry.Registry +import net.minecraft.registry.RegistryKey +import net.minecraft.util.Identifier + +/** + * Utility class to create [Identifier]s and [RegistryKey]s using a specified [namespace][Identifier.namespace] and + * registry. + * + * @param TContent The type of the content to register + * @param modId The [namespace][Identifier.namespace] of the content to register. + * @param registry The registry to register the content in + */ +open class RegistryKeyUtil( + protected val modId: String, + protected val registry: RegistryKey> +) { + init { + require(Identifier.isNamespaceValid(modId)) { "Mod ID is not a valid namespace" } + } + + /** + * Creates an [Identifier] from the namespace specified in the constructor and a given path. + * + * @param path The path of the [Identifier] to create + */ + fun id(path: String): Identifier = Identifier.of(modId, path) + + /** + * Creates a [RegistryKey] from the registry and namespace specified in the constructor and a given path. + * + * @param path The path of the [Identifier] to create a registry key from + */ + fun registryKey(path: String): RegistryKey = RegistryKey.of(registry, id(path)) +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/RegistryUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/RegistryUtil.kt new file mode 100644 index 000000000..27d9256a3 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/RegistryUtil.kt @@ -0,0 +1,52 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.util + +import dev.architectury.registry.registries.DeferredRegister +import dev.architectury.registry.registries.RegistrySupplier +import net.minecraft.registry.Registry +import net.minecraft.registry.RegistryKey +import net.minecraft.util.Identifier + +/** + * Utility class to register content to Minecraft registries. + * + * @param TContent The type of the content to register + * @param modId The [namespace][Identifier.namespace] of the content to register. + * @param registry The registry to register the content in + */ +abstract class RegistryUtil(modId: String, registry: RegistryKey>) : + RegistryKeyUtil(modId, registry) { + private val deferredRegister = DeferredRegister.create(modId, registry) + + /** + * Adds a content to be registered in a Minecraft registry using Architectury API. + * + * @param path The [path][Identifier.path] of the identifier of the content to register + * @param factory The function creating + */ + protected fun register(path: String, factory: (RegistryKey) -> T): RegistrySupplier = + deferredRegister.register(path) { factory(registryKey(path)) } + + /** + * @suppress + */ + @JvmSynthetic + internal open fun register() = deferredRegister.register() +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt index c8eb33076..f1d4c7a2e 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt @@ -29,20 +29,20 @@ import net.minecraft.util.math.Vec3d import net.minecraft.world.RaycastContext import opekope2.avm_staff.api.component.StaffItemComponent import opekope2.avm_staff.api.staff.StaffHandler -import opekope2.avm_staff.api.staffItemComponentType +import opekope2.avm_staff.content.ComponentTypes /** * Checks if an item is added the given staff item stack. */ val ItemStack.isItemInStaff: Boolean @JvmName("isItemInStaff") - get() = staffItemComponentType.get() in this + get() = ComponentTypes.staffItem in this /** * Gets the item inserted into the given staff item stack. */ val ItemStack.itemInStaff: Item? - get() = getOrDefault(staffItemComponentType.get(), null)?.item?.item + get() = getOrDefault(ComponentTypes.staffItem, null)?.item?.item /** * Gets the item stack inserted into the given staff item stack. @@ -51,7 +51,7 @@ val ItemStack.itemInStaff: Item? * @see mutableItemStackInStaff */ val ItemStack.itemStackInStaff: ItemStack? - get() = getOrDefault(staffItemComponentType.get(), null)?.item + get() = getOrDefault(ComponentTypes.staffItem, null)?.item /** * Gets or sets a copy of the item stack inserted into the given staff item stack. The value returned or passed in can @@ -65,9 +65,9 @@ var ItemStack.mutableItemStackInStaff: ItemStack? val changes = ComponentChanges.builder() if (value == null || value.isEmpty) { - changes.remove(staffItemComponentType.get()) + changes.remove(ComponentTypes.staffItem) } else { - changes.add(staffItemComponentType.get(), StaffItemComponent(value.copy())) + changes.add(ComponentTypes.staffItem, StaffItemComponent(value.copy())) } applyChanges(changes.build()) From e4c8e995b0481af2965bd8464f134bd18b39c210 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 16 Nov 2024 01:41:13 +0100 Subject: [PATCH 28/83] Refactor initializers and event handlers Possibly improve lunar client compatibility based on an OptiGUI issue --- .../avm_staff/internal/fabric/StaffMod.kt | 28 ++- .../internal/fabric/StaffModClient.kt | 27 ++- FabricMod/src/main/resources/fabric.mod.json | 28 --- .../avm_staff/internal/neoforge/StaffMod.kt | 15 +- .../internal/neoforge/StaffModClient.kt | 16 +- .../avm_staff/internal/Initializer.kt | 224 ------------------ .../event_handler/ClientEventHandlers.kt | 44 ++++ .../internal/event_handler/EventHandlers.kt | 167 +++++++++++++ .../event_handler/KeyBindingHandler.kt | 55 +++-- .../internal/initializer/ClientInitializer.kt | 54 +++++ .../internal/initializer/Initializer.kt | 51 ++++ .../internal/model/ModelPredicates.kt | 29 ++- 12 files changed, 417 insertions(+), 321 deletions(-) delete mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/ClientEventHandlers.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/EventHandlers.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/ClientInitializer.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt diff --git a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffMod.kt b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffMod.kt index b01eee09a..361d16737 100644 --- a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffMod.kt +++ b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffMod.kt @@ -38,23 +38,35 @@ import opekope2.avm_staff.api.IStaffModPlatform import opekope2.avm_staff.api.item.CrownItem import opekope2.avm_staff.api.item.StaffItem import opekope2.avm_staff.api.item.renderer.StaffRenderer +import opekope2.avm_staff.internal.event_handler.ClientEventHandlers +import opekope2.avm_staff.internal.event_handler.EventHandlers import opekope2.avm_staff.internal.fabric.item.FabricStaffItem -import opekope2.avm_staff.internal.subscribeToClientEvents +import opekope2.avm_staff.internal.initializer.Initializer +import opekope2.avm_staff.internal.staff.handler.registerVanillaStaffHandlers @Suppress("unused") -object StaffMod : ModInitializer, IStaffModPlatform { +object StaffMod : ModInitializer, IStaffModPlatform, AttackEntityCallback { override fun onInitialize() { - AttackEntityCallback.EVENT.register(::dispatchStaffEntityAttack) - + Initializer + EventHandlers + subscribeToFabricEvents() + registerVanillaStaffHandlers() if (FabricLoader.getInstance().environmentType == EnvType.CLIENT) { // Needs to be called before client entry point because of Fabric Loader and Architectury API - subscribeToClientEvents() + ClientEventHandlers } } - @Suppress("UNUSED_PARAMETER") - private fun dispatchStaffEntityAttack( - player: PlayerEntity, world: World, hand: Hand, target: Entity, hit: EntityHitResult? + private fun subscribeToFabricEvents() { + AttackEntityCallback.EVENT.register(this) + } + + override fun interact( + player: PlayerEntity, + world: World, + hand: Hand, + target: Entity, + hit: EntityHitResult? ): ActionResult { val staffStack = player.getStackInHand(hand) val staffItem = staffStack.item as? StaffItem ?: return ActionResult.PASS diff --git a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModClient.kt b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModClient.kt index 5c1134b36..9566e46a3 100644 --- a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModClient.kt +++ b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModClient.kt @@ -28,23 +28,38 @@ import net.minecraft.client.render.RenderLayer import opekope2.avm_staff.api.particle.FlamethrowerParticle import opekope2.avm_staff.content.Blocks import opekope2.avm_staff.content.ParticleTypes -import opekope2.avm_staff.internal.model.registerModelPredicateProviders +import opekope2.avm_staff.internal.initializer.ClientInitializer +import opekope2.avm_staff.internal.model.ModelPredicates +import opekope2.avm_staff.internal.staff.handler.registerVanillaStaffItemRenderers @Suppress("unused") @Environment(EnvType.CLIENT) object StaffModClient : ClientModInitializer { override fun onInitializeClient() { - ParticleFactoryRegistry.getInstance().apply { - register(ParticleTypes.flame, FlamethrowerParticle::Factory) - register(ParticleTypes.soulFireFlame, FlamethrowerParticle::Factory) - } + ClientInitializer + registerVanillaStaffItemRenderers() + + registerParticleFactories(ParticleFactoryRegistry.getInstance()) + registerBlockRenderLayers() + registerModelPredicateProviders() + } + private fun registerParticleFactories(particleFactoryRegistry: ParticleFactoryRegistry) { + particleFactoryRegistry.register(ParticleTypes.flame, FlamethrowerParticle::Factory) + particleFactoryRegistry.register(ParticleTypes.soulFireFlame, FlamethrowerParticle::Factory) + } + + private fun registerBlockRenderLayers() { BlockRenderLayerMap.INSTANCE.putBlocks( RenderLayer.getCutout(), Blocks.crownOfKingOrange, Blocks.wallCrownOfKingOrange ) + } - registerModelPredicateProviders(ModelPredicateProviderRegistry::register) + private fun registerModelPredicateProviders() { + for ((key, value) in ModelPredicates) { + ModelPredicateProviderRegistry.register(key, value) + } } } diff --git a/FabricMod/src/main/resources/fabric.mod.json b/FabricMod/src/main/resources/fabric.mod.json index c28095b3e..8ca6aa32f 100644 --- a/FabricMod/src/main/resources/fabric.mod.json +++ b/FabricMod/src/main/resources/fabric.mod.json @@ -46,40 +46,12 @@ { "adapter": "kotlin", "value": "opekope2.avm_staff.internal.fabric.StaffMod" - }, - { - "adapter": "kotlin", - "value": "opekope2.avm_staff.internal.InitializerKt::registerContent" - }, - { - "adapter": "kotlin", - "value": "opekope2.avm_staff.internal.InitializerKt::initializeNetworking" - }, - { - "adapter": "kotlin", - "value": "opekope2.avm_staff.internal.InitializerKt::subscribeToEvents" - }, - { - "adapter": "kotlin", - "value": "opekope2.avm_staff.internal.staff.handler.VanillaStaffHandlersKt::registerVanillaStaffHandlers" } ], "client": [ { "adapter": "kotlin", "value": "opekope2.avm_staff.internal.fabric.StaffModClient" - }, - { - "adapter": "kotlin", - "value": "opekope2.avm_staff.internal.InitializerKt::registerClientContent" - }, - { - "adapter": "kotlin", - "value": "opekope2.avm_staff.internal.InitializerKt::registerSmithingTableTextures" - }, - { - "adapter": "kotlin", - "value": "opekope2.avm_staff.internal.staff.handler.VanillaStaffHandlersKt::registerVanillaStaffItemRenderers" } ] }, diff --git a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffMod.kt b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffMod.kt index b34dac936..ee260189e 100644 --- a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffMod.kt +++ b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffMod.kt @@ -20,20 +20,19 @@ package opekope2.avm_staff.internal.neoforge import dev.architectury.registry.registries.RegistrySupplier import net.minecraft.block.Block +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.Item import net.minecraft.particle.SimpleParticleType import net.neoforged.api.distmarker.Dist import net.neoforged.fml.common.Mod import net.neoforged.neoforge.event.entity.living.LivingDropsEvent import opekope2.avm_staff.api.IStaffModPlatform -import opekope2.avm_staff.internal.initializeNetworking +import opekope2.avm_staff.internal.event_handler.EventHandlers +import opekope2.avm_staff.internal.initializer.Initializer import opekope2.avm_staff.internal.neoforge.item.NeoForgeCrownItem import opekope2.avm_staff.internal.neoforge.item.NeoForgeStaffItem import opekope2.avm_staff.internal.neoforge.item.NeoForgeStaffRendererItem -import opekope2.avm_staff.internal.registerContent import opekope2.avm_staff.internal.staff.handler.registerVanillaStaffHandlers -import opekope2.avm_staff.internal.stopUsingStaffWhenDropped -import opekope2.avm_staff.internal.subscribeToEvents import opekope2.avm_staff.util.MOD_ID import thedarkcolour.kotlinforforge.neoforge.forge.FORGE_BUS import thedarkcolour.kotlinforforge.neoforge.forge.runWhenOn @@ -41,9 +40,8 @@ import thedarkcolour.kotlinforforge.neoforge.forge.runWhenOn @Mod(MOD_ID) object StaffMod : IStaffModPlatform { init { - registerContent() - initializeNetworking() - subscribeToEvents() + Initializer + EventHandlers subscribeToNeoForgeEvents() registerVanillaStaffHandlers() runWhenOn(Dist.CLIENT) { StaffModClient.initializeClient() } @@ -54,8 +52,9 @@ object StaffMod : IStaffModPlatform { } private fun dropInventory(event: LivingDropsEvent) { + val player = event.entity as? PlayerEntity ?: return for (item in event.drops) { - stopUsingStaffWhenDropped(event.entity, item) + EventHandlers.drop(player, item) } } diff --git a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModClient.kt b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModClient.kt index faea9726a..497c27e11 100644 --- a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModClient.kt +++ b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModClient.kt @@ -26,19 +26,17 @@ import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent import net.neoforged.neoforge.client.event.RegisterParticleProvidersEvent import opekope2.avm_staff.api.particle.FlamethrowerParticle import opekope2.avm_staff.content.ParticleTypes -import opekope2.avm_staff.internal.model.registerModelPredicateProviders -import opekope2.avm_staff.internal.registerClientContent -import opekope2.avm_staff.internal.registerSmithingTableTextures +import opekope2.avm_staff.internal.event_handler.ClientEventHandlers +import opekope2.avm_staff.internal.initializer.ClientInitializer +import opekope2.avm_staff.internal.model.ModelPredicates import opekope2.avm_staff.internal.staff.handler.registerVanillaStaffItemRenderers -import opekope2.avm_staff.internal.subscribeToClientEvents import thedarkcolour.kotlinforforge.neoforge.forge.MOD_BUS @OnlyIn(Dist.CLIENT) object StaffModClient { fun initializeClient() { - registerClientContent() - registerSmithingTableTextures() - subscribeToClientEvents() + ClientInitializer + ClientEventHandlers registerVanillaStaffItemRenderers() MOD_BUS.register(this) } @@ -46,7 +44,9 @@ object StaffModClient { @SubscribeEvent fun initializeClient(event: FMLClientSetupEvent) { event.enqueueWork { - registerModelPredicateProviders(ModelPredicateProviderRegistry::registerGeneric) + for ((key, value) in ModelPredicates) { + ModelPredicateProviderRegistry.registerGeneric(key, value) + } } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt deleted file mode 100644 index 4f579ebe5..000000000 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ /dev/null @@ -1,224 +0,0 @@ -/* - * AvM Staff Mod - * Copyright (c) 2024 opekope2 - * - * This mod is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This mod is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this mod. If not, see . - */ - -package opekope2.avm_staff.internal - -import dev.architectury.event.CompoundEventResult -import dev.architectury.event.EventResult -import dev.architectury.event.events.client.ClientTickEvent -import dev.architectury.event.events.common.* -import dev.architectury.registry.client.level.entity.EntityRendererRegistry -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment -import net.minecraft.block.DispenserBlock -import net.minecraft.client.render.entity.EmptyEntityRenderer -import net.minecraft.client.render.entity.TntEntityRenderer -import net.minecraft.entity.Entity -import net.minecraft.entity.ItemEntity -import net.minecraft.entity.LivingEntity -import net.minecraft.entity.damage.DamageSource -import net.minecraft.entity.mob.AbstractPiglinEntity -import net.minecraft.entity.player.PlayerEntity -import net.minecraft.item.ItemStack -import net.minecraft.loot.LootPool -import net.minecraft.loot.LootTable -import net.minecraft.loot.entry.LootTableEntry -import net.minecraft.registry.RegistryKey -import net.minecraft.registry.RegistryKeys -import net.minecraft.server.network.ServerPlayerEntity -import net.minecraft.util.Hand -import net.minecraft.util.Identifier -import net.minecraft.util.hit.EntityHitResult -import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.Box -import net.minecraft.util.math.Direction -import net.minecraft.world.World -import opekope2.avm_staff.api.block.dispenser.CakeDispenserBehavior -import opekope2.avm_staff.api.entity.CakeEntity -import opekope2.avm_staff.api.entity.renderer.CakeEntityRenderer -import opekope2.avm_staff.api.item.StaffItem -import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures -import opekope2.avm_staff.content.* -import opekope2.avm_staff.internal.event_handler.handleKeyBindings -import opekope2.avm_staff.internal.event_handler.registerKeyBindings -import opekope2.avm_staff.internal.networking.c2s.play.AttackC2SPacket -import opekope2.avm_staff.internal.networking.c2s.play.InsertItemIntoStaffC2SPacket -import opekope2.avm_staff.internal.networking.c2s.play.RemoveItemFromStaffC2SPacket -import opekope2.avm_staff.internal.networking.s2c.play.MassDestructionS2CPacket -import opekope2.avm_staff.mixin.IPiglinBrainAccessor -import opekope2.avm_staff.mixin.ISmithingTemplateItemAccessor -import opekope2.avm_staff.util.* -import net.minecraft.item.Items as MinecraftItems - -fun registerContent() { - Blocks.register() - ComponentTypes.register() - Criteria.register() - EntityTypes.register() - ItemGroups.register() - Items.register() - ParticleTypes.register() - SoundEvents.register() -} - -fun initializeNetworking() { - AttackC2SPacket.registerReceiver() - InsertItemIntoStaffC2SPacket.registerReceiver() - RemoveItemFromStaffC2SPacket.registerReceiver() - - MassDestructionS2CPacket.registerReceiver() -} - -fun subscribeToEvents() { - EntityEvent.LIVING_DEATH.register(::stopUsingStaffOnPlayerDeath) - InteractionEvent.LEFT_CLICK_BLOCK.register(::dispatchStaffBlockAttack) - InteractionEvent.RIGHT_CLICK_ITEM.register(::tryThrowCake) - LifecycleEvent.SETUP.register(::setup) - LootEvent.MODIFY_LOOT_TABLE.register(::modifyLootTables) - PlayerEvent.ATTACK_ENTITY.register(::tryAngerPiglins) - PlayerEvent.DROP_ITEM.register(::stopUsingStaffWhenDropped) - EntityEvent.LIVING_HURT.register(::triggerDamageWhileUsingItemCriterion) -} - -@Suppress("UNUSED_PARAMETER") -private fun stopUsingStaffOnPlayerDeath(entity: LivingEntity, damageSource: DamageSource): EventResult { - if (entity !is PlayerEntity) return EventResult.pass() - - if (entity.activeItem.isStaff) { - entity.stopUsingItem() - } - - return EventResult.pass() -} - -private fun dispatchStaffBlockAttack( - player: PlayerEntity, hand: Hand, target: BlockPos, direction: Direction -): EventResult { - val staffStack = player.getStackInHand(hand) - val staffItem = staffStack.item as? StaffItem ?: return EventResult.pass() - - return staffItem.attackBlock(staffStack, player.entityWorld, player, target, direction, hand) -} - -private fun tryThrowCake(player: PlayerEntity, hand: Hand): CompoundEventResult { - val world = player.entityWorld - val cake = player.getStackInHand(hand) - val spawnPos = EntityTypes.cake.getSpawnPosition(world, player.approximateStaffTipPosition) - - if (!cake.isOf(MinecraftItems.CAKE)) return CompoundEventResult.pass() - if (spawnPos == null) return CompoundEventResult.pass() - if (world.isClient) return CompoundEventResult.interruptTrue(cake) - if (!world.gameRules.getBoolean(GameRules.THROWABLE_CAKES)) return CompoundEventResult.pass() - - CakeEntity.throwCake(world, spawnPos, player.rotationVector * .5 + player.velocity, player) - cake.decrementUnlessCreative(1, player) - - return CompoundEventResult.interruptFalse(cake) -} - -private fun setup() { - DispenserBlock.registerBehavior(MinecraftItems.CAKE, CakeDispenserBehavior()) -} - -private val MODIFIABLE_LOOT_TABLES = setOf( - Identifier.ofVanilla("chests/bastion_treasure"), - Identifier.ofVanilla("chests/trial_chambers/reward_unique") -) - -private fun modifyLootTables( - lootTable: RegistryKey, - context: LootEvent.LootTableModificationContext, - builtin: Boolean -) { - if (!builtin) return - if (lootTable.value !in MODIFIABLE_LOOT_TABLES) return - - context.addPool( - LootPool.builder().with( - LootTableEntry.builder( - RegistryKey.of(RegistryKeys.LOOT_TABLE, Identifier.of(MOD_ID, "add_loot_pool/${lootTable.value.path}")) - ) - ) - ) -} - -private const val MAX_ANGER_DISTANCE = 16.0 - -@Suppress("UNUSED_PARAMETER") -private fun tryAngerPiglins( - player: PlayerEntity, world: World, target: Entity, hand: Hand, hit: EntityHitResult? -): EventResult { - if (world.isClient) return EventResult.pass() - if (target !is LivingEntity) return EventResult.pass() - if (!player.getStackInHand(hand).isStaff) return EventResult.pass() - if (!player.armorItems.any { it.isOf(Items.crownOfKingOrange) }) return EventResult.pass() - - val box = Box.of(player.pos, 2 * MAX_ANGER_DISTANCE, 2 * MAX_ANGER_DISTANCE, 2 * MAX_ANGER_DISTANCE) - world.getEntitiesByClass(AbstractPiglinEntity::class.java, box) { - it !== target && it.squaredDistanceTo(player) <= MAX_ANGER_DISTANCE * MAX_ANGER_DISTANCE - }.forEach { - IPiglinBrainAccessor.callBecomeAngryWith(it, target) - } - - return EventResult.pass() -} - -fun stopUsingStaffWhenDropped(entity: LivingEntity, item: ItemEntity): EventResult { - val staffItem = item.stack.item as? StaffItem ?: return EventResult.pass() - staffItem.onStoppedUsing(item.stack, entity.entityWorld, entity, entity.itemUseTimeLeft) - return EventResult.pass() -} - -@Suppress("UNUSED_PARAMETER") -fun triggerDamageWhileUsingItemCriterion(entity: LivingEntity, damage: DamageSource, amount: Float): EventResult { - if (entity is ServerPlayerEntity && entity.isUsingItem) { - Criteria.takeDamageWhileUsingItem.trigger(entity, entity.activeItem, damage) - } - return EventResult.pass() -} - -@Environment(EnvType.CLIENT) -fun registerClientContent() { - registerKeyBindings() - EntityRendererRegistry.register(EntityTypes.IMPACT_TNT, ::TntEntityRenderer) - EntityRendererRegistry.register(EntityTypes.CAKE, ::CakeEntityRenderer) - EntityRendererRegistry.register(EntityTypes.CAMPFIRE_FLAME, ::EmptyEntityRenderer) -} - -@Environment(EnvType.CLIENT) -fun registerSmithingTableTextures() { - StaffInfusionSmithingRecipeTextures.register( - Identifier.of(MOD_ID, "item/smithing_table/empty_slot_royal_staff"), - ISmithingTemplateItemAccessor.emptySlotRedstoneDustTexture() - ) -} - -@Environment(EnvType.CLIENT) -fun subscribeToClientEvents() { - ClientTickEvent.CLIENT_POST.register(::handleKeyBindings) - InteractionEvent.CLIENT_LEFT_CLICK_AIR.register(::clientAttack) -} - -@Environment(EnvType.CLIENT) -private fun clientAttack(player: PlayerEntity, hand: Hand) { - val staffStack = player.getStackInHand(hand) - val staffItem = staffStack.item as? StaffItem ?: return - - staffItem.attack(staffStack, player.entityWorld, player, hand) - AttackC2SPacket(hand).sendToServer() -} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/ClientEventHandlers.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/ClientEventHandlers.kt new file mode 100644 index 000000000..e067019fb --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/ClientEventHandlers.kt @@ -0,0 +1,44 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.internal.event_handler + +import dev.architectury.event.events.client.ClientTickEvent +import dev.architectury.event.events.common.InteractionEvent +import net.fabricmc.api.EnvType +import net.fabricmc.api.Environment +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.util.Hand +import opekope2.avm_staff.api.item.StaffItem +import opekope2.avm_staff.internal.networking.c2s.play.AttackC2SPacket + +@Environment(EnvType.CLIENT) +object ClientEventHandlers : InteractionEvent.ClientLeftClickAir { + init { + ClientTickEvent.CLIENT_POST.register(KeyBindingHandler) + InteractionEvent.CLIENT_LEFT_CLICK_AIR.register(this) + } + + override fun click(player: PlayerEntity, hand: Hand) { + val staffStack = player.getStackInHand(hand) + val staffItem = staffStack.item as? StaffItem ?: return + + staffItem.attack(staffStack, player.entityWorld, player, hand) + AttackC2SPacket(hand).sendToServer() + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/EventHandlers.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/EventHandlers.kt new file mode 100644 index 000000000..336bea92b --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/EventHandlers.kt @@ -0,0 +1,167 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.internal.event_handler + +import dev.architectury.event.CompoundEventResult +import dev.architectury.event.EventResult +import dev.architectury.event.events.common.* +import net.minecraft.block.DispenserBlock +import net.minecraft.entity.Entity +import net.minecraft.entity.ItemEntity +import net.minecraft.entity.LivingEntity +import net.minecraft.entity.damage.DamageSource +import net.minecraft.entity.mob.AbstractPiglinEntity +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.ItemStack +import net.minecraft.item.Items +import net.minecraft.loot.LootPool +import net.minecraft.loot.LootTable +import net.minecraft.loot.entry.LootTableEntry +import net.minecraft.registry.RegistryKey +import net.minecraft.registry.RegistryKeys +import net.minecraft.server.network.ServerPlayerEntity +import net.minecraft.util.Hand +import net.minecraft.util.Identifier +import net.minecraft.util.hit.EntityHitResult +import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Box +import net.minecraft.util.math.Direction +import net.minecraft.world.World +import opekope2.avm_staff.api.block.dispenser.CakeDispenserBehavior +import opekope2.avm_staff.api.entity.CakeEntity +import opekope2.avm_staff.api.item.StaffItem +import opekope2.avm_staff.content.Criteria +import opekope2.avm_staff.content.EntityTypes +import opekope2.avm_staff.content.GameRules +import opekope2.avm_staff.mixin.IPiglinBrainAccessor +import opekope2.avm_staff.util.* + +object EventHandlers : EntityEvent.LivingDeath, EntityEvent.LivingHurt, InteractionEvent.LeftClickBlock, + InteractionEvent.RightClickItem, Runnable, LootEvent.ModifyLootTable, PlayerEvent.AttackEntity, + PlayerEvent.DropItem { + private val MODIFIABLE_LOOT_TABLES = setOf( + Identifier.ofVanilla("chests/bastion_treasure"), + Identifier.ofVanilla("chests/trial_chambers/reward_unique") + ) + private const val MAX_ANGER_DISTANCE = 16.0 + + init { + EntityEvent.LIVING_DEATH.register(this) + EntityEvent.LIVING_HURT.register(this) + InteractionEvent.LEFT_CLICK_BLOCK.register(this) + InteractionEvent.RIGHT_CLICK_ITEM.register(this) + LifecycleEvent.SETUP.register(this) + LootEvent.MODIFY_LOOT_TABLE.register(this) + PlayerEvent.ATTACK_ENTITY.register(this) + PlayerEvent.DROP_ITEM.register(this) + } + + override fun die(entity: LivingEntity, damageSource: DamageSource): EventResult { + if (entity !is PlayerEntity) return EventResult.pass() + + if (entity.activeItem.isStaff) { + entity.stopUsingItem() + } + + return EventResult.pass() + } + + override fun hurt(entity: LivingEntity, damage: DamageSource, amount: Float): EventResult { + if (entity is ServerPlayerEntity && entity.isUsingItem) { + Criteria.takeDamageWhileUsingItem.trigger(entity, entity.activeItem, damage) + } + return EventResult.pass() + } + + override fun click(player: PlayerEntity, hand: Hand, target: BlockPos, direction: Direction): EventResult { + val staffStack = player.getStackInHand(hand) + val staffItem = staffStack.item as? StaffItem ?: return EventResult.pass() + + return staffItem.attackBlock(staffStack, player.entityWorld, player, target, direction, hand) + } + + override fun click(player: PlayerEntity, hand: Hand): CompoundEventResult { + val world = player.entityWorld + val cake = player.getStackInHand(hand) + val spawnPos = EntityTypes.cake.getSpawnPosition(world, player.approximateStaffTipPosition) + + if (!cake.isOf(Items.CAKE)) return CompoundEventResult.pass() + if (spawnPos == null) return CompoundEventResult.pass() + if (world.isClient) return CompoundEventResult.interruptTrue(cake) + if (!world.gameRules.getBoolean(GameRules.THROWABLE_CAKES)) return CompoundEventResult.pass() + + CakeEntity.throwCake(world, spawnPos, player.rotationVector * .5 + player.velocity, player) + cake.decrementUnlessCreative(1, player) + + return CompoundEventResult.interruptFalse(cake) + } + + // setup + override fun run() { + DispenserBlock.registerBehavior(Items.CAKE, CakeDispenserBehavior()) + } + + override fun modifyLootTable( + lootTable: RegistryKey, + context: LootEvent.LootTableModificationContext, + builtin: Boolean + ) { + if (!builtin) return + if (lootTable.value !in MODIFIABLE_LOOT_TABLES) return + + context.addPool( + LootPool.builder().with( + LootTableEntry.builder( + RegistryKey.of( + RegistryKeys.LOOT_TABLE, + Identifier.of(MOD_ID, "add_loot_pool/${lootTable.value.path}") + ) + ) + ) + ) + } + + override fun attack( + player: PlayerEntity, + world: World, + target: Entity, + hand: Hand, + hit: EntityHitResult? + ): EventResult { + if (world.isClient) return EventResult.pass() + if (target !is LivingEntity) return EventResult.pass() + if (!player.getStackInHand(hand).isStaff) return EventResult.pass() + if (!player.armorItems.any { it.isOf(opekope2.avm_staff.content.Items.crownOfKingOrange) }) return EventResult.pass() + + val box = Box.of(player.pos, 2 * MAX_ANGER_DISTANCE, 2 * MAX_ANGER_DISTANCE, 2 * MAX_ANGER_DISTANCE) + world.getEntitiesByClass(AbstractPiglinEntity::class.java, box) { + it !== target && it.squaredDistanceTo(player) <= MAX_ANGER_DISTANCE * MAX_ANGER_DISTANCE + }.forEach { + IPiglinBrainAccessor.callBecomeAngryWith(it, target) + } + + return EventResult.pass() + } + + override fun drop(entity: PlayerEntity, item: ItemEntity): EventResult { + val staffItem = item.stack.item as? StaffItem ?: return EventResult.pass() + staffItem.onStoppedUsing(item.stack, entity.entityWorld, entity, entity.itemUseTimeLeft) + return EventResult.pass() + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/KeyBindingHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/KeyBindingHandler.kt index 810b095ca..0764ce935 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/KeyBindingHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/KeyBindingHandler.kt @@ -16,11 +16,9 @@ * along with this mod. If not, see . */ -@file: Environment(EnvType.CLIENT) -@file: Suppress("UNUSED_PARAMETER") - package opekope2.avm_staff.internal.event_handler +import dev.architectury.event.events.client.ClientTickEvent import dev.architectury.registry.client.keymappings.KeyMappingRegistry import net.fabricmc.api.EnvType import net.fabricmc.api.Environment @@ -36,34 +34,39 @@ import opekope2.avm_staff.internal.networking.c2s.play.RemoveItemFromStaffC2SPac import opekope2.avm_staff.util.MOD_ID import org.lwjgl.glfw.GLFW -private val addRemoveStaffItemKeyBinding = KeyBinding( - "key.$MOD_ID.add_remove_staff_item", - InputUtil.Type.KEYSYM, - GLFW.GLFW_KEY_R, - "key.categories.$MOD_ID" -) +@Environment(EnvType.CLIENT) +internal object KeyBindingHandler : ClientTickEvent.Client { + private val ADD_REMOVE_STAFF_ITEM = KeyBinding( + "key.$MOD_ID.add_remove_staff_item", + InputUtil.Type.KEYSYM, + GLFW.GLFW_KEY_R, + "key.categories.$MOD_ID" + ) -internal fun registerKeyBindings() { - KeyMappingRegistry.register(addRemoveStaffItemKeyBinding) -} + init { + KeyMappingRegistry.register(ADD_REMOVE_STAFF_ITEM) + } -internal fun handleKeyBindings(client: MinecraftClient) { - if (!addRemoveStaffItemKeyBinding.isPressed) return - addRemoveStaffItemKeyBinding.isPressed = false + override fun tick(client: MinecraftClient) { + if (!ADD_REMOVE_STAFF_ITEM.isPressed) return + ADD_REMOVE_STAFF_ITEM.isPressed = false - val player = client.player ?: return + val player = client.player ?: return - if (!player.tryInsertItemIntoStaff(::sendInsertPacket)) { - player.tryRemoveItemFromStaff(::sendRemovePacket) + if (!player.tryInsertItemIntoStaff(KeyBindingHandler::sendInsertPacket)) { + player.tryRemoveItemFromStaff(KeyBindingHandler::sendRemovePacket) + } } -} -private fun sendRemovePacket(player: PlayerEntity, staffStack: ItemStack, targetSlot: Int) { - RemoveItemFromStaffC2SPacket().sendToServer() - player.resetLastAttackedTicks() -} + @Suppress("UNUSED_PARAMETER") + private fun sendRemovePacket(player: PlayerEntity, staffStack: ItemStack, targetSlot: Int) { + RemoveItemFromStaffC2SPacket().sendToServer() + player.resetLastAttackedTicks() + } -private fun sendInsertPacket(player: PlayerEntity, staffStack: ItemStack, itemStackToAdd: ItemStack) { - InsertItemIntoStaffC2SPacket().sendToServer() - player.resetLastAttackedTicks() + @Suppress("UNUSED_PARAMETER") + private fun sendInsertPacket(player: PlayerEntity, staffStack: ItemStack, itemStackToAdd: ItemStack) { + InsertItemIntoStaffC2SPacket().sendToServer() + player.resetLastAttackedTicks() + } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/ClientInitializer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/ClientInitializer.kt new file mode 100644 index 000000000..5315f4ad3 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/ClientInitializer.kt @@ -0,0 +1,54 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.internal.initializer + +import dev.architectury.registry.client.level.entity.EntityRendererRegistry +import net.fabricmc.api.EnvType +import net.fabricmc.api.Environment +import net.minecraft.client.render.entity.EmptyEntityRenderer +import net.minecraft.client.render.entity.TntEntityRenderer +import net.minecraft.util.Identifier +import opekope2.avm_staff.api.entity.renderer.CakeEntityRenderer +import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures +import opekope2.avm_staff.content.EntityTypes +import opekope2.avm_staff.internal.event_handler.KeyBindingHandler +import opekope2.avm_staff.mixin.ISmithingTemplateItemAccessor +import opekope2.avm_staff.util.MOD_ID + +@Environment(EnvType.CLIENT) +object ClientInitializer { + init { + KeyBindingHandler + registerEntityRenderers() + registerSmithingTableTextures() + } + + private fun registerEntityRenderers() { + EntityRendererRegistry.register(EntityTypes.IMPACT_TNT, ::TntEntityRenderer) + EntityRendererRegistry.register(EntityTypes.CAKE, ::CakeEntityRenderer) + EntityRendererRegistry.register(EntityTypes.CAMPFIRE_FLAME, ::EmptyEntityRenderer) + } + + private fun registerSmithingTableTextures() { + StaffInfusionSmithingRecipeTextures.register( + Identifier.of(MOD_ID, "item/smithing_table/empty_slot_royal_staff"), + ISmithingTemplateItemAccessor.emptySlotRedstoneDustTexture() + ) + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt new file mode 100644 index 000000000..2bb7801f1 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt @@ -0,0 +1,51 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.internal.initializer + +import opekope2.avm_staff.content.* +import opekope2.avm_staff.internal.networking.c2s.play.AttackC2SPacket +import opekope2.avm_staff.internal.networking.c2s.play.InsertItemIntoStaffC2SPacket +import opekope2.avm_staff.internal.networking.c2s.play.RemoveItemFromStaffC2SPacket +import opekope2.avm_staff.internal.networking.s2c.play.MassDestructionS2CPacket + +object Initializer { + init { + registerContent() + initializeNetworking() + } + + private fun registerContent() { + Blocks.register() + ComponentTypes.register() + Criteria.register() + EntityTypes.register() + ItemGroups.register() + Items.register() + ParticleTypes.register() + SoundEvents.register() + } + + private fun initializeNetworking() { + AttackC2SPacket.registerReceiver() + InsertItemIntoStaffC2SPacket.registerReceiver() + RemoveItemFromStaffC2SPacket.registerReceiver() + + MassDestructionS2CPacket.registerReceiver() + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt index fd9dd7e75..66abe190f 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt @@ -24,23 +24,26 @@ import net.minecraft.client.item.ClampedModelPredicateProvider import net.minecraft.item.ItemStack import net.minecraft.util.Identifier import opekope2.avm_staff.api.component.StaffRendererPartComponent +import opekope2.avm_staff.api.registry.RegistryBase import opekope2.avm_staff.content.ComponentTypes import opekope2.avm_staff.util.MOD_ID -// ModelPredicateProviderRegistry.register is private in common project @Environment(EnvType.CLIENT) -inline fun registerModelPredicateProviders(register: (Identifier, ClampedModelPredicateProvider) -> Unit) { - register(Identifier.of(MOD_ID, "using_item")) { stack, _, entity, _ -> - if (entity != null && entity.isUsingItem && ItemStack.areEqual(entity.activeItem, stack)) 1f - else 0f +object ModelPredicates : RegistryBase() { + init { + register(Identifier.of(MOD_ID, "using_item")) { stack, _, entity, _ -> + if (entity != null && entity.isUsingItem && ItemStack.areEqual(entity.activeItem, stack)) 1f + else 0f + } + register(Identifier.of(MOD_ID, "head"), matchStaffRendererPart(StaffRendererPartComponent.HEAD)) + register(Identifier.of(MOD_ID, "item"), matchStaffRendererPart(StaffRendererPartComponent.ITEM)) + register(Identifier.of(MOD_ID, "rod_top"), matchStaffRendererPart(StaffRendererPartComponent.ROD_TOP)) + register(Identifier.of(MOD_ID, "rod_bottom"), matchStaffRendererPart(StaffRendererPartComponent.ROD_BOTTOM)) } - register(Identifier.of(MOD_ID, "head"), matchStaffRendererPart(StaffRendererPartComponent.HEAD)) - register(Identifier.of(MOD_ID, "item"), matchStaffRendererPart(StaffRendererPartComponent.ITEM)) - register(Identifier.of(MOD_ID, "rod_top"), matchStaffRendererPart(StaffRendererPartComponent.ROD_TOP)) - register(Identifier.of(MOD_ID, "rod_bottom"), matchStaffRendererPart(StaffRendererPartComponent.ROD_BOTTOM)) -} -fun matchStaffRendererPart(part: StaffRendererPartComponent) = ClampedModelPredicateProvider { stack, _, _, _ -> - if (stack[ComponentTypes.staffRendererPart] == part) 1f - else 0f + private fun matchStaffRendererPart(part: StaffRendererPartComponent) = + ClampedModelPredicateProvider { stack, _, _, _ -> + if (stack[ComponentTypes.staffRendererPart] == part) 1f + else 0f + } } From f9e26ec56505e4012b5b587bd028c47da1a2c7d0 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 16 Nov 2024 23:30:08 +0100 Subject: [PATCH 29/83] Update bell staff Ringing it will tell nearby entity brains, make nearby raiders glow, and emit vibration frequency 10 Attacking will inflict glowing --- .../mixin/IBellBlockEntityAccessor.java | 38 +++++++++++++++++++ .../{BellBlockHandler.kt => BellHandler.kt} | 29 +++++++++++++- .../staff/handler/VanillaStaffHandlers.kt | 2 +- .../src/main/resources/avm_staff.mixins.json | 1 + 4 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 StaffMod/src/main/java/opekope2/avm_staff/mixin/IBellBlockEntityAccessor.java rename StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/{BellBlockHandler.kt => BellHandler.kt} (66%) diff --git a/StaffMod/src/main/java/opekope2/avm_staff/mixin/IBellBlockEntityAccessor.java b/StaffMod/src/main/java/opekope2/avm_staff/mixin/IBellBlockEntityAccessor.java new file mode 100644 index 000000000..8ae446fd8 --- /dev/null +++ b/StaffMod/src/main/java/opekope2/avm_staff/mixin/IBellBlockEntityAccessor.java @@ -0,0 +1,38 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.mixin; + +import net.minecraft.block.entity.BellBlockEntity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.util.math.BlockPos; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(BellBlockEntity.class) +public interface IBellBlockEntityAccessor { + @Invoker + static void callApplyGlowToEntity(LivingEntity entity) { + throw new AssertionError(); + } + + @Invoker + static boolean callIsRaiderEntity(BlockPos pos, LivingEntity entity) { + throw new AssertionError(); + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt similarity index 66% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellBlockHandler.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt index 19450b295..e79707d75 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt @@ -22,6 +22,7 @@ import dev.architectury.event.EventResult import net.minecraft.component.type.AttributeModifierSlot import net.minecraft.entity.Entity import net.minecraft.entity.LivingEntity +import net.minecraft.entity.ai.brain.MemoryModuleType import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack @@ -29,13 +30,16 @@ import net.minecraft.sound.SoundCategory import net.minecraft.sound.SoundEvents import net.minecraft.util.Hand import net.minecraft.util.TypedActionResult +import net.minecraft.util.math.Box import net.minecraft.world.World +import net.minecraft.world.event.GameEvent import opekope2.avm_staff.api.staff.StaffAttributeModifiersComponentBuilder import opekope2.avm_staff.api.staff.StaffHandler +import opekope2.avm_staff.mixin.IBellBlockEntityAccessor import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.attackSpeed -internal class BellBlockHandler : StaffHandler() { +internal class BellHandler : StaffHandler() { override val attributeModifiers = StaffAttributeModifiersComponentBuilder() .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(8.0), AttributeModifierSlot.MAINHAND) .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(1.5), AttributeModifierSlot.MAINHAND) @@ -51,6 +55,25 @@ internal class BellBlockHandler : StaffHandler() { ): TypedActionResult { world.playSound(user, user.blockPos, SoundEvents.BLOCK_BELL_USE, SoundCategory.BLOCKS, 2f, 1f) + if (!world.isClient) { + val box = Box(user.blockPos).expand(48.0) + val hearingEntities = world.getNonSpectatingEntities(LivingEntity::class.java, box) + var resonate = false + for (entity in hearingEntities) { + if (entity.isAlive && !entity.isRemoved && user.blockPos.isWithinDistance(entity.pos, 32.0)) { + entity.brain.remember(MemoryModuleType.HEARD_BELL_TIME, world.time) + } + if (IBellBlockEntityAccessor.callIsRaiderEntity(user.blockPos, entity)) { + IBellBlockEntityAccessor.callApplyGlowToEntity(entity) + resonate = true + } + } + if (resonate) { + world.playSound(null, user.blockPos, SoundEvents.BLOCK_BELL_RESONATE, SoundCategory.BLOCKS, 1.0f, 1.0f) + } + world.emitGameEvent(user, GameEvent.RESONATE_10, user.pos) + } + return TypedActionResult.success(staffStack) } @@ -70,6 +93,10 @@ internal class BellBlockHandler : StaffHandler() { 1f ) + if (!world.isClient && target is LivingEntity) { + IBellBlockEntityAccessor.callApplyGlowToEntity(target) + } + return EventResult.pass() } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt index 8bbb6b004..c92fae8fc 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt @@ -39,7 +39,7 @@ fun registerVanillaStaffHandlers() { StaffHandler.register(CHIPPED_ANVIL, AnvilHandler(DAMAGED_ANVIL)) StaffHandler.register(DAMAGED_ANVIL, AnvilHandler(null)) - StaffHandler.register(BELL, BellBlockHandler()) + StaffHandler.register(BELL, BellHandler()) StaffHandler.register(BONE_BLOCK, BoneBlockHandler()) diff --git a/StaffMod/src/main/resources/avm_staff.mixins.json b/StaffMod/src/main/resources/avm_staff.mixins.json index ba3e2dbb3..1f2c6a948 100644 --- a/StaffMod/src/main/resources/avm_staff.mixins.json +++ b/StaffMod/src/main/resources/avm_staff.mixins.json @@ -17,6 +17,7 @@ "IAbstractFurnaceBlockEntityAccessor", "IAnvilBlockAccessor", "IBeehiveBlockEntityAccessor", + "IBellBlockEntityAccessor", "ICakeBlockAccessor", "IPiglinBrainAccessor", "ISmithingTemplateItemAccessor", From a0e0b954eba5e9e8614f9c59009dba0282b80a24 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 16 Nov 2024 23:31:12 +0100 Subject: [PATCH 30/83] Emit vibration frequency 5 when adding/removing an item from the staff --- .../networking/c2s/play/InsertItemIntoStaffC2SPacket.kt | 2 ++ .../networking/c2s/play/RemoveItemFromStaffC2SPacket.kt | 2 ++ 2 files changed, 4 insertions(+) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/InsertItemIntoStaffC2SPacket.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/InsertItemIntoStaffC2SPacket.kt index 1445b6ad4..9268166bf 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/InsertItemIntoStaffC2SPacket.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/InsertItemIntoStaffC2SPacket.kt @@ -23,6 +23,7 @@ import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack import net.minecraft.network.PacketByteBuf import net.minecraft.util.Identifier +import net.minecraft.world.event.GameEvent import opekope2.avm_staff.internal.networking.IC2SPacket import opekope2.avm_staff.internal.networking.PacketRegistrarAndReceiver import opekope2.avm_staff.util.* @@ -45,6 +46,7 @@ internal class InsertItemIntoStaffC2SPacket() : IC2SPacket { context.player.tryInsertItemIntoStaff { player, staffStack, toInsert -> staffStack.mutableItemStackInStaff = toInsert.split(1) player.resetLastAttackedTicks() + player.entityWorld.emitGameEvent(player, GameEvent.RESONATE_5, player.pos) } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/RemoveItemFromStaffC2SPacket.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/RemoveItemFromStaffC2SPacket.kt index 546a10423..0b77506df 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/RemoveItemFromStaffC2SPacket.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/RemoveItemFromStaffC2SPacket.kt @@ -24,6 +24,7 @@ import net.minecraft.entity.player.PlayerInventory import net.minecraft.item.ItemStack import net.minecraft.network.PacketByteBuf import net.minecraft.util.Identifier +import net.minecraft.world.event.GameEvent import opekope2.avm_staff.internal.networking.IC2SPacket import opekope2.avm_staff.internal.networking.PacketRegistrarAndReceiver import opekope2.avm_staff.util.* @@ -47,6 +48,7 @@ internal class RemoveItemFromStaffC2SPacket() : IC2SPacket { player.inventory.insertStack(targetSlot, staffStack.mutableItemStackInStaff) staffStack.mutableItemStackInStaff = null player.resetLastAttackedTicks() + player.entityWorld.emitGameEvent(player, GameEvent.RESONATE_5, player.pos) } } From 72b4bdcc2298a25d6e6ca1e29f0d4f5a56a852b8 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 17 Nov 2024 22:49:16 +0100 Subject: [PATCH 31/83] Add pickup ability with using staffs --- .../internal/fabric/item/FabricStaffItem.kt | 6 +- .../neoforge/item/NeoForgeStaffItem.kt | 6 +- .../AbstractFurnaceBlockEntityMixin.java | 39 ++++++ .../IClearableBeforeInsertedIntoStaff.kt | 38 ++++++ .../api/component/BlockPickupData.kt | 39 ++++++ .../opekope2/avm_staff/api/item/StaffItem.kt | 26 ++-- .../avm_staff/api/staff/StaffHandler.kt | 114 ++++++++++++++++-- .../avm_staff/content/ComponentTypes.kt | 17 +++ .../opekope2/avm_staff/content/Items.kt | 2 +- .../opekope2/avm_staff/util/StaffUtil.kt | 15 ++- .../src/main/resources/avm_staff.mixins.json | 1 + 11 files changed, 270 insertions(+), 33 deletions(-) create mode 100644 StaffMod/src/main/java/opekope2/avm_staff/mixin/AbstractFurnaceBlockEntityMixin.java create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/block/IClearableBeforeInsertedIntoStaff.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/BlockPickupData.kt diff --git a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/FabricStaffItem.kt b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/FabricStaffItem.kt index e285471be..2a352fef6 100644 --- a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/FabricStaffItem.kt +++ b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/FabricStaffItem.kt @@ -30,7 +30,7 @@ import net.minecraft.util.Hand import opekope2.avm_staff.api.item.StaffItem import opekope2.avm_staff.api.item.renderer.StaffRenderer import opekope2.avm_staff.util.itemInStaff -import opekope2.avm_staff.util.staffHandlerOrDefault +import opekope2.avm_staff.util.staffHandlerOrFallback class FabricStaffItem(settings: Item.Settings, repairIngredient: RegistrySupplier?) : StaffItem(settings, repairIngredient), FabricItem { @@ -46,8 +46,8 @@ class FabricStaffItem(settings: Item.Settings, repairIngredient: RegistrySupplie oldStack: ItemStack, newStack: ItemStack ): Boolean { - val oldHandler = oldStack.itemInStaff.staffHandlerOrDefault - val newHandler = newStack.itemInStaff.staffHandlerOrDefault + val oldHandler = oldStack.itemInStaff.staffHandlerOrFallback + val newHandler = newStack.itemInStaff.staffHandlerOrFallback return if (oldHandler !== newHandler) true else oldHandler.allowComponentsUpdateAnimation(oldStack, newStack, player, hand) diff --git a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/NeoForgeStaffItem.kt b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/NeoForgeStaffItem.kt index a3dabebfc..0b649252e 100644 --- a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/NeoForgeStaffItem.kt +++ b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/NeoForgeStaffItem.kt @@ -36,7 +36,7 @@ import opekope2.avm_staff.api.item.renderer.StaffRenderer import opekope2.avm_staff.util.blockEntityRenderDispatcher import opekope2.avm_staff.util.entityModelLoader import opekope2.avm_staff.util.itemInStaff -import opekope2.avm_staff.util.staffHandlerOrDefault +import opekope2.avm_staff.util.staffHandlerOrFallback import java.util.function.Consumer class NeoForgeStaffItem(settings: Item.Settings, repairIngredientSupplier: RegistrySupplier?) : @@ -60,8 +60,8 @@ class NeoForgeStaffItem(settings: Item.Settings, repairIngredientSupplier: Regis attackEntity(stack, player.entityWorld, player, entity, Hand.MAIN_HAND).interruptsFurtherEvaluation() override fun shouldCauseReequipAnimation(oldStack: ItemStack, newStack: ItemStack, slotChanged: Boolean): Boolean { - val oldHandler = oldStack.itemInStaff.staffHandlerOrDefault - val newHandler = newStack.itemInStaff.staffHandlerOrDefault + val oldHandler = oldStack.itemInStaff.staffHandlerOrFallback + val newHandler = newStack.itemInStaff.staffHandlerOrFallback return if (oldHandler !== newHandler) true else oldHandler.allowReequipAnimation(oldStack, newStack, slotChanged) diff --git a/StaffMod/src/main/java/opekope2/avm_staff/mixin/AbstractFurnaceBlockEntityMixin.java b/StaffMod/src/main/java/opekope2/avm_staff/mixin/AbstractFurnaceBlockEntityMixin.java new file mode 100644 index 000000000..fe5cdfac9 --- /dev/null +++ b/StaffMod/src/main/java/opekope2/avm_staff/mixin/AbstractFurnaceBlockEntityMixin.java @@ -0,0 +1,39 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.mixin; + +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import net.minecraft.block.entity.AbstractFurnaceBlockEntity; +import net.minecraft.util.Identifier; +import opekope2.avm_staff.api.block.IClearableBeforeInsertedIntoStaff; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(AbstractFurnaceBlockEntity.class) +public abstract class AbstractFurnaceBlockEntityMixin implements IClearableBeforeInsertedIntoStaff { + @Shadow + @Final + private Object2IntOpenHashMap recipesUsed; + + @Override + public void staffMod_clearBeforeRemovedFromWorld() { + recipesUsed.clear(); + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/block/IClearableBeforeInsertedIntoStaff.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/block/IClearableBeforeInsertedIntoStaff.kt new file mode 100644 index 000000000..410c92e50 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/block/IClearableBeforeInsertedIntoStaff.kt @@ -0,0 +1,38 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.api.block + +import net.minecraft.block.entity.AbstractFurnaceBlockEntity +import net.minecraft.util.Clearable + +/** + * Performs additional clearing after [Clearable.clear]. Mixed into [AbstractFurnaceBlockEntity] to prevent XP + * duplication. + * + * @see Clearable.clear + */ +interface IClearableBeforeInsertedIntoStaff { + /** + * Called before a block is inserted into a staff and removed from the world. + * + * @see Clearable.clear + */ + @Suppress("FunctionName") // Mixin + fun staffMod_clearBeforeRemovedFromWorld() +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/BlockPickupData.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/BlockPickupData.kt new file mode 100644 index 000000000..ff7acdf55 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/BlockPickupData.kt @@ -0,0 +1,39 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.api.component + +import net.minecraft.block.BlockState +import net.minecraft.block.Blocks +import net.minecraft.network.RegistryByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.util.math.BlockPos + +/** + * Data component to store the block about to be picked up by an empty staff. + * + * @param pos The position of the block to be picked up from. Only available server-side + * @param state The block state to be picked up. Only available server-side + */ +data class BlockPickupData(val pos: BlockPos, val state: BlockState) { + companion object { + @JvmField + val PACKET_CODEC: PacketCodec = + PacketCodec.of({ _, _ -> }, { BlockPickupData(BlockPos.ORIGIN, Blocks.AIR.defaultState) }) + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt index 4e2a45f95..eaf2196e3 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt @@ -55,32 +55,32 @@ abstract class StaffItem(settings: Settings, private val repairIngredientSupplie } override fun postProcessComponents(stack: ItemStack) { - stack[DataComponentTypes.ATTRIBUTE_MODIFIERS] = stack.itemInStaff.staffHandlerOrDefault.attributeModifiers + stack[DataComponentTypes.ATTRIBUTE_MODIFIERS] = stack.itemInStaff.staffHandlerOrFallback.attributeModifiers } override fun getMaxUseTime(stack: ItemStack, user: LivingEntity): Int { - return stack.itemInStaff.staffHandlerOrDefault.getMaxUseTime(stack, user.entityWorld, user) + return stack.itemInStaff.staffHandlerOrFallback.getMaxUseTime(stack, user.entityWorld, user) } override fun use(world: World, user: PlayerEntity, hand: Hand): TypedActionResult { val staffStack = user.getStackInHand(hand) - return staffStack.itemInStaff.staffHandlerOrDefault.use(staffStack, world, user, hand) + return staffStack.itemInStaff.staffHandlerOrFallback.use(staffStack, world, user, hand) } override fun usageTick(world: World, user: LivingEntity, stack: ItemStack, remainingUseTicks: Int) { - stack.itemInStaff.staffHandlerOrDefault.usageTick(stack, world, user, remainingUseTicks) + stack.itemInStaff.staffHandlerOrFallback.usageTick(stack, world, user, remainingUseTicks) } override fun onStoppedUsing(stack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - stack.itemInStaff.staffHandlerOrDefault.onStoppedUsing(stack, world, user, remainingUseTicks) + stack.itemInStaff.staffHandlerOrFallback.onStoppedUsing(stack, world, user, remainingUseTicks) } override fun finishUsing(stack: ItemStack, world: World, user: LivingEntity): ItemStack { - return stack.itemInStaff.staffHandlerOrDefault.finishUsing(stack, world, user) + return stack.itemInStaff.staffHandlerOrFallback.finishUsing(stack, world, user) } override fun useOnBlock(context: ItemUsageContext): ActionResult { - return context.stack.itemInStaff.staffHandlerOrDefault.useOnBlock( + return context.stack.itemInStaff.staffHandlerOrFallback.useOnBlock( context.stack, context.world, context.player ?: return ActionResult.PASS, @@ -91,40 +91,40 @@ abstract class StaffItem(settings: Settings, private val repairIngredientSupplie } override fun useOnEntity(stack: ItemStack, user: PlayerEntity, entity: LivingEntity, hand: Hand): ActionResult { - return stack.itemInStaff.staffHandlerOrDefault.useOnEntity(stack, user.world, user, entity, hand) + return stack.itemInStaff.staffHandlerOrFallback.useOnEntity(stack, user.world, user, entity, hand) } /** * @see StaffHandler.attack */ open fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand) = - staffStack.itemInStaff.staffHandlerOrDefault.attack(staffStack, world, attacker, hand) + staffStack.itemInStaff.staffHandlerOrFallback.attack(staffStack, world, attacker, hand) /** * @see StaffHandler.attackBlock */ open fun attackBlock( staffStack: ItemStack, world: World, attacker: LivingEntity, target: BlockPos, side: Direction, hand: Hand - ) = staffStack.itemInStaff.staffHandlerOrDefault.attackBlock(staffStack, world, attacker, target, side, hand) + ) = staffStack.itemInStaff.staffHandlerOrFallback.attackBlock(staffStack, world, attacker, target, side, hand) /** * @see StaffHandler.attackEntity */ open fun attackEntity( staffStack: ItemStack, world: World, attacker: LivingEntity, target: Entity, hand: Hand - ) = staffStack.itemInStaff.staffHandlerOrDefault.attackEntity(staffStack, world, attacker, target, hand) + ) = staffStack.itemInStaff.staffHandlerOrFallback.attackEntity(staffStack, world, attacker, target, hand) /** * @see StaffHandler.canSwingHand */ open fun canSwingHand(staffStack: ItemStack, world: World, holder: LivingEntity, hand: Hand) = - staffStack.itemInStaff.staffHandlerOrDefault.canSwingHand(staffStack, world, holder, hand) + staffStack.itemInStaff.staffHandlerOrFallback.canSwingHand(staffStack, world, holder, hand) /** * @see StaffHandler.disablesShield */ open fun disablesShield(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand) = - staffStack.itemInStaff.staffHandlerOrDefault.disablesShield(staffStack, world, attacker, hand) + staffStack.itemInStaff.staffHandlerOrFallback.disablesShield(staffStack, world, attacker, hand) override fun getName(stack: ItemStack): Text { val staffItem = stack.itemStackInStaff ?: return super.getName(stack) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt index 6433a4531..8cb37d7ce 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt @@ -20,23 +20,28 @@ package opekope2.avm_staff.api.staff import dev.architectury.event.EventResult import net.minecraft.advancement.criterion.Criteria +import net.minecraft.block.BlockState import net.minecraft.component.type.AttributeModifiersComponent import net.minecraft.entity.Entity import net.minecraft.entity.LivingEntity import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.BlockItem import net.minecraft.item.Item import net.minecraft.item.ItemStack import net.minecraft.registry.Registries import net.minecraft.stat.Stats -import net.minecraft.util.ActionResult -import net.minecraft.util.Hand -import net.minecraft.util.Identifier -import net.minecraft.util.TypedActionResult +import net.minecraft.util.* import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction import net.minecraft.world.World import net.minecraft.world.event.GameEvent +import opekope2.avm_staff.api.block.IClearableBeforeInsertedIntoStaff +import opekope2.avm_staff.api.component.BlockPickupData import opekope2.avm_staff.api.registry.RegistryBase +import opekope2.avm_staff.content.ComponentTypes +import opekope2.avm_staff.util.approximateStaffItemPosition +import opekope2.avm_staff.util.mutableItemStackInStaff +import kotlin.math.roundToInt /** * Provides functionality for a staff, when an item is inserted into it. @@ -46,7 +51,7 @@ abstract class StaffHandler { * Gets the attribute modifiers (damage, attack speed, etc.) of the staff when held. */ open val attributeModifiers: AttributeModifiersComponent - get() = Default.ATTRIBUTE_MODIFIERS + get() = Fallback.ATTRIBUTE_MODIFIERS /** * Called on both the client and the server my Minecraft to get the number of ticks the staff can be used for using @@ -312,13 +317,108 @@ abstract class StaffHandler { ) = oldStaffStack != newStaffStack /** - * Handler of a staff with no item inserted into it. + * Default implementation of [StaffHandler]. Used for staffs with no [registered][Registry.register] handler. */ - object Default : StaffHandler() { + object Fallback : StaffHandler() { @JvmField val ATTRIBUTE_MODIFIERS = StaffAttributeModifiersComponentBuilder.default() } + /** + * Handler of a staff with no item inserted into it. + */ + object Empty : StaffHandler() { + private inline val LivingEntity.targetPos: BlockPos + get() = BlockPos.ofFloored(approximateStaffItemPosition) + + override fun getMaxUseTime(staffStack: ItemStack, world: World, user: LivingEntity): Int { + val targetPos = user.targetPos + val state = world.getBlockState(targetPos) + return if (!canPickUp(world, targetPos, state)) 0 + else 20 + (state.getHardness(world, targetPos) / 2).roundToInt() + } + + override fun use( + staffStack: ItemStack, + world: World, + user: PlayerEntity, + hand: Hand + ): TypedActionResult { + val targetPos = user.targetPos + val state = world.getBlockState(targetPos) + if (!canPickUp(world, targetPos, state)) return TypedActionResult.fail(staffStack) + + staffStack[ComponentTypes.blockPickupData] = BlockPickupData(targetPos, state) + + user.setCurrentHand(hand) + return TypedActionResult.consume(staffStack) + } + + private fun canPickUp(world: World, pos: BlockPos, state: BlockState) = !state.isAir && + state.getHardness(world, pos) != -1f && + state.block.asItem() in Registry + + private fun userChangedTarget(world: World, user: LivingEntity, blockPickupData: BlockPickupData?): Boolean { + val targetPos = user.targetPos + val state = world.getBlockState(targetPos) + return blockPickupData == null || blockPickupData.pos != targetPos || blockPickupData.state != state + } + + override fun usageTick(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { + if (!world.isClient && userChangedTarget(world, user, staffStack[ComponentTypes.blockPickupData])) { + user.stopUsingItem() + } + } + + override fun onStoppedUsing(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { + staffStack.remove(ComponentTypes.blockPickupData) + } + + override fun finishUsing(staffStack: ItemStack, world: World, user: LivingEntity): ItemStack { + val blockPickupData = staffStack[ComponentTypes.blockPickupData] + if (!userChangedTarget(world, user, blockPickupData)) { + require(blockPickupData != null) + tryPickUp(world, blockPickupData.pos, blockPickupData.state, staffStack) + (user as? PlayerEntity)?.resetLastAttackedTicks() + } + + onStoppedUsing(staffStack, world, user, 0) + return staffStack + } + + private fun tryPickUp(world: World, pos: BlockPos, state: BlockState, staffStack: ItemStack): Boolean { + if (!canPickUp(world, pos, state)) return false + + val pickStack = state.block.getPickStack(world, pos, state) + world.getBlockEntity(pos)?.apply { + val nbt = createComponentlessNbtWithIdentifyingData(world.registryManager) + removeFromCopiedStackNbt(nbt) + BlockItem.setBlockEntityData(pickStack, type, nbt) + pickStack.applyComponentsFrom(createComponentMap()) + (this as? Clearable)?.clear() + (this as? IClearableBeforeInsertedIntoStaff)?.staffMod_clearBeforeRemovedFromWorld() + } + + staffStack.mutableItemStackInStaff = pickStack + world.removeBlock(pos, false) + + return true + } + + override fun allowComponentsUpdateAnimation( + oldStaffStack: ItemStack, + newStaffStack: ItemStack, + player: PlayerEntity, + hand: Hand + ) = false + + override fun allowReequipAnimation( + oldStaffStack: ItemStack, + newStaffStack: ItemStack, + selectedSlotChanged: Boolean + ) = selectedSlotChanged + } + companion object Registry : RegistryBase() { private inline val Item.registryId: Identifier get() = Registries.ITEM.getId(this) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt index 39e935dca..c4f1b645d 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt @@ -21,6 +21,7 @@ package opekope2.avm_staff.content import net.minecraft.component.ComponentType import net.minecraft.network.codec.PacketCodec import net.minecraft.registry.RegistryKeys +import opekope2.avm_staff.api.component.BlockPickupData import opekope2.avm_staff.api.component.StaffFurnaceDataComponent import opekope2.avm_staff.api.component.StaffItemComponent import opekope2.avm_staff.api.component.StaffRendererPartComponent @@ -101,4 +102,20 @@ object ComponentTypes : RegistryUtil>(MOD_ID, RegistryKeys.DATA val staffRendererPart: ComponentType @JvmName("staffRendererPart") get() = STAFF_RENDERER_PART.get() + + /** + * Data component registered as `avm_staff:block_pickup_data`. + */ + @JvmField + val BLOCK_PICKUP_DATA = register("block_pickup_data") { + ComponentType.builder() + .packetCodec(BlockPickupData.PACKET_CODEC) + .build() + } + + /** + * @see BLOCK_PICKUP_DATA + */ + val blockPickupData: ComponentType + get() = BLOCK_PICKUP_DATA.get() } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt index 96075f93c..76bf6499a 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt @@ -92,7 +92,7 @@ object Items : RegistryUtil(MOD_ID, RegistryKeys.ITEM) { @JvmField val ROYAL_STAFF = register("royal_staff") { IStaffModPlatform.staffItem( - settings().maxCount(1).rarity(Rarity.EPIC).attributeModifiers(StaffHandler.Default.ATTRIBUTE_MODIFIERS) + settings().maxCount(1).rarity(Rarity.EPIC).attributeModifiers(StaffHandler.Fallback.ATTRIBUTE_MODIFIERS) .maxDamage(5179).`arch$tab`(ItemGroups.AVM_STAFF_MOD_ITEMS), ROYAL_STAFF_INGREDIENT ) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt index f1d4c7a2e..f4b575532 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt @@ -83,15 +83,18 @@ val Item.hasStaffHandler: Boolean /** * Returns the registered staff handler of the given item if available. */ -val Item.staffHandler: StaffHandler? - get() = if (!hasStaffHandler) null - else StaffHandler.Registry[this] +val Item?.staffHandler: StaffHandler? + get() = when { + this == null -> StaffHandler.Empty + !hasStaffHandler -> null + else -> StaffHandler.Registry[this] + } /** - * Returns the registered staff handler of the given item if available, [StaffHandler.Default] otherwise. + * Returns the registered staff handler of the given item if available, [StaffHandler.Fallback] otherwise. */ -val Item?.staffHandlerOrDefault: StaffHandler - get() = this?.staffHandler ?: StaffHandler.Default +val Item?.staffHandlerOrFallback: StaffHandler + get() = staffHandler ?: StaffHandler.Fallback private const val STAFF_MODEL_LENGTH = 40.0 / 16.0 private const val STAFF_MODEL_ITEM_POSITION_CENTER = 33.5 / 16.0 diff --git a/StaffMod/src/main/resources/avm_staff.mixins.json b/StaffMod/src/main/resources/avm_staff.mixins.json index 1f2c6a948..6672c255c 100644 --- a/StaffMod/src/main/resources/avm_staff.mixins.json +++ b/StaffMod/src/main/resources/avm_staff.mixins.json @@ -13,6 +13,7 @@ "IParticleMixin" ], "mixins": [ + "AbstractFurnaceBlockEntityMixin", "BeehiveBlockMixin", "IAbstractFurnaceBlockEntityAccessor", "IAnvilBlockAccessor", From c4bbd3a9278ab706e3d51b685586b1cc521d9d63 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 17 Nov 2024 23:19:10 +0100 Subject: [PATCH 32/83] Refactor some item components --- ...kupData.kt => BlockPickupDataComponent.kt} | 9 +++++--- .../component/StaffFurnaceDataComponent.kt | 17 ++++----------- .../avm_staff/api/staff/StaffHandler.kt | 10 ++++++--- .../avm_staff/content/ComponentTypes.kt | 14 +++++++------ .../opekope2/avm_staff/internal/Aliases.kt | 3 +++ .../internal/staff/handler/CampfireHandler.kt | 4 ++-- .../internal/staff/handler/FurnaceHandler.kt | 21 +++++++++++++++---- 7 files changed, 47 insertions(+), 31 deletions(-) rename StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/{BlockPickupData.kt => BlockPickupDataComponent.kt} (76%) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/BlockPickupData.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/BlockPickupDataComponent.kt similarity index 76% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/BlockPickupData.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/BlockPickupDataComponent.kt index ff7acdf55..524e8be47 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/BlockPickupData.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/BlockPickupDataComponent.kt @@ -30,10 +30,13 @@ import net.minecraft.util.math.BlockPos * @param pos The position of the block to be picked up from. Only available server-side * @param state The block state to be picked up. Only available server-side */ -data class BlockPickupData(val pos: BlockPos, val state: BlockState) { +data class BlockPickupDataComponent(val pos: BlockPos, val state: BlockState) { companion object { + /** + * [PacketCodec] for [BlockPickupDataComponent], which doesn't sync its data. + */ @JvmField - val PACKET_CODEC: PacketCodec = - PacketCodec.of({ _, _ -> }, { BlockPickupData(BlockPos.ORIGIN, Blocks.AIR.defaultState) }) + val NON_SYNCING_PACKET_CODEC: PacketCodec = + PacketCodec.of({ _, _ -> }, { BlockPickupDataComponent(BlockPos.ORIGIN, Blocks.AIR.defaultState) }) } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/StaffFurnaceDataComponent.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/StaffFurnaceDataComponent.kt index 47dd2b5a8..c39c5872a 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/StaffFurnaceDataComponent.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/StaffFurnaceDataComponent.kt @@ -24,24 +24,15 @@ import net.minecraft.network.codec.PacketCodec /** * Data components to store the state of a furnace staff. * - * @param serverBurnTicks The ticks the furnace has been on for minus the items smelted. This data is not synced to - * the client + * @param burnTicks The ticks the furnace has been on for minus the items smelted. Only available server-side */ -class StaffFurnaceDataComponent(var serverBurnTicks: Int) { - override fun equals(other: Any?) = when { - this === other -> true - javaClass != other?.javaClass -> false - else -> true - } - - override fun hashCode() = javaClass.hashCode() - +data class StaffFurnaceDataComponent(var burnTicks: Int) { companion object { /** - * [PacketCodec] for [StaffFurnaceDataComponent], which doesn't sync [serverBurnTicks]. + * [PacketCodec] for [StaffFurnaceDataComponent], which doesn't sync its data. */ @JvmField - val PACKET_CODEC: PacketCodec = + val NON_SYNCING_PACKET_CODEC: PacketCodec = PacketCodec.of({ _, _ -> }, { StaffFurnaceDataComponent(0) }) } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt index 8cb37d7ce..603bff7b2 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt @@ -36,7 +36,7 @@ import net.minecraft.util.math.Direction import net.minecraft.world.World import net.minecraft.world.event.GameEvent import opekope2.avm_staff.api.block.IClearableBeforeInsertedIntoStaff -import opekope2.avm_staff.api.component.BlockPickupData +import opekope2.avm_staff.api.component.BlockPickupDataComponent import opekope2.avm_staff.api.registry.RegistryBase import opekope2.avm_staff.content.ComponentTypes import opekope2.avm_staff.util.approximateStaffItemPosition @@ -348,7 +348,7 @@ abstract class StaffHandler { val state = world.getBlockState(targetPos) if (!canPickUp(world, targetPos, state)) return TypedActionResult.fail(staffStack) - staffStack[ComponentTypes.blockPickupData] = BlockPickupData(targetPos, state) + staffStack[ComponentTypes.blockPickupData] = BlockPickupDataComponent(targetPos, state) user.setCurrentHand(hand) return TypedActionResult.consume(staffStack) @@ -358,7 +358,11 @@ abstract class StaffHandler { state.getHardness(world, pos) != -1f && state.block.asItem() in Registry - private fun userChangedTarget(world: World, user: LivingEntity, blockPickupData: BlockPickupData?): Boolean { + private fun userChangedTarget( + world: World, + user: LivingEntity, + blockPickupData: BlockPickupDataComponent? + ): Boolean { val targetPos = user.targetPos val state = world.getBlockState(targetPos) return blockPickupData == null || blockPickupData.pos != targetPos || blockPickupData.state != state diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt index c4f1b645d..92ddfe5b9 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt @@ -21,11 +21,12 @@ package opekope2.avm_staff.content import net.minecraft.component.ComponentType import net.minecraft.network.codec.PacketCodec import net.minecraft.registry.RegistryKeys -import opekope2.avm_staff.api.component.BlockPickupData +import opekope2.avm_staff.api.component.BlockPickupDataComponent import opekope2.avm_staff.api.component.StaffFurnaceDataComponent import opekope2.avm_staff.api.component.StaffItemComponent import opekope2.avm_staff.api.component.StaffRendererPartComponent import opekope2.avm_staff.internal.MinecraftUnit +import opekope2.avm_staff.internal.minecraftUnit import opekope2.avm_staff.util.MOD_ID import opekope2.avm_staff.util.RegistryUtil @@ -58,7 +59,7 @@ object ComponentTypes : RegistryUtil>(MOD_ID, RegistryKeys.DATA val ROCKET_MODE = register("rocket_mode") { ComponentType.builder() .codec(MinecraftUnit.CODEC) - .packetCodec(PacketCodec.unit(MinecraftUnit.INSTANCE)) + .packetCodec(PacketCodec.unit(minecraftUnit)) .build() } @@ -75,7 +76,7 @@ object ComponentTypes : RegistryUtil>(MOD_ID, RegistryKeys.DATA @JvmField val FURNACE_DATA = register("furnace_data") { ComponentType.builder() - .packetCodec(StaffFurnaceDataComponent.PACKET_CODEC) + .packetCodec(StaffFurnaceDataComponent.NON_SYNCING_PACKET_CODEC) .build() } @@ -108,14 +109,15 @@ object ComponentTypes : RegistryUtil>(MOD_ID, RegistryKeys.DATA */ @JvmField val BLOCK_PICKUP_DATA = register("block_pickup_data") { - ComponentType.builder() - .packetCodec(BlockPickupData.PACKET_CODEC) + ComponentType.builder() + .packetCodec(BlockPickupDataComponent.NON_SYNCING_PACKET_CODEC) .build() } /** * @see BLOCK_PICKUP_DATA */ - val blockPickupData: ComponentType + val blockPickupData: ComponentType + @JvmName("blockPickupData") get() = BLOCK_PICKUP_DATA.get() } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Aliases.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Aliases.kt index c6afad535..9af6214ee 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Aliases.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Aliases.kt @@ -19,3 +19,6 @@ package opekope2.avm_staff.internal internal typealias MinecraftUnit = net.minecraft.util.Unit + +internal val minecraftUnit: MinecraftUnit + get() = MinecraftUnit.INSTANCE diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt index 79455d001..d0a552fe7 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt @@ -32,7 +32,7 @@ import net.minecraft.world.World import opekope2.avm_staff.api.entity.CampfireFlameEntity import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.content.ComponentTypes -import opekope2.avm_staff.internal.MinecraftUnit +import opekope2.avm_staff.internal.minecraftUnit import opekope2.avm_staff.util.approximateStaffTipPosition import opekope2.avm_staff.util.canUseStaff import opekope2.avm_staff.util.times @@ -47,7 +47,7 @@ internal class CampfireHandler(private val parameters: Parameters) : StaffHandle hand: Hand ): TypedActionResult { if (user.isSneaking && !user.isOnGround) { - staffStack[ComponentTypes.rocketMode] = MinecraftUnit.INSTANCE + staffStack[ComponentTypes.rocketMode] = minecraftUnit } user.setCurrentHand(hand) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt index 736767524..454d96ea9 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt @@ -69,7 +69,7 @@ internal class FurnaceHandler( staffStack[ComponentTypes.furnaceData] = StaffFurnaceDataComponent(0) user.setCurrentHand(hand) - return TypedActionResult.consume(staffStack) + return TypedActionResult.pass(staffStack) } override fun usageTick(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { @@ -84,10 +84,10 @@ internal class FurnaceHandler( } val furnaceData = staffStack[ComponentTypes.furnaceData]!! - furnaceData.serverBurnTicks++ + furnaceData.burnTicks++ val stackToSmelt = itemToSmelt?.stack ?: return - if (furnaceData.serverBurnTicks < stackToSmelt.count) return + if (furnaceData.burnTicks < stackToSmelt.count) return val recipeInput = SingleStackRecipeInput(itemToSmelt.stack) val recipe = world.recipeManager.getFirstMatch(recipeType, recipeInput, world).getOrNull()?.value ?: return @@ -100,7 +100,7 @@ internal class FurnaceHandler( ) itemToSmelt.discard() - furnaceData.serverBurnTicks -= stackToSmelt.count + furnaceData.burnTicks -= stackToSmelt.count } private fun findItemToSmelt(world: World, smeltingPosition: Vec3d): ItemEntity? { @@ -133,6 +133,19 @@ internal class FurnaceHandler( return staffStack } + override fun allowComponentsUpdateAnimation( + oldStaffStack: ItemStack, + newStaffStack: ItemStack, + player: PlayerEntity, + hand: Hand + ) = false + + override fun allowReequipAnimation( + oldStaffStack: ItemStack, + newStaffStack: ItemStack, + selectedSlotChanged: Boolean + ) = selectedSlotChanged + private companion object { private val ITEM_DIMENSIONS = EntityType.ITEM.dimensions private val SMELTING_VOLUME = Box(-0.5, -0.5, -0.5, 0.5, 0.5, 0.5).contract( From 973b473eb43e05f665e1ddb6caab1642856f16c5 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 18 Nov 2024 00:36:21 +0100 Subject: [PATCH 33/83] Validate StaffItemComponent --- .../avm_staff/api/component/StaffItemComponent.kt | 15 ++++++++++++++- .../opekope2/avm_staff/content/ComponentTypes.kt | 2 +- .../staff/handler/VanillaStaffHandlers.kt | 2 +- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/StaffItemComponent.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/StaffItemComponent.kt index 10f185db0..f24261e2c 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/StaffItemComponent.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/StaffItemComponent.kt @@ -19,11 +19,13 @@ package opekope2.avm_staff.api.component import com.mojang.serialization.Codec +import com.mojang.serialization.DataResult import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.component.ComponentType import net.minecraft.item.ItemStack import net.minecraft.network.RegistryByteBuf import net.minecraft.network.codec.PacketCodec +import opekope2.avm_staff.api.staff.StaffHandler /** * [ItemStack] wrapper to make them compatible with [ComponentType]s. @@ -43,6 +45,11 @@ class StaffItemComponent(val item: ItemStack) { return ItemStack.hashCode(item) } + private fun validate(): DataResult { + return if (item.item in StaffHandler.Registry) DataResult.success(this) + else DataResult.error { "There is no staff handler registered for item ${item.item}" } + } + companion object { /** * [Codec] for [StaffItemComponent]. @@ -50,10 +57,16 @@ class StaffItemComponent(val item: ItemStack) { @JvmField val CODEC: Codec = RecordCodecBuilder.create { instance -> instance.group( - ItemStack.CODEC.fieldOf("item").forGetter(StaffItemComponent::item) + ItemStack.VALIDATED_CODEC.fieldOf("item").forGetter(StaffItemComponent::item) ).apply(instance, ::StaffItemComponent) } + /** + * Validated [Codec] for [StaffItemComponent]. This only allows [item]s registered in [StaffHandler.Registry]. + */ + @JvmField + val VALIDATED_CODEC: Codec = CODEC.validate(StaffItemComponent::validate) + /** * [PacketCodec] for [StaffItemComponent]. */ diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt index 92ddfe5b9..985121b09 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt @@ -40,7 +40,7 @@ object ComponentTypes : RegistryUtil>(MOD_ID, RegistryKeys.DATA @JvmField val STAFF_ITEM = register("staff_item") { ComponentType.builder() - .codec(StaffItemComponent.CODEC) + .codec(StaffItemComponent.VALIDATED_CODEC) .packetCodec(StaffItemComponent.PACKET_CODEC) .build() } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt index c92fae8fc..c5a763f77 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt @@ -58,7 +58,7 @@ fun registerVanillaStaffHandlers() { ) ) - // TODO command block + StaffHandler.register(COMMAND_BLOCK, StaffHandler.Fallback) // TODO StaffHandler.register(DIAMOND_BLOCK, DiamondBlockHandler()) From 5827fd704c996c5ed4514e277e880affb1c0b584 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 23 Nov 2024 00:13:06 +0100 Subject: [PATCH 34/83] Rename criteria avm_staff:break_block_with_staff to avm_staff:destroy_block_with_staff --- .../opekope2/avm_staff/api/staff/StaffHandler.kt | 2 +- .../kotlin/opekope2/avm_staff/content/Criteria.kt | 12 ++++++------ .../data/avm_staff/advancement/bulldozer.json | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt index 603bff7b2..ce0236a32 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt @@ -241,7 +241,7 @@ abstract class StaffHandler { * @param target The block the [attacker] attacked * @param side The side of the [block][target], which was attacked * @param hand The hand of the [attacker], in which the [staff][staffStack] is - * @see opekope2.avm_staff.content.Criteria.breakBlockWithStaff + * @see opekope2.avm_staff.content.Criteria.destroyBlockWithStaff */ open fun attackBlock( staffStack: ItemStack, world: World, attacker: LivingEntity, target: BlockPos, side: Direction, hand: Hand diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Criteria.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Criteria.kt index f54ddfbc1..b3135aafd 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Criteria.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Criteria.kt @@ -45,17 +45,17 @@ object Criteria : RegistryUtil>(MOD_ID, RegistryKeys.CRITERION) { get() = TAKE_DAMAGE_WHILE_USING_ITEM.get() /** - * Criterion registered as `avm_staff:break_block_with_staff`. Triggers before a block is broken by a staff. + * Criterion registered as `avm_staff:destroy_block_with_staff`. Triggers before a block is destroyed by a staff. */ @JvmField - val BREAK_BLOCK_WITH_STAFF = register("break_block_with_staff") { + val DESTROY_BLOCK_WITH_STAFF = register("destroy_block_with_staff") { BreakBlockWithStaffCriterion() } /** - * @see BREAK_BLOCK_WITH_STAFF + * @see DESTROY_BLOCK_WITH_STAFF */ - val breakBlockWithStaff: BreakBlockWithStaffCriterion - @JvmName("breakBlockWithStaff") - get() = BREAK_BLOCK_WITH_STAFF.get() + val destroyBlockWithStaff: BreakBlockWithStaffCriterion + @JvmName("destroyBlockWithStaff") + get() = DESTROY_BLOCK_WITH_STAFF.get() } diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/bulldozer.json b/StaffMod/src/main/resources/data/avm_staff/advancement/bulldozer.json index 65ecb0dd0..fe5da97b5 100644 --- a/StaffMod/src/main/resources/data/avm_staff/advancement/bulldozer.json +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/bulldozer.json @@ -20,7 +20,7 @@ }, "criteria": { "use_diamond_block_staff": { - "trigger": "avm_staff:break_block_with_staff", + "trigger": "avm_staff:destroy_block_with_staff", "conditions": { "player": { "equipment": { @@ -39,7 +39,7 @@ } }, "use_netherite_block_staff": { - "trigger": "avm_staff:break_block_with_staff", + "trigger": "avm_staff:destroy_block_with_staff", "conditions": { "player": { "equipment": { From 25d1d32379915821a18384a2536eac8afa879ada Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 23 Nov 2024 00:15:46 +0100 Subject: [PATCH 35/83] Add stat avm_staff:used_item_in_staff --- .../opekope2/avm_staff/content/StatTypes.kt | 47 +++++++++++++++++++ .../internal/initializer/Initializer.kt | 1 + .../assets/avm_staff/lang/en_us.json | 1 + 3 files changed, 49 insertions(+) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/content/StatTypes.kt diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/StatTypes.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/StatTypes.kt new file mode 100644 index 000000000..7c73dad37 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/StatTypes.kt @@ -0,0 +1,47 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.content + +import net.minecraft.item.Item +import net.minecraft.registry.Registries +import net.minecraft.registry.RegistryKeys +import net.minecraft.stat.StatType +import net.minecraft.text.Text +import opekope2.avm_staff.util.MOD_ID +import opekope2.avm_staff.util.RegistryUtil + +/** + * Stats added by AVM Staffs mod. + */ +object StatTypes : RegistryUtil>(MOD_ID, RegistryKeys.STAT_TYPE) { + /** + * Stat type registered as `avm_staff:used_item_in_staff` + */ + @JvmField + val USED_ITEM_IN_STAFF = register("used_item_in_staff") { key -> + StatType(Registries.ITEM, Text.translatable("stat_type.${key.value.namespace}.${key.value.path}")) + } + + /** + * @see USED_ITEM_IN_STAFF + */ + val usedItemInStaff: StatType + @JvmName("usedItemInStaff") + get() = USED_ITEM_IN_STAFF.get() +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt index 2bb7801f1..60c5d4a13 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt @@ -39,6 +39,7 @@ object Initializer { Items.register() ParticleTypes.register() SoundEvents.register() + StatTypes.register() } private fun initializeNetworking() { diff --git a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json index e882c03a8..0b73cfa35 100644 --- a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json +++ b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json @@ -1,4 +1,5 @@ { + "stat_type.avm_staff.used_item_in_staff": "Used in Staff", "advancements.avm_staff.bazeboze.description": "Hit a %s using a %s", "advancements.avm_staff.bazeboze.title": "Bazeboze", "advancements.avm_staff.bulldozer.description": "Cause mass destruction using a staff", From 4a62254918843a3c019ce0f0214f341b7fb99dd6 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 23 Nov 2024 00:16:31 +0100 Subject: [PATCH 36/83] Fix piglins not picking up crown --- .../data/minecraft/tags/{items => item}/piglin_loved.json | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename StaffMod/src/main/resources/data/minecraft/tags/{items => item}/piglin_loved.json (100%) diff --git a/StaffMod/src/main/resources/data/minecraft/tags/items/piglin_loved.json b/StaffMod/src/main/resources/data/minecraft/tags/item/piglin_loved.json similarity index 100% rename from StaffMod/src/main/resources/data/minecraft/tags/items/piglin_loved.json rename to StaffMod/src/main/resources/data/minecraft/tags/item/piglin_loved.json From d246dd9a063906582bfc3aedff2e138b636f4c89 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 23 Nov 2024 00:23:02 +0100 Subject: [PATCH 37/83] Add utilities --- .../opekope2/avm_staff/util/ItemStackUtil.kt | 9 +++++ .../opekope2/avm_staff/util/StatUtil.kt | 40 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/util/StatUtil.kt diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/ItemStackUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/ItemStackUtil.kt index 67b883367..1d3ac5288 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/ItemStackUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/ItemStackUtil.kt @@ -20,7 +20,9 @@ package opekope2.avm_staff.util +import net.minecraft.entity.LivingEntity import net.minecraft.item.ItemStack +import net.minecraft.util.Hand import opekope2.avm_staff.api.item.StaffItem /** @@ -28,3 +30,10 @@ import opekope2.avm_staff.api.item.StaffItem */ inline val ItemStack.isStaff get() = item is StaffItem + +/** + * @see ItemStack.damage + */ +fun ItemStack.damage(amount: Int = 1, entity: LivingEntity, hand: Hand = entity.activeHand) { + damage(amount, entity, LivingEntity.getSlotForHand(hand)) +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StatUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StatUtil.kt new file mode 100644 index 000000000..c24a3e3d2 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StatUtil.kt @@ -0,0 +1,40 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +@file: JvmName("StatUtil") + +package opekope2.avm_staff.util + +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.Item +import net.minecraft.stat.Stats +import opekope2.avm_staff.content.StatTypes + +/** + * Increments [Stats.USED] of [item] by 1. + */ +fun PlayerEntity.incrementItemUseStat(item: Item) { + incrementStat(Stats.USED.getOrCreateStat(item)) +} + +/** + * Increments [StatTypes.usedItemInStaff] of [item] by 1. + */ +fun PlayerEntity.incrementStaffItemUseStat(item: Item) { + incrementStat(StatTypes.usedItemInStaff.getOrCreateStat(item)) +} From ba27390f04d3146957de7e060b39e2caa61bd209 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 23 Nov 2024 00:32:02 +0100 Subject: [PATCH 38/83] Extract common code of destructive staffs Damage staff Increment stats --- .../AbstractMassDestructiveStaffHandler.kt | 91 +++++++++++++++++++ .../staff/handler/DiamondBlockHandler.kt | 54 ++--------- .../staff/handler/GoldBlockHandler.kt | 49 +++------- .../staff/handler/NetheriteBlockHandler.kt | 50 +++------- .../util/destruction/DestructionUtil.kt | 2 +- .../DiamondBlockStaffShapePredicate.kt | 7 +- .../GoldBlockStaffShapePredicate.kt | 7 +- .../IShapedBlockDestructionPredicate.kt | 31 +++++++ .../NetheriteBlockStaffShapePredicate.kt | 7 +- 9 files changed, 162 insertions(+), 136 deletions(-) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractMassDestructiveStaffHandler.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/util/destruction/IShapedBlockDestructionPredicate.kt diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractMassDestructiveStaffHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractMassDestructiveStaffHandler.kt new file mode 100644 index 000000000..3f02f1162 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractMassDestructiveStaffHandler.kt @@ -0,0 +1,91 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.internal.staff.handler + +import dev.architectury.event.EventResult +import net.minecraft.entity.LivingEntity +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.ItemStack +import net.minecraft.server.world.ServerWorld +import net.minecraft.util.Hand +import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Direction +import net.minecraft.world.World +import opekope2.avm_staff.api.staff.StaffHandler +import opekope2.avm_staff.util.destruction.BlockDestructionPredicate +import opekope2.avm_staff.util.destruction.IShapedBlockDestructionPredicate +import opekope2.avm_staff.util.destruction.destroyBox +import opekope2.avm_staff.util.dropcollector.ChunkedBlockDropCollector +import opekope2.avm_staff.util.dropcollector.IBlockDropCollector +import opekope2.avm_staff.util.dropcollector.NoOpBlockDropCollector +import opekope2.avm_staff.util.incrementItemUseStat +import opekope2.avm_staff.util.incrementStaffItemUseStat +import opekope2.avm_staff.util.isAttackCoolingDown +import opekope2.avm_staff.util.itemInStaff + +internal abstract class AbstractMassDestructiveStaffHandler : StaffHandler() { + override fun attackBlock( + staffStack: ItemStack, + world: World, + attacker: LivingEntity, + target: BlockPos, + side: Direction, + hand: Hand + ): EventResult { + if (world.isClient) return EventResult.pass() + if (attacker is PlayerEntity && attacker.isAttackCoolingDown) return EventResult.pass() + require(world is ServerWorld) + + val shapePredicate = createBlockDestructionShapePredicate(world, attacker, target) + val dropCollector = + if (attacker is PlayerEntity && attacker.abilities.creativeMode) NoOpBlockDropCollector() + else createBlockDropCollector(shapePredicate) + + destroyBox( + world, + shapePredicate.volume, + dropCollector, + attacker, + staffStack, + createDestructionPredicate(shapePredicate) + ) + dropCollector.dropAll(world) + + (attacker as? PlayerEntity)?.incrementItemUseStat(staffStack.item) + (attacker as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + + // "Mismatch in destroy block pos" in server logs if I interrupt on server but not on client side. Nothing bad should happen, right? + return EventResult.pass() + } + + protected abstract fun createBlockDestructionShapePredicate( + world: World, + attacker: LivingEntity, + target: BlockPos + ): IShapedBlockDestructionPredicate + + protected abstract fun createDestructionPredicate(shapePredicate: IShapedBlockDestructionPredicate): BlockDestructionPredicate + + protected open fun createBlockDropCollector(shapePredicate: IShapedBlockDestructionPredicate): IBlockDropCollector = + ChunkedBlockDropCollector(shapePredicate.volume, MAX_CHUNK_SIZE) + + companion object { + const val MAX_CHUNK_SIZE = 3 + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/DiamondBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/DiamondBlockHandler.kt index 4adcbb254..9b086c0b0 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/DiamondBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/DiamondBlockHandler.kt @@ -18,33 +18,22 @@ package opekope2.avm_staff.internal.staff.handler -import dev.architectury.event.EventResult import net.minecraft.block.Blocks import net.minecraft.component.type.AttributeModifierSlot import net.minecraft.entity.LivingEntity import net.minecraft.entity.attribute.EntityAttributes -import net.minecraft.entity.player.PlayerEntity -import net.minecraft.item.ItemStack -import net.minecraft.server.network.ServerPlayerEntity -import net.minecraft.server.world.ServerWorld -import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.Direction import net.minecraft.world.World import opekope2.avm_staff.api.staff.StaffAttributeModifiersComponentBuilder -import opekope2.avm_staff.api.staff.StaffHandler -import opekope2.avm_staff.content.Criteria import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.attackSpeed import opekope2.avm_staff.util.cameraUp +import opekope2.avm_staff.util.destruction.BlockDestructionPredicate import opekope2.avm_staff.util.destruction.DiamondBlockStaffShapePredicate +import opekope2.avm_staff.util.destruction.IShapedBlockDestructionPredicate import opekope2.avm_staff.util.destruction.MaxHardnessPredicate -import opekope2.avm_staff.util.destruction.destroyBox -import opekope2.avm_staff.util.dropcollector.ChunkedBlockDropCollector -import opekope2.avm_staff.util.dropcollector.NoOpBlockDropCollector -import opekope2.avm_staff.util.isAttackCoolingDown -class DiamondBlockHandler : StaffHandler() { +internal class DiamondBlockHandler : AbstractMassDestructiveStaffHandler() { override val attributeModifiers = StaffAttributeModifiersComponentBuilder() .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(18.0), AttributeModifierSlot.MAINHAND) .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(1.0), AttributeModifierSlot.MAINHAND) @@ -52,43 +41,20 @@ class DiamondBlockHandler : StaffHandler() { .addDefault(EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE) .build() - override fun attackBlock( - staffStack: ItemStack, + override fun createBlockDestructionShapePredicate( world: World, attacker: LivingEntity, - target: BlockPos, - side: Direction, - hand: Hand - ): EventResult { - if (world.isClient) return EventResult.pass() - if (attacker is PlayerEntity && attacker.isAttackCoolingDown) return EventResult.pass() - require(world is ServerWorld) - + target: BlockPos + ): IShapedBlockDestructionPredicate { val forwardVector = attacker.facing.vector val upVector = attacker.cameraUp.vector - val shapePredicate = DiamondBlockStaffShapePredicate(target, forwardVector, upVector, world.random) - val dropCollector = - if (attacker is PlayerEntity && attacker.abilities.creativeMode) NoOpBlockDropCollector() - else ChunkedBlockDropCollector(shapePredicate.volume, MAX_CHUNK_SIZE) - - if (attacker is ServerPlayerEntity) Criteria.breakBlockWithStaff.trigger(attacker, world, target) - - destroyBox( - world, - shapePredicate.volume, - dropCollector, - attacker, - staffStack, - MAX_DIAMOND_HARDNESS.and(shapePredicate) - ) - dropCollector.dropAll(world) - - // "Mismatch in destroy block pos" in server logs if I interrupt on server but not on client side. Nothing bad should happen, right? - return EventResult.pass() + return DiamondBlockStaffShapePredicate(target, forwardVector, upVector, world.random) } + override fun createDestructionPredicate(shapePredicate: IShapedBlockDestructionPredicate): BlockDestructionPredicate = + MAX_DIAMOND_HARDNESS.and(shapePredicate) + private companion object { - private const val MAX_CHUNK_SIZE = 3 private val MAX_DIAMOND_HARDNESS = MaxHardnessPredicate(Blocks.DIAMOND_BLOCK) } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/GoldBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/GoldBlockHandler.kt index 4de70da40..64066e708 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/GoldBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/GoldBlockHandler.kt @@ -18,31 +18,23 @@ package opekope2.avm_staff.internal.staff.handler -import dev.architectury.event.EventResult import net.minecraft.block.Blocks import net.minecraft.component.type.AttributeModifierSlot import net.minecraft.entity.LivingEntity import net.minecraft.entity.attribute.EntityAttributes -import net.minecraft.entity.player.PlayerEntity -import net.minecraft.item.ItemStack -import net.minecraft.server.world.ServerWorld -import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.Direction import net.minecraft.world.World import opekope2.avm_staff.api.staff.StaffAttributeModifiersComponentBuilder -import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.attackSpeed import opekope2.avm_staff.util.cameraUp +import opekope2.avm_staff.util.destruction.BlockDestructionPredicate import opekope2.avm_staff.util.destruction.GoldBlockStaffShapePredicate +import opekope2.avm_staff.util.destruction.IShapedBlockDestructionPredicate import opekope2.avm_staff.util.destruction.MaxHardnessPredicate -import opekope2.avm_staff.util.destruction.destroyBox -import opekope2.avm_staff.util.dropcollector.NoOpBlockDropCollector import opekope2.avm_staff.util.dropcollector.VanillaBlockDropCollector -import opekope2.avm_staff.util.isAttackCoolingDown -class GoldBlockHandler : StaffHandler() { +internal class GoldBlockHandler : AbstractMassDestructiveStaffHandler() { override val attributeModifiers = StaffAttributeModifiersComponentBuilder() .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(14.0), AttributeModifierSlot.MAINHAND) .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(1.0), AttributeModifierSlot.MAINHAND) @@ -50,38 +42,21 @@ class GoldBlockHandler : StaffHandler() { .addDefault(EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE) .build() - override fun attackBlock( - staffStack: ItemStack, + override fun createBlockDestructionShapePredicate( world: World, attacker: LivingEntity, - target: BlockPos, - side: Direction, - hand: Hand - ): EventResult { - if (world.isClient) return EventResult.pass() - if (attacker is PlayerEntity && attacker.isAttackCoolingDown) return EventResult.pass() - require(world is ServerWorld) - + target: BlockPos + ): IShapedBlockDestructionPredicate { val forwardVector = attacker.facing.vector val upVector = attacker.cameraUp.vector - val shapePredicate = GoldBlockStaffShapePredicate(target, forwardVector, upVector) - val dropCollector = - if (attacker is PlayerEntity && attacker.abilities.creativeMode) NoOpBlockDropCollector() - else VanillaBlockDropCollector() + return GoldBlockStaffShapePredicate(target, forwardVector, upVector) + } - destroyBox( - world, - shapePredicate.volume, - dropCollector, - attacker, - staffStack, - MAX_OBSIDIAN_HARDNESS.and(shapePredicate) - ) - dropCollector.dropAll(world) + override fun createDestructionPredicate(shapePredicate: IShapedBlockDestructionPredicate): BlockDestructionPredicate = + MAX_OBSIDIAN_HARDNESS.and(shapePredicate) - // "Mismatch in destroy block pos" in server logs if I interrupt on server but not on client side. Nothing bad should happen, right? - return EventResult.pass() - } + override fun createBlockDropCollector(shapePredicate: IShapedBlockDestructionPredicate) = + VanillaBlockDropCollector() private companion object { private val MAX_OBSIDIAN_HARDNESS = MaxHardnessPredicate(Blocks.OBSIDIAN) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/NetheriteBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/NetheriteBlockHandler.kt index 8f7675154..3a327bc95 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/NetheriteBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/NetheriteBlockHandler.kt @@ -26,27 +26,20 @@ import net.minecraft.entity.LivingEntity import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.server.world.ServerWorld import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.Direction import net.minecraft.util.math.MathHelper import net.minecraft.util.math.Vec2f import net.minecraft.world.World import net.minecraft.world.WorldEvents import opekope2.avm_staff.api.staff.StaffAttributeModifiersComponentBuilder -import opekope2.avm_staff.api.staff.StaffHandler -import opekope2.avm_staff.content.Criteria import opekope2.avm_staff.util.* -import opekope2.avm_staff.util.destruction.InTruncatedPyramidPredicate -import opekope2.avm_staff.util.destruction.MaxHardnessPredicate -import opekope2.avm_staff.util.destruction.NetheriteBlockStaffShapePredicate -import opekope2.avm_staff.util.destruction.destroyBox +import opekope2.avm_staff.util.destruction.* import opekope2.avm_staff.util.dropcollector.ChunkedBlockDropCollector import opekope2.avm_staff.util.dropcollector.NoOpBlockDropCollector -class NetheriteBlockHandler : StaffHandler() { +internal class NetheriteBlockHandler : AbstractMassDestructiveStaffHandler() { override val attributeModifiers = StaffAttributeModifiersComponentBuilder() .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(20.0), AttributeModifierSlot.MAINHAND) .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(1.0), AttributeModifierSlot.MAINHAND) @@ -101,46 +94,25 @@ class NetheriteBlockHandler : StaffHandler() { world.syncWorldEvent(WorldEvents.SMASH_ATTACK, target.steppingPos, 750) + (attacker as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + return EventResult.pass() } - override fun attackBlock( - staffStack: ItemStack, + override fun createBlockDestructionShapePredicate( world: World, attacker: LivingEntity, - target: BlockPos, - side: Direction, - hand: Hand - ): EventResult { - if (world.isClient) return EventResult.pass() - if (attacker is PlayerEntity && attacker.isAttackCoolingDown) return EventResult.pass() - require(world is ServerWorld) - + target: BlockPos + ): IShapedBlockDestructionPredicate { val forwardVector = attacker.facing.vector val upVector = attacker.cameraUp.vector - val shapePredicate = NetheriteBlockStaffShapePredicate(target, forwardVector, upVector) - val dropCollector = - if (attacker is PlayerEntity && attacker.abilities.creativeMode) NoOpBlockDropCollector() - else ChunkedBlockDropCollector(shapePredicate.volume, MAX_CHUNK_SIZE) - - if (attacker is ServerPlayerEntity) Criteria.breakBlockWithStaff.trigger(attacker, world, target) - - destroyBox( - world, - shapePredicate.volume, - dropCollector, - attacker, - staffStack, - MAX_NETHERITE_HARDNESS.and(shapePredicate) - ) - dropCollector.dropAll(world) - - // "Mismatch in destroy block pos" in server logs if I interrupt on server but not on client side. Nothing bad should happen, right? - return EventResult.pass() + return NetheriteBlockStaffShapePredicate(target, forwardVector, upVector) } + override fun createDestructionPredicate(shapePredicate: IShapedBlockDestructionPredicate): BlockDestructionPredicate = + MAX_NETHERITE_HARDNESS.and(shapePredicate) + private companion object { - private const val MAX_CHUNK_SIZE = 3 private val MAX_NETHERITE_HARDNESS = MaxHardnessPredicate(Blocks.NETHERITE_BLOCK) } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/destruction/DestructionUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/destruction/DestructionUtil.kt index d8fd7ba76..25a2c77af 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/destruction/DestructionUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/destruction/DestructionUtil.kt @@ -141,7 +141,7 @@ private fun destroyBlock( world.emitGameEvent(GameEvent.BLOCK_DESTROY, pos, GameEvent.Emitter.of(destroyer, state)) } - tool.postMine(world, breakState, pos, destroyer) + tool.item.postMine(tool, world, breakState, pos, destroyer) if (!broke) return false diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/destruction/DiamondBlockStaffShapePredicate.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/destruction/DiamondBlockStaffShapePredicate.kt index bd0d1c33e..da0fe6c67 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/destruction/DiamondBlockStaffShapePredicate.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/destruction/DiamondBlockStaffShapePredicate.kt @@ -39,7 +39,7 @@ import kotlin.math.abs * @param rng Random number generator deciding the pattern of destruction */ class DiamondBlockStaffShapePredicate(origin: BlockPos, forwardVector: Vec3i, upVector: Vec3i, rng: Random) : - BlockDestructionPredicate { + IShapedBlockDestructionPredicate { private val rightVector: Vec3i = forwardVector.crossProduct(upVector) private val farBottomLeft = origin + forwardVector * 8 + upVector * -1 + rightVector * -4 @@ -48,10 +48,7 @@ class DiamondBlockStaffShapePredicate(origin: BlockPos, forwardVector: Vec3i, up private val nonDestroyablePositions: Set - /** - * The bounding volume of the destroyable blocks. - */ - val volume = encompassPositions(farBottomLeft, nearTopRight)!! + override val volume = encompassPositions(farBottomLeft, nearTopRight)!! init { nonDestroyablePositions = mutableSetOf() diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/destruction/GoldBlockStaffShapePredicate.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/destruction/GoldBlockStaffShapePredicate.kt index b22d92588..3094aece7 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/destruction/GoldBlockStaffShapePredicate.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/destruction/GoldBlockStaffShapePredicate.kt @@ -33,13 +33,10 @@ import opekope2.avm_staff.util.times * @param upVector Vector pointing "upward" relative to the block destroyer's POV */ class GoldBlockStaffShapePredicate(private val origin: BlockPos, forwardVector: Vec3i, upVector: Vec3i) : - BlockDestructionPredicate { + IShapedBlockDestructionPredicate { private val rightVector = forwardVector.crossProduct(upVector) - /** - * The bounding volume of the destroyable blocks. - */ - val volume = encompassPositions( + override val volume = encompassPositions( origin + forwardVector + upVector + rightVector * -1, origin + upVector * -1 + rightVector )!! diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/destruction/IShapedBlockDestructionPredicate.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/destruction/IShapedBlockDestructionPredicate.kt new file mode 100644 index 000000000..c9a66f791 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/destruction/IShapedBlockDestructionPredicate.kt @@ -0,0 +1,31 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.util.destruction + +import net.minecraft.util.math.BlockBox + +/** + * A [BlockDestructionPredicate], which can only break blocks in its [volume], this should be tested in [test]. + */ +interface IShapedBlockDestructionPredicate : BlockDestructionPredicate { + /** + * The bounding volume of the destroyable blocks. + */ + val volume: BlockBox +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/destruction/NetheriteBlockStaffShapePredicate.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/destruction/NetheriteBlockStaffShapePredicate.kt index e0e550572..b7c7caf55 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/destruction/NetheriteBlockStaffShapePredicate.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/destruction/NetheriteBlockStaffShapePredicate.kt @@ -33,17 +33,14 @@ import opekope2.avm_staff.util.times * @param upVector Vector pointing "upward" relative to the block destroyer's POV */ class NetheriteBlockStaffShapePredicate(origin: BlockPos, forwardVector: Vec3i, upVector: Vec3i) : - BlockDestructionPredicate { + IShapedBlockDestructionPredicate { private val rightVector = forwardVector.crossProduct(upVector) private val farBottomLeft = origin + forwardVector * 10 + upVector * -3 + rightVector * -6 private val furtherBottomLeft = origin + forwardVector * 11 + upVector * -3 + rightVector * -6 private val nearTopRight = origin + upVector * 9 + rightVector * 6 - /** - * The bounding volume of the destroyable blocks. - */ - val volume = encompassPositions(furtherBottomLeft, nearTopRight)!! + override val volume = encompassPositions(furtherBottomLeft, nearTopRight)!! override fun test(world: ServerWorld, pos: BlockPos): Boolean { if (pos !in volume) return false From 0e229e1cb936dedd2b238fe3d5051aac02900f6f Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 23 Nov 2024 00:34:22 +0100 Subject: [PATCH 39/83] Extract common code of projectile shooting staffs Damage staff Increment stats --- .../AbstractProjectileShootingStaffHandler.kt | 85 +++++++++++++++++++ .../internal/staff/handler/CakeHandler.kt | 48 ++++------- .../staff/handler/MagmaBlockHandler.kt | 50 ++++------- .../staff/handler/SnowBlockHandler.kt | 55 ++++-------- .../handler/WitherSkeletonSkullHandler.kt | 59 ++++++------- 5 files changed, 160 insertions(+), 137 deletions(-) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt new file mode 100644 index 000000000..291bd5ed6 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt @@ -0,0 +1,85 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.internal.staff.handler + +import net.minecraft.entity.LivingEntity +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.ItemStack +import net.minecraft.util.Hand +import net.minecraft.util.TypedActionResult +import net.minecraft.world.World +import opekope2.avm_staff.api.staff.StaffHandler +import opekope2.avm_staff.util.* + +internal abstract class AbstractProjectileShootingStaffHandler : StaffHandler() { + override fun getMaxUseTime(staffStack: ItemStack, world: World, user: LivingEntity) = 72000 + + override fun use( + staffStack: ItemStack, + world: World, + user: PlayerEntity, + hand: Hand + ): TypedActionResult { + user.setCurrentHand(hand) + return TypedActionResult.consume(staffStack) + } + + override fun usageTick(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { + if (tryShootProjectile(world, user, ProjectileShootReason.USE)) { + staffStack.damage(entity = user) + (user as? PlayerEntity)?.incrementItemUseStat(staffStack.item) + (user as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + } + } + + override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand) { + if (tryShootProjectile(world, attacker, ProjectileShootReason.ATTACK)) { + staffStack.damage(entity = attacker) + (attacker as? PlayerEntity)?.incrementItemUseStat(staffStack.item) + (attacker as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + } + (attacker as? PlayerEntity)?.resetLastAttackedTicks() + } + + protected open fun tryShootProjectile(world: World, shooter: LivingEntity, reason: ProjectileShootReason): Boolean { + if (world.isClient) return false + if (!shooter.canUseStaff) return false + if (shooter is PlayerEntity && shooter.isAttackCoolingDown) return false + + return true + } + + override fun allowComponentsUpdateAnimation( + oldStaffStack: ItemStack, + newStaffStack: ItemStack, + player: PlayerEntity, + hand: Hand + ) = false + + override fun allowReequipAnimation( + oldStaffStack: ItemStack, + newStaffStack: ItemStack, + selectedSlotChanged: Boolean + ) = selectedSlotChanged + + protected enum class ProjectileShootReason { + ATTACK, + USE + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CakeHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CakeHandler.kt index 65f62c751..f1c886255 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CakeHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CakeHandler.kt @@ -19,45 +19,27 @@ package opekope2.avm_staff.internal.staff.handler import net.minecraft.entity.LivingEntity -import net.minecraft.entity.player.PlayerEntity -import net.minecraft.item.ItemStack -import net.minecraft.util.Hand -import net.minecraft.util.TypedActionResult import net.minecraft.world.World import opekope2.avm_staff.api.entity.CakeEntity -import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.content.EntityTypes -import opekope2.avm_staff.util.* +import opekope2.avm_staff.util.approximateStaffTipPosition +import opekope2.avm_staff.util.getSpawnPosition +import opekope2.avm_staff.util.plus +import opekope2.avm_staff.util.times -internal class CakeHandler : StaffHandler() { - override fun getMaxUseTime(staffStack: ItemStack, world: World, user: LivingEntity) = 72000 +internal class CakeHandler : AbstractProjectileShootingStaffHandler() { + private val ProjectileShootReason.velocity: Double + get() = when (this) { + ProjectileShootReason.ATTACK -> 0.5 + ProjectileShootReason.USE -> 1.0 + } - override fun use( - staffStack: ItemStack, - world: World, - user: PlayerEntity, - hand: Hand - ): TypedActionResult { - user.setCurrentHand(hand) - return TypedActionResult.consume(staffStack) - } - - override fun usageTick(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - tryThrowCake(world, user, 1.0) - } - - override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand) { - tryThrowCake(world, attacker, 0.5) - (attacker as? PlayerEntity)?.resetLastAttackedTicks() - } - - private fun tryThrowCake(world: World, user: LivingEntity, velocityMultiplier: Double) { - if (world.isClient) return - if (!user.canUseStaff) return - if (user is PlayerEntity && user.isAttackCoolingDown) return + override fun tryShootProjectile(world: World, shooter: LivingEntity, reason: ProjectileShootReason): Boolean { + if (!super.tryShootProjectile(world, shooter, reason)) return false - val spawnPos = EntityTypes.cake.getSpawnPosition(world, user.approximateStaffTipPosition) ?: return + val spawnPos = EntityTypes.cake.getSpawnPosition(world, shooter.approximateStaffTipPosition) ?: return false + CakeEntity.throwCake(world, spawnPos, shooter.rotationVector * reason.velocity + shooter.velocity, shooter) - CakeEntity.throwCake(world, spawnPos, user.rotationVector * velocityMultiplier + user.velocity, user) + return true } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/MagmaBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/MagmaBlockHandler.kt index 32bcfce74..a8e590eba 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/MagmaBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/MagmaBlockHandler.kt @@ -28,16 +28,12 @@ import net.minecraft.entity.player.PlayerEntity import net.minecraft.entity.projectile.SmallFireballEntity import net.minecraft.item.ItemStack import net.minecraft.util.Hand -import net.minecraft.util.TypedActionResult import net.minecraft.world.World import net.minecraft.world.WorldEvents import opekope2.avm_staff.api.staff.StaffAttributeModifiersComponentBuilder -import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.* -internal class MagmaBlockHandler : StaffHandler() { - override fun getMaxUseTime(staffStack: ItemStack, world: World, user: LivingEntity) = 72000 - +internal class MagmaBlockHandler : AbstractProjectileShootingStaffHandler() { override val attributeModifiers = StaffAttributeModifiersComponentBuilder() .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(10.0), AttributeModifierSlot.MAINHAND) .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(1.25), AttributeModifierSlot.MAINHAND) @@ -45,25 +41,23 @@ internal class MagmaBlockHandler : StaffHandler() { .addDefault(EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE) .build() - override fun use( - staffStack: ItemStack, - world: World, - user: PlayerEntity, - hand: Hand - ): TypedActionResult { - user.setCurrentHand(hand) - return TypedActionResult.consume(staffStack) - } - override fun usageTick(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - if ((remainingUseTicks and 1) == 0) { - tryShootFireball(world, user) - } + if ((remainingUseTicks and 1) == 0) super.usageTick(staffStack, world, user, remainingUseTicks) } - override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand) { - tryShootFireball(world, attacker) - (attacker as? PlayerEntity)?.resetLastAttackedTicks() + override fun tryShootProjectile(world: World, shooter: LivingEntity, reason: ProjectileShootReason): Boolean { + if (!super.tryShootProjectile(world, shooter, reason)) return false + + val spawnPos = EntityType.SMALL_FIREBALL.getSpawnPosition(world, shooter.approximateStaffTipPosition) + ?: return false + + world.spawnEntity(SmallFireballEntity(world, shooter, shooter.rotationVector).apply { + owner = shooter + setPosition(spawnPos) + }) + world.syncWorldEvent(WorldEvents.BLAZE_SHOOTS, shooter.blockPos, 0) + + return true } override fun attackEntity( @@ -74,19 +68,9 @@ internal class MagmaBlockHandler : StaffHandler() { hand: Hand ): EventResult { target.setOnFireFor(8f) - return EventResult.pass() - } - - private fun tryShootFireball(world: World, shooter: LivingEntity) { - if (world.isClient) return - if (!shooter.canUseStaff) return - if (shooter is PlayerEntity && shooter.isAttackCoolingDown) return - val spawnPos = EntityType.SMALL_FIREBALL.getSpawnPosition(world, shooter.approximateStaffTipPosition) ?: return + (attacker as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) - world.spawnEntity(SmallFireballEntity(world, shooter, shooter.rotationVector).apply { - setPosition(spawnPos) - }) - world.syncWorldEvent(WorldEvents.BLAZE_SHOOTS, shooter.blockPos, 0) + return EventResult.pass() } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/SnowBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/SnowBlockHandler.kt index c01ecf624..81a90f55d 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/SnowBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/SnowBlockHandler.kt @@ -20,58 +20,37 @@ package opekope2.avm_staff.internal.staff.handler import net.minecraft.entity.EntityType import net.minecraft.entity.LivingEntity -import net.minecraft.entity.player.PlayerEntity import net.minecraft.entity.projectile.thrown.SnowballEntity -import net.minecraft.item.ItemStack import net.minecraft.sound.SoundEvents -import net.minecraft.util.Hand -import net.minecraft.util.TypedActionResult import net.minecraft.world.World -import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.* -internal class SnowBlockHandler : StaffHandler() { - override fun getMaxUseTime(staffStack: ItemStack, world: World, user: LivingEntity) = 72000 +internal class SnowBlockHandler : AbstractProjectileShootingStaffHandler() { + private val ProjectileShootReason.velocity: Float + get() = when (this) { + ProjectileShootReason.ATTACK -> 1.5f + ProjectileShootReason.USE -> 3f + } - override fun use( - staffStack: ItemStack, - world: World, - user: PlayerEntity, - hand: Hand - ): TypedActionResult { - user.setCurrentHand(hand) - return TypedActionResult.consume(staffStack) - } - - override fun usageTick(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - tryThrowSnowball(world, user) - } + override fun tryShootProjectile(world: World, shooter: LivingEntity, reason: ProjectileShootReason): Boolean { + if (!super.tryShootProjectile(world, shooter, reason)) return false - override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand) { - tryThrowSnowball(world, attacker) - (attacker as? PlayerEntity)?.resetLastAttackedTicks() - } - - private fun tryThrowSnowball(world: World, thrower: LivingEntity) { - if (world.isClient) return - if (!thrower.canUseStaff) return - if (thrower is PlayerEntity && thrower.isAttackCoolingDown) return - - val spawnPos = EntityType.SNOWBALL.getSpawnPosition(world, thrower.approximateStaffTipPosition) ?: return + val spawnPos = EntityType.SNOWBALL.getSpawnPosition(world, shooter.approximateStaffTipPosition) ?: return false val (x, y, z) = spawnPos world.spawnEntity(SnowballEntity(world, x, y, z).apply { - owner = thrower - // TODO speed - setVelocity(thrower, thrower.pitch, thrower.yaw, 0f, 4f, 1f) + owner = shooter + setVelocity(shooter, shooter.pitch, shooter.yaw, 0f, reason.velocity, 1f) }) world.playSound( null, - thrower.blockPos, + shooter.blockPos, SoundEvents.ENTITY_SNOWBALL_THROW, - thrower.soundCategory, - 0.5f, - 0.4f / (world.getRandom().nextFloat() * 0.4f + 0.8f) + shooter.soundCategory, + .5f, + .4f / (world.random.nextFloat() * .4f + .8f) ) + + return true } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt index a1d384fd5..fc5204585 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt @@ -28,54 +28,41 @@ import net.minecraft.entity.player.PlayerEntity import net.minecraft.entity.projectile.WitherSkullEntity import net.minecraft.item.ItemStack import net.minecraft.util.Hand -import net.minecraft.util.TypedActionResult import net.minecraft.world.Difficulty import net.minecraft.world.World import net.minecraft.world.WorldEvents -import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.approximateStaffTipPosition -import opekope2.avm_staff.util.canUseStaff import opekope2.avm_staff.util.getSpawnPosition -import opekope2.avm_staff.util.isAttackCoolingDown +import opekope2.avm_staff.util.incrementStaffItemUseStat +import opekope2.avm_staff.util.itemInStaff -internal class WitherSkeletonSkullHandler : StaffHandler() { +internal class WitherSkeletonSkullHandler : AbstractProjectileShootingStaffHandler() { override fun getMaxUseTime(staffStack: ItemStack, world: World, user: LivingEntity) = 20 - override fun use( - staffStack: ItemStack, - world: World, - user: PlayerEntity, - hand: Hand - ): TypedActionResult { - user.setCurrentHand(hand) - return TypedActionResult.consume(staffStack) - } - override fun usageTick(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - if ((remainingUseTicks and 1) == 0) { - tryShootSkull(world, user, Math.random() < 0.1f) // TODO ratio - } + if ((remainingUseTicks and 1) == 0) super.usageTick(staffStack, world, user, remainingUseTicks) } override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand) { if (attacker is PlayerEntity && attacker.itemCooldownManager.isCoolingDown(staffStack.item)) return - - tryShootSkull(world, attacker, false) - (attacker as? PlayerEntity)?.resetLastAttackedTicks() + super.attack(staffStack, world, attacker, hand) + if (attacker is PlayerEntity) addCooldown(staffStack, world, attacker, 0) } - private fun tryShootSkull(world: World, user: LivingEntity, charged: Boolean) { - if (world.isClient) return - if (!user.canUseStaff) return - if (user is PlayerEntity && user.isAttackCoolingDown) return + override fun tryShootProjectile(world: World, shooter: LivingEntity, reason: ProjectileShootReason): Boolean { + if (!super.tryShootProjectile(world, shooter, reason)) return false - val spawnPos = EntityType.WITHER_SKULL.getSpawnPosition(world, user.approximateStaffTipPosition) ?: return + val spawnPos = EntityType.WITHER_SKULL.getSpawnPosition(world, shooter.approximateStaffTipPosition) + ?: return false - world.spawnEntity(WitherSkullEntity(world, user, user.rotationVector).apply { - isCharged = charged + world.spawnEntity(WitherSkullEntity(world, shooter, shooter.rotationVector).apply { + owner = shooter + isCharged = reason == ProjectileShootReason.ATTACK setPosition(spawnPos) }) - world.syncWorldEvent(WorldEvents.WITHER_SHOOTS, user.blockPos, 0) + world.syncWorldEvent(WorldEvents.WITHER_SHOOTS, shooter.blockPos, 0) + + return true } override fun attackEntity( @@ -89,20 +76,26 @@ internal class WitherSkeletonSkullHandler : StaffHandler() { if (target is LivingEntity && !target.isInvulnerableTo(world.damageSources.wither())) { val amplifier = if (world.difficulty == Difficulty.HARD) 1 else 0 target.addStatusEffect(StatusEffectInstance(StatusEffects.WITHER, 10 * 20, amplifier)) + (attacker as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) } return EventResult.pass() } override fun onStoppedUsing(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - (user as? PlayerEntity)?.itemCooldownManager?.set( - staffStack.item, - 4 * (getMaxUseTime(staffStack, world, user) - remainingUseTicks) - ) + if (user is PlayerEntity) addCooldown(staffStack, world, user, remainingUseTicks) } override fun finishUsing(staffStack: ItemStack, world: World, user: LivingEntity): ItemStack { onStoppedUsing(staffStack, world, user, 0) return staffStack } + + private fun addCooldown(staffStack: ItemStack, world: World, player: PlayerEntity, remainingUseTicks: Int) { + if (player.abilities.creativeMode) return + player.itemCooldownManager.set( + staffStack.item, + 4 * (getMaxUseTime(staffStack, world, player) - remainingUseTicks) + ) + } } From dba5fbfe0228e7459bee39ac3ecf9e57810f436c Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 23 Nov 2024 00:35:26 +0100 Subject: [PATCH 40/83] Damage staff and increment stats for the rest of the blocks --- .../avm_staff/api/staff/StaffHandler.kt | 3 +++ .../internal/staff/handler/AnvilHandler.kt | 13 +++++++--- .../internal/staff/handler/BellHandler.kt | 4 ++++ .../staff/handler/BoneBlockHandler.kt | 9 +++++++ .../internal/staff/handler/CampfireHandler.kt | 24 ++++++++++++++++--- .../internal/staff/handler/FurnaceHandler.kt | 4 ++++ .../staff/handler/LightningRodHandler.kt | 20 ++++++++++++++-- .../internal/staff/handler/TntHandler.kt | 19 ++++++++++----- .../internal/staff/handler/WoolHandler.kt | 14 +++++++---- 9 files changed, 92 insertions(+), 18 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt index ce0236a32..b6a02d45a 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt @@ -28,6 +28,7 @@ import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.BlockItem import net.minecraft.item.Item import net.minecraft.item.ItemStack +import net.minecraft.item.Items import net.minecraft.registry.Registries import net.minecraft.stat.Stats import net.minecraft.util.* @@ -40,6 +41,7 @@ import opekope2.avm_staff.api.component.BlockPickupDataComponent import opekope2.avm_staff.api.registry.RegistryBase import opekope2.avm_staff.content.ComponentTypes import opekope2.avm_staff.util.approximateStaffItemPosition +import opekope2.avm_staff.util.incrementStaffItemUseStat import opekope2.avm_staff.util.mutableItemStackInStaff import kotlin.math.roundToInt @@ -387,6 +389,7 @@ abstract class StaffHandler { } onStoppedUsing(staffStack, world, user, 0) + (user as? PlayerEntity)?.incrementStaffItemUseStat(Items.AIR) return staffStack } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AnvilHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AnvilHandler.kt index 85a6a20af..ee8162e3a 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AnvilHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AnvilHandler.kt @@ -75,7 +75,7 @@ internal class AnvilHandler(private val damagedItem: Item?) : StaffHandler() { val fallDistance = ceil(attacker.fallDistance - 1f) if (fallDistance <= 0) return EventResult.interruptDefault() - aoeAttack(world, attacker, target, fallDistance) + val damagedEntities = aoeAttack(world, attacker, target, fallDistance) world.syncWorldEvent(WorldEvents.SMASH_ATTACK, target.steppingPos, 750) attacker.fallDistance = 0f @@ -87,10 +87,14 @@ internal class AnvilHandler(private val damagedItem: Item?) : StaffHandler() { 0 ) + (attacker as? PlayerEntity)?.incrementItemUseStat(staffStack.item) + (attacker as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + staffStack.damage(damagedEntities, attacker, LivingEntity.getSlotForHand(hand)) + return EventResult.interruptDefault() } - private fun aoeAttack(world: World, attacker: LivingEntity, target: Entity, fallDistance: Float) { + private fun aoeAttack(world: World, attacker: LivingEntity, target: Entity, fallDistance: Float): Int { val cappedFallDistance = floor(fallDistance * IAnvilBlockAccessor.fallingBlockEntityDamageMultiplier()) .coerceAtMost(IAnvilBlockAccessor.fallingBlockEntityMaxDamage().toFloat()) val cooldownProgress = @@ -103,9 +107,12 @@ internal class AnvilHandler(private val damagedItem: Item?) : StaffHandler() { .and(EntityPredicates.VALID_LIVING_ENTITY) .and(EntityPredicates.maxDistance(target.x, target.y, target.z, radius)) - world.getOtherEntities(attacker, box, predicate).forEach { entity -> + val entities = world.getOtherEntities(attacker, box, predicate) + for (entity in entities) { entity.damage(world.damageSources.fallingAnvil(attacker), amount / (entity.distanceTo(target) + 1)) } + + return entities.size } private fun damageAnvil(staffStack: ItemStack, attacker: LivingEntity, fallDistance: Float): Boolean { diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt index e79707d75..573b63f0d 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt @@ -38,6 +38,8 @@ import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.mixin.IBellBlockEntityAccessor import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.attackSpeed +import opekope2.avm_staff.util.incrementStaffItemUseStat +import opekope2.avm_staff.util.itemInStaff internal class BellHandler : StaffHandler() { override val attributeModifiers = StaffAttributeModifiersComponentBuilder() @@ -97,6 +99,8 @@ internal class BellHandler : StaffHandler() { IBellBlockEntityAccessor.callApplyGlowToEntity(target) } + (attacker as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + return EventResult.pass() } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BoneBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BoneBlockHandler.kt index bd9e327ee..7be1b2eaa 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BoneBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BoneBlockHandler.kt @@ -21,6 +21,7 @@ package opekope2.avm_staff.internal.staff.handler import net.minecraft.component.type.AttributeModifierSlot import net.minecraft.entity.LivingEntity import net.minecraft.entity.attribute.EntityAttributes +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.BoneMealItem import net.minecraft.item.ItemStack import net.minecraft.item.Items @@ -35,6 +36,8 @@ import opekope2.avm_staff.api.staff.StaffAttributeModifiersComponentBuilder import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.attackSpeed +import opekope2.avm_staff.util.incrementStaffItemUseStat +import opekope2.avm_staff.util.itemInStaff internal class BoneBlockHandler : StaffHandler() { override val attributeModifiers = StaffAttributeModifiersComponentBuilder() @@ -59,6 +62,9 @@ internal class BoneBlockHandler : StaffHandler() { world.syncWorldEvent(WorldEvents.BONE_MEAL_USED, target, 15) } + (user as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + staffStack.damage(1, user, LivingEntity.getSlotForHand(hand)) + return ActionResult.SUCCESS } @@ -73,6 +79,9 @@ internal class BoneBlockHandler : StaffHandler() { world.syncWorldEvent(WorldEvents.BONE_MEAL_USED, neighborOnUsedSide, 15) } + (user as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + staffStack.damage(1, user, LivingEntity.getSlotForHand(hand)) + return ActionResult.SUCCESS } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt index d0a552fe7..2bc93e96b 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt @@ -33,9 +33,7 @@ import opekope2.avm_staff.api.entity.CampfireFlameEntity import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.content.ComponentTypes import opekope2.avm_staff.internal.minecraftUnit -import opekope2.avm_staff.util.approximateStaffTipPosition -import opekope2.avm_staff.util.canUseStaff -import opekope2.avm_staff.util.times +import opekope2.avm_staff.util.* internal class CampfireHandler(private val parameters: Parameters) : StaffHandler() { override fun getMaxUseTime(staffStack: ItemStack, world: World, user: LivingEntity) = 72000 @@ -89,10 +87,14 @@ internal class CampfireHandler(private val parameters: Parameters) : StaffHandle user ) ) + + staffStack.damage(1, user, LivingEntity.getSlotForHand(user.activeHand)) } override fun onStoppedUsing(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { staffStack.remove(ComponentTypes.rocketMode) + (user as? PlayerEntity)?.incrementItemUseStat(staffStack.item) + (user as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) } override fun finishUsing(staffStack: ItemStack, world: World, user: LivingEntity): ItemStack { @@ -108,9 +110,25 @@ internal class CampfireHandler(private val parameters: Parameters) : StaffHandle hand: Hand ): EventResult { target.setOnFireFor(parameters.attackFireSeconds) + + (attacker as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + return EventResult.pass() } + override fun allowComponentsUpdateAnimation( + oldStaffStack: ItemStack, + newStaffStack: ItemStack, + player: PlayerEntity, + hand: Hand + ) = false + + override fun allowReequipAnimation( + oldStaffStack: ItemStack, + newStaffStack: ItemStack, + selectedSlotChanged: Boolean + ) = selectedSlotChanged + data class Parameters( val flammableBlockFireChance: Double, val nonFlammableBlockFireChance: Double, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt index 454d96ea9..989fdabff 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt @@ -101,6 +101,9 @@ internal class FurnaceHandler( itemToSmelt.discard() furnaceData.burnTicks -= stackToSmelt.count + + staffStack.damage(stackToSmelt.count, user, LivingEntity.getSlotForHand(user.activeHand)) + (user as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) } private fun findItemToSmelt(world: World, smeltingPosition: Vec3d): ItemEntity? { @@ -126,6 +129,7 @@ internal class FurnaceHandler( override fun onStoppedUsing(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { staffStack.remove(ComponentTypes.furnaceData) + (user as? PlayerEntity)?.incrementItemUseStat(staffStack.item) } override fun finishUsing(staffStack: ItemStack, world: World, user: LivingEntity): ItemStack { diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/LightningRodHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/LightningRodHandler.kt index a7eacd03f..39f91404c 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/LightningRodHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/LightningRodHandler.kt @@ -35,8 +35,10 @@ import net.minecraft.util.math.Vec3d import net.minecraft.world.World import opekope2.avm_staff.api.staff.StaffAttributeModifiersComponentBuilder import opekope2.avm_staff.api.staff.StaffHandler +import opekope2.avm_staff.util.incrementStaffItemUseStat import opekope2.avm_staff.util.interactionRange import opekope2.avm_staff.util.isItemCoolingDown +import opekope2.avm_staff.util.itemInStaff internal class LightningRodHandler : StaffHandler() { override val attributeModifiers = StaffAttributeModifiersComponentBuilder() @@ -55,7 +57,14 @@ internal class LightningRodHandler : StaffHandler() { hand: Hand ): ActionResult { val lightningPos = Vec3d.add(target.offset(side), 0.5, 0.0, 0.5) - return tryStrike(staffStack, world, user, lightningPos) + val result = tryStrike(staffStack, world, user, lightningPos) + + if (result.isAccepted) staffStack.damage(1, user, LivingEntity.getSlotForHand(hand)) + if (result.shouldIncrementStat()) { + (user as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + } + + return result } override fun useOnEntity( @@ -65,7 +74,14 @@ internal class LightningRodHandler : StaffHandler() { target: LivingEntity, hand: Hand ): ActionResult { - return tryStrike(staffStack, world, user, target.pos) + val result = tryStrike(staffStack, world, user, target.pos) + + if (result.isAccepted) staffStack.damage(1, user, LivingEntity.getSlotForHand(hand)) + if (result.shouldIncrementStat()) { + (user as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + } + + return result } override fun attackEntity( diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt index 672ec4a49..1071fc488 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt @@ -33,16 +33,21 @@ import opekope2.avm_staff.util.* internal class TntHandler : StaffHandler() { override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand) { - tryShootTnt(world, attacker) + if (tryShootTnt(world, attacker)) { + staffStack.damage(1, attacker, LivingEntity.getSlotForHand(hand)) + (attacker as? PlayerEntity)?.incrementItemUseStat(staffStack.item) + (attacker as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + } (attacker as? PlayerEntity)?.resetLastAttackedTicks() } - private fun tryShootTnt(world: World, shooter: LivingEntity) { - if (world.isClient) return - if (!shooter.canUseStaff) return - if (shooter is PlayerEntity && shooter.isAttackCoolingDown) return + private fun tryShootTnt(world: World, shooter: LivingEntity): Boolean { + if (world.isClient) return false + if (!shooter.canUseStaff) return false + if (shooter is PlayerEntity && shooter.isAttackCoolingDown) return false - val spawnPos = EntityTypes.impactTnt.getSpawnPosition(world, shooter.approximateStaffTipPosition) ?: return + val spawnPos = + EntityTypes.impactTnt.getSpawnPosition(world, shooter.approximateStaffTipPosition) ?: return false val (x, y, z) = spawnPos world.spawnEntity(ImpactTntEntity(world, x, y, z, shooter.rotationVector + shooter.velocity, shooter)) @@ -54,5 +59,7 @@ internal class TntHandler : StaffHandler() { ) world.playSound(null, x, y, z, SoundEvents.ENTITY_TNT_PRIMED, SoundCategory.BLOCKS, 1f, 1f) world.emitGameEvent(shooter, GameEvent.PRIME_FUSE, spawnPos) + + return true } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WoolHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WoolHandler.kt index 387554fae..09e4c2cea 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WoolHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WoolHandler.kt @@ -37,9 +37,7 @@ import net.minecraft.world.World import opekope2.avm_staff.api.staff.StaffAttributeModifiersComponentBuilder import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.mixin.IMinecraftClientAccessor -import opekope2.avm_staff.util.attackDamage -import opekope2.avm_staff.util.attackSpeed -import opekope2.avm_staff.util.mutableItemStackInStaff +import opekope2.avm_staff.util.* internal class WoolHandler(private val woolItem: BlockItem, private val carpetItem: BlockItem) : StaffHandler() { override val attributeModifiers = StaffAttributeModifiersComponentBuilder() @@ -73,7 +71,15 @@ internal class WoolHandler(private val woolItem: BlockItem, private val carpetIt staffStack.mutableItemStackInStaff!!, BlockHitResult(target.toCenterPos(), side, target, false) ) - return itemToPlace.place(woolPlaceContext) + + val result = itemToPlace.place(woolPlaceContext) + + if (result.isAccepted) staffStack.damage(1, user, LivingEntity.getSlotForHand(hand)) + if (result.shouldIncrementStat()) { + (user as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + } + + return result } private class WoolPlacementContext( From ded11fdd5d83095e434a6b671a1926940b8c67a9 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 23 Nov 2024 00:39:30 +0100 Subject: [PATCH 41/83] Make royal staff damageable --- .../main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt | 7 +++++++ .../src/main/kotlin/opekope2/avm_staff/content/Items.kt | 5 ++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt index eaf2196e3..1b1d3da48 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt @@ -21,6 +21,7 @@ package opekope2.avm_staff.api.item import dev.architectury.registry.registries.RegistrySupplier import net.minecraft.component.DataComponentTypes import net.minecraft.entity.Entity +import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.ItemEntity import net.minecraft.entity.LivingEntity import net.minecraft.entity.player.PlayerEntity @@ -79,6 +80,12 @@ abstract class StaffItem(settings: Settings, private val repairIngredientSupplie return stack.itemInStaff.staffHandlerOrFallback.finishUsing(stack, world, user) } + override fun postHit(stack: ItemStack, target: LivingEntity, attacker: LivingEntity) = true + + override fun postDamageEntity(stack: ItemStack, target: LivingEntity, attacker: LivingEntity) { + stack.damage(1, attacker, EquipmentSlot.MAINHAND) + } + override fun useOnBlock(context: ItemUsageContext): ActionResult { return context.stack.itemInStaff.staffHandlerOrFallback.useOnBlock( context.stack, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt index 76bf6499a..a9e110579 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt @@ -19,6 +19,8 @@ package opekope2.avm_staff.content import dev.architectury.registry.CreativeTabRegistry +import net.minecraft.component.DataComponentTypes +import net.minecraft.component.type.ToolComponent import net.minecraft.item.Item import net.minecraft.item.SmithingTemplateItem import net.minecraft.registry.RegistryKeys @@ -93,7 +95,8 @@ object Items : RegistryUtil(MOD_ID, RegistryKeys.ITEM) { val ROYAL_STAFF = register("royal_staff") { IStaffModPlatform.staffItem( settings().maxCount(1).rarity(Rarity.EPIC).attributeModifiers(StaffHandler.Fallback.ATTRIBUTE_MODIFIERS) - .maxDamage(5179).`arch$tab`(ItemGroups.AVM_STAFF_MOD_ITEMS), + .maxDamage(5179).component(DataComponentTypes.TOOL, ToolComponent(listOf(), 1f, 1)) + .`arch$tab`(ItemGroups.AVM_STAFF_MOD_ITEMS), ROYAL_STAFF_INGREDIENT ) } From 7392a0821848302b79ff9b2355ec364c3081d3cc Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 23 Nov 2024 00:39:44 +0100 Subject: [PATCH 42/83] Add durability enchantments to staffs --- .../data/minecraft/tags/item/enchantable/durability.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/durability.json diff --git a/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/durability.json b/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/durability.json new file mode 100644 index 000000000..641e9fc93 --- /dev/null +++ b/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/durability.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "#avm_staff:staffs" + ] +} From 9c295adb057e9209544924e7784ec7ae337a29d1 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 23 Nov 2024 01:18:01 +0100 Subject: [PATCH 43/83] Move ItemTags into Items --- .../opekope2/avm_staff/content/ItemTags.kt | 36 ------------------- .../opekope2/avm_staff/content/Items.kt | 13 +++++++ 2 files changed, 13 insertions(+), 36 deletions(-) delete mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/content/ItemTags.kt diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ItemTags.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ItemTags.kt deleted file mode 100644 index 874b0912f..000000000 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ItemTags.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * AvM Staff Mod - * Copyright (c) 2024 opekope2 - * - * This mod is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This mod is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this mod. If not, see . - */ - -package opekope2.avm_staff.content - -import net.minecraft.item.Item -import net.minecraft.registry.RegistryKeys -import net.minecraft.registry.tag.TagKey -import net.minecraft.util.Identifier -import opekope2.avm_staff.util.MOD_ID - -/** - * Item tags added by AVM Staffs mod. - */ -object ItemTags { - /** - * Item tag registered as `avm_staff:staffs`. - */ - @JvmField - val STAFFS: TagKey = TagKey.of(RegistryKeys.ITEM, Identifier.of(MOD_ID, "staffs")) -} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt index a9e110579..e192192af 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt @@ -24,7 +24,9 @@ import net.minecraft.component.type.ToolComponent import net.minecraft.item.Item import net.minecraft.item.SmithingTemplateItem import net.minecraft.registry.RegistryKeys +import net.minecraft.registry.tag.TagKey import net.minecraft.text.Text +import net.minecraft.util.Identifier import net.minecraft.util.Rarity import opekope2.avm_staff.api.IStaffModPlatform import opekope2.avm_staff.api.item.CrownItem @@ -172,4 +174,15 @@ object Items : RegistryUtil(MOD_ID, RegistryKeys.ITEM) { // Because SmithingTemplateItem doesn't take Item.Settings in its constructor CreativeTabRegistry.append(ItemGroups.AVM_STAFF_MOD_ITEMS, STAFF_INFUSION_SMITHING_TEMPLATE) } + + /** + * Item tags added by AVM Staffs mod. + */ + object Tags { + /** + * Item tag registered as `avm_staff:staffs`. + */ + @JvmField + val STAFFS: TagKey = TagKey.of(RegistryKeys.ITEM, Identifier.of(MOD_ID, "staffs")) + } } From 59b0cd523ad87c1552dc1f3f62d3e4c9e8cdba3a Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 23 Nov 2024 13:29:44 +0100 Subject: [PATCH 44/83] Add TagKeyUtil --- .../opekope2/avm_staff/content/Items.kt | 7 ++- .../opekope2/avm_staff/util/TagKeyUtil.kt | 54 +++++++++++++++++++ 2 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/util/TagKeyUtil.kt diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt index e192192af..e0112bc4e 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt @@ -24,9 +24,7 @@ import net.minecraft.component.type.ToolComponent import net.minecraft.item.Item import net.minecraft.item.SmithingTemplateItem import net.minecraft.registry.RegistryKeys -import net.minecraft.registry.tag.TagKey import net.minecraft.text.Text -import net.minecraft.util.Identifier import net.minecraft.util.Rarity import opekope2.avm_staff.api.IStaffModPlatform import opekope2.avm_staff.api.item.CrownItem @@ -36,6 +34,7 @@ import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures import opekope2.avm_staff.mixin.ISmithingTemplateItemAccessor import opekope2.avm_staff.util.MOD_ID import opekope2.avm_staff.util.RegistryUtil +import opekope2.avm_staff.util.TagKeyUtil /** * Items added by AVM Staffs mod. @@ -178,11 +177,11 @@ object Items : RegistryUtil(MOD_ID, RegistryKeys.ITEM) { /** * Item tags added by AVM Staffs mod. */ - object Tags { + object Tags : TagKeyUtil(MOD_ID, RegistryKeys.ITEM) { /** * Item tag registered as `avm_staff:staffs`. */ @JvmField - val STAFFS: TagKey = TagKey.of(RegistryKeys.ITEM, Identifier.of(MOD_ID, "staffs")) + val STAFFS = tagKey("staffs") } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/TagKeyUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/TagKeyUtil.kt new file mode 100644 index 000000000..bc49aa60e --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/TagKeyUtil.kt @@ -0,0 +1,54 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.util + +import net.minecraft.registry.Registry +import net.minecraft.registry.RegistryKey +import net.minecraft.registry.tag.TagKey +import net.minecraft.util.Identifier + +/** + * Utility class to create [Identifier]s and [TagKey]s using a specified [namespace][Identifier.namespace] and registry. + * + * @param TContent The type of the content to register + * @param modId The [namespace][Identifier.namespace] of the content to register. + * @param registry The registry the content is registered in + */ +open class TagKeyUtil( + protected val modId: String, + protected val registry: RegistryKey> +) { + init { + require(Identifier.isNamespaceValid(modId)) { "Mod ID is not a valid namespace" } + } + + /** + * Creates an [Identifier] from the namespace specified in the constructor and a given path. + * + * @param path The path of the [Identifier] to create + */ + fun id(path: String): Identifier = Identifier.of(modId, path) + + /** + * Creates a [TagKey] from the registry and namespace specified in the constructor and a given path. + * + * @param path The path of the [Identifier] to create a tag key from + */ + fun tagKey(path: String): TagKey = TagKey.of(registry, id(path)) +} From 90b846339a564a78c122dfa1008b5d5d918b8dac Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 23 Nov 2024 13:31:43 +0100 Subject: [PATCH 45/83] Make staffs enchantable with fortune and silk touch --- .../data/minecraft/tags/item/enchantable/mining_loot.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/mining_loot.json diff --git a/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/mining_loot.json b/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/mining_loot.json new file mode 100644 index 000000000..641e9fc93 --- /dev/null +++ b/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/mining_loot.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "#avm_staff:staffs" + ] +} From 88cd0620f601ec9e7628d07d802584cc8ce397da Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 23 Nov 2024 13:34:31 +0100 Subject: [PATCH 46/83] Add rapid fire enchantment tag to staffs --- .../avm_staff/content/Enchantments.kt | 40 +++++++++++++++++++ .../AbstractProjectileShootingStaffHandler.kt | 8 ++++ .../allows_projectile_rapid_fire.json | 6 +++ .../tags/item/enchantable/crossbow.json | 6 +++ 4 files changed, 60 insertions(+) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt create mode 100644 StaffMod/src/main/resources/data/avm_staff/tags/enchantment/allows_projectile_rapid_fire.json create mode 100644 StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/crossbow.json diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt new file mode 100644 index 000000000..18ab465a3 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt @@ -0,0 +1,40 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.content + +import net.minecraft.enchantment.Enchantment +import net.minecraft.registry.RegistryKeys +import opekope2.avm_staff.util.MOD_ID +import opekope2.avm_staff.util.TagKeyUtil + +/** + * Enchantments added by AVM Staffs mod. + */ +object Enchantments { + /** + * Enchantment tags added by AVM Staffs mod. + */ + object Tags : TagKeyUtil(MOD_ID, RegistryKeys.ENCHANTMENT) { + /** + * Enchantment registered as `avm_staff:allows_projectile_rapid_fire`. + */ + @JvmField + val ALLOWS_PROJECTILE_RAPID_FIRE = tagKey("allows_projectile_rapid_fire") + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt index 291bd5ed6..54706cf94 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt @@ -18,6 +18,7 @@ package opekope2.avm_staff.internal.staff.handler +import net.minecraft.enchantment.EnchantmentHelper import net.minecraft.entity.LivingEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack @@ -25,6 +26,7 @@ import net.minecraft.util.Hand import net.minecraft.util.TypedActionResult import net.minecraft.world.World import opekope2.avm_staff.api.staff.StaffHandler +import opekope2.avm_staff.content.Enchantments import opekope2.avm_staff.util.* internal abstract class AbstractProjectileShootingStaffHandler : StaffHandler() { @@ -36,6 +38,12 @@ internal abstract class AbstractProjectileShootingStaffHandler : StaffHandler() user: PlayerEntity, hand: Hand ): TypedActionResult { + val allowsProjectileRapidFire = EnchantmentHelper.hasAnyEnchantmentsIn( + user.mainHandStack, + Enchantments.Tags.ALLOWS_PROJECTILE_RAPID_FIRE + ) + if (!allowsProjectileRapidFire) return TypedActionResult.pass(staffStack) + user.setCurrentHand(hand) return TypedActionResult.consume(staffStack) } diff --git a/StaffMod/src/main/resources/data/avm_staff/tags/enchantment/allows_projectile_rapid_fire.json b/StaffMod/src/main/resources/data/avm_staff/tags/enchantment/allows_projectile_rapid_fire.json new file mode 100644 index 000000000..081cbd801 --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/tags/enchantment/allows_projectile_rapid_fire.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "minecraft:multishot" + ] +} diff --git a/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/crossbow.json b/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/crossbow.json new file mode 100644 index 000000000..641e9fc93 --- /dev/null +++ b/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/crossbow.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "#avm_staff:staffs" + ] +} From 4f547f622d5b93e69343cffddf8a57e4df60442e Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 23 Nov 2024 15:51:23 +0100 Subject: [PATCH 47/83] Enable knocking back impact TNT with a silk touch item --- .../avm_staff/api/entity/ImpactTntEntity.kt | 33 +++++++++++++++++++ .../avm_staff/content/Enchantments.kt | 6 ++++ .../enchantment/redirects_impact_tnt.json | 6 ++++ 3 files changed, 45 insertions(+) create mode 100644 StaffMod/src/main/resources/data/avm_staff/tags/enchantment/redirects_impact_tnt.json diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntEntity.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntEntity.kt index f2c1cb03e..d8a62828b 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntEntity.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntEntity.kt @@ -18,11 +18,16 @@ package opekope2.avm_staff.api.entity +import net.minecraft.enchantment.EnchantmentHelper import net.minecraft.entity.* +import net.minecraft.entity.damage.DamageSource import net.minecraft.predicate.entity.EntityPredicates +import net.minecraft.registry.tag.DamageTypeTags import net.minecraft.util.math.Vec3d import net.minecraft.world.World +import opekope2.avm_staff.content.Enchantments import opekope2.avm_staff.content.EntityTypes +import opekope2.avm_staff.util.plus /** * A TNT entity, which explodes on collision. @@ -52,6 +57,11 @@ class ImpactTntEntity(entityType: EntityType, world: World) : T this.owner = owner } + override fun tick() { + super.tick() + if (timeUntilRegen > 0) timeUntilRegen-- + } + override fun move(movementType: MovementType?, movement: Vec3d?) { super.move(movementType, movement) if (!world.isClient) { @@ -59,6 +69,29 @@ class ImpactTntEntity(entityType: EntityType, world: World) : T } } + override fun damage(source: DamageSource, amount: Float): Boolean { + if (world.isClient) return super.damage(source, amount) + + if (!isRemoved && !isInvulnerableTo(source) && !source.isIn(DamageTypeTags.IS_EXPLOSION) && timeUntilRegen == 0) { + val attacker = source.attacker + if (attacker is LivingEntity) { + owner = attacker + val redirect = EnchantmentHelper.hasAnyEnchantmentsIn( + attacker.mainHandStack, + Enchantments.Tags.REDIRECTS_IMPACT_TNT + ) + if (redirect) { + timeUntilRegen = 10 + velocity += attacker.rotationVector + } else { + explodeLater() + } + } + } + + return super.damage(source, amount) + } + private fun explodeOnImpact() { if (horizontalCollision || verticalCollision) { explodeLater() diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt index 18ab465a3..ccfbca4ec 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt @@ -31,6 +31,12 @@ object Enchantments { * Enchantment tags added by AVM Staffs mod. */ object Tags : TagKeyUtil(MOD_ID, RegistryKeys.ENCHANTMENT) { + /** + * Enchantment registered as `avm_staff:redirects_impact_tnt`. + */ + @JvmField + val REDIRECTS_IMPACT_TNT = tagKey("redirects_impact_tnt") + /** * Enchantment registered as `avm_staff:allows_projectile_rapid_fire`. */ diff --git a/StaffMod/src/main/resources/data/avm_staff/tags/enchantment/redirects_impact_tnt.json b/StaffMod/src/main/resources/data/avm_staff/tags/enchantment/redirects_impact_tnt.json new file mode 100644 index 000000000..fc88a55b6 --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/tags/enchantment/redirects_impact_tnt.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "minecraft:silk_touch" + ] +} From b7579f2270e3f4c274214d88faf756e7682c3cc5 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 23 Nov 2024 15:52:09 +0100 Subject: [PATCH 48/83] Change cake attacked code --- .../opekope2/avm_staff/api/entity/CakeEntity.kt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt index c71b1e73b..9c01f5860 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt @@ -30,6 +30,7 @@ import net.minecraft.entity.data.DataTracker import net.minecraft.nbt.NbtCompound import net.minecraft.network.packet.s2c.play.EntitySpawnS2CPacket import net.minecraft.predicate.entity.EntityPredicates +import net.minecraft.registry.tag.DamageTypeTags import net.minecraft.server.network.EntityTrackerEntry import net.minecraft.sound.SoundCategory import net.minecraft.util.math.BlockPos @@ -77,13 +78,6 @@ class CakeEntity(entityType: EntityType, world: World) : Entity(enti this.thrower = thrower } - override fun handleAttack(attacker: Entity?): Boolean { - if (!world.isClient) { - discard() - } - return true - } - /** * The position, where the cake was spawned. */ @@ -199,11 +193,18 @@ class CakeEntity(entityType: EntityType, world: World) : Entity(enti override fun handleFallDamage(fallDistance: Float, damageMultiplier: Float, damageSource: DamageSource) = false override fun damage(source: DamageSource, amount: Float): Boolean { + if (world.isClient) return super.damage(source, amount) + val causer = source.source if (causer is ImpactTntEntity && causer.owner != null) { thrower = causer.owner redirectedByImpactTnt = true } + + if (!isRemoved && !isInvulnerableTo(source) && !source.isIn(DamageTypeTags.IS_EXPLOSION)) { + discard() + } + return super.damage(source, amount) } From f41476e062f05fe5f02def4f242c955212c71083 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 23 Nov 2024 16:38:42 +0100 Subject: [PATCH 49/83] Add juggler advancement --- .../avm_staff/api/entity/ImpactTntEntity.kt | 30 ++++++++++++++- .../assets/avm_staff/lang/en_us.json | 2 + .../data/avm_staff/advancement/juggler.json | 38 +++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 StaffMod/src/main/resources/data/avm_staff/advancement/juggler.json diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntEntity.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntEntity.kt index d8a62828b..e9c3d540a 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntEntity.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntEntity.kt @@ -18,11 +18,14 @@ package opekope2.avm_staff.api.entity +import net.minecraft.advancement.criterion.Criteria import net.minecraft.enchantment.EnchantmentHelper import net.minecraft.entity.* import net.minecraft.entity.damage.DamageSource +import net.minecraft.nbt.NbtCompound import net.minecraft.predicate.entity.EntityPredicates import net.minecraft.registry.tag.DamageTypeTags +import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.util.math.Vec3d import net.minecraft.world.World import opekope2.avm_staff.content.Enchantments @@ -33,6 +36,7 @@ import opekope2.avm_staff.util.plus * A TNT entity, which explodes on collision. */ class ImpactTntEntity(entityType: EntityType, world: World) : TntEntity(entityType, world), Ownable { + private var juggles = 0 private var owner: LivingEntity? = null /** @@ -75,7 +79,13 @@ class ImpactTntEntity(entityType: EntityType, world: World) : T if (!isRemoved && !isInvulnerableTo(source) && !source.isIn(DamageTypeTags.IS_EXPLOSION) && timeUntilRegen == 0) { val attacker = source.attacker if (attacker is LivingEntity) { - owner = attacker + if (owner === attacker) { + juggles++ + } else { + owner = attacker + juggles = 0 + } + val redirect = EnchantmentHelper.hasAnyEnchantmentsIn( attacker.mainHandStack, Enchantments.Tags.REDIRECTS_IMPACT_TNT @@ -83,6 +93,10 @@ class ImpactTntEntity(entityType: EntityType, world: World) : T if (redirect) { timeUntilRegen = 10 velocity += attacker.rotationVector + + if (attacker is ServerPlayerEntity) { + Criteria.PLAYER_HURT_ENTITY.trigger(attacker, this, source, amount, 0f, false) + } } else { explodeLater() } @@ -92,6 +106,16 @@ class ImpactTntEntity(entityType: EntityType, world: World) : T return super.damage(source, amount) } + override fun readCustomDataFromNbt(nbt: NbtCompound) { + super.readCustomDataFromNbt(nbt) + juggles = nbt.getInt(JUGGLES_KEY) + } + + override fun writeCustomDataToNbt(nbt: NbtCompound) { + super.writeCustomDataToNbt(nbt) + nbt.putInt(JUGGLES_KEY, juggles) + } + private fun explodeOnImpact() { if (horizontalCollision || verticalCollision) { explodeLater() @@ -127,4 +151,8 @@ class ImpactTntEntity(entityType: EntityType, world: World) : T } override fun getOwner() = owner + + private companion object { + private const val JUGGLES_KEY = "Juggles" + } } diff --git a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json index 0b73cfa35..3018f8419 100644 --- a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json +++ b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json @@ -16,6 +16,8 @@ "advancements.avm_staff.get_pranked_lol.title": "Get pranked LOL", "advancements.avm_staff.infinite_power.description": "Obtain a staff", "advancements.avm_staff.infinite_power.title": "Infinite Power!", + "advancements.avm_staff.juggler.description": "Hit an %s 3 times", + "advancements.avm_staff.juggler.title": "Juggler", "advancements.avm_staff.learning_to_fly.description": "Use a %s to fly", "advancements.avm_staff.learning_to_fly.title": "Learning to fly", "advancements.avm_staff.meet_the_engineer.description": "Get thrown with a %s launched by an %s", diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/juggler.json b/StaffMod/src/main/resources/data/avm_staff/advancement/juggler.json new file mode 100644 index 000000000..f20172bef --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/juggler.json @@ -0,0 +1,38 @@ +{ + "parent": "avm_staff:infinite_power", + "display": { + "icon": { + "id": "avm_staff:royal_staff", + "components": { + "avm_staff:staff_item": { + "item": { + "id": "minecraft:tnt" + } + } + } + }, + "title": { + "translate": "advancements.avm_staff.juggler.title" + }, + "description": { + "translate": "advancements.avm_staff.juggler.description", + "with": [ + { + "translate": "entity.avm_staff.impact_tnt" + } + ] + }, + "frame": "challenge" + }, + "criteria": { + "juggler": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { + "entity": { + "type": "avm_staff:impact_tnt", + "nbt": "{Juggles:3}" + } + } + } + } +} From 042a704128ca05e4b8b96a54729a7893495a2a44 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 23 Nov 2024 16:48:29 +0100 Subject: [PATCH 50/83] Trigger criteria when killing cake and impact TNT --- .../kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt | 7 +++++++ .../opekope2/avm_staff/api/entity/ImpactTntEntity.kt | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt index 9c01f5860..00d7144bc 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CakeEntity.kt @@ -20,6 +20,7 @@ package opekope2.avm_staff.api.entity import net.fabricmc.api.EnvType import net.fabricmc.api.Environment +import net.minecraft.advancement.criterion.Criteria import net.minecraft.block.Blocks import net.minecraft.client.option.GraphicsMode import net.minecraft.client.particle.BlockDustParticle @@ -32,6 +33,7 @@ import net.minecraft.network.packet.s2c.play.EntitySpawnS2CPacket import net.minecraft.predicate.entity.EntityPredicates import net.minecraft.registry.tag.DamageTypeTags import net.minecraft.server.network.EntityTrackerEntry +import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.sound.SoundCategory import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Vec3d @@ -203,6 +205,11 @@ class CakeEntity(entityType: EntityType, world: World) : Entity(enti if (!isRemoved && !isInvulnerableTo(source) && !source.isIn(DamageTypeTags.IS_EXPLOSION)) { discard() + + val attacker = source.attacker + if (attacker is ServerPlayerEntity) { + Criteria.PLAYER_KILLED_ENTITY.trigger(attacker, this, source) + } } return super.damage(source, amount) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntEntity.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntEntity.kt index e9c3d540a..da27de112 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntEntity.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntEntity.kt @@ -99,6 +99,10 @@ class ImpactTntEntity(entityType: EntityType, world: World) : T } } else { explodeLater() + + if (attacker is ServerPlayerEntity) { + Criteria.PLAYER_KILLED_ENTITY.trigger(attacker, this, source) + } } } } From f6d8fd286b26e4bc1b0d652e2891e3bd380e2e6a Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 23 Nov 2024 18:03:39 +0100 Subject: [PATCH 51/83] Adjust advancements an en_us.json --- .../assets/avm_staff/lang/en_us.json | 30 +++++++++---------- .../data/avm_staff/advancement/bazeboze.json | 30 +++++++++++-------- .../data/avm_staff/advancement/bulldozer.json | 16 +++++++--- .../avm_staff/advancement/coming_down.json | 2 +- .../flying_into_space_like_a_rocket.json | 19 +++++++----- .../advancement/get_pranked_lol.json | 9 ++++-- .../avm_staff/advancement/infinite_power.json | 10 ++++++- .../data/avm_staff/advancement/juggler.json | 9 ++++-- .../advancement/learning_to_fly.json | 19 +++++++----- .../advancement/meet_the_engineer.json | 27 ++++++++++++----- .../data/avm_staff/advancement/prankster.json | 9 ++++-- .../advancement/trust_me_im_an_engineer.json | 27 ++++++++++++----- 12 files changed, 135 insertions(+), 72 deletions(-) diff --git a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json index 3018f8419..83d7ec21a 100644 --- a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json +++ b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json @@ -1,30 +1,29 @@ { - "stat_type.avm_staff.used_item_in_staff": "Used in Staff", - "advancements.avm_staff.bazeboze.description": "Hit a %s using a %s", + "advancements.avm_staff.bazeboze.description": "Hit %s using %s", "advancements.avm_staff.bazeboze.title": "Bazeboze", - "advancements.avm_staff.bulldozer.description": "Cause mass destruction using a staff", + "advancements.avm_staff.bulldozer.description": "Cause mass destruction using %s", "advancements.avm_staff.bulldozer.title": "Bulldozer", "advancements.avm_staff.coming_down.description": "...is the hardest thing", "advancements.avm_staff.coming_down.title": "Coming down", - "advancements.avm_staff.coronavirus.description": "Die while wearing a %s cursed with %s", + "advancements.avm_staff.coronavirus.description": "Die while wearing %s cursed with %s", "advancements.avm_staff.coronavirus.title": "Coronavirus", - "advancements.avm_staff.engineered_attack.description": "Use an %s to launch a %s at someone", + "advancements.avm_staff.engineered_attack.description": "Use %s to launch %s at someone", "advancements.avm_staff.engineered_attack.title": "Trust me, I'm an engineer!", - "advancements.avm_staff.flying_into_space_like_a_rocket.description": "Use a %s to fly above build limit", + "advancements.avm_staff.flying_into_space_like_a_rocket.description": "Use %s to fly above build limit", "advancements.avm_staff.flying_into_space_like_a_rocket.title": "Flying into space like a rocket", - "advancements.avm_staff.get_pranked_lol.description": "Get thrown with a %s", + "advancements.avm_staff.get_pranked_lol.description": "Get thrown with %s", "advancements.avm_staff.get_pranked_lol.title": "Get pranked LOL", - "advancements.avm_staff.infinite_power.description": "Obtain a staff", + "advancements.avm_staff.infinite_power.description": "Obtain %s", "advancements.avm_staff.infinite_power.title": "Infinite Power!", - "advancements.avm_staff.juggler.description": "Hit an %s 3 times", + "advancements.avm_staff.juggler.description": "Hit %s 3 times", "advancements.avm_staff.juggler.title": "Juggler", - "advancements.avm_staff.learning_to_fly.description": "Use a %s to fly", + "advancements.avm_staff.learning_to_fly.description": "Use %s to fly", "advancements.avm_staff.learning_to_fly.title": "Learning to fly", - "advancements.avm_staff.meet_the_engineer.description": "Get thrown with a %s launched by an %s", + "advancements.avm_staff.meet_the_engineer.description": "Get thrown with %s launched by %s", "advancements.avm_staff.meet_the_engineer.title": "Meet the Engineer", - "advancements.avm_staff.meteor.description": "Reach Mach 0.5 falling down", + "advancements.avm_staff.meteor.description": "Reach Mach 0.5 while falling down", "advancements.avm_staff.meteor.title": "Meteor", - "advancements.avm_staff.prankster.description": "Throw a %s at someone", + "advancements.avm_staff.prankster.description": "Throw %s at someone", "advancements.avm_staff.prankster.title": "Prankster", "block.avm_staff.crown_of_king_orange": "Crown of King Orange", "death.attack.avm_staff.pranked": "%s was pranked", @@ -41,15 +40,16 @@ "item.avm_staff.royal_staff": "Royal staff", "item.avm_staff.royal_staff.with_item": "Royal staff with %s", "item.avm_staff.royal_staff_ingredient": "Royal staff ingredient", + "item.avm_staff.staff": "Staff", + "item.avm_staff.staff.with_item": "Staff with %s", "item.avm_staff.staff_infusion_smithing_template": "Smithing Template", "item.avm_staff.staff_infusion_smithing_template.applies_to": "Faint staffs", "item.avm_staff.staff_infusion_smithing_template.base_slot_description": "Add faint staff", "item.avm_staff.staff_infusion_smithing_template.title": "Staff Infusion Template", - "item.avm_staff.staff_template": "Staff", - "item.avm_staff.staff_template.with_item": "Staff with %s", "itemGroup.avm_staff_items": "Staff Mod", "key.avm_staff.add_remove_staff_item": "Add/remove staff item", "key.categories.avm_staff": "Staff Mod", + "stat_type.avm_staff.used_item_in_staff": "Used in Staff", "subtitles.entity.avm_staff.cake.splash": "Cake splashes", "subtitles.entity.avm_staff.cake.throw": "Cake flies", "tag.item.avm_staff.staffs": "Staffs" diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/bazeboze.json b/StaffMod/src/main/resources/data/avm_staff/advancement/bazeboze.json index cd2e36b58..16fb83ba6 100644 --- a/StaffMod/src/main/resources/data/avm_staff/advancement/bazeboze.json +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/bazeboze.json @@ -1,5 +1,5 @@ { - "parent": "avm_staff:infinite_power", + "parent": "avm_staff:bulldozer", "display": { "icon": { "id": "avm_staff:royal_staff", @@ -17,17 +17,23 @@ "description": { "translate": "advancements.avm_staff.bazeboze.description", "with": [ - { - "translate": "entity.minecraft.bat" - }, - { - "translate": "item.avm_staff.staff_template.with_item", - "with": [ - { - "translate": "block.minecraft.netherite_block" - } - ] - } + [ + "a ", + { + "translate": "entity.minecraft.bat" + } + ], + [ + "a ", + { + "translate": "item.avm_staff.staff.with_item", + "with": [ + { + "translate": "block.minecraft.netherite_block" + } + ] + } + ] ] } }, diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/bulldozer.json b/StaffMod/src/main/resources/data/avm_staff/advancement/bulldozer.json index fe5da97b5..858d9675b 100644 --- a/StaffMod/src/main/resources/data/avm_staff/advancement/bulldozer.json +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/bulldozer.json @@ -6,7 +6,7 @@ "components": { "avm_staff:staff_item": { "item": { - "id": "minecraft:netherite_block" + "id": "minecraft:diamond_block" } } } @@ -14,9 +14,17 @@ "title": { "translate": "advancements.avm_staff.bulldozer.title" }, - "description": { - "translate": "advancements.avm_staff.bulldozer.description" - } + "description": [ + [ + "a ", + { + "translate": "item.avm_staff.staff" + } + ], + { + "translate": "advancements.avm_staff.bulldozer.description" + } + ] }, "criteria": { "use_diamond_block_staff": { diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/coming_down.json b/StaffMod/src/main/resources/data/avm_staff/advancement/coming_down.json index bace7c38c..e292bbcc7 100644 --- a/StaffMod/src/main/resources/data/avm_staff/advancement/coming_down.json +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/coming_down.json @@ -2,7 +2,7 @@ "parent": "avm_staff:learning_to_fly", "display": { "icon": { - "id": "minecraft:anvil" + "id": "minecraft:damaged_anvil" }, "title": { "translate": "advancements.avm_staff.coming_down.title" diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/flying_into_space_like_a_rocket.json b/StaffMod/src/main/resources/data/avm_staff/advancement/flying_into_space_like_a_rocket.json index 40368876b..0cb8912fd 100644 --- a/StaffMod/src/main/resources/data/avm_staff/advancement/flying_into_space_like_a_rocket.json +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/flying_into_space_like_a_rocket.json @@ -17,14 +17,17 @@ "description": { "translate": "advancements.avm_staff.flying_into_space_like_a_rocket.description", "with": [ - { - "translate": "item.avm_staff.staff_template.with_item", - "with": [ - { - "translate": "block.minecraft.campfire" - } - ] - } + [ + "a ", + { + "translate": "item.avm_staff.staff.with_item", + "with": [ + { + "translate": "block.minecraft.campfire" + } + ] + } + ] ] } }, diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/get_pranked_lol.json b/StaffMod/src/main/resources/data/avm_staff/advancement/get_pranked_lol.json index 2b8fd8472..75f0c2986 100644 --- a/StaffMod/src/main/resources/data/avm_staff/advancement/get_pranked_lol.json +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/get_pranked_lol.json @@ -10,9 +10,12 @@ "description": { "translate": "advancements.avm_staff.get_pranked_lol.description", "with": [ - { - "translate": "block.minecraft.cake" - } + [ + "a ", + { + "translate": "block.minecraft.cake" + } + ] ] } }, diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/infinite_power.json b/StaffMod/src/main/resources/data/avm_staff/advancement/infinite_power.json index 00489979c..6b17db508 100644 --- a/StaffMod/src/main/resources/data/avm_staff/advancement/infinite_power.json +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/infinite_power.json @@ -14,7 +14,15 @@ "translate": "advancements.avm_staff.infinite_power.title" }, "description": { - "translate": "advancements.avm_staff.infinite_power.description" + "translate": "advancements.avm_staff.infinite_power.description", + "with": [ + [ + "a ", + { + "translate": "item.avm_staff.staff" + } + ] + ] }, "frame": "goal", "background": "minecraft:textures/block/smithing_table_top.png" diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/juggler.json b/StaffMod/src/main/resources/data/avm_staff/advancement/juggler.json index f20172bef..dc4df4054 100644 --- a/StaffMod/src/main/resources/data/avm_staff/advancement/juggler.json +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/juggler.json @@ -17,9 +17,12 @@ "description": { "translate": "advancements.avm_staff.juggler.description", "with": [ - { - "translate": "entity.avm_staff.impact_tnt" - } + [ + "an ", + { + "translate": "entity.avm_staff.impact_tnt" + } + ] ] }, "frame": "challenge" diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/learning_to_fly.json b/StaffMod/src/main/resources/data/avm_staff/advancement/learning_to_fly.json index 0883fd8d2..3c8ecba8b 100644 --- a/StaffMod/src/main/resources/data/avm_staff/advancement/learning_to_fly.json +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/learning_to_fly.json @@ -17,14 +17,17 @@ "description": { "translate": "advancements.avm_staff.learning_to_fly.description", "with": [ - { - "translate": "item.avm_staff.staff_template.with_item", - "with": [ - { - "translate": "block.minecraft.campfire" - } - ] - } + [ + "a ", + { + "translate": "item.avm_staff.staff.with_item", + "with": [ + { + "translate": "block.minecraft.campfire" + } + ] + } + ] ] } }, diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/meet_the_engineer.json b/StaffMod/src/main/resources/data/avm_staff/advancement/meet_the_engineer.json index fdf35141f..d301de4d3 100644 --- a/StaffMod/src/main/resources/data/avm_staff/advancement/meet_the_engineer.json +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/meet_the_engineer.json @@ -2,7 +2,14 @@ "parent": "avm_staff:get_pranked_lol", "display": { "icon": { - "id": "minecraft:cake" + "id": "avm_staff:royal_staff", + "components": { + "avm_staff:staff_item": { + "item": { + "id": "minecraft:cake" + } + } + } }, "title": { "translate": "advancements.avm_staff.meet_the_engineer.title" @@ -10,12 +17,18 @@ "description": { "translate": "advancements.avm_staff.meet_the_engineer.description", "with": [ - { - "translate": "block.minecraft.cake" - }, - { - "translate": "entity.avm_staff.impact_tnt" - } + [ + "a ", + { + "translate": "block.minecraft.cake" + } + ], + [ + "an ", + { + "translate": "entity.avm_staff.impact_tnt" + } + ] ] }, "hidden": true diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/prankster.json b/StaffMod/src/main/resources/data/avm_staff/advancement/prankster.json index 70b9d4437..b6f2cd839 100644 --- a/StaffMod/src/main/resources/data/avm_staff/advancement/prankster.json +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/prankster.json @@ -10,9 +10,12 @@ "description": { "translate": "advancements.avm_staff.prankster.description", "with": [ - { - "translate": "block.minecraft.cake" - } + [ + "a ", + { + "translate": "block.minecraft.cake" + } + ] ] } }, diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/trust_me_im_an_engineer.json b/StaffMod/src/main/resources/data/avm_staff/advancement/trust_me_im_an_engineer.json index 0f4a95212..476e01ad0 100644 --- a/StaffMod/src/main/resources/data/avm_staff/advancement/trust_me_im_an_engineer.json +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/trust_me_im_an_engineer.json @@ -2,7 +2,14 @@ "parent": "avm_staff:prankster", "display": { "icon": { - "id": "minecraft:cake" + "id": "avm_staff:royal_staff", + "components": { + "avm_staff:staff_item": { + "item": { + "id": "minecraft:cake" + } + } + } }, "title": { "translate": "advancements.avm_staff.engineered_attack.title" @@ -10,12 +17,18 @@ "description": { "translate": "advancements.avm_staff.engineered_attack.description", "with": [ - { - "translate": "entity.avm_staff.impact_tnt" - }, - { - "translate": "block.minecraft.cake" - } + [ + "an ", + { + "translate": "entity.avm_staff.impact_tnt" + } + ], + [ + "a ", + { + "translate": "block.minecraft.cake" + } + ] ] }, "frame": "challenge", From c9454fbe75247cb7e84beb74dee47e4bf897c01a Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 23 Nov 2024 18:32:45 +0100 Subject: [PATCH 52/83] Only increment stats server-side --- .../kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt | 3 ++- .../staff/handler/AbstractMassDestructiveStaffHandler.kt | 5 +++-- .../handler/AbstractProjectileShootingStaffHandler.kt | 9 +++++---- .../avm_staff/internal/staff/handler/AnvilHandler.kt | 5 +++-- .../avm_staff/internal/staff/handler/BellHandler.kt | 3 ++- .../avm_staff/internal/staff/handler/BoneBlockHandler.kt | 6 +++--- .../avm_staff/internal/staff/handler/CampfireHandler.kt | 7 ++++--- .../avm_staff/internal/staff/handler/FurnaceHandler.kt | 5 +++-- .../internal/staff/handler/LightningRodHandler.kt | 5 +++-- .../internal/staff/handler/MagmaBlockHandler.kt | 4 ++-- .../internal/staff/handler/NetheriteBlockHandler.kt | 3 ++- .../avm_staff/internal/staff/handler/TntHandler.kt | 5 +++-- .../internal/staff/handler/WitherSkeletonSkullHandler.kt | 3 ++- .../avm_staff/internal/staff/handler/WoolHandler.kt | 3 ++- .../src/main/kotlin/opekope2/avm_staff/util/StatUtil.kt | 6 +++--- 15 files changed, 42 insertions(+), 30 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt index b6a02d45a..4875be828 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt @@ -30,6 +30,7 @@ import net.minecraft.item.Item import net.minecraft.item.ItemStack import net.minecraft.item.Items import net.minecraft.registry.Registries +import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.stat.Stats import net.minecraft.util.* import net.minecraft.util.math.BlockPos @@ -389,7 +390,7 @@ abstract class StaffHandler { } onStoppedUsing(staffStack, world, user, 0) - (user as? PlayerEntity)?.incrementStaffItemUseStat(Items.AIR) + (user as? ServerPlayerEntity)?.incrementStaffItemUseStat(Items.AIR) return staffStack } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractMassDestructiveStaffHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractMassDestructiveStaffHandler.kt index 3f02f1162..f0b1917e2 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractMassDestructiveStaffHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractMassDestructiveStaffHandler.kt @@ -22,6 +22,7 @@ import dev.architectury.event.EventResult import net.minecraft.entity.LivingEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack +import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.server.world.ServerWorld import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos @@ -67,8 +68,8 @@ internal abstract class AbstractMassDestructiveStaffHandler : StaffHandler() { ) dropCollector.dropAll(world) - (attacker as? PlayerEntity)?.incrementItemUseStat(staffStack.item) - (attacker as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + (attacker as? ServerPlayerEntity)?.incrementItemUseStat(staffStack.item) + (attacker as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) // "Mismatch in destroy block pos" in server logs if I interrupt on server but not on client side. Nothing bad should happen, right? return EventResult.pass() diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt index 54706cf94..b45a0a0df 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt @@ -22,6 +22,7 @@ import net.minecraft.enchantment.EnchantmentHelper import net.minecraft.entity.LivingEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack +import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.util.Hand import net.minecraft.util.TypedActionResult import net.minecraft.world.World @@ -51,16 +52,16 @@ internal abstract class AbstractProjectileShootingStaffHandler : StaffHandler() override fun usageTick(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { if (tryShootProjectile(world, user, ProjectileShootReason.USE)) { staffStack.damage(entity = user) - (user as? PlayerEntity)?.incrementItemUseStat(staffStack.item) - (user as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + (user as? ServerPlayerEntity)?.incrementItemUseStat(staffStack.item) + (user as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) } } override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand) { if (tryShootProjectile(world, attacker, ProjectileShootReason.ATTACK)) { staffStack.damage(entity = attacker) - (attacker as? PlayerEntity)?.incrementItemUseStat(staffStack.item) - (attacker as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + (attacker as? ServerPlayerEntity)?.incrementItemUseStat(staffStack.item) + (attacker as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) } (attacker as? PlayerEntity)?.resetLastAttackedTicks() } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AnvilHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AnvilHandler.kt index ee8162e3a..bda8cf50e 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AnvilHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AnvilHandler.kt @@ -28,6 +28,7 @@ import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.Item import net.minecraft.item.ItemStack import net.minecraft.predicate.entity.EntityPredicates +import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.util.Hand import net.minecraft.util.Identifier import net.minecraft.util.math.BlockPos @@ -87,8 +88,8 @@ internal class AnvilHandler(private val damagedItem: Item?) : StaffHandler() { 0 ) - (attacker as? PlayerEntity)?.incrementItemUseStat(staffStack.item) - (attacker as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + (attacker as? ServerPlayerEntity)?.incrementItemUseStat(staffStack.item) + (attacker as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) staffStack.damage(damagedEntities, attacker, LivingEntity.getSlotForHand(hand)) return EventResult.interruptDefault() diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt index 573b63f0d..b37acd30d 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt @@ -26,6 +26,7 @@ import net.minecraft.entity.ai.brain.MemoryModuleType import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack +import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.sound.SoundCategory import net.minecraft.sound.SoundEvents import net.minecraft.util.Hand @@ -99,7 +100,7 @@ internal class BellHandler : StaffHandler() { IBellBlockEntityAccessor.callApplyGlowToEntity(target) } - (attacker as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + (attacker as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) return EventResult.pass() } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BoneBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BoneBlockHandler.kt index 7be1b2eaa..ea2ff1380 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BoneBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BoneBlockHandler.kt @@ -21,10 +21,10 @@ package opekope2.avm_staff.internal.staff.handler import net.minecraft.component.type.AttributeModifierSlot import net.minecraft.entity.LivingEntity import net.minecraft.entity.attribute.EntityAttributes -import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.BoneMealItem import net.minecraft.item.ItemStack import net.minecraft.item.Items +import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.util.ActionResult import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos @@ -62,7 +62,7 @@ internal class BoneBlockHandler : StaffHandler() { world.syncWorldEvent(WorldEvents.BONE_MEAL_USED, target, 15) } - (user as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + (user as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) staffStack.damage(1, user, LivingEntity.getSlotForHand(hand)) return ActionResult.SUCCESS @@ -79,7 +79,7 @@ internal class BoneBlockHandler : StaffHandler() { world.syncWorldEvent(WorldEvents.BONE_MEAL_USED, neighborOnUsedSide, 15) } - (user as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + (user as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) staffStack.damage(1, user, LivingEntity.getSlotForHand(hand)) return ActionResult.SUCCESS diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt index 2bc93e96b..cbd7e243d 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt @@ -25,6 +25,7 @@ import net.minecraft.entity.LivingEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack import net.minecraft.particle.SimpleParticleType +import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.util.Hand import net.minecraft.util.TypedActionResult import net.minecraft.util.math.MathHelper @@ -93,8 +94,8 @@ internal class CampfireHandler(private val parameters: Parameters) : StaffHandle override fun onStoppedUsing(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { staffStack.remove(ComponentTypes.rocketMode) - (user as? PlayerEntity)?.incrementItemUseStat(staffStack.item) - (user as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + (user as? ServerPlayerEntity)?.incrementItemUseStat(staffStack.item) + (user as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) } override fun finishUsing(staffStack: ItemStack, world: World, user: LivingEntity): ItemStack { @@ -111,7 +112,7 @@ internal class CampfireHandler(private val parameters: Parameters) : StaffHandle ): EventResult { target.setOnFireFor(parameters.attackFireSeconds) - (attacker as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + (attacker as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) return EventResult.pass() } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt index 989fdabff..20ee1aa6d 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt @@ -31,6 +31,7 @@ import net.minecraft.particle.ParticleTypes import net.minecraft.recipe.AbstractCookingRecipe import net.minecraft.recipe.RecipeType import net.minecraft.recipe.input.SingleStackRecipeInput +import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.server.world.ServerWorld import net.minecraft.sound.SoundCategory import net.minecraft.sound.SoundEvent @@ -103,7 +104,7 @@ internal class FurnaceHandler( furnaceData.burnTicks -= stackToSmelt.count staffStack.damage(stackToSmelt.count, user, LivingEntity.getSlotForHand(user.activeHand)) - (user as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + (user as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) } private fun findItemToSmelt(world: World, smeltingPosition: Vec3d): ItemEntity? { @@ -129,7 +130,7 @@ internal class FurnaceHandler( override fun onStoppedUsing(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { staffStack.remove(ComponentTypes.furnaceData) - (user as? PlayerEntity)?.incrementItemUseStat(staffStack.item) + (user as? ServerPlayerEntity)?.incrementItemUseStat(staffStack.item) } override fun finishUsing(staffStack: ItemStack, world: World, user: LivingEntity): ItemStack { diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/LightningRodHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/LightningRodHandler.kt index 39f91404c..a2c99d639 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/LightningRodHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/LightningRodHandler.kt @@ -27,6 +27,7 @@ import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.Item import net.minecraft.item.ItemStack +import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.util.ActionResult import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos @@ -61,7 +62,7 @@ internal class LightningRodHandler : StaffHandler() { if (result.isAccepted) staffStack.damage(1, user, LivingEntity.getSlotForHand(hand)) if (result.shouldIncrementStat()) { - (user as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + (user as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) } return result @@ -78,7 +79,7 @@ internal class LightningRodHandler : StaffHandler() { if (result.isAccepted) staffStack.damage(1, user, LivingEntity.getSlotForHand(hand)) if (result.shouldIncrementStat()) { - (user as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + (user as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) } return result diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/MagmaBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/MagmaBlockHandler.kt index a8e590eba..7626c0fd6 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/MagmaBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/MagmaBlockHandler.kt @@ -24,9 +24,9 @@ import net.minecraft.entity.Entity import net.minecraft.entity.EntityType import net.minecraft.entity.LivingEntity import net.minecraft.entity.attribute.EntityAttributes -import net.minecraft.entity.player.PlayerEntity import net.minecraft.entity.projectile.SmallFireballEntity import net.minecraft.item.ItemStack +import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.util.Hand import net.minecraft.world.World import net.minecraft.world.WorldEvents @@ -69,7 +69,7 @@ internal class MagmaBlockHandler : AbstractProjectileShootingStaffHandler() { ): EventResult { target.setOnFireFor(8f) - (attacker as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + (attacker as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) return EventResult.pass() } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/NetheriteBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/NetheriteBlockHandler.kt index 3a327bc95..4e826c7e7 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/NetheriteBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/NetheriteBlockHandler.kt @@ -26,6 +26,7 @@ import net.minecraft.entity.LivingEntity import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack +import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.server.world.ServerWorld import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos @@ -94,7 +95,7 @@ internal class NetheriteBlockHandler : AbstractMassDestructiveStaffHandler() { world.syncWorldEvent(WorldEvents.SMASH_ATTACK, target.steppingPos, 750) - (attacker as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + (attacker as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) return EventResult.pass() } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt index 1071fc488..811a2dd34 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt @@ -21,6 +21,7 @@ package opekope2.avm_staff.internal.staff.handler import net.minecraft.entity.LivingEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack +import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.sound.SoundCategory import net.minecraft.sound.SoundEvents import net.minecraft.util.Hand @@ -35,8 +36,8 @@ internal class TntHandler : StaffHandler() { override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand) { if (tryShootTnt(world, attacker)) { staffStack.damage(1, attacker, LivingEntity.getSlotForHand(hand)) - (attacker as? PlayerEntity)?.incrementItemUseStat(staffStack.item) - (attacker as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + (attacker as? ServerPlayerEntity)?.incrementItemUseStat(staffStack.item) + (attacker as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) } (attacker as? PlayerEntity)?.resetLastAttackedTicks() } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt index fc5204585..593256811 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt @@ -27,6 +27,7 @@ import net.minecraft.entity.effect.StatusEffects import net.minecraft.entity.player.PlayerEntity import net.minecraft.entity.projectile.WitherSkullEntity import net.minecraft.item.ItemStack +import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.util.Hand import net.minecraft.world.Difficulty import net.minecraft.world.World @@ -76,7 +77,7 @@ internal class WitherSkeletonSkullHandler : AbstractProjectileShootingStaffHandl if (target is LivingEntity && !target.isInvulnerableTo(world.damageSources.wither())) { val amplifier = if (world.difficulty == Difficulty.HARD) 1 else 0 target.addStatusEffect(StatusEffectInstance(StatusEffects.WITHER, 10 * 20, amplifier)) - (attacker as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + (attacker as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) } return EventResult.pass() diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WoolHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WoolHandler.kt index 09e4c2cea..325816379 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WoolHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WoolHandler.kt @@ -28,6 +28,7 @@ import net.minecraft.item.BlockItem import net.minecraft.item.ItemPlacementContext import net.minecraft.item.ItemStack import net.minecraft.registry.tag.BlockTags +import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.util.ActionResult import net.minecraft.util.Hand import net.minecraft.util.hit.BlockHitResult @@ -76,7 +77,7 @@ internal class WoolHandler(private val woolItem: BlockItem, private val carpetIt if (result.isAccepted) staffStack.damage(1, user, LivingEntity.getSlotForHand(hand)) if (result.shouldIncrementStat()) { - (user as? PlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + (user as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) } return result diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StatUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StatUtil.kt index c24a3e3d2..b52ae53ec 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StatUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StatUtil.kt @@ -20,21 +20,21 @@ package opekope2.avm_staff.util -import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.Item +import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.stat.Stats import opekope2.avm_staff.content.StatTypes /** * Increments [Stats.USED] of [item] by 1. */ -fun PlayerEntity.incrementItemUseStat(item: Item) { +fun ServerPlayerEntity.incrementItemUseStat(item: Item) { incrementStat(Stats.USED.getOrCreateStat(item)) } /** * Increments [StatTypes.usedItemInStaff] of [item] by 1. */ -fun PlayerEntity.incrementStaffItemUseStat(item: Item) { +fun ServerPlayerEntity.incrementStaffItemUseStat(item: Item) { incrementStat(StatTypes.usedItemInStaff.getOrCreateStat(item)) } From e7880525f30ef3662b7680e12bb1dc607e38aa45 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 23 Nov 2024 22:23:30 +0100 Subject: [PATCH 53/83] Add right click throw to TNT staff --- .../api/component/StaffTntDataComponent.kt | 39 ++++++++++ .../avm_staff/content/ComponentTypes.kt | 22 ++++-- .../internal/staff/handler/TntHandler.kt | 71 ++++++++++++++++--- 3 files changed, 120 insertions(+), 12 deletions(-) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/StaffTntDataComponent.kt diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/StaffTntDataComponent.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/StaffTntDataComponent.kt new file mode 100644 index 000000000..8090f0106 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/component/StaffTntDataComponent.kt @@ -0,0 +1,39 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.api.component + +import net.minecraft.network.RegistryByteBuf +import net.minecraft.network.codec.PacketCodec +import opekope2.avm_staff.api.entity.ImpactTntEntity + +/** + * Data components to store the shot TNT in a TNT staff. + * + * @param tnt The shot TNT entity. Only available server-side + */ +data class StaffTntDataComponent(val tnt: ImpactTntEntity?) { + companion object { + /** + * [PacketCodec] for [StaffTntDataComponent], which doesn't sync its data. + */ + @JvmField + val NON_SYNCING_PACKET_CODEC: PacketCodec = + PacketCodec.of({ _, _ -> }, { StaffTntDataComponent(null) }) + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt index 985121b09..626fb4a2d 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt @@ -21,10 +21,7 @@ package opekope2.avm_staff.content import net.minecraft.component.ComponentType import net.minecraft.network.codec.PacketCodec import net.minecraft.registry.RegistryKeys -import opekope2.avm_staff.api.component.BlockPickupDataComponent -import opekope2.avm_staff.api.component.StaffFurnaceDataComponent -import opekope2.avm_staff.api.component.StaffItemComponent -import opekope2.avm_staff.api.component.StaffRendererPartComponent +import opekope2.avm_staff.api.component.* import opekope2.avm_staff.internal.MinecraftUnit import opekope2.avm_staff.internal.minecraftUnit import opekope2.avm_staff.util.MOD_ID @@ -120,4 +117,21 @@ object ComponentTypes : RegistryUtil>(MOD_ID, RegistryKeys.DATA val blockPickupData: ComponentType @JvmName("blockPickupData") get() = BLOCK_PICKUP_DATA.get() + + /** + * Data component registered as `avm_staff:tnt_data`. + */ + @JvmField + val TNT_DATA = register("tnt_data") { + ComponentType.builder() + .packetCodec(StaffTntDataComponent.NON_SYNCING_PACKET_CODEC) + .build() + } + + /** + * @see TNT_DATA + */ + val tntData: ComponentType + @JvmName("tntData") + get() = TNT_DATA.get() } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt index 811a2dd34..ee5dfada2 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt @@ -25,16 +25,57 @@ import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.sound.SoundCategory import net.minecraft.sound.SoundEvents import net.minecraft.util.Hand +import net.minecraft.util.TypedActionResult import net.minecraft.world.World import net.minecraft.world.event.GameEvent +import opekope2.avm_staff.api.component.StaffTntDataComponent import opekope2.avm_staff.api.entity.ImpactTntEntity import opekope2.avm_staff.api.staff.StaffHandler +import opekope2.avm_staff.content.ComponentTypes import opekope2.avm_staff.content.EntityTypes import opekope2.avm_staff.util.* internal class TntHandler : StaffHandler() { + override fun getMaxUseTime(staffStack: ItemStack, world: World, user: LivingEntity) = 4 * 20 + + override fun use( + staffStack: ItemStack, + world: World, + user: PlayerEntity, + hand: Hand + ): TypedActionResult { + val tnt = tryShootTnt(world, user) ?: return TypedActionResult.pass(staffStack) + + staffStack[ComponentTypes.tntData] = StaffTntDataComponent(tnt) + + user.setCurrentHand(hand) + return TypedActionResult.consume(staffStack) + } + + override fun usageTick(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { + if (!world.isClient && staffStack[ComponentTypes.tntData]?.tnt?.isRemoved == true) { + user.stopUsingItem() // TODO reset last attacked ticks on client + } + } + + override fun onStoppedUsing(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { + val tntData = staffStack.remove(ComponentTypes.tntData) + if (!world.isClient && tntData?.tnt?.isAlive == true) { + tntData.tnt.explodeLater() + } + + (user as? ServerPlayerEntity)?.incrementItemUseStat(staffStack.item) + (user as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + (user as? PlayerEntity)?.resetLastAttackedTicks() + } + + override fun finishUsing(staffStack: ItemStack, world: World, user: LivingEntity): ItemStack { + onStoppedUsing(staffStack, world, user, 0) + return staffStack + } + override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand) { - if (tryShootTnt(world, attacker)) { + if (tryShootTnt(world, attacker) != null) { staffStack.damage(1, attacker, LivingEntity.getSlotForHand(hand)) (attacker as? ServerPlayerEntity)?.incrementItemUseStat(staffStack.item) (attacker as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) @@ -42,16 +83,30 @@ internal class TntHandler : StaffHandler() { (attacker as? PlayerEntity)?.resetLastAttackedTicks() } - private fun tryShootTnt(world: World, shooter: LivingEntity): Boolean { - if (world.isClient) return false - if (!shooter.canUseStaff) return false - if (shooter is PlayerEntity && shooter.isAttackCoolingDown) return false + override fun allowComponentsUpdateAnimation( + oldStaffStack: ItemStack, + newStaffStack: ItemStack, + player: PlayerEntity, + hand: Hand + ) = false + + override fun allowReequipAnimation( + oldStaffStack: ItemStack, + newStaffStack: ItemStack, + selectedSlotChanged: Boolean + ) = selectedSlotChanged + + private fun tryShootTnt(world: World, shooter: LivingEntity): ImpactTntEntity? { + if (world.isClient) return null + if (!shooter.canUseStaff) return null + if (shooter is PlayerEntity && shooter.isAttackCoolingDown) return null val spawnPos = - EntityTypes.impactTnt.getSpawnPosition(world, shooter.approximateStaffTipPosition) ?: return false + EntityTypes.impactTnt.getSpawnPosition(world, shooter.approximateStaffTipPosition) ?: return null val (x, y, z) = spawnPos - world.spawnEntity(ImpactTntEntity(world, x, y, z, shooter.rotationVector + shooter.velocity, shooter)) + val tnt = ImpactTntEntity(world, x, y, z, shooter.rotationVector + shooter.velocity, shooter) + world.spawnEntity(tnt) world.playSound( null, x, y, z, @@ -61,6 +116,6 @@ internal class TntHandler : StaffHandler() { world.playSound(null, x, y, z, SoundEvents.ENTITY_TNT_PRIMED, SoundCategory.BLOCKS, 1f, 1f) world.emitGameEvent(shooter, GameEvent.PRIME_FUSE, spawnPos) - return true + return tnt } } From 81f7904c415135725b8c9afc3e40d3eeaeac119d Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 24 Nov 2024 00:42:56 +0100 Subject: [PATCH 54/83] Add efficiency enchantment to bone block staff --- .../staff/handler/BoneBlockHandler.kt | 60 +++++++++++++------ .../tags/item/enchantable/mining.json | 6 ++ 2 files changed, 47 insertions(+), 19 deletions(-) create mode 100644 StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/mining.json diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BoneBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BoneBlockHandler.kt index ea2ff1380..af782c83f 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BoneBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BoneBlockHandler.kt @@ -19,11 +19,14 @@ package opekope2.avm_staff.internal.staff.handler import net.minecraft.component.type.AttributeModifierSlot +import net.minecraft.enchantment.EnchantmentHelper +import net.minecraft.enchantment.Enchantments import net.minecraft.entity.LivingEntity import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.item.BoneMealItem import net.minecraft.item.ItemStack import net.minecraft.item.Items +import net.minecraft.registry.RegistryKeys import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.util.ActionResult import net.minecraft.util.Hand @@ -34,10 +37,7 @@ import net.minecraft.world.WorldEvents import net.minecraft.world.event.GameEvent import opekope2.avm_staff.api.staff.StaffAttributeModifiersComponentBuilder import opekope2.avm_staff.api.staff.StaffHandler -import opekope2.avm_staff.util.attackDamage -import opekope2.avm_staff.util.attackSpeed -import opekope2.avm_staff.util.incrementStaffItemUseStat -import opekope2.avm_staff.util.itemInStaff +import opekope2.avm_staff.util.* internal class BoneBlockHandler : StaffHandler() { override val attributeModifiers = StaffAttributeModifiersComponentBuilder() @@ -55,33 +55,55 @@ internal class BoneBlockHandler : StaffHandler() { side: Direction, hand: Hand ): ActionResult { - if (BoneMealItem.useOnFertilizable(Items.BONE_MEAL.defaultStack, world, target)) { - // TODO fertilize area when enchanted - if (!world.isClient) { - user.emitGameEvent(GameEvent.ITEM_INTERACT_FINISH) - world.syncWorldEvent(WorldEvents.BONE_MEAL_USED, target, 15) - } + if (!useOnFertilizable(world, user, target)) { + return if (useOnGround(world, user, target, side)) { + (user as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + staffStack.damage(1, user, LivingEntity.getSlotForHand(hand)) + ActionResult.SUCCESS + } else ActionResult.PASS + } + + val efficiencyRef = world.registryManager[RegistryKeys.ENCHANTMENT].getEntry(Enchantments.EFFICIENCY).get() + val range = 0.5 + EnchantmentHelper.getLevel(efficiencyRef, staffStack).coerceAtMost(5) / 2.0 + val rangeSquare = range * range + var uses = 0 + + for (pos in BlockPos.iterateOutwards(target, range.toInt(), range.toInt(), range.toInt())) { + if (pos == target) continue + val offset = pos - target + if (offset.x * offset.x + offset.y * offset.y + offset.z * offset.z > rangeSquare) continue + + if (useOnFertilizable(world, user, pos)) uses++ + } + + (user as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) + staffStack.damage(uses, user, hand) + + return ActionResult.SUCCESS + } - (user as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) - staffStack.damage(1, user, LivingEntity.getSlotForHand(hand)) + private fun useOnFertilizable(world: World, user: LivingEntity, target: BlockPos): Boolean { + if (!BoneMealItem.useOnFertilizable(Items.BONE_MEAL.defaultStack, world, target)) return false - return ActionResult.SUCCESS + if (!world.isClient) { + user.emitGameEvent(GameEvent.ITEM_INTERACT_FINISH) + world.syncWorldEvent(WorldEvents.BONE_MEAL_USED, target, 15) } + return true + } + private fun useOnGround(world: World, user: LivingEntity, target: BlockPos, side: Direction): Boolean { val targetState = world.getBlockState(target) - if (!targetState.isSideSolidFullSquare(world, target, side)) return ActionResult.PASS + if (!targetState.isSideSolidFullSquare(world, target, side)) return false val neighborOnUsedSide = target.offset(side) - if (!BoneMealItem.useOnGround(staffStack.copy(), world, neighborOnUsedSide, side)) return ActionResult.PASS + if (!BoneMealItem.useOnGround(Items.BONE_MEAL.defaultStack, world, neighborOnUsedSide, side)) return false if (!world.isClient) { user.emitGameEvent(GameEvent.ITEM_INTERACT_FINISH) world.syncWorldEvent(WorldEvents.BONE_MEAL_USED, neighborOnUsedSide, 15) } - (user as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) - staffStack.damage(1, user, LivingEntity.getSlotForHand(hand)) - - return ActionResult.SUCCESS + return true } } diff --git a/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/mining.json b/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/mining.json new file mode 100644 index 000000000..641e9fc93 --- /dev/null +++ b/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/mining.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "#avm_staff:staffs" + ] +} From 4eae5567f83a1aff6e42656934dece53e0ba00ce Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 24 Nov 2024 14:53:56 +0100 Subject: [PATCH 55/83] Make staffs cursable with vanishing --- .../data/minecraft/tags/item/enchantable/vanishing.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/vanishing.json diff --git a/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/vanishing.json b/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/vanishing.json new file mode 100644 index 000000000..641e9fc93 --- /dev/null +++ b/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/vanishing.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "#avm_staff:staffs" + ] +} From ff1386452fe4ec113c19449bb7540d7c906b39b3 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 24 Nov 2024 17:01:33 +0100 Subject: [PATCH 56/83] Forgot to register some content --- .../opekope2/avm_staff/internal/initializer/Initializer.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt index 60c5d4a13..c570bce41 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt @@ -34,9 +34,13 @@ object Initializer { Blocks.register() ComponentTypes.register() Criteria.register() + DamageTypes + Enchantments.Tags EntityTypes.register() + GameRules ItemGroups.register() Items.register() + Items.Tags ParticleTypes.register() SoundEvents.register() StatTypes.register() From 2a4adb5815a0e246b9de09c15077b750c5dd2cbe Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 24 Nov 2024 17:04:30 +0100 Subject: [PATCH 57/83] Rename ComponentTypes to DataComponentTypes to align with registry name --- .../avm_staff/api/item/renderer/StaffRenderer.kt | 6 +++--- .../opekope2/avm_staff/api/staff/StaffHandler.kt | 10 +++++----- .../{ComponentTypes.kt => DataComponentTypes.kt} | 2 +- .../avm_staff/internal/initializer/Initializer.kt | 2 +- .../avm_staff/internal/model/ModelPredicates.kt | 4 ++-- .../internal/staff/handler/CampfireHandler.kt | 8 ++++---- .../internal/staff/handler/FurnaceHandler.kt | 8 ++++---- .../avm_staff/internal/staff/handler/TntHandler.kt | 8 ++++---- .../staff/item_renderer/FurnaceStaffItemRenderer.kt | 4 ++-- .../main/kotlin/opekope2/avm_staff/util/StaffUtil.kt | 12 ++++++------ 10 files changed, 32 insertions(+), 32 deletions(-) rename StaffMod/src/main/kotlin/opekope2/avm_staff/content/{ComponentTypes.kt => DataComponentTypes.kt} (97%) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt index f67937d92..977835d90 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt @@ -26,7 +26,7 @@ import net.minecraft.client.render.model.json.ModelTransformationMode import net.minecraft.client.util.math.MatrixStack import net.minecraft.item.ItemStack import opekope2.avm_staff.api.component.StaffRendererPartComponent -import opekope2.avm_staff.content.ComponentTypes +import opekope2.avm_staff.content.DataComponentTypes import opekope2.avm_staff.util.bakedModelManager import opekope2.avm_staff.util.itemRenderer import opekope2.avm_staff.util.itemStackInStaff @@ -194,9 +194,9 @@ object StaffRenderer { } private fun safeGetModel(staffStack: ItemStack, part: StaffRendererPartComponent): BakedModel { - staffStack[ComponentTypes.staffRendererPart] = part + staffStack[DataComponentTypes.staffRendererPart] = part val model = itemRenderer.getModel(staffStack, null, null, 0) - staffStack.remove(ComponentTypes.staffRendererPart) + staffStack.remove(DataComponentTypes.staffRendererPart) // Prevent StackOverflowError if an override is missing return if (!model.isBuiltin) model diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt index 4875be828..e10f7c15d 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt @@ -40,7 +40,7 @@ import net.minecraft.world.event.GameEvent import opekope2.avm_staff.api.block.IClearableBeforeInsertedIntoStaff import opekope2.avm_staff.api.component.BlockPickupDataComponent import opekope2.avm_staff.api.registry.RegistryBase -import opekope2.avm_staff.content.ComponentTypes +import opekope2.avm_staff.content.DataComponentTypes import opekope2.avm_staff.util.approximateStaffItemPosition import opekope2.avm_staff.util.incrementStaffItemUseStat import opekope2.avm_staff.util.mutableItemStackInStaff @@ -351,7 +351,7 @@ abstract class StaffHandler { val state = world.getBlockState(targetPos) if (!canPickUp(world, targetPos, state)) return TypedActionResult.fail(staffStack) - staffStack[ComponentTypes.blockPickupData] = BlockPickupDataComponent(targetPos, state) + staffStack[DataComponentTypes.blockPickupData] = BlockPickupDataComponent(targetPos, state) user.setCurrentHand(hand) return TypedActionResult.consume(staffStack) @@ -372,17 +372,17 @@ abstract class StaffHandler { } override fun usageTick(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - if (!world.isClient && userChangedTarget(world, user, staffStack[ComponentTypes.blockPickupData])) { + if (!world.isClient && userChangedTarget(world, user, staffStack[DataComponentTypes.blockPickupData])) { user.stopUsingItem() } } override fun onStoppedUsing(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - staffStack.remove(ComponentTypes.blockPickupData) + staffStack.remove(DataComponentTypes.blockPickupData) } override fun finishUsing(staffStack: ItemStack, world: World, user: LivingEntity): ItemStack { - val blockPickupData = staffStack[ComponentTypes.blockPickupData] + val blockPickupData = staffStack[DataComponentTypes.blockPickupData] if (!userChangedTarget(world, user, blockPickupData)) { require(blockPickupData != null) tryPickUp(world, blockPickupData.pos, blockPickupData.state, staffStack) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/DataComponentTypes.kt similarity index 97% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/content/DataComponentTypes.kt index 626fb4a2d..b8a81dd00 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ComponentTypes.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/DataComponentTypes.kt @@ -30,7 +30,7 @@ import opekope2.avm_staff.util.RegistryUtil /** * Component types added by AVM Staffs mod. */ -object ComponentTypes : RegistryUtil>(MOD_ID, RegistryKeys.DATA_COMPONENT_TYPE) { +object DataComponentTypes : RegistryUtil>(MOD_ID, RegistryKeys.DATA_COMPONENT_TYPE) { /** * Data component registered as `avm_staff:staff_item`. Stores the item inserted into the staff. */ diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt index c570bce41..38312401c 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt @@ -32,9 +32,9 @@ object Initializer { private fun registerContent() { Blocks.register() - ComponentTypes.register() Criteria.register() DamageTypes + DataComponentTypes.register() Enchantments.Tags EntityTypes.register() GameRules diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt index 66abe190f..481c6afc2 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt @@ -25,7 +25,7 @@ import net.minecraft.item.ItemStack import net.minecraft.util.Identifier import opekope2.avm_staff.api.component.StaffRendererPartComponent import opekope2.avm_staff.api.registry.RegistryBase -import opekope2.avm_staff.content.ComponentTypes +import opekope2.avm_staff.content.DataComponentTypes import opekope2.avm_staff.util.MOD_ID @Environment(EnvType.CLIENT) @@ -43,7 +43,7 @@ object ModelPredicates : RegistryBase private fun matchStaffRendererPart(part: StaffRendererPartComponent) = ClampedModelPredicateProvider { stack, _, _, _ -> - if (stack[ComponentTypes.staffRendererPart] == part) 1f + if (stack[DataComponentTypes.staffRendererPart] == part) 1f else 0f } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt index cbd7e243d..97fb60fb9 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt @@ -32,7 +32,7 @@ import net.minecraft.util.math.MathHelper import net.minecraft.world.World import opekope2.avm_staff.api.entity.CampfireFlameEntity import opekope2.avm_staff.api.staff.StaffHandler -import opekope2.avm_staff.content.ComponentTypes +import opekope2.avm_staff.content.DataComponentTypes import opekope2.avm_staff.internal.minecraftUnit import opekope2.avm_staff.util.* @@ -46,7 +46,7 @@ internal class CampfireHandler(private val parameters: Parameters) : StaffHandle hand: Hand ): TypedActionResult { if (user.isSneaking && !user.isOnGround) { - staffStack[ComponentTypes.rocketMode] = minecraftUnit + staffStack[DataComponentTypes.rocketMode] = minecraftUnit } user.setCurrentHand(hand) @@ -60,7 +60,7 @@ internal class CampfireHandler(private val parameters: Parameters) : StaffHandle val origin = user.approximateStaffTipPosition val relativeRight = user.getRotationVector(0f, MathHelper.wrapDegrees(user.yaw + 90f)).normalize() val relativeUp = relativeRight.crossProduct(forward).normalize() - val rocketMode = ComponentTypes.rocketMode in staffStack + val rocketMode = DataComponentTypes.rocketMode in staffStack if (rocketMode) { user.addVelocity(forward * -parameters.rocketThrust) @@ -93,7 +93,7 @@ internal class CampfireHandler(private val parameters: Parameters) : StaffHandle } override fun onStoppedUsing(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - staffStack.remove(ComponentTypes.rocketMode) + staffStack.remove(DataComponentTypes.rocketMode) (user as? ServerPlayerEntity)?.incrementItemUseStat(staffStack.item) (user as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt index 20ee1aa6d..326f3812d 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt @@ -43,7 +43,7 @@ import net.minecraft.world.World import opekope2.avm_staff.api.component.StaffFurnaceDataComponent import opekope2.avm_staff.api.staff.StaffAttributeModifiersComponentBuilder import opekope2.avm_staff.api.staff.StaffHandler -import opekope2.avm_staff.content.ComponentTypes +import opekope2.avm_staff.content.DataComponentTypes import opekope2.avm_staff.mixin.IAbstractFurnaceBlockEntityAccessor import opekope2.avm_staff.util.* import kotlin.jvm.optionals.getOrNull @@ -67,7 +67,7 @@ internal class FurnaceHandler( user: PlayerEntity, hand: Hand ): TypedActionResult { - staffStack[ComponentTypes.furnaceData] = StaffFurnaceDataComponent(0) + staffStack[DataComponentTypes.furnaceData] = StaffFurnaceDataComponent(0) user.setCurrentHand(hand) return TypedActionResult.pass(staffStack) @@ -84,7 +84,7 @@ internal class FurnaceHandler( return } - val furnaceData = staffStack[ComponentTypes.furnaceData]!! + val furnaceData = staffStack[DataComponentTypes.furnaceData]!! furnaceData.burnTicks++ val stackToSmelt = itemToSmelt?.stack ?: return @@ -129,7 +129,7 @@ internal class FurnaceHandler( } override fun onStoppedUsing(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - staffStack.remove(ComponentTypes.furnaceData) + staffStack.remove(DataComponentTypes.furnaceData) (user as? ServerPlayerEntity)?.incrementItemUseStat(staffStack.item) } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt index ee5dfada2..88594af6c 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt @@ -31,7 +31,7 @@ import net.minecraft.world.event.GameEvent import opekope2.avm_staff.api.component.StaffTntDataComponent import opekope2.avm_staff.api.entity.ImpactTntEntity import opekope2.avm_staff.api.staff.StaffHandler -import opekope2.avm_staff.content.ComponentTypes +import opekope2.avm_staff.content.DataComponentTypes import opekope2.avm_staff.content.EntityTypes import opekope2.avm_staff.util.* @@ -46,20 +46,20 @@ internal class TntHandler : StaffHandler() { ): TypedActionResult { val tnt = tryShootTnt(world, user) ?: return TypedActionResult.pass(staffStack) - staffStack[ComponentTypes.tntData] = StaffTntDataComponent(tnt) + staffStack[DataComponentTypes.tntData] = StaffTntDataComponent(tnt) user.setCurrentHand(hand) return TypedActionResult.consume(staffStack) } override fun usageTick(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - if (!world.isClient && staffStack[ComponentTypes.tntData]?.tnt?.isRemoved == true) { + if (!world.isClient && staffStack[DataComponentTypes.tntData]?.tnt?.isRemoved == true) { user.stopUsingItem() // TODO reset last attacked ticks on client } } override fun onStoppedUsing(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - val tntData = staffStack.remove(ComponentTypes.tntData) + val tntData = staffStack.remove(DataComponentTypes.tntData) if (!world.isClient && tntData?.tnt?.isAlive == true) { tntData.tnt.explodeLater() } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/FurnaceStaffItemRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/FurnaceStaffItemRenderer.kt index a42496106..90690d05c 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/FurnaceStaffItemRenderer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/FurnaceStaffItemRenderer.kt @@ -29,7 +29,7 @@ import net.minecraft.client.util.math.MatrixStack import net.minecraft.item.ItemStack import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer import opekope2.avm_staff.api.item.renderer.StaffItemRenderer -import opekope2.avm_staff.content.ComponentTypes +import opekope2.avm_staff.content.DataComponentTypes @Environment(EnvType.CLIENT) class FurnaceStaffItemRenderer(unlitState: BlockState, litState: BlockState) : StaffItemRenderer() { @@ -50,7 +50,7 @@ class FurnaceStaffItemRenderer(unlitState: BlockState, litState: BlockState) : S overlay: Int ) { val renderer = - if (ComponentTypes.furnaceData in staffStack) litRenderer + if (DataComponentTypes.furnaceData in staffStack) litRenderer else unlitRenderer renderer.renderItemInStaff(staffStack, mode, matrices, vertexConsumers, light, overlay) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt index f4b575532..4ca01c70e 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt @@ -29,20 +29,20 @@ import net.minecraft.util.math.Vec3d import net.minecraft.world.RaycastContext import opekope2.avm_staff.api.component.StaffItemComponent import opekope2.avm_staff.api.staff.StaffHandler -import opekope2.avm_staff.content.ComponentTypes +import opekope2.avm_staff.content.DataComponentTypes /** * Checks if an item is added the given staff item stack. */ val ItemStack.isItemInStaff: Boolean @JvmName("isItemInStaff") - get() = ComponentTypes.staffItem in this + get() = DataComponentTypes.staffItem in this /** * Gets the item inserted into the given staff item stack. */ val ItemStack.itemInStaff: Item? - get() = getOrDefault(ComponentTypes.staffItem, null)?.item?.item + get() = getOrDefault(DataComponentTypes.staffItem, null)?.item?.item /** * Gets the item stack inserted into the given staff item stack. @@ -51,7 +51,7 @@ val ItemStack.itemInStaff: Item? * @see mutableItemStackInStaff */ val ItemStack.itemStackInStaff: ItemStack? - get() = getOrDefault(ComponentTypes.staffItem, null)?.item + get() = getOrDefault(DataComponentTypes.staffItem, null)?.item /** * Gets or sets a copy of the item stack inserted into the given staff item stack. The value returned or passed in can @@ -65,9 +65,9 @@ var ItemStack.mutableItemStackInStaff: ItemStack? val changes = ComponentChanges.builder() if (value == null || value.isEmpty) { - changes.remove(ComponentTypes.staffItem) + changes.remove(DataComponentTypes.staffItem) } else { - changes.add(ComponentTypes.staffItem, StaffItemComponent(value.copy())) + changes.add(DataComponentTypes.staffItem, StaffItemComponent(value.copy())) } applyChanges(changes.build()) From a9e8d2160ce013ce6436d0fb67fafa1513b24a82 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 24 Nov 2024 17:11:30 +0100 Subject: [PATCH 58/83] Order registered content alphabetically --- .../opekope2/avm_staff/content/Criteria.kt | 28 ++++---- .../avm_staff/content/DataComponentTypes.kt | 68 +++++++++--------- .../avm_staff/content/Enchantments.kt | 8 +-- .../opekope2/avm_staff/content/EntityTypes.kt | 42 +++++------ .../opekope2/avm_staff/content/Items.kt | 70 +++++++++---------- 5 files changed, 108 insertions(+), 108 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Criteria.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Criteria.kt index b3135aafd..58c15ca50 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Criteria.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Criteria.kt @@ -30,32 +30,32 @@ import opekope2.avm_staff.util.RegistryUtil */ object Criteria : RegistryUtil>(MOD_ID, RegistryKeys.CRITERION) { /** - * Criterion registered as `avm_staff:get_hurt_while_using_item`. + * Criterion registered as `avm_staff:destroy_block_with_staff`. Triggers before a block is destroyed by a staff. */ @JvmField - val TAKE_DAMAGE_WHILE_USING_ITEM = register("get_hurt_while_using_item") { - TakeDamageWhileUsingItemCriterion() + val DESTROY_BLOCK_WITH_STAFF = register("destroy_block_with_staff") { + BreakBlockWithStaffCriterion() } /** - * @see TAKE_DAMAGE_WHILE_USING_ITEM + * @see DESTROY_BLOCK_WITH_STAFF */ - val takeDamageWhileUsingItem: TakeDamageWhileUsingItemCriterion - @JvmName("takeDamageWhileUsingItem") - get() = TAKE_DAMAGE_WHILE_USING_ITEM.get() + val destroyBlockWithStaff: BreakBlockWithStaffCriterion + @JvmName("destroyBlockWithStaff") + get() = DESTROY_BLOCK_WITH_STAFF.get() /** - * Criterion registered as `avm_staff:destroy_block_with_staff`. Triggers before a block is destroyed by a staff. + * Criterion registered as `avm_staff:get_hurt_while_using_item`. */ @JvmField - val DESTROY_BLOCK_WITH_STAFF = register("destroy_block_with_staff") { - BreakBlockWithStaffCriterion() + val TAKE_DAMAGE_WHILE_USING_ITEM = register("get_hurt_while_using_item") { + TakeDamageWhileUsingItemCriterion() } /** - * @see DESTROY_BLOCK_WITH_STAFF + * @see TAKE_DAMAGE_WHILE_USING_ITEM */ - val destroyBlockWithStaff: BreakBlockWithStaffCriterion - @JvmName("destroyBlockWithStaff") - get() = DESTROY_BLOCK_WITH_STAFF.get() + val takeDamageWhileUsingItem: TakeDamageWhileUsingItemCriterion + @JvmName("takeDamageWhileUsingItem") + get() = TAKE_DAMAGE_WHILE_USING_ITEM.get() } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/DataComponentTypes.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/DataComponentTypes.kt index b8a81dd00..0348adbf1 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/DataComponentTypes.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/DataComponentTypes.kt @@ -32,22 +32,38 @@ import opekope2.avm_staff.util.RegistryUtil */ object DataComponentTypes : RegistryUtil>(MOD_ID, RegistryKeys.DATA_COMPONENT_TYPE) { /** - * Data component registered as `avm_staff:staff_item`. Stores the item inserted into the staff. + * Data component registered as `avm_staff:block_pickup_data`. */ @JvmField - val STAFF_ITEM = register("staff_item") { - ComponentType.builder() - .codec(StaffItemComponent.VALIDATED_CODEC) - .packetCodec(StaffItemComponent.PACKET_CODEC) + val BLOCK_PICKUP_DATA = register("block_pickup_data") { + ComponentType.builder() + .packetCodec(BlockPickupDataComponent.NON_SYNCING_PACKET_CODEC) .build() } /** - * @see STAFF_ITEM + * @see BLOCK_PICKUP_DATA */ - val staffItem: ComponentType - @JvmName("staffItem") - get() = STAFF_ITEM.get() + val blockPickupData: ComponentType + @JvmName("blockPickupData") + get() = BLOCK_PICKUP_DATA.get() + + /** + * Data component registered as `avm_staff:furnace_data`. If this is present, the furnace is lit. + */ + @JvmField + val FURNACE_DATA = register("furnace_data") { + ComponentType.builder() + .packetCodec(StaffFurnaceDataComponent.NON_SYNCING_PACKET_CODEC) + .build() + } + + /** + * @see FURNACE_DATA + */ + val furnaceData: ComponentType + @JvmName("furnaceData") + get() = FURNACE_DATA.get() /** * Data component registered as `avm_staff:rocket_mode`. Stores if a campfire staff should propel its user. @@ -68,21 +84,22 @@ object DataComponentTypes : RegistryUtil>(MOD_ID, RegistryKeys. get() = ROCKET_MODE.get() /** - * Data component registered as `avm_staff:furnace_data`. If this is present, the furnace is lit. + * Data component registered as `avm_staff:staff_item`. Stores the item inserted into the staff. */ @JvmField - val FURNACE_DATA = register("furnace_data") { - ComponentType.builder() - .packetCodec(StaffFurnaceDataComponent.NON_SYNCING_PACKET_CODEC) + val STAFF_ITEM = register("staff_item") { + ComponentType.builder() + .codec(StaffItemComponent.VALIDATED_CODEC) + .packetCodec(StaffItemComponent.PACKET_CODEC) .build() } /** - * @see FURNACE_DATA + * @see STAFF_ITEM */ - val furnaceData: ComponentType - @JvmName("furnaceData") - get() = FURNACE_DATA.get() + val staffItem: ComponentType + @JvmName("staffItem") + get() = STAFF_ITEM.get() /** * Data component registered as `avm_staff:staff_renderer_part`. Only used for rendering. @@ -101,23 +118,6 @@ object DataComponentTypes : RegistryUtil>(MOD_ID, RegistryKeys. @JvmName("staffRendererPart") get() = STAFF_RENDERER_PART.get() - /** - * Data component registered as `avm_staff:block_pickup_data`. - */ - @JvmField - val BLOCK_PICKUP_DATA = register("block_pickup_data") { - ComponentType.builder() - .packetCodec(BlockPickupDataComponent.NON_SYNCING_PACKET_CODEC) - .build() - } - - /** - * @see BLOCK_PICKUP_DATA - */ - val blockPickupData: ComponentType - @JvmName("blockPickupData") - get() = BLOCK_PICKUP_DATA.get() - /** * Data component registered as `avm_staff:tnt_data`. */ diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt index ccfbca4ec..e16aab3b6 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt @@ -32,15 +32,15 @@ object Enchantments { */ object Tags : TagKeyUtil(MOD_ID, RegistryKeys.ENCHANTMENT) { /** - * Enchantment registered as `avm_staff:redirects_impact_tnt`. + * Enchantment registered as `avm_staff:allows_projectile_rapid_fire`. */ @JvmField - val REDIRECTS_IMPACT_TNT = tagKey("redirects_impact_tnt") + val ALLOWS_PROJECTILE_RAPID_FIRE = tagKey("allows_projectile_rapid_fire") /** - * Enchantment registered as `avm_staff:allows_projectile_rapid_fire`. + * Enchantment registered as `avm_staff:redirects_impact_tnt`. */ @JvmField - val ALLOWS_PROJECTILE_RAPID_FIRE = tagKey("allows_projectile_rapid_fire") + val REDIRECTS_IMPACT_TNT = tagKey("redirects_impact_tnt") } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/EntityTypes.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/EntityTypes.kt index 79daea2ee..982f188a3 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/EntityTypes.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/EntityTypes.kt @@ -34,27 +34,6 @@ import kotlin.math.max * Entity types added by AVM Staffs mod. */ object EntityTypes : RegistryUtil>(MOD_ID, RegistryKeys.ENTITY_TYPE) { - /** - * Entity registered as `avm_staff:impact_tnt`. - */ - @JvmField - val IMPACT_TNT = register("impact_tnt") { - EntityType.Builder.create(::ImpactTntEntity, SpawnGroup.MISC) - .makeFireImmune() - .dimensions(EntityType.TNT.dimensions.width, EntityType.TNT.dimensions.height) - .eyeHeight(EntityType.TNT.dimensions.eyeHeight) - .maxTrackingRange(EntityType.TNT.maxTrackDistance) - .trackingTickInterval(EntityType.TNT.trackTickInterval) - .build(Identifier.of(MOD_ID, "impact_tnt").toString()) - } - - /** - * @see IMPACT_TNT - */ - val impactTnt: EntityType - @JvmName("impactTnt") - get() = IMPACT_TNT.get() - /** * Entity registered as `avm_staff:cake` */ @@ -100,4 +79,25 @@ object EntityTypes : RegistryUtil>(MOD_ID, RegistryKeys.ENTITY_TYP val campfireFlame: EntityType @JvmName("campfireFlame") get() = CAMPFIRE_FLAME.get() + + /** + * Entity registered as `avm_staff:impact_tnt`. + */ + @JvmField + val IMPACT_TNT = register("impact_tnt") { + EntityType.Builder.create(::ImpactTntEntity, SpawnGroup.MISC) + .makeFireImmune() + .dimensions(EntityType.TNT.dimensions.width, EntityType.TNT.dimensions.height) + .eyeHeight(EntityType.TNT.dimensions.eyeHeight) + .maxTrackingRange(EntityType.TNT.maxTrackDistance) + .trackingTickInterval(EntityType.TNT.trackTickInterval) + .build(Identifier.of(MOD_ID, "impact_tnt").toString()) + } + + /** + * @see IMPACT_TNT + */ + val impactTnt: EntityType + @JvmName("impactTnt") + get() = IMPACT_TNT.get() } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt index e0112bc4e..f0fdce64c 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt @@ -43,19 +43,40 @@ object Items : RegistryUtil(MOD_ID, RegistryKeys.ITEM) { private fun settings() = Item.Settings() /** - * Item registered as `avm_staff:faint_staff_rod`. + * Item registered as `avm_staff:crown_of_king_orange`. */ @JvmField - val FAINT_STAFF_ROD = register("faint_staff_rod") { - Item(settings().`arch$tab`(ItemGroups.AVM_STAFF_MOD_ITEMS)) + val CROWN_OF_KING_ORANGE = register("crown_of_king_orange") { + IStaffModPlatform.crownItem( + Blocks.CROWN_OF_KING_ORANGE.get(), + Blocks.WALL_CROWN_OF_KING_ORANGE.get(), + settings().maxCount(1).rarity(Rarity.UNCOMMON).`arch$tab`(ItemGroups.AVM_STAFF_MOD_ITEMS) + ) } /** - * @see FAINT_STAFF_ROD + * @see CROWN_OF_KING_ORANGE */ - val faintStaffRod: Item - @JvmName("faintStaffRod") - get() = FAINT_STAFF_ROD.get() + val crownOfKingOrange: CrownItem + @JvmName("crownOfKingOrange") + get() = CROWN_OF_KING_ORANGE.get() + + /** + * Item registered as `avm_staff:faint_royal_staff`. + */ + @JvmField + val FAINT_ROYAL_STAFF = register("faint_royal_staff") { + IStaffModPlatform.itemWithStaffRenderer( + settings().maxCount(1).rarity(Rarity.RARE).`arch$tab`(ItemGroups.AVM_STAFF_MOD_ITEMS) + ) + } + + /** + * @see FAINT_ROYAL_STAFF + */ + val faintRoyalStaff: Item + @JvmName("faintRoyalStaff") + get() = FAINT_ROYAL_STAFF.get() /** * Item registered as `avm_staff:faint_royal_staff_head`. @@ -73,21 +94,19 @@ object Items : RegistryUtil(MOD_ID, RegistryKeys.ITEM) { get() = FAINT_ROYAL_STAFF_HEAD.get() /** - * Item registered as `avm_staff:faint_royal_staff`. + * Item registered as `avm_staff:faint_staff_rod`. */ @JvmField - val FAINT_ROYAL_STAFF = register("faint_royal_staff") { - IStaffModPlatform.itemWithStaffRenderer( - settings().maxCount(1).rarity(Rarity.RARE).`arch$tab`(ItemGroups.AVM_STAFF_MOD_ITEMS) - ) + val FAINT_STAFF_ROD = register("faint_staff_rod") { + Item(settings().`arch$tab`(ItemGroups.AVM_STAFF_MOD_ITEMS)) } /** - * @see FAINT_ROYAL_STAFF + * @see FAINT_STAFF_ROD */ - val faintRoyalStaff: Item - @JvmName("faintRoyalStaff") - get() = FAINT_ROYAL_STAFF.get() + val faintStaffRod: Item + @JvmName("faintStaffRod") + get() = FAINT_STAFF_ROD.get() /** * Item registered as `avm_staff:royal_staff`. @@ -124,25 +143,6 @@ object Items : RegistryUtil(MOD_ID, RegistryKeys.ITEM) { @JvmName("royalStaffIngredient") get() = ROYAL_STAFF_INGREDIENT.get() - /** - * Item registered as `avm_staff:crown_of_king_orange`. - */ - @JvmField - val CROWN_OF_KING_ORANGE = register("crown_of_king_orange") { - IStaffModPlatform.crownItem( - Blocks.CROWN_OF_KING_ORANGE.get(), - Blocks.WALL_CROWN_OF_KING_ORANGE.get(), - settings().maxCount(1).rarity(Rarity.UNCOMMON).`arch$tab`(ItemGroups.AVM_STAFF_MOD_ITEMS) - ) - } - - /** - * @see CROWN_OF_KING_ORANGE - */ - val crownOfKingOrange: CrownItem - @JvmName("crownOfKingOrange") - get() = CROWN_OF_KING_ORANGE.get() - /** * Item registered as `avm_staff:staff_infusion_smithing_template`. */ From 7f94683527792b756ab6fb6bd58ba62f93ea486d Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 24 Nov 2024 19:05:37 +0100 Subject: [PATCH 59/83] Add spectre enchantment --- .../avm_staff/content/Enchantments.kt | 6 +- .../internal/event_handler/EventHandlers.kt | 1 + .../internal/initializer/Initializer.kt | 1 + .../internal/staff/handler/BellHandler.kt | 4 -- .../assets/avm_staff/lang/en_us.json | 1 + .../data/avm_staff/enchantment/spectre.json | 62 +++++++++++++++++++ .../add_loot_pool/chests/bastion_other.json | 24 +++++++ 7 files changed, 94 insertions(+), 5 deletions(-) create mode 100644 StaffMod/src/main/resources/data/avm_staff/enchantment/spectre.json create mode 100644 StaffMod/src/main/resources/data/avm_staff/loot_table/add_loot_pool/chests/bastion_other.json diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt index e16aab3b6..4876e6e71 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt @@ -21,12 +21,16 @@ package opekope2.avm_staff.content import net.minecraft.enchantment.Enchantment import net.minecraft.registry.RegistryKeys import opekope2.avm_staff.util.MOD_ID +import opekope2.avm_staff.util.RegistryKeyUtil import opekope2.avm_staff.util.TagKeyUtil /** * Enchantments added by AVM Staffs mod. */ -object Enchantments { +object Enchantments : RegistryKeyUtil(MOD_ID, RegistryKeys.ENCHANTMENT) { + @JvmField + val SPECTRE = registryKey("spectre") + /** * Enchantment tags added by AVM Staffs mod. */ diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/EventHandlers.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/EventHandlers.kt index 336bea92b..befe64be2 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/EventHandlers.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/EventHandlers.kt @@ -57,6 +57,7 @@ object EventHandlers : EntityEvent.LivingDeath, EntityEvent.LivingHurt, Interact PlayerEvent.DropItem { private val MODIFIABLE_LOOT_TABLES = setOf( Identifier.ofVanilla("chests/bastion_treasure"), + Identifier.ofVanilla("chests/bastion_other"), Identifier.ofVanilla("chests/trial_chambers/reward_unique") ) private const val MAX_ANGER_DISTANCE = 16.0 diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt index 38312401c..97aea63ac 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt @@ -35,6 +35,7 @@ object Initializer { Criteria.register() DamageTypes DataComponentTypes.register() + Enchantments Enchantments.Tags EntityTypes.register() GameRules diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt index b37acd30d..edbe0ae95 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt @@ -96,10 +96,6 @@ internal class BellHandler : StaffHandler() { 1f ) - if (!world.isClient && target is LivingEntity) { - IBellBlockEntityAccessor.callApplyGlowToEntity(target) - } - (attacker as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) return EventResult.pass() diff --git a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json index 83d7ec21a..0653f0fc5 100644 --- a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json +++ b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json @@ -29,6 +29,7 @@ "death.attack.avm_staff.pranked": "%s was pranked", "death.attack.avm_staff.pranked.player": "%s was pranked by %s", "death.attack.avm_staff.pranked.player.item": "%s was pranked by %s using %s", + "enchantment.avm_staff.spectre": "Spectre", "entity.avm_staff.cake": "Cake", "entity.avm_staff.campfire_flame": "Campfire flame", "entity.avm_staff.impact_tnt": "Impact TNT", diff --git a/StaffMod/src/main/resources/data/avm_staff/enchantment/spectre.json b/StaffMod/src/main/resources/data/avm_staff/enchantment/spectre.json new file mode 100644 index 000000000..9204cbe6a --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/enchantment/spectre.json @@ -0,0 +1,62 @@ +{ + "description": { + "translate": "enchantment.avm_staff.spectre" + }, + "supported_items": "#avm_staff:staffs", + "weight": 1, + "max_level": 3, + "min_cost": { + "base": 10, + "per_level_above_first": 10 + }, + "max_cost": { + "base": 25, + "per_level_above_first": 10 + }, + "anvil_cost": 4, + "slots": [ + "mainhand" + ], + "effects": { + "minecraft:post_attack": [ + { + "enchanted": "attacker", + "affected": "victim", + "effect": { + "type": "minecraft:apply_mob_effect", + "to_apply": "minecraft:glowing", + "min_duration": { + "type": "minecraft:linear", + "base": 10, + "per_level_above_first": 10 + }, + "max_duration": { + "type": "minecraft:linear", + "base": 10, + "per_level_above_first": 10 + }, + "min_amplifier": 0, + "max_amplifier": 0 + }, + "requirements": { + "condition": "minecraft:entity_properties", + "entity": "attacker", + "predicate": { + "equipment": { + "mainhand": { + "items": "#avm_staff:staffs", + "components": { + "avm_staff:staff_item": { + "item": { + "id": "minecraft:bell" + } + } + } + } + } + } + } + } + ] + } +} diff --git a/StaffMod/src/main/resources/data/avm_staff/loot_table/add_loot_pool/chests/bastion_other.json b/StaffMod/src/main/resources/data/avm_staff/loot_table/add_loot_pool/chests/bastion_other.json new file mode 100644 index 000000000..64c30b007 --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/loot_table/add_loot_pool/chests/bastion_other.json @@ -0,0 +1,24 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:empty", + "weight": 79 + }, + { + "type": "minecraft:item", + "name": "minecraft:book", + "weight": 10, + "functions": [ + { + "function": "minecraft:enchant_randomly", + "options": "avm_staff:spectre" + } + ] + } + ] + } + ] +} From 6c56111b7c2f28d7dded16ccd937e59ad5f7a05b Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 24 Nov 2024 23:51:01 +0100 Subject: [PATCH 60/83] Add rapid fire enchantment --- .../avm_staff/content/Enchantments.kt | 9 ++-- .../AbstractProjectileShootingStaffHandler.kt | 20 ++++---- .../internal/staff/handler/CakeHandler.kt | 2 + .../staff/handler/MagmaBlockHandler.kt | 4 +- .../staff/handler/SnowBlockHandler.kt | 2 + .../handler/WitherSkeletonSkullHandler.kt | 6 +-- .../avm_staff/util/EnchantmentUtil.kt | 48 +++++++++++++++++++ .../avm_staff/util/RegistryKeyUtil.kt | 10 ++++ .../assets/avm_staff/lang/en_us.json | 1 + .../avm_staff/enchantment/rapid_fire.json | 18 +++++++ .../allows_projectile_rapid_fire.json | 6 --- .../tags/item/enchantable/crossbow.json | 6 --- 12 files changed, 97 insertions(+), 35 deletions(-) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/util/EnchantmentUtil.kt create mode 100644 StaffMod/src/main/resources/data/avm_staff/enchantment/rapid_fire.json delete mode 100644 StaffMod/src/main/resources/data/avm_staff/tags/enchantment/allows_projectile_rapid_fire.json delete mode 100644 StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/crossbow.json diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt index 4876e6e71..12262b808 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt @@ -28,6 +28,9 @@ import opekope2.avm_staff.util.TagKeyUtil * Enchantments added by AVM Staffs mod. */ object Enchantments : RegistryKeyUtil(MOD_ID, RegistryKeys.ENCHANTMENT) { + @JvmField + val RAPID_FIRE = registryKey("rapid_fire") + @JvmField val SPECTRE = registryKey("spectre") @@ -35,12 +38,6 @@ object Enchantments : RegistryKeyUtil(MOD_ID, RegistryKeys.ENCHANTM * Enchantment tags added by AVM Staffs mod. */ object Tags : TagKeyUtil(MOD_ID, RegistryKeys.ENCHANTMENT) { - /** - * Enchantment registered as `avm_staff:allows_projectile_rapid_fire`. - */ - @JvmField - val ALLOWS_PROJECTILE_RAPID_FIRE = tagKey("allows_projectile_rapid_fire") - /** * Enchantment registered as `avm_staff:redirects_impact_tnt`. */ diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt index b45a0a0df..54c647c32 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt @@ -18,7 +18,6 @@ package opekope2.avm_staff.internal.staff.handler -import net.minecraft.enchantment.EnchantmentHelper import net.minecraft.entity.LivingEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack @@ -31,6 +30,8 @@ import opekope2.avm_staff.content.Enchantments import opekope2.avm_staff.util.* internal abstract class AbstractProjectileShootingStaffHandler : StaffHandler() { + protected abstract fun getFireRateDenominator(rapidFireLevel: Int): Int + override fun getMaxUseTime(staffStack: ItemStack, world: World, user: LivingEntity) = 72000 override fun use( @@ -39,10 +40,7 @@ internal abstract class AbstractProjectileShootingStaffHandler : StaffHandler() user: PlayerEntity, hand: Hand ): TypedActionResult { - val allowsProjectileRapidFire = EnchantmentHelper.hasAnyEnchantmentsIn( - user.mainHandStack, - Enchantments.Tags.ALLOWS_PROJECTILE_RAPID_FIRE - ) + val allowsProjectileRapidFire = staffStack.isEnchantedWith(Enchantments.RAPID_FIRE, world.registryManager) if (!allowsProjectileRapidFire) return TypedActionResult.pass(staffStack) user.setCurrentHand(hand) @@ -50,11 +48,13 @@ internal abstract class AbstractProjectileShootingStaffHandler : StaffHandler() } override fun usageTick(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - if (tryShootProjectile(world, user, ProjectileShootReason.USE)) { - staffStack.damage(entity = user) - (user as? ServerPlayerEntity)?.incrementItemUseStat(staffStack.item) - (user as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) - } + val rapidFire = staffStack.getEnchantmentLevel(Enchantments.RAPID_FIRE, world.registryManager) + if (remainingUseTicks % getFireRateDenominator(rapidFire) != 0) return + if (!tryShootProjectile(world, user, ProjectileShootReason.USE)) return + + staffStack.damage(entity = user) + (user as? ServerPlayerEntity)?.incrementItemUseStat(staffStack.item) + (user as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) } override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand) { diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CakeHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CakeHandler.kt index f1c886255..00f1c3aab 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CakeHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CakeHandler.kt @@ -28,6 +28,8 @@ import opekope2.avm_staff.util.plus import opekope2.avm_staff.util.times internal class CakeHandler : AbstractProjectileShootingStaffHandler() { + override fun getFireRateDenominator(rapidFireLevel: Int) = if (rapidFireLevel >= 2) 1 else 2 + private val ProjectileShootReason.velocity: Double get() = when (this) { ProjectileShootReason.ATTACK -> 0.5 diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/MagmaBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/MagmaBlockHandler.kt index 7626c0fd6..f40ef3f54 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/MagmaBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/MagmaBlockHandler.kt @@ -41,9 +41,7 @@ internal class MagmaBlockHandler : AbstractProjectileShootingStaffHandler() { .addDefault(EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE) .build() - override fun usageTick(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - if ((remainingUseTicks and 1) == 0) super.usageTick(staffStack, world, user, remainingUseTicks) - } + override fun getFireRateDenominator(rapidFireLevel: Int) = if (rapidFireLevel >= 2) 2 else 4 override fun tryShootProjectile(world: World, shooter: LivingEntity, reason: ProjectileShootReason): Boolean { if (!super.tryShootProjectile(world, shooter, reason)) return false diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/SnowBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/SnowBlockHandler.kt index 81a90f55d..6506bea4f 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/SnowBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/SnowBlockHandler.kt @@ -32,6 +32,8 @@ internal class SnowBlockHandler : AbstractProjectileShootingStaffHandler() { ProjectileShootReason.USE -> 3f } + override fun getFireRateDenominator(rapidFireLevel: Int) = if (rapidFireLevel >= 2) 1 else 2 + override fun tryShootProjectile(world: World, shooter: LivingEntity, reason: ProjectileShootReason): Boolean { if (!super.tryShootProjectile(world, shooter, reason)) return false diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt index 593256811..9f194b57e 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt @@ -38,11 +38,9 @@ import opekope2.avm_staff.util.incrementStaffItemUseStat import opekope2.avm_staff.util.itemInStaff internal class WitherSkeletonSkullHandler : AbstractProjectileShootingStaffHandler() { - override fun getMaxUseTime(staffStack: ItemStack, world: World, user: LivingEntity) = 20 + override fun getFireRateDenominator(rapidFireLevel: Int) = if (rapidFireLevel >= 2) 2 else 4 - override fun usageTick(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - if ((remainingUseTicks and 1) == 0) super.usageTick(staffStack, world, user, remainingUseTicks) - } + override fun getMaxUseTime(staffStack: ItemStack, world: World, user: LivingEntity) = 20 override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand) { if (attacker is PlayerEntity && attacker.itemCooldownManager.isCoolingDown(staffStack.item)) return diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/EnchantmentUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/EnchantmentUtil.kt new file mode 100644 index 000000000..c10881797 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/EnchantmentUtil.kt @@ -0,0 +1,48 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +@file: JvmName("EnchantmentUtil") + +package opekope2.avm_staff.util + +import net.minecraft.enchantment.Enchantment +import net.minecraft.enchantment.EnchantmentHelper +import net.minecraft.item.ItemStack +import net.minecraft.registry.DynamicRegistryManager +import net.minecraft.registry.RegistryKey +import opekope2.avm_staff.content.Enchantments.getEntry + +/** + * Gets an enchantment level on an item + * + * @param enchantment The registry key of the enchantment to check + * @param registryManager The registry manager of a world + * @see EnchantmentHelper.getLevel + */ +fun ItemStack.getEnchantmentLevel(enchantment: RegistryKey, registryManager: DynamicRegistryManager) = + EnchantmentHelper.getLevel(enchantment.getEntry(registryManager), this) + +/** + * Checks is an item is enchanted with [enchantment] + * + * @param enchantment The registry key of the enchantment to check + * @param registryManager The registry manager of a world + * @see EnchantmentHelper.getLevel + */ +fun ItemStack.isEnchantedWith(enchantment: RegistryKey, registryManager: DynamicRegistryManager) = + getEnchantmentLevel(enchantment, registryManager) > 0 diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/RegistryKeyUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/RegistryKeyUtil.kt index 1d528e993..7ee96941a 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/RegistryKeyUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/RegistryKeyUtil.kt @@ -18,9 +18,11 @@ package opekope2.avm_staff.util +import net.minecraft.registry.DynamicRegistryManager import net.minecraft.registry.Registry import net.minecraft.registry.RegistryKey import net.minecraft.util.Identifier +import kotlin.jvm.optionals.getOrNull /** * Utility class to create [Identifier]s and [RegistryKey]s using a specified [namespace][Identifier.namespace] and @@ -51,4 +53,12 @@ open class RegistryKeyUtil( * @param path The path of the [Identifier] to create a registry key from */ fun registryKey(path: String): RegistryKey = RegistryKey.of(registry, id(path)) + + /** + * Gets the registry entry of the given registry key from the given registry manager or `null`, if it's not found. + * + * @param registryManager The registry manager of a world + */ + fun RegistryKey.getEntry(registryManager: DynamicRegistryManager) = + registryManager.get(this@RegistryKeyUtil.registry).getEntry(this).getOrNull() } diff --git a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json index 0653f0fc5..3d5497813 100644 --- a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json +++ b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json @@ -29,6 +29,7 @@ "death.attack.avm_staff.pranked": "%s was pranked", "death.attack.avm_staff.pranked.player": "%s was pranked by %s", "death.attack.avm_staff.pranked.player.item": "%s was pranked by %s using %s", + "enchantment.avm_staff.rapid_fire": "Rapid Fire", "enchantment.avm_staff.spectre": "Spectre", "entity.avm_staff.cake": "Cake", "entity.avm_staff.campfire_flame": "Campfire flame", diff --git a/StaffMod/src/main/resources/data/avm_staff/enchantment/rapid_fire.json b/StaffMod/src/main/resources/data/avm_staff/enchantment/rapid_fire.json new file mode 100644 index 000000000..e713e27e6 --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/enchantment/rapid_fire.json @@ -0,0 +1,18 @@ +{ + "description": { + "translate": "enchantment.avm_staff.rapid_fire" + }, + "supported_items": "#avm_staff:staffs", + "weight": 1, + "max_level": 2, + "min_cost": { + "base": 10, + "per_level_above_first": 20 + }, + "max_cost": { + "base": 60, + "per_level_above_first": 20 + }, + "anvil_cost": 8, + "slots": [] +} diff --git a/StaffMod/src/main/resources/data/avm_staff/tags/enchantment/allows_projectile_rapid_fire.json b/StaffMod/src/main/resources/data/avm_staff/tags/enchantment/allows_projectile_rapid_fire.json deleted file mode 100644 index 081cbd801..000000000 --- a/StaffMod/src/main/resources/data/avm_staff/tags/enchantment/allows_projectile_rapid_fire.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:multishot" - ] -} diff --git a/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/crossbow.json b/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/crossbow.json deleted file mode 100644 index 641e9fc93..000000000 --- a/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/crossbow.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "replace": false, - "values": [ - "#avm_staff:staffs" - ] -} From 729093bf2b40ef61659d34cee56ce09138a85f06 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 29 Nov 2024 19:48:04 +0100 Subject: [PATCH 61/83] Make BoneBlockHandler use EnchantmentUtil --- .../avm_staff/internal/staff/handler/BoneBlockHandler.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BoneBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BoneBlockHandler.kt index af782c83f..253bcec9c 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BoneBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BoneBlockHandler.kt @@ -19,14 +19,12 @@ package opekope2.avm_staff.internal.staff.handler import net.minecraft.component.type.AttributeModifierSlot -import net.minecraft.enchantment.EnchantmentHelper import net.minecraft.enchantment.Enchantments import net.minecraft.entity.LivingEntity import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.item.BoneMealItem import net.minecraft.item.ItemStack import net.minecraft.item.Items -import net.minecraft.registry.RegistryKeys import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.util.ActionResult import net.minecraft.util.Hand @@ -63,8 +61,8 @@ internal class BoneBlockHandler : StaffHandler() { } else ActionResult.PASS } - val efficiencyRef = world.registryManager[RegistryKeys.ENCHANTMENT].getEntry(Enchantments.EFFICIENCY).get() - val range = 0.5 + EnchantmentHelper.getLevel(efficiencyRef, staffStack).coerceAtMost(5) / 2.0 + val range = + 0.5 + staffStack.getEnchantmentLevel(Enchantments.EFFICIENCY, world.registryManager).coerceAtMost(5) / 2.0 val rangeSquare = range * range var uses = 0 From c69e2616891aee3e7590ba812a0ac9d00034e1df Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 29 Nov 2024 21:02:21 +0100 Subject: [PATCH 62/83] Add quick draw enchantment --- .../opekope2/avm_staff/content/Enchantments.kt | 3 +++ .../resources/assets/avm_staff/lang/en_us.json | 1 + .../data/avm_staff/enchantment/quick_draw.json | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+) create mode 100644 StaffMod/src/main/resources/data/avm_staff/enchantment/quick_draw.json diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt index 12262b808..2d49a3b2f 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt @@ -28,6 +28,9 @@ import opekope2.avm_staff.util.TagKeyUtil * Enchantments added by AVM Staffs mod. */ object Enchantments : RegistryKeyUtil(MOD_ID, RegistryKeys.ENCHANTMENT) { + @JvmField + val QUICK_DRAW = registryKey("quick_draw") + @JvmField val RAPID_FIRE = registryKey("rapid_fire") diff --git a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json index 3d5497813..4584b67c7 100644 --- a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json +++ b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json @@ -29,6 +29,7 @@ "death.attack.avm_staff.pranked": "%s was pranked", "death.attack.avm_staff.pranked.player": "%s was pranked by %s", "death.attack.avm_staff.pranked.player.item": "%s was pranked by %s using %s", + "enchantment.avm_staff.quick_draw": "Quick Draw", "enchantment.avm_staff.rapid_fire": "Rapid Fire", "enchantment.avm_staff.spectre": "Spectre", "entity.avm_staff.cake": "Cake", diff --git a/StaffMod/src/main/resources/data/avm_staff/enchantment/quick_draw.json b/StaffMod/src/main/resources/data/avm_staff/enchantment/quick_draw.json new file mode 100644 index 000000000..cf496531b --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/enchantment/quick_draw.json @@ -0,0 +1,18 @@ +{ + "description": { + "translate": "enchantment.avm_staff.quick_draw" + }, + "supported_items": "#avm_staff:staffs", + "weight": 1, + "max_level": 4, + "min_cost": { + "base": 15, + "per_level_above_first": 9 + }, + "max_cost": { + "base": 65, + "per_level_above_first": 9 + }, + "anvil_cost": 8, + "slots": [] +} From b74c85832833b2472d21e2ff2922b191254fff59 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 29 Nov 2024 21:03:43 +0100 Subject: [PATCH 63/83] Make picking up blocks affected by quick draw enchantment --- .../kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt index e10f7c15d..7184fb271 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt @@ -41,7 +41,9 @@ import opekope2.avm_staff.api.block.IClearableBeforeInsertedIntoStaff import opekope2.avm_staff.api.component.BlockPickupDataComponent import opekope2.avm_staff.api.registry.RegistryBase import opekope2.avm_staff.content.DataComponentTypes +import opekope2.avm_staff.content.Enchantments import opekope2.avm_staff.util.approximateStaffItemPosition +import opekope2.avm_staff.util.getEnchantmentLevel import opekope2.avm_staff.util.incrementStaffItemUseStat import opekope2.avm_staff.util.mutableItemStackInStaff import kotlin.math.roundToInt @@ -337,8 +339,10 @@ abstract class StaffHandler { override fun getMaxUseTime(staffStack: ItemStack, world: World, user: LivingEntity): Int { val targetPos = user.targetPos val state = world.getBlockState(targetPos) + val quickDraw = staffStack.getEnchantmentLevel(Enchantments.QUICK_DRAW, world.registryManager) + 1 + return if (!canPickUp(world, targetPos, state)) 0 - else 20 + (state.getHardness(world, targetPos) / 2).roundToInt() + else 10 + (state.getHardness(world, targetPos) / quickDraw).roundToInt() } override fun use( From f7aad84186afd1f4e1e842aceaa867e44bcf09fc Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 29 Nov 2024 21:05:58 +0100 Subject: [PATCH 64/83] Make wither skeleton staff cooldown affected by quick draw enchantment --- .../staff/handler/WitherSkeletonSkullHandler.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt index 9f194b57e..a45f12cfc 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt @@ -32,10 +32,8 @@ import net.minecraft.util.Hand import net.minecraft.world.Difficulty import net.minecraft.world.World import net.minecraft.world.WorldEvents -import opekope2.avm_staff.util.approximateStaffTipPosition -import opekope2.avm_staff.util.getSpawnPosition -import opekope2.avm_staff.util.incrementStaffItemUseStat -import opekope2.avm_staff.util.itemInStaff +import opekope2.avm_staff.content.Enchantments +import opekope2.avm_staff.util.* internal class WitherSkeletonSkullHandler : AbstractProjectileShootingStaffHandler() { override fun getFireRateDenominator(rapidFireLevel: Int) = if (rapidFireLevel >= 2) 2 else 4 @@ -92,9 +90,11 @@ internal class WitherSkeletonSkullHandler : AbstractProjectileShootingStaffHandl private fun addCooldown(staffStack: ItemStack, world: World, player: PlayerEntity, remainingUseTicks: Int) { if (player.abilities.creativeMode) return + + val quickDraw = staffStack.getEnchantmentLevel(Enchantments.QUICK_DRAW, world.registryManager) + 1 player.itemCooldownManager.set( staffStack.item, - 4 * (getMaxUseTime(staffStack, world, player) - remainingUseTicks) + 4 * (getMaxUseTime(staffStack, world, player) - remainingUseTicks) / quickDraw ) } } From 39d249afc4e48d1a4d5a3e04f5f64725f1721be7 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 29 Nov 2024 21:11:35 +0100 Subject: [PATCH 65/83] Change StaffHandler.use to accept LivingEntity instead of PlayerEntity --- .../kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt | 6 +++--- .../staff/handler/AbstractProjectileShootingStaffHandler.kt | 2 +- .../avm_staff/internal/staff/handler/BellHandler.kt | 2 +- .../avm_staff/internal/staff/handler/CampfireHandler.kt | 2 +- .../avm_staff/internal/staff/handler/FurnaceHandler.kt | 2 +- .../opekope2/avm_staff/internal/staff/handler/TntHandler.kt | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt index 7184fb271..1069e485d 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt @@ -72,7 +72,7 @@ abstract class StaffHandler { * Called on both the client and the server by Minecraft when the player uses the staff. * * If the staff can be used for multiple ticks, override [getMaxUseTime] to return a positive number, and call - * [PlayerEntity.setCurrentHand] on [user] with [hand] as the argument. + * [LivingEntity.setCurrentHand] on [user] with [hand] as the argument. * * @return * On the logical client: @@ -97,7 +97,7 @@ abstract class StaffHandler { * @param hand The hand of the [user], in which the [staff][staffStack] is * @see Item.use */ - open fun use(staffStack: ItemStack, world: World, user: PlayerEntity, hand: Hand): TypedActionResult = + open fun use(staffStack: ItemStack, world: World, user: LivingEntity, hand: Hand): TypedActionResult = TypedActionResult.pass(user.getStackInHand(hand)) /** @@ -348,7 +348,7 @@ abstract class StaffHandler { override fun use( staffStack: ItemStack, world: World, - user: PlayerEntity, + user: LivingEntity, hand: Hand ): TypedActionResult { val targetPos = user.targetPos diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt index 54c647c32..f932faca7 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt @@ -37,7 +37,7 @@ internal abstract class AbstractProjectileShootingStaffHandler : StaffHandler() override fun use( staffStack: ItemStack, world: World, - user: PlayerEntity, + user: LivingEntity, hand: Hand ): TypedActionResult { val allowsProjectileRapidFire = staffStack.isEnchantedWith(Enchantments.RAPID_FIRE, world.registryManager) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt index edbe0ae95..1f88de85f 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt @@ -53,7 +53,7 @@ internal class BellHandler : StaffHandler() { override fun use( staffStack: ItemStack, world: World, - user: PlayerEntity, + user: LivingEntity, hand: Hand ): TypedActionResult { world.playSound(user, user.blockPos, SoundEvents.BLOCK_BELL_USE, SoundCategory.BLOCKS, 2f, 1f) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt index 97fb60fb9..932e0b034 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt @@ -42,7 +42,7 @@ internal class CampfireHandler(private val parameters: Parameters) : StaffHandle override fun use( staffStack: ItemStack, world: World, - user: PlayerEntity, + user: LivingEntity, hand: Hand ): TypedActionResult { if (user.isSneaking && !user.isOnGround) { diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt index 326f3812d..bed1369b6 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/FurnaceHandler.kt @@ -64,7 +64,7 @@ internal class FurnaceHandler( override fun use( staffStack: ItemStack, world: World, - user: PlayerEntity, + user: LivingEntity, hand: Hand ): TypedActionResult { staffStack[DataComponentTypes.furnaceData] = StaffFurnaceDataComponent(0) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt index 88594af6c..e277a35f9 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt @@ -41,7 +41,7 @@ internal class TntHandler : StaffHandler() { override fun use( staffStack: ItemStack, world: World, - user: PlayerEntity, + user: LivingEntity, hand: Hand ): TypedActionResult { val tnt = tryShootTnt(world, user) ?: return TypedActionResult.pass(staffStack) From 2c7a9bd9cecdcd3d345c276f769589bfc44d8c4a Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 30 Nov 2024 00:07:40 +0100 Subject: [PATCH 66/83] Add power charge enchantment --- .../avm_staff/content/Enchantments.kt | 3 ++ .../AbstractProjectileShootingStaffHandler.kt | 16 +++++-- .../internal/staff/handler/CakeHandler.kt | 10 ++++- .../staff/handler/MagmaBlockHandler.kt | 43 +++++++++++++++---- .../staff/handler/SnowBlockHandler.kt | 10 ++++- .../internal/staff/handler/TntHandler.kt | 1 + .../handler/WitherSkeletonSkullHandler.kt | 11 +++-- .../assets/avm_staff/lang/en_us.json | 1 + .../avm_staff/enchantment/power_charge.json | 18 ++++++++ 9 files changed, 93 insertions(+), 20 deletions(-) create mode 100644 StaffMod/src/main/resources/data/avm_staff/enchantment/power_charge.json diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt index 2d49a3b2f..c9b16c0b7 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt @@ -28,6 +28,9 @@ import opekope2.avm_staff.util.TagKeyUtil * Enchantments added by AVM Staffs mod. */ object Enchantments : RegistryKeyUtil(MOD_ID, RegistryKeys.ENCHANTMENT) { + @JvmField + val POWER_CHARGE = registryKey("power_charge") + @JvmField val QUICK_DRAW = registryKey("quick_draw") diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt index f932faca7..24d073ab8 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractProjectileShootingStaffHandler.kt @@ -50,7 +50,7 @@ internal abstract class AbstractProjectileShootingStaffHandler : StaffHandler() override fun usageTick(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { val rapidFire = staffStack.getEnchantmentLevel(Enchantments.RAPID_FIRE, world.registryManager) if (remainingUseTicks % getFireRateDenominator(rapidFire) != 0) return - if (!tryShootProjectile(world, user, ProjectileShootReason.USE)) return + if (!tryShootProjectile(staffStack, world, user, ProjectileShootReason.USE)) return staffStack.damage(entity = user) (user as? ServerPlayerEntity)?.incrementItemUseStat(staffStack.item) @@ -58,7 +58,7 @@ internal abstract class AbstractProjectileShootingStaffHandler : StaffHandler() } override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand) { - if (tryShootProjectile(world, attacker, ProjectileShootReason.ATTACK)) { + if (tryShootProjectile(staffStack, world, attacker, ProjectileShootReason.ATTACK)) { staffStack.damage(entity = attacker) (attacker as? ServerPlayerEntity)?.incrementItemUseStat(staffStack.item) (attacker as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) @@ -66,7 +66,12 @@ internal abstract class AbstractProjectileShootingStaffHandler : StaffHandler() (attacker as? PlayerEntity)?.resetLastAttackedTicks() } - protected open fun tryShootProjectile(world: World, shooter: LivingEntity, reason: ProjectileShootReason): Boolean { + protected open fun tryShootProjectile( + staffStack: ItemStack, + world: World, + shooter: LivingEntity, + reason: ProjectileShootReason + ): Boolean { if (world.isClient) return false if (!shooter.canUseStaff) return false if (shooter is PlayerEntity && shooter.isAttackCoolingDown) return false @@ -89,6 +94,9 @@ internal abstract class AbstractProjectileShootingStaffHandler : StaffHandler() protected enum class ProjectileShootReason { ATTACK, - USE + USE; + + inline val isAttack: Boolean + get() = this == ATTACK } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CakeHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CakeHandler.kt index 00f1c3aab..191789567 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CakeHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CakeHandler.kt @@ -19,6 +19,7 @@ package opekope2.avm_staff.internal.staff.handler import net.minecraft.entity.LivingEntity +import net.minecraft.item.ItemStack import net.minecraft.world.World import opekope2.avm_staff.api.entity.CakeEntity import opekope2.avm_staff.content.EntityTypes @@ -36,8 +37,13 @@ internal class CakeHandler : AbstractProjectileShootingStaffHandler() { ProjectileShootReason.USE -> 1.0 } - override fun tryShootProjectile(world: World, shooter: LivingEntity, reason: ProjectileShootReason): Boolean { - if (!super.tryShootProjectile(world, shooter, reason)) return false + override fun tryShootProjectile( + staffStack: ItemStack, + world: World, + shooter: LivingEntity, + reason: ProjectileShootReason + ): Boolean { + if (!super.tryShootProjectile(staffStack, world, shooter, reason)) return false val spawnPos = EntityTypes.cake.getSpawnPosition(world, shooter.approximateStaffTipPosition) ?: return false CakeEntity.throwCake(world, spawnPos, shooter.rotationVector * reason.velocity + shooter.velocity, shooter) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/MagmaBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/MagmaBlockHandler.kt index f40ef3f54..aa6d24c02 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/MagmaBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/MagmaBlockHandler.kt @@ -24,6 +24,8 @@ import net.minecraft.entity.Entity import net.minecraft.entity.EntityType import net.minecraft.entity.LivingEntity import net.minecraft.entity.attribute.EntityAttributes +import net.minecraft.entity.projectile.AbstractFireballEntity +import net.minecraft.entity.projectile.FireballEntity import net.minecraft.entity.projectile.SmallFireballEntity import net.minecraft.item.ItemStack import net.minecraft.server.network.ServerPlayerEntity @@ -31,6 +33,7 @@ import net.minecraft.util.Hand import net.minecraft.world.World import net.minecraft.world.WorldEvents import opekope2.avm_staff.api.staff.StaffAttributeModifiersComponentBuilder +import opekope2.avm_staff.content.Enchantments import opekope2.avm_staff.util.* internal class MagmaBlockHandler : AbstractProjectileShootingStaffHandler() { @@ -43,17 +46,39 @@ internal class MagmaBlockHandler : AbstractProjectileShootingStaffHandler() { override fun getFireRateDenominator(rapidFireLevel: Int) = if (rapidFireLevel >= 2) 2 else 4 - override fun tryShootProjectile(world: World, shooter: LivingEntity, reason: ProjectileShootReason): Boolean { - if (!super.tryShootProjectile(world, shooter, reason)) return false + override fun tryShootProjectile( + staffStack: ItemStack, + world: World, + shooter: LivingEntity, + reason: ProjectileShootReason + ): Boolean { + if (!super.tryShootProjectile(staffStack, world, shooter, reason)) return false - val spawnPos = EntityType.SMALL_FIREBALL.getSpawnPosition(world, shooter.approximateStaffTipPosition) - ?: return false + return if (reason.isAttack && staffStack.isEnchantedWith(Enchantments.POWER_CHARGE, world.registryManager)) { + shootFireball(world, shooter, WorldEvents.GHAST_SHOOTS, EntityType.FIREBALL) { + FireballEntity(world, shooter, shooter.rotationVector, 1) + } + } else { + shootFireball(world, shooter, WorldEvents.BLAZE_SHOOTS, EntityType.SMALL_FIREBALL) { + SmallFireballEntity(world, shooter, shooter.rotationVector) + } + } + } + + private inline fun shootFireball( + world: World, + shooter: LivingEntity, + soundWorldEvent: Int, + fireballType: EntityType, + fireballFactory: () -> T + ): Boolean { + val spawnPos = fireballType.getSpawnPosition(world, shooter.approximateStaffTipPosition) ?: return false + val fireball = fireballFactory() + fireball.setPosition(spawnPos) + fireball.owner = shooter - world.spawnEntity(SmallFireballEntity(world, shooter, shooter.rotationVector).apply { - owner = shooter - setPosition(spawnPos) - }) - world.syncWorldEvent(WorldEvents.BLAZE_SHOOTS, shooter.blockPos, 0) + world.spawnEntity(fireball) + world.syncWorldEvent(soundWorldEvent, shooter.blockPos, 0) return true } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/SnowBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/SnowBlockHandler.kt index 6506bea4f..0734a89fe 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/SnowBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/SnowBlockHandler.kt @@ -21,6 +21,7 @@ package opekope2.avm_staff.internal.staff.handler import net.minecraft.entity.EntityType import net.minecraft.entity.LivingEntity import net.minecraft.entity.projectile.thrown.SnowballEntity +import net.minecraft.item.ItemStack import net.minecraft.sound.SoundEvents import net.minecraft.world.World import opekope2.avm_staff.util.* @@ -34,8 +35,13 @@ internal class SnowBlockHandler : AbstractProjectileShootingStaffHandler() { override fun getFireRateDenominator(rapidFireLevel: Int) = if (rapidFireLevel >= 2) 1 else 2 - override fun tryShootProjectile(world: World, shooter: LivingEntity, reason: ProjectileShootReason): Boolean { - if (!super.tryShootProjectile(world, shooter, reason)) return false + override fun tryShootProjectile( + staffStack: ItemStack, + world: World, + shooter: LivingEntity, + reason: ProjectileShootReason + ): Boolean { + if (!super.tryShootProjectile(staffStack, world, shooter, reason)) return false val spawnPos = EntityType.SNOWBALL.getSpawnPosition(world, shooter.approximateStaffTipPosition) ?: return false val (x, y, z) = spawnPos diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt index e277a35f9..fa49236f5 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt @@ -106,6 +106,7 @@ internal class TntHandler : StaffHandler() { val (x, y, z) = spawnPos val tnt = ImpactTntEntity(world, x, y, z, shooter.rotationVector + shooter.velocity, shooter) + // TODO Power Charge enchantment: increase explosion power world.spawnEntity(tnt) world.playSound( null, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt index a45f12cfc..614ef7348 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/WitherSkeletonSkullHandler.kt @@ -46,15 +46,20 @@ internal class WitherSkeletonSkullHandler : AbstractProjectileShootingStaffHandl if (attacker is PlayerEntity) addCooldown(staffStack, world, attacker, 0) } - override fun tryShootProjectile(world: World, shooter: LivingEntity, reason: ProjectileShootReason): Boolean { - if (!super.tryShootProjectile(world, shooter, reason)) return false + override fun tryShootProjectile( + staffStack: ItemStack, + world: World, + shooter: LivingEntity, + reason: ProjectileShootReason + ): Boolean { + if (!super.tryShootProjectile(staffStack, world, shooter, reason)) return false val spawnPos = EntityType.WITHER_SKULL.getSpawnPosition(world, shooter.approximateStaffTipPosition) ?: return false world.spawnEntity(WitherSkullEntity(world, shooter, shooter.rotationVector).apply { owner = shooter - isCharged = reason == ProjectileShootReason.ATTACK + isCharged = reason.isAttack && staffStack.isEnchantedWith(Enchantments.POWER_CHARGE, world.registryManager) setPosition(spawnPos) }) world.syncWorldEvent(WorldEvents.WITHER_SHOOTS, shooter.blockPos, 0) diff --git a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json index 4584b67c7..d1f066c7f 100644 --- a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json +++ b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json @@ -29,6 +29,7 @@ "death.attack.avm_staff.pranked": "%s was pranked", "death.attack.avm_staff.pranked.player": "%s was pranked by %s", "death.attack.avm_staff.pranked.player.item": "%s was pranked by %s using %s", + "enchantment.avm_staff.power_charge": "Power Charge", "enchantment.avm_staff.quick_draw": "Quick Draw", "enchantment.avm_staff.rapid_fire": "Rapid Fire", "enchantment.avm_staff.spectre": "Spectre", diff --git a/StaffMod/src/main/resources/data/avm_staff/enchantment/power_charge.json b/StaffMod/src/main/resources/data/avm_staff/enchantment/power_charge.json new file mode 100644 index 000000000..62d904184 --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/enchantment/power_charge.json @@ -0,0 +1,18 @@ +{ + "description": { + "translate": "enchantment.avm_staff.power_charge" + }, + "supported_items": "#avm_staff:staffs", + "weight": 1, + "max_level": 1, + "min_cost": { + "base": 20, + "per_level_above_first": 0 + }, + "max_cost": { + "base": 50, + "per_level_above_first": 0 + }, + "anvil_cost": 4, + "slots": [] +} From ca85163a819c408184170f553b6d7de467426df0 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 30 Nov 2024 01:46:40 +0100 Subject: [PATCH 67/83] Fix bulldozer Add juggler advancement description --- .../data/avm_staff/advancement/bulldozer.json | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/bulldozer.json b/StaffMod/src/main/resources/data/avm_staff/advancement/bulldozer.json index 858d9675b..10c829093 100644 --- a/StaffMod/src/main/resources/data/avm_staff/advancement/bulldozer.json +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/bulldozer.json @@ -14,17 +14,17 @@ "title": { "translate": "advancements.avm_staff.bulldozer.title" }, - "description": [ - [ - "a ", - { - "translate": "item.avm_staff.staff" - } - ], - { - "translate": "advancements.avm_staff.bulldozer.description" - } - ] + "description": { + "translate": "advancements.avm_staff.bulldozer.description", + "with": [ + [ + "a ", + { + "translate": "item.avm_staff.staff" + } + ] + ] + } }, "criteria": { "use_diamond_block_staff": { From 65f00b181ec06e16521f236f5621b363efb3069b Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 30 Nov 2024 01:47:43 +0100 Subject: [PATCH 68/83] Add distant detonation enchantment --- .../opekope2/avm_staff/content/Enchantments.kt | 3 +++ .../internal/staff/handler/TntHandler.kt | 3 +++ .../resources/assets/avm_staff/lang/en_us.json | 1 + .../enchantment/distant_detonation.json | 18 ++++++++++++++++++ 4 files changed, 25 insertions(+) create mode 100644 StaffMod/src/main/resources/data/avm_staff/enchantment/distant_detonation.json diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt index c9b16c0b7..3934be026 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Enchantments.kt @@ -28,6 +28,9 @@ import opekope2.avm_staff.util.TagKeyUtil * Enchantments added by AVM Staffs mod. */ object Enchantments : RegistryKeyUtil(MOD_ID, RegistryKeys.ENCHANTMENT) { + @JvmField + val DISTANT_DETONATION = registryKey("distant_detonation") + @JvmField val POWER_CHARGE = registryKey("power_charge") diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt index fa49236f5..9677c6edb 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/TntHandler.kt @@ -32,6 +32,7 @@ import opekope2.avm_staff.api.component.StaffTntDataComponent import opekope2.avm_staff.api.entity.ImpactTntEntity import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.content.DataComponentTypes +import opekope2.avm_staff.content.Enchantments import opekope2.avm_staff.content.EntityTypes import opekope2.avm_staff.util.* @@ -44,6 +45,8 @@ internal class TntHandler : StaffHandler() { user: LivingEntity, hand: Hand ): TypedActionResult { + if (!staffStack.isEnchantedWith(Enchantments.DISTANT_DETONATION, world.registryManager)) + return TypedActionResult.pass(staffStack) val tnt = tryShootTnt(world, user) ?: return TypedActionResult.pass(staffStack) staffStack[DataComponentTypes.tntData] = StaffTntDataComponent(tnt) diff --git a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json index d1f066c7f..82f75f2fe 100644 --- a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json +++ b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json @@ -29,6 +29,7 @@ "death.attack.avm_staff.pranked": "%s was pranked", "death.attack.avm_staff.pranked.player": "%s was pranked by %s", "death.attack.avm_staff.pranked.player.item": "%s was pranked by %s using %s", + "enchantment.avm_staff.distant_detonation": "Distant Detonation", "enchantment.avm_staff.power_charge": "Power Charge", "enchantment.avm_staff.quick_draw": "Quick Draw", "enchantment.avm_staff.rapid_fire": "Rapid Fire", diff --git a/StaffMod/src/main/resources/data/avm_staff/enchantment/distant_detonation.json b/StaffMod/src/main/resources/data/avm_staff/enchantment/distant_detonation.json new file mode 100644 index 000000000..da40f7004 --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/enchantment/distant_detonation.json @@ -0,0 +1,18 @@ +{ + "description": { + "translate": "enchantment.avm_staff.distant_detonation" + }, + "supported_items": "#avm_staff:staffs", + "weight": 1, + "max_level": 1, + "min_cost": { + "base": 20, + "per_level_above_first": 0 + }, + "max_cost": { + "base": 50, + "per_level_above_first": 0 + }, + "anvil_cost": 4, + "slots": [] +} From 15332b46c278d85e96b7618cc2a0512f40a68526 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 30 Nov 2024 17:47:14 +0100 Subject: [PATCH 69/83] Balance and generate enchantments as loot --- .../internal/event_handler/EventHandlers.kt | 5 +-- .../enchantment/distant_detonation.json | 2 +- .../avm_staff/enchantment/power_charge.json | 2 +- .../avm_staff/enchantment/quick_draw.json | 2 +- .../avm_staff/enchantment/rapid_fire.json | 2 +- .../add_loot_pool/chests/ancient_city.json | 35 +++++++++++++++++++ .../tags/enchantment/non_treasure.json | 7 ++++ .../minecraft/tags/enchantment/treasure.json | 8 +++++ 8 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 StaffMod/src/main/resources/data/avm_staff/loot_table/add_loot_pool/chests/ancient_city.json create mode 100644 StaffMod/src/main/resources/data/minecraft/tags/enchantment/non_treasure.json create mode 100644 StaffMod/src/main/resources/data/minecraft/tags/enchantment/treasure.json diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/EventHandlers.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/EventHandlers.kt index befe64be2..f5756a8c0 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/EventHandlers.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/EventHandlers.kt @@ -56,9 +56,10 @@ object EventHandlers : EntityEvent.LivingDeath, EntityEvent.LivingHurt, Interact InteractionEvent.RightClickItem, Runnable, LootEvent.ModifyLootTable, PlayerEvent.AttackEntity, PlayerEvent.DropItem { private val MODIFIABLE_LOOT_TABLES = setOf( - Identifier.ofVanilla("chests/bastion_treasure"), + Identifier.ofVanilla("chests/ancient_city"), Identifier.ofVanilla("chests/bastion_other"), - Identifier.ofVanilla("chests/trial_chambers/reward_unique") + Identifier.ofVanilla("chests/bastion_treasure"), + Identifier.ofVanilla("chests/trial_chambers/reward_unique"), ) private const val MAX_ANGER_DISTANCE = 16.0 diff --git a/StaffMod/src/main/resources/data/avm_staff/enchantment/distant_detonation.json b/StaffMod/src/main/resources/data/avm_staff/enchantment/distant_detonation.json index da40f7004..f9531efea 100644 --- a/StaffMod/src/main/resources/data/avm_staff/enchantment/distant_detonation.json +++ b/StaffMod/src/main/resources/data/avm_staff/enchantment/distant_detonation.json @@ -3,7 +3,7 @@ "translate": "enchantment.avm_staff.distant_detonation" }, "supported_items": "#avm_staff:staffs", - "weight": 1, + "weight": 2, "max_level": 1, "min_cost": { "base": 20, diff --git a/StaffMod/src/main/resources/data/avm_staff/enchantment/power_charge.json b/StaffMod/src/main/resources/data/avm_staff/enchantment/power_charge.json index 62d904184..76a1e84dc 100644 --- a/StaffMod/src/main/resources/data/avm_staff/enchantment/power_charge.json +++ b/StaffMod/src/main/resources/data/avm_staff/enchantment/power_charge.json @@ -3,7 +3,7 @@ "translate": "enchantment.avm_staff.power_charge" }, "supported_items": "#avm_staff:staffs", - "weight": 1, + "weight": 2, "max_level": 1, "min_cost": { "base": 20, diff --git a/StaffMod/src/main/resources/data/avm_staff/enchantment/quick_draw.json b/StaffMod/src/main/resources/data/avm_staff/enchantment/quick_draw.json index cf496531b..c20004299 100644 --- a/StaffMod/src/main/resources/data/avm_staff/enchantment/quick_draw.json +++ b/StaffMod/src/main/resources/data/avm_staff/enchantment/quick_draw.json @@ -3,7 +3,7 @@ "translate": "enchantment.avm_staff.quick_draw" }, "supported_items": "#avm_staff:staffs", - "weight": 1, + "weight": 2, "max_level": 4, "min_cost": { "base": 15, diff --git a/StaffMod/src/main/resources/data/avm_staff/enchantment/rapid_fire.json b/StaffMod/src/main/resources/data/avm_staff/enchantment/rapid_fire.json index e713e27e6..b93829ce9 100644 --- a/StaffMod/src/main/resources/data/avm_staff/enchantment/rapid_fire.json +++ b/StaffMod/src/main/resources/data/avm_staff/enchantment/rapid_fire.json @@ -3,7 +3,7 @@ "translate": "enchantment.avm_staff.rapid_fire" }, "supported_items": "#avm_staff:staffs", - "weight": 1, + "weight": 2, "max_level": 2, "min_cost": { "base": 10, diff --git a/StaffMod/src/main/resources/data/avm_staff/loot_table/add_loot_pool/chests/ancient_city.json b/StaffMod/src/main/resources/data/avm_staff/loot_table/add_loot_pool/chests/ancient_city.json new file mode 100644 index 000000000..07132058a --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/loot_table/add_loot_pool/chests/ancient_city.json @@ -0,0 +1,35 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:empty", + "weight": 80 + }, + { + "type": "minecraft:item", + "name": "minecraft:book", + "weight": 3, + "functions": [ + { + "function": "minecraft:enchant_randomly", + "options": "avm_staff:quick_draw" + } + ] + }, + { + "type": "minecraft:item", + "name": "minecraft:book", + "weight": 3, + "functions": [ + { + "function": "minecraft:enchant_randomly", + "options": "avm_staff:rapid_fire" + } + ] + } + ] + } + ] +} diff --git a/StaffMod/src/main/resources/data/minecraft/tags/enchantment/non_treasure.json b/StaffMod/src/main/resources/data/minecraft/tags/enchantment/non_treasure.json new file mode 100644 index 000000000..e2cf9ba4d --- /dev/null +++ b/StaffMod/src/main/resources/data/minecraft/tags/enchantment/non_treasure.json @@ -0,0 +1,7 @@ +{ + "replace": false, + "values": [ + "avm_staff:distant_detonation", + "avm_staff:power_charge" + ] +} diff --git a/StaffMod/src/main/resources/data/minecraft/tags/enchantment/treasure.json b/StaffMod/src/main/resources/data/minecraft/tags/enchantment/treasure.json new file mode 100644 index 000000000..9111ba3b8 --- /dev/null +++ b/StaffMod/src/main/resources/data/minecraft/tags/enchantment/treasure.json @@ -0,0 +1,8 @@ +{ + "replace": false, + "values": [ + "avm_staff:quick_draw", + "avm_staff:rapid_fire", + "avm_staff:spectre" + ] +} From 0d17534d299c9755da4963d9668f44eb9e33eb7f Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 30 Nov 2024 19:21:10 +0100 Subject: [PATCH 70/83] Use the provided RegistryKey in SoundEvent registration --- .../main/kotlin/opekope2/avm_staff/content/SoundEvents.kt | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/SoundEvents.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/SoundEvents.kt index e0eea898e..5ede95a88 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/SoundEvents.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/SoundEvents.kt @@ -31,9 +31,7 @@ object SoundEvents : RegistryUtil(MOD_ID, RegistryKeys.SOUND_EVENT) * Sound event registered as `avm_staff:entity.cake.splash`. */ @JvmField - val CAKE_SPLASH = register("entity.cake.splash") { - SoundEvent.of(id("entity.cake.splash")) - } + val CAKE_SPLASH = register("entity.cake.splash") { SoundEvent.of(it.value) } /** * @see CAKE_SPLASH @@ -46,9 +44,7 @@ object SoundEvents : RegistryUtil(MOD_ID, RegistryKeys.SOUND_EVENT) * Sound event registered as `avm_staff:entity.cake.throw`. */ @JvmField - val CAKE_THROW = register("entity.cake.throw") { - SoundEvent.of(id("entity.cake.throw")) - } + val CAKE_THROW = register("entity.cake.throw") { SoundEvent.of(it.value) } /** * @see CAKE_THROW From ffc163d546fe349fe49253c9681adfb2c8bb5ccf Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 30 Nov 2024 20:33:14 +0100 Subject: [PATCH 71/83] Add enchantment descriptions --- StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json index 82f75f2fe..745114325 100644 --- a/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json +++ b/StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json @@ -30,10 +30,15 @@ "death.attack.avm_staff.pranked.player": "%s was pranked by %s", "death.attack.avm_staff.pranked.player.item": "%s was pranked by %s using %s", "enchantment.avm_staff.distant_detonation": "Distant Detonation", + "enchantment.avm_staff.distant_detonation.desc": "Hold the use key to throw a TNT from a Staff. Release the key to detonate the TNT", "enchantment.avm_staff.power_charge": "Power Charge", + "enchantment.avm_staff.power_charge.desc": "Fire more powerful projectiles from a Staff", "enchantment.avm_staff.quick_draw": "Quick Draw", + "enchantment.avm_staff.quick_draw.desc": "Reduce the cooldown of a Staff", "enchantment.avm_staff.rapid_fire": "Rapid Fire", + "enchantment.avm_staff.rapid_fire.desc": "Fire projectiles quicker from a Staff", "enchantment.avm_staff.spectre": "Spectre", + "enchantment.avm_staff.spectre.desc": "Inflict Glowing to the attacked entity when attacking using a Staff with Bell", "entity.avm_staff.cake": "Cake", "entity.avm_staff.campfire_flame": "Campfire flame", "entity.avm_staff.impact_tnt": "Impact TNT", From e00f790ecfb90d132d93973d230f5c1def55f798 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 30 Nov 2024 20:56:05 +0100 Subject: [PATCH 72/83] Change versioning scheme --- build.gradle.kts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index cdbb62ca6..b503bc954 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -60,13 +60,14 @@ allprojects { apply(plugin = "architectury-plugin") val javaVersion = rootProject.libs.versions.java.get() + val minecraftVersion = rootProject.libs.versions.minecraft.get() base { archivesName = "staff-mod" } - val suffix = if (extra.has("loom.platform")) "+${extra["loom.platform"]}" else "" - version = rootProject.libs.versions.staff.mod.get() + suffix + val loaderSuffix = if (extra.has("loom.platform")) "${extra["loom.platform"]}." else "" + version = rootProject.libs.versions.staff.mod.get() + "-" + loaderSuffix + minecraftVersion group = "opekope2.avm_staff" repositories { From 4ddc6dff88c7d20251f4bb85103f7538cd4e7fd9 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 30 Nov 2024 20:59:37 +0100 Subject: [PATCH 73/83] Bump version --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d66560bd1..41ff52454 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] java = "21" # Don't forget to update *.mixins.json kotlin = "2.0.0" -staff-mod = "0.19.1" +staff-mod = "0.20.0" architectury-plugin = "3.4-SNAPSHOT" architectury-loom = "1.7-SNAPSHOT" yarn = "1.21+build.9" From 0a90105b8d21115e0f2dc5e29d46c8aaa0fa2043 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 1 Dec 2024 03:20:01 +0100 Subject: [PATCH 74/83] Port to Forge --- .../avm_staff/api/IStaffModPlatform.kt | 4 +- .../api/entity/CampfireFlameEntity.kt | 25 ++- .../opekope2/avm_staff/api/item/StaffItem.kt | 4 +- .../opekope2/avm_staff/content/Blocks.kt | 8 +- .../opekope2/avm_staff/content/EntityTypes.kt | 4 +- .../opekope2/avm_staff/content/ItemGroups.kt | 25 ++- .../opekope2/avm_staff/content/Items.kt | 23 +-- .../avm_staff/content/ParticleTypes.kt | 4 +- .../opekope2/avm_staff/content/SoundEvents.kt | 4 +- .../event_handler/ClientEventHandlers.kt | 21 ++- .../internal/event_handler/EventHandlers.kt | 145 ++++++++++-------- .../event_handler/KeyBindingHandler.kt | 15 +- .../avm_staff/internal/forge/StaffMod.kt | 6 +- .../internal/forge/StaffModClient.kt | 58 ++----- .../internal/forge/item/ForgeStaffItem.kt | 6 +- .../internal/initializer/ClientInitializer.kt | 19 +-- .../internal/initializer/Initializer.kt | 8 +- .../internal/model/ModelPredicates.kt | 6 +- .../AbstractMassDestructiveStaffHandler.kt | 10 +- .../internal/staff/handler/BellHandler.kt | 10 -- .../internal/staff/handler/CampfireHandler.kt | 6 +- .../staff/handler/VanillaStaffHandlers.kt | 2 - .../item_renderer/BellStaffItemRenderer.kt | 6 +- .../item_renderer/FurnaceStaffItemRenderer.kt | 6 +- .../LightningRodStaffItemRenderer.kt | 6 +- .../WitherSkeletonSkullStaffItemRenderer.kt | 6 +- .../avm_staff/util/MinecraftClientUtil.kt | 6 +- .../opekope2/avm_staff/util/RegistryUtil.kt | 39 +++-- 28 files changed, 233 insertions(+), 249 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/IStaffModPlatform.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/IStaffModPlatform.kt index f5741a01b..4b42f6bfc 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/IStaffModPlatform.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/IStaffModPlatform.kt @@ -18,10 +18,10 @@ package opekope2.avm_staff.api -import dev.architectury.registry.registries.RegistrySupplier import net.minecraft.block.Block import net.minecraft.item.Item import net.minecraft.particle.SimpleParticleType +import net.minecraftforge.registries.RegistryObject import opekope2.avm_staff.api.IStaffModPlatform.Instance import opekope2.avm_staff.api.item.CrownItem import opekope2.avm_staff.api.item.StaffItem @@ -38,7 +38,7 @@ interface IStaffModPlatform { * * @param settings The item settings to pass to the constructor */ - fun staffItem(settings: Item.Settings, repairIngredient: RegistrySupplier?): StaffItem + fun staffItem(settings: Item.Settings, repairIngredient: RegistryObject?): StaffItem /** * Creates an item, which is rendered like a staff. diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CampfireFlameEntity.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CampfireFlameEntity.kt index 0425d5a4a..02ba26f85 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CampfireFlameEntity.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/CampfireFlameEntity.kt @@ -18,10 +18,6 @@ package opekope2.avm_staff.api.entity -import dev.architectury.extensions.network.EntitySpawnExtension -import dev.architectury.networking.NetworkManager -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment import net.minecraft.block.* import net.minecraft.block.piston.PistonBehavior import net.minecraft.client.option.GraphicsMode @@ -32,14 +28,11 @@ import net.minecraft.entity.data.DataTracker import net.minecraft.entity.projectile.ProjectileUtil import net.minecraft.nbt.NbtCompound import net.minecraft.network.PacketByteBuf -import net.minecraft.network.listener.ClientPlayPacketListener -import net.minecraft.network.packet.Packet import net.minecraft.particle.ParticleEffect import net.minecraft.particle.ParticleType import net.minecraft.registry.Registries import net.minecraft.registry.RegistryKey import net.minecraft.registry.RegistryKeys -import net.minecraft.server.network.EntityTrackerEntry import net.minecraft.state.property.Properties.LIT import net.minecraft.util.hit.BlockHitResult import net.minecraft.util.hit.HitResult @@ -49,6 +42,9 @@ import net.minecraft.util.math.Vec3d import net.minecraft.world.RaycastContext import net.minecraft.world.World import net.minecraft.world.event.GameEvent +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn +import net.minecraftforge.entity.IEntityAdditionalSpawnData import opekope2.avm_staff.content.EntityTypes import opekope2.avm_staff.content.ParticleTypes import opekope2.avm_staff.util.* @@ -57,7 +53,7 @@ import java.util.* /** * Technical entity representing a part of a flame of a campfire staff. */ -class CampfireFlameEntity : Entity, EntitySpawnExtension { +class CampfireFlameEntity : Entity, IEntityAdditionalSpawnData { private var currentRelativeRight: Vec3d = Vec3d.ZERO private var currentRelativeUp: Vec3d = Vec3d.ZERO @@ -151,7 +147,7 @@ class CampfireFlameEntity : Entity, EntitySpawnExtension { if (!world.isClient && age >= parameters.stepResolution) discard() } - @Environment(EnvType.CLIENT) + @OnlyIn(Dist.CLIENT) private fun spawnParticle(particleEffect: ParticleEffect, start: Vec3d, end: Vec3d) { val particleOffset = (end - start) * random.nextDouble() + currentRelativeRight * ((random.nextDouble() * 2 - 1) / rayResolution) + @@ -184,7 +180,7 @@ class CampfireFlameEntity : Entity, EntitySpawnExtension { } } - @Environment(EnvType.CLIENT) + @OnlyIn(Dist.CLIENT) private fun tickRayClient(start: Vec3d, end: Vec3d): HitResult.Type { val blockHit = raycastBlock(start, end) val entityHit = raycastEntity(start, end, false) @@ -306,15 +302,12 @@ class CampfireFlameEntity : Entity, EntitySpawnExtension { override fun getPistonBehavior() = PistonBehavior.IGNORE - override fun createSpawnPacket(entityTrackerEntry: EntityTrackerEntry): Packet = - NetworkManager.createAddEntityPacket(this, entityTrackerEntry) - - override fun saveAdditionalSpawnData(buf: PacketByteBuf) { + override fun writeSpawnData(buf: PacketByteBuf) { parameters.write(buf) buf.writeVarInt(shooter.id) } - override fun loadAdditionalSpawnData(buf: PacketByteBuf) { + override fun readSpawnData(buf: PacketByteBuf) { parameters = Parameters(buf) shooter = world.getEntityById(buf.readVarInt()) as LivingEntity } @@ -392,7 +385,7 @@ class CampfireFlameEntity : Entity, EntitySpawnExtension { get() = this == HitResult.Type.BLOCK private val flameParticleRayResolution: Int - @Environment(EnvType.CLIENT) + @OnlyIn(Dist.CLIENT) get() = when (clientOptions.graphicsMode.value) { GraphicsMode.FABULOUS -> 6 GraphicsMode.FANCY -> 5 diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt index 1b1d3da48..6204522d5 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt @@ -18,7 +18,6 @@ package opekope2.avm_staff.api.item -import dev.architectury.registry.registries.RegistrySupplier import net.minecraft.component.DataComponentTypes import net.minecraft.entity.Entity import net.minecraft.entity.EquipmentSlot @@ -36,6 +35,7 @@ import net.minecraft.util.TypedActionResult import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction import net.minecraft.world.World +import net.minecraftforge.registries.RegistryObject import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.* @@ -44,7 +44,7 @@ import opekope2.avm_staff.util.* * Implementing loader-specific interfaces is highly recommended when extending the class to pass loader-specific * functionality to [StaffHandler]. */ -abstract class StaffItem(settings: Settings, private val repairIngredientSupplier: RegistrySupplier?) : +abstract class StaffItem(settings: Settings, private val repairIngredientSupplier: RegistryObject?) : Item(settings) { override fun canRepair(stack: ItemStack, ingredient: ItemStack) = repairIngredientSupplier != null && ingredient.isOf(repairIngredientSupplier.get()) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Blocks.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Blocks.kt index cd1e10393..a4721dadf 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Blocks.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Blocks.kt @@ -18,13 +18,13 @@ package opekope2.avm_staff.content -import dev.architectury.registry.registries.RegistrySupplier import net.minecraft.block.AbstractBlock import net.minecraft.block.Block import net.minecraft.block.enums.NoteBlockInstrument import net.minecraft.block.piston.PistonBehavior -import net.minecraft.registry.RegistryKeys import net.minecraft.sound.BlockSoundGroup +import net.minecraftforge.registries.ForgeRegistries +import net.minecraftforge.registries.RegistryObject import opekope2.avm_staff.api.block.CrownBlock import opekope2.avm_staff.api.block.WallCrownBlock import opekope2.avm_staff.util.MOD_ID @@ -33,9 +33,9 @@ import opekope2.avm_staff.util.RegistryUtil /** * Blocks added by AVM Staffs mod. */ -object Blocks : RegistryUtil(MOD_ID, RegistryKeys.BLOCK) { +object Blocks : RegistryUtil(MOD_ID, ForgeRegistries.BLOCKS) { private fun settings() = AbstractBlock.Settings.create() - private fun settings(block: RegistrySupplier) = AbstractBlock.Settings.copy(block.get()) + private fun settings(block: RegistryObject) = AbstractBlock.Settings.copy(block.get()) /** * Block registered as `avm_staff:crown_of_king_orange`. diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/EntityTypes.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/EntityTypes.kt index 982f188a3..2b5a1c367 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/EntityTypes.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/EntityTypes.kt @@ -20,8 +20,8 @@ package opekope2.avm_staff.content import net.minecraft.entity.EntityType import net.minecraft.entity.SpawnGroup -import net.minecraft.registry.RegistryKeys import net.minecraft.util.Identifier +import net.minecraftforge.registries.ForgeRegistries import opekope2.avm_staff.api.entity.CakeEntity import opekope2.avm_staff.api.entity.CampfireFlameEntity import opekope2.avm_staff.api.entity.ImpactTntEntity @@ -33,7 +33,7 @@ import kotlin.math.max /** * Entity types added by AVM Staffs mod. */ -object EntityTypes : RegistryUtil>(MOD_ID, RegistryKeys.ENTITY_TYPE) { +object EntityTypes : RegistryUtil>(MOD_ID, ForgeRegistries.ENTITY_TYPES) { /** * Entity registered as `avm_staff:cake` */ diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ItemGroups.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ItemGroups.kt index 46d48cf2b..4aba5ee7a 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ItemGroups.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ItemGroups.kt @@ -18,11 +18,10 @@ package opekope2.avm_staff.content -import dev.architectury.registry.CreativeTabRegistry -import dev.architectury.registry.registries.RegistrySupplier import net.minecraft.item.ItemGroup import net.minecraft.registry.RegistryKeys import net.minecraft.text.Text +import net.minecraftforge.registries.RegistryObject import opekope2.avm_staff.util.MOD_ID import opekope2.avm_staff.util.RegistryUtil import opekope2.avm_staff.util.mutableItemStackInStaff @@ -35,12 +34,24 @@ object ItemGroups : RegistryUtil(MOD_ID, RegistryKeys.ITEM_GROUP) { * Item group containing items added by Staff Mod. */ @JvmField - val AVM_STAFF_MOD_ITEMS: RegistrySupplier = ItemGroups.register("${MOD_ID}_items") { - CreativeTabRegistry.create(Text.translatable("itemGroup.${MOD_ID}_items")) { - Items.royalStaff.defaultStack.apply { - mutableItemStackInStaff = net.minecraft.item.Items.COMMAND_BLOCK.defaultStack + val AVM_STAFF_MOD_ITEMS: RegistryObject = ItemGroups.register("${MOD_ID}_items") { + ItemGroup.builder() + .displayName(Text.translatable("itemGroup.${MOD_ID}_items")) + .icon { + Items.royalStaff.defaultStack.apply { + mutableItemStackInStaff = net.minecraft.item.Items.COMMAND_BLOCK.defaultStack + } } - } + .entries { _, entries -> + entries.add(Items.faintStaffRod) + entries.add(Items.faintRoyalStaffHead) + entries.add(Items.faintRoyalStaff) + entries.add(Items.royalStaff) + entries.add(Items.royalStaffIngredient) + entries.add(Items.crownOfKingOrange) + entries.add(Items.staffInfusionSmithingTemplate) + } + .build() } /** diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt index f0fdce64c..180bec42a 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/Items.kt @@ -18,7 +18,6 @@ package opekope2.avm_staff.content -import dev.architectury.registry.CreativeTabRegistry import net.minecraft.component.DataComponentTypes import net.minecraft.component.type.ToolComponent import net.minecraft.item.Item @@ -26,6 +25,7 @@ import net.minecraft.item.SmithingTemplateItem import net.minecraft.registry.RegistryKeys import net.minecraft.text.Text import net.minecraft.util.Rarity +import net.minecraftforge.registries.ForgeRegistries import opekope2.avm_staff.api.IStaffModPlatform import opekope2.avm_staff.api.item.CrownItem import opekope2.avm_staff.api.item.StaffItem @@ -39,7 +39,7 @@ import opekope2.avm_staff.util.TagKeyUtil /** * Items added by AVM Staffs mod. */ -object Items : RegistryUtil(MOD_ID, RegistryKeys.ITEM) { +object Items : RegistryUtil(MOD_ID, ForgeRegistries.ITEMS) { private fun settings() = Item.Settings() /** @@ -50,7 +50,7 @@ object Items : RegistryUtil(MOD_ID, RegistryKeys.ITEM) { IStaffModPlatform.crownItem( Blocks.CROWN_OF_KING_ORANGE.get(), Blocks.WALL_CROWN_OF_KING_ORANGE.get(), - settings().maxCount(1).rarity(Rarity.UNCOMMON).`arch$tab`(ItemGroups.AVM_STAFF_MOD_ITEMS) + settings().maxCount(1).rarity(Rarity.UNCOMMON) ) } @@ -67,7 +67,7 @@ object Items : RegistryUtil(MOD_ID, RegistryKeys.ITEM) { @JvmField val FAINT_ROYAL_STAFF = register("faint_royal_staff") { IStaffModPlatform.itemWithStaffRenderer( - settings().maxCount(1).rarity(Rarity.RARE).`arch$tab`(ItemGroups.AVM_STAFF_MOD_ITEMS) + settings().maxCount(1).rarity(Rarity.RARE) ) } @@ -83,7 +83,7 @@ object Items : RegistryUtil(MOD_ID, RegistryKeys.ITEM) { */ @JvmField val FAINT_ROYAL_STAFF_HEAD = register("faint_royal_staff_head") { - Item(settings().maxCount(16).rarity(Rarity.RARE).`arch$tab`(ItemGroups.AVM_STAFF_MOD_ITEMS)) + Item(settings().maxCount(16).rarity(Rarity.RARE)) } /** @@ -98,7 +98,7 @@ object Items : RegistryUtil(MOD_ID, RegistryKeys.ITEM) { */ @JvmField val FAINT_STAFF_ROD = register("faint_staff_rod") { - Item(settings().`arch$tab`(ItemGroups.AVM_STAFF_MOD_ITEMS)) + Item(settings()) } /** @@ -115,8 +115,7 @@ object Items : RegistryUtil(MOD_ID, RegistryKeys.ITEM) { val ROYAL_STAFF = register("royal_staff") { IStaffModPlatform.staffItem( settings().maxCount(1).rarity(Rarity.EPIC).attributeModifiers(StaffHandler.Fallback.ATTRIBUTE_MODIFIERS) - .maxDamage(5179).component(DataComponentTypes.TOOL, ToolComponent(listOf(), 1f, 1)) - .`arch$tab`(ItemGroups.AVM_STAFF_MOD_ITEMS), + .maxDamage(5179).component(DataComponentTypes.TOOL, ToolComponent(listOf(), 1f, 1)), ROYAL_STAFF_INGREDIENT ) } @@ -133,7 +132,7 @@ object Items : RegistryUtil(MOD_ID, RegistryKeys.ITEM) { */ @JvmField val ROYAL_STAFF_INGREDIENT = register("royal_staff_ingredient") { - Item(settings().`arch$tab`(ItemGroups.AVM_STAFF_MOD_ITEMS)) + Item(settings()) } /** @@ -168,12 +167,6 @@ object Items : RegistryUtil(MOD_ID, RegistryKeys.ITEM) { @JvmName("staffInfusionSmithingTemplate") get() = STAFF_INFUSION_SMITHING_TEMPLATE.get() - override fun register() { - super.register() - // Because SmithingTemplateItem doesn't take Item.Settings in its constructor - CreativeTabRegistry.append(ItemGroups.AVM_STAFF_MOD_ITEMS, STAFF_INFUSION_SMITHING_TEMPLATE) - } - /** * Item tags added by AVM Staffs mod. */ diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ParticleTypes.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ParticleTypes.kt index 1dbf0ef7b..1e5e193c6 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ParticleTypes.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/ParticleTypes.kt @@ -21,7 +21,7 @@ package opekope2.avm_staff.content import net.minecraft.client.particle.ParticleManager import net.minecraft.particle.ParticleType import net.minecraft.particle.SimpleParticleType -import net.minecraft.registry.RegistryKeys +import net.minecraftforge.registries.ForgeRegistries import opekope2.avm_staff.api.IStaffModPlatform import opekope2.avm_staff.util.MOD_ID import opekope2.avm_staff.util.RegistryUtil @@ -29,7 +29,7 @@ import opekope2.avm_staff.util.RegistryUtil /** * Particle types added by AVM Staffs mod. */ -object ParticleTypes : RegistryUtil>(MOD_ID, RegistryKeys.PARTICLE_TYPE) { +object ParticleTypes : RegistryUtil>(MOD_ID, ForgeRegistries.PARTICLE_TYPES) { /** * Particle registered as `avm_staff:flame`. * diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/SoundEvents.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/SoundEvents.kt index 5ede95a88..17a6e0167 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/SoundEvents.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/SoundEvents.kt @@ -18,15 +18,15 @@ package opekope2.avm_staff.content -import net.minecraft.registry.RegistryKeys import net.minecraft.sound.SoundEvent +import net.minecraftforge.registries.ForgeRegistries import opekope2.avm_staff.util.MOD_ID import opekope2.avm_staff.util.RegistryUtil /** * Sound events added by AVM Staffs mod. */ -object SoundEvents : RegistryUtil(MOD_ID, RegistryKeys.SOUND_EVENT) { +object SoundEvents : RegistryUtil(MOD_ID, ForgeRegistries.SOUND_EVENTS) { /** * Sound event registered as `avm_staff:entity.cake.splash`. */ diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/ClientEventHandlers.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/ClientEventHandlers.kt index e067019fb..297dee693 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/ClientEventHandlers.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/ClientEventHandlers.kt @@ -18,23 +18,22 @@ package opekope2.avm_staff.internal.event_handler -import dev.architectury.event.events.client.ClientTickEvent -import dev.architectury.event.events.common.InteractionEvent -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment -import net.minecraft.entity.player.PlayerEntity -import net.minecraft.util.Hand +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn +import net.minecraftforge.event.entity.player.PlayerInteractEvent.LeftClickEmpty import opekope2.avm_staff.api.item.StaffItem import opekope2.avm_staff.internal.networking.c2s.play.AttackC2SPacket +import thedarkcolour.kotlinforforge.forge.FORGE_BUS -@Environment(EnvType.CLIENT) -object ClientEventHandlers : InteractionEvent.ClientLeftClickAir { +@OnlyIn(Dist.CLIENT) +object ClientEventHandlers { init { - ClientTickEvent.CLIENT_POST.register(KeyBindingHandler) - InteractionEvent.CLIENT_LEFT_CLICK_AIR.register(this) + FORGE_BUS.addListener(::click) } - override fun click(player: PlayerEntity, hand: Hand) { + private fun click(event: LeftClickEmpty) { + val player = event.entity + val hand = event.hand val staffStack = player.getStackInHand(hand) val staffItem = staffStack.item as? StaffItem ?: return diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/EventHandlers.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/EventHandlers.kt index f5756a8c0..561cc7ef1 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/EventHandlers.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/EventHandlers.kt @@ -18,31 +18,29 @@ package opekope2.avm_staff.internal.event_handler -import dev.architectury.event.CompoundEventResult -import dev.architectury.event.EventResult -import dev.architectury.event.events.common.* import net.minecraft.block.DispenserBlock -import net.minecraft.entity.Entity import net.minecraft.entity.ItemEntity import net.minecraft.entity.LivingEntity -import net.minecraft.entity.damage.DamageSource import net.minecraft.entity.mob.AbstractPiglinEntity import net.minecraft.entity.player.PlayerEntity -import net.minecraft.item.ItemStack import net.minecraft.item.Items import net.minecraft.loot.LootPool -import net.minecraft.loot.LootTable import net.minecraft.loot.entry.LootTableEntry import net.minecraft.registry.RegistryKey import net.minecraft.registry.RegistryKeys import net.minecraft.server.network.ServerPlayerEntity -import net.minecraft.util.Hand +import net.minecraft.util.ActionResult import net.minecraft.util.Identifier -import net.minecraft.util.hit.EntityHitResult -import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Box -import net.minecraft.util.math.Direction -import net.minecraft.world.World +import net.minecraftforge.event.LootTableLoadEvent +import net.minecraftforge.event.entity.item.ItemTossEvent +import net.minecraftforge.event.entity.living.LivingDeathEvent +import net.minecraftforge.event.entity.living.LivingHurtEvent +import net.minecraftforge.event.entity.player.AttackEntityEvent +import net.minecraftforge.event.entity.player.PlayerInteractEvent.LeftClickBlock +import net.minecraftforge.event.entity.player.PlayerInteractEvent.RightClickItem +import net.minecraftforge.eventbus.api.Event +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent import opekope2.avm_staff.api.block.dispenser.CakeDispenserBehavior import opekope2.avm_staff.api.entity.CakeEntity import opekope2.avm_staff.api.item.StaffItem @@ -51,10 +49,9 @@ import opekope2.avm_staff.content.EntityTypes import opekope2.avm_staff.content.GameRules import opekope2.avm_staff.mixin.IPiglinBrainAccessor import opekope2.avm_staff.util.* +import thedarkcolour.kotlinforforge.forge.FORGE_BUS -object EventHandlers : EntityEvent.LivingDeath, EntityEvent.LivingHurt, InteractionEvent.LeftClickBlock, - InteractionEvent.RightClickItem, Runnable, LootEvent.ModifyLootTable, PlayerEvent.AttackEntity, - PlayerEvent.DropItem { +object EventHandlers { private val MODIFIABLE_LOOT_TABLES = setOf( Identifier.ofVanilla("chests/ancient_city"), Identifier.ofVanilla("chests/bastion_other"), @@ -64,92 +61,104 @@ object EventHandlers : EntityEvent.LivingDeath, EntityEvent.LivingHurt, Interact private const val MAX_ANGER_DISTANCE = 16.0 init { - EntityEvent.LIVING_DEATH.register(this) - EntityEvent.LIVING_HURT.register(this) - InteractionEvent.LEFT_CLICK_BLOCK.register(this) - InteractionEvent.RIGHT_CLICK_ITEM.register(this) - LifecycleEvent.SETUP.register(this) - LootEvent.MODIFY_LOOT_TABLE.register(this) - PlayerEvent.ATTACK_ENTITY.register(this) - PlayerEvent.DROP_ITEM.register(this) + FORGE_BUS.addListener(::die) + FORGE_BUS.addListener(::hurt) + FORGE_BUS.addListener(::leftClickBlock) + FORGE_BUS.addListener(::rightClickItem) + FORGE_BUS.addListener(::setup) + FORGE_BUS.addListener(::modifyLootTable) + FORGE_BUS.addListener(::attack) + FORGE_BUS.addListener(::drop) } - override fun die(entity: LivingEntity, damageSource: DamageSource): EventResult { - if (entity !is PlayerEntity) return EventResult.pass() + private fun die(event: LivingDeathEvent) { + val entity = event.entity + if (entity !is PlayerEntity) return if (entity.activeItem.isStaff) { entity.stopUsingItem() } - - return EventResult.pass() } - override fun hurt(entity: LivingEntity, damage: DamageSource, amount: Float): EventResult { + private fun hurt(event: LivingHurtEvent) { + val entity = event.entity + val damage = event.source + if (entity is ServerPlayerEntity && entity.isUsingItem) { Criteria.takeDamageWhileUsingItem.trigger(entity, entity.activeItem, damage) } - return EventResult.pass() } - override fun click(player: PlayerEntity, hand: Hand, target: BlockPos, direction: Direction): EventResult { + private fun leftClickBlock(event: LeftClickBlock) { + val player = event.entity + val hand = event.hand + val target = event.pos + val direction = event.face!! val staffStack = player.getStackInHand(hand) - val staffItem = staffStack.item as? StaffItem ?: return EventResult.pass() - - return staffItem.attackBlock(staffStack, player.entityWorld, player, target, direction, hand) + val staffItem = staffStack.item as? StaffItem ?: return + + val result = staffItem.attackBlock(staffStack, player.entityWorld, player, target, direction, hand) + if (result != ActionResult.PASS) { + event.isCanceled = true + event.cancellationResult = result + event.useBlock = Event.Result.DENY + event.useItem = Event.Result.DENY + } } - override fun click(player: PlayerEntity, hand: Hand): CompoundEventResult { + private fun rightClickItem(event: RightClickItem) { + val player = event.entity + val hand = event.hand val world = player.entityWorld val cake = player.getStackInHand(hand) val spawnPos = EntityTypes.cake.getSpawnPosition(world, player.approximateStaffTipPosition) - if (!cake.isOf(Items.CAKE)) return CompoundEventResult.pass() - if (spawnPos == null) return CompoundEventResult.pass() - if (world.isClient) return CompoundEventResult.interruptTrue(cake) - if (!world.gameRules.getBoolean(GameRules.THROWABLE_CAKES)) return CompoundEventResult.pass() + if (!cake.isOf(Items.CAKE)) return + if (spawnPos == null) return + if (world.isClient) { + event.isCanceled = true + event.cancellationResult = ActionResult.SUCCESS + return + } + if (!world.gameRules.getBoolean(GameRules.THROWABLE_CAKES)) return CakeEntity.throwCake(world, spawnPos, player.rotationVector * .5 + player.velocity, player) cake.decrementUnlessCreative(1, player) - return CompoundEventResult.interruptFalse(cake) + event.isCanceled = true + event.cancellationResult = ActionResult.FAIL } - // setup - override fun run() { - DispenserBlock.registerBehavior(Items.CAKE, CakeDispenserBehavior()) + private fun setup(event: FMLCommonSetupEvent) { + event.enqueueWork { + DispenserBlock.registerBehavior(Items.CAKE, CakeDispenserBehavior()) + } } - override fun modifyLootTable( - lootTable: RegistryKey, - context: LootEvent.LootTableModificationContext, - builtin: Boolean - ) { - if (!builtin) return - if (lootTable.value !in MODIFIABLE_LOOT_TABLES) return + private fun modifyLootTable(event: LootTableLoadEvent) { + val lootTable = event.name + if (lootTable !in MODIFIABLE_LOOT_TABLES) return - context.addPool( + event.table.addPool( LootPool.builder().with( LootTableEntry.builder( RegistryKey.of( RegistryKeys.LOOT_TABLE, - Identifier.of(MOD_ID, "add_loot_pool/${lootTable.value.path}") + Identifier.of(MOD_ID, "add_loot_pool/${lootTable.path}") ) ) - ) + ).build() ) } - override fun attack( - player: PlayerEntity, - world: World, - target: Entity, - hand: Hand, - hit: EntityHitResult? - ): EventResult { - if (world.isClient) return EventResult.pass() - if (target !is LivingEntity) return EventResult.pass() - if (!player.getStackInHand(hand).isStaff) return EventResult.pass() - if (!player.armorItems.any { it.isOf(opekope2.avm_staff.content.Items.crownOfKingOrange) }) return EventResult.pass() + private fun attack(event: AttackEntityEvent) { + val player = event.entity + val world = player.entityWorld + val target = event.target + if (world.isClient) return + if (target !is LivingEntity) return + if (!player.mainHandStack.isStaff) return + if (!player.armorItems.any { it.isOf(opekope2.avm_staff.content.Items.crownOfKingOrange) }) return val box = Box.of(player.pos, 2 * MAX_ANGER_DISTANCE, 2 * MAX_ANGER_DISTANCE, 2 * MAX_ANGER_DISTANCE) world.getEntitiesByClass(AbstractPiglinEntity::class.java, box) { @@ -157,13 +166,15 @@ object EventHandlers : EntityEvent.LivingDeath, EntityEvent.LivingHurt, Interact }.forEach { IPiglinBrainAccessor.callBecomeAngryWith(it, target) } + } - return EventResult.pass() + private fun drop(event: ItemTossEvent) { + drop(event.player, event.entity) } - override fun drop(entity: PlayerEntity, item: ItemEntity): EventResult { - val staffItem = item.stack.item as? StaffItem ?: return EventResult.pass() + fun drop(entity: PlayerEntity, item: ItemEntity) { + val staffItem = item.stack.item as? StaffItem ?: return + staffItem.onStoppedUsing(item.stack, entity.entityWorld, entity, entity.itemUseTimeLeft) - return EventResult.pass() } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/KeyBindingHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/KeyBindingHandler.kt index 6fe7991cd..a0e521fa1 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/KeyBindingHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/KeyBindingHandler.kt @@ -26,15 +26,17 @@ import net.minecraft.item.ItemStack import net.minecraftforge.api.distmarker.Dist import net.minecraftforge.api.distmarker.OnlyIn import net.minecraftforge.client.event.RegisterKeyMappingsEvent +import net.minecraftforge.event.TickEvent.ClientTickEvent import opekope2.avm_staff.internal.networking.c2s.play.InsertItemIntoStaffC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.InsertItemIntoStaffC2SPacket.Companion.tryInsertItemIntoStaff import opekope2.avm_staff.internal.networking.c2s.play.RemoveItemFromStaffC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.RemoveItemFromStaffC2SPacket.Companion.tryRemoveItemFromStaff import opekope2.avm_staff.util.MOD_ID import org.lwjgl.glfw.GLFW +import thedarkcolour.kotlinforforge.forge.FORGE_BUS @OnlyIn(Dist.CLIENT) -internal object KeyBindingHandler : ClientTickEvent.Client { +internal object KeyBindingHandler { private val ADD_REMOVE_STAFF_ITEM = KeyBinding( "key.$MOD_ID.add_remove_staff_item", InputUtil.Type.KEYSYM, @@ -43,10 +45,17 @@ internal object KeyBindingHandler : ClientTickEvent.Client { ) init { - KeyMappingRegistry.register(ADD_REMOVE_STAFF_ITEM) + FORGE_BUS.addListener(::register) + FORGE_BUS.addListener(::tick) } - override fun tick(client: MinecraftClient) { + private fun register(event: RegisterKeyMappingsEvent) { + event.register(ADD_REMOVE_STAFF_ITEM) + } + + @Suppress("UNUSED_PARAMETER") + private fun tick(event: ClientTickEvent.Post) { + val client = MinecraftClient.getInstance() if (!ADD_REMOVE_STAFF_ITEM.isPressed) return ADD_REMOVE_STAFF_ITEM.isPressed = false diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt index b4c9f285a..64f84622a 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt @@ -18,7 +18,6 @@ package opekope2.avm_staff.internal.forge -import dev.architectury.registry.registries.RegistrySupplier import net.minecraft.block.Block import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.Item @@ -26,12 +25,13 @@ import net.minecraft.particle.SimpleParticleType import net.minecraftforge.api.distmarker.Dist import net.minecraftforge.event.entity.living.LivingDropsEvent import net.minecraftforge.fml.common.Mod +import net.minecraftforge.registries.RegistryObject import opekope2.avm_staff.api.IStaffModPlatform import opekope2.avm_staff.internal.event_handler.EventHandlers -import opekope2.avm_staff.internal.initializer.Initializer import opekope2.avm_staff.internal.forge.item.ForgeCrownItem import opekope2.avm_staff.internal.forge.item.ForgeStaffItem import opekope2.avm_staff.internal.forge.item.ForgeStaffRendererItem +import opekope2.avm_staff.internal.initializer.Initializer import opekope2.avm_staff.internal.staff.handler.registerVanillaStaffHandlers import opekope2.avm_staff.util.MOD_ID import thedarkcolour.kotlinforforge.forge.FORGE_BUS @@ -58,7 +58,7 @@ object StaffMod : IStaffModPlatform { } } - override fun staffItem(settings: Item.Settings, repairIngredient: RegistrySupplier?) = + override fun staffItem(settings: Item.Settings, repairIngredient: RegistryObject?) = ForgeStaffItem(settings, repairIngredient) override fun itemWithStaffRenderer(settings: Item.Settings) = ForgeStaffRendererItem(settings) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt index 1c2b4d7b3..1f16f5329 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt @@ -18,75 +18,41 @@ package opekope2.avm_staff.internal.forge -import net.minecraft.block.DispenserBlock -import net.minecraft.client.MinecraftClient -import net.minecraft.client.render.entity.TntEntityRenderer -import net.minecraft.item.Items +import net.minecraft.client.item.ModelPredicateProviderRegistry import net.minecraftforge.api.distmarker.Dist import net.minecraftforge.api.distmarker.OnlyIn -import net.minecraftforge.client.event.EntityRenderersEvent.RegisterRenderers import net.minecraftforge.client.event.RegisterParticleProvidersEvent -import net.minecraftforge.event.TickEvent -import net.minecraftforge.event.entity.player.PlayerInteractEvent.LeftClickEmpty import net.minecraftforge.eventbus.api.SubscribeEvent import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent -import opekope2.avm_staff.api.block.dispenser.CakeDispenserBehavior -import opekope2.avm_staff.api.cakeEntityType -import opekope2.avm_staff.api.entity.renderer.CakeEntityRenderer -import opekope2.avm_staff.api.flamethrowerParticleType -import opekope2.avm_staff.api.impactTntEntityType import opekope2.avm_staff.api.particle.FlamethrowerParticle -import opekope2.avm_staff.api.soulFlamethrowerParticleType -import opekope2.avm_staff.internal.clientAttack -import opekope2.avm_staff.internal.event_handler.handleKeyBindings -import opekope2.avm_staff.internal.event_handler.registerKeyBindings -import opekope2.avm_staff.internal.model.registerModelPredicateProviders -import opekope2.avm_staff.internal.registerSmithingTableTextures +import opekope2.avm_staff.content.ParticleTypes +import opekope2.avm_staff.internal.event_handler.ClientEventHandlers +import opekope2.avm_staff.internal.initializer.ClientInitializer +import opekope2.avm_staff.internal.model.ModelPredicates import opekope2.avm_staff.internal.staff.handler.registerVanillaStaffItemRenderers -import thedarkcolour.kotlinforforge.forge.FORGE_BUS import thedarkcolour.kotlinforforge.forge.MOD_BUS @OnlyIn(Dist.CLIENT) object StaffModClient { fun initializeClient() { - registerSmithingTableTextures() - subscribeToClientEvents() + ClientInitializer + ClientEventHandlers registerVanillaStaffItemRenderers() - MOD_BUS.register(::registerKeyBindings) MOD_BUS.register(this) } - private fun subscribeToClientEvents() { - FORGE_BUS.addListener(::clientTick) - FORGE_BUS.addListener(::clientAttack) - } - @SubscribeEvent fun initializeClient(event: FMLClientSetupEvent) { event.enqueueWork { - registerModelPredicateProviders() - DispenserBlock.registerBehavior(Items.CAKE, CakeDispenserBehavior()) + for ((key, value) in ModelPredicates) { + ModelPredicateProviderRegistry.registerGeneric(key, value) + } } } @SubscribeEvent fun registerParticleProviders(event: RegisterParticleProvidersEvent) { - event.registerSpriteSet(flamethrowerParticleType.get(), FlamethrowerParticle::Factory) - event.registerSpriteSet(soulFlamethrowerParticleType.get(), FlamethrowerParticle::Factory) - } - - @SubscribeEvent - fun registerRenderers(event: RegisterRenderers) { - event.registerEntityRenderer(impactTntEntityType.get(), ::TntEntityRenderer) - event.registerEntityRenderer(cakeEntityType.get(), ::CakeEntityRenderer) - } - - @Suppress("UNUSED_PARAMETER") - fun clientTick(event: TickEvent.ClientTickEvent.Post) { - handleKeyBindings(MinecraftClient.getInstance()) - } - - fun clientAttack(event: LeftClickEmpty) { - clientAttack(event.entity, event.hand) + event.registerSpriteSet(ParticleTypes.flame, FlamethrowerParticle::Factory) + event.registerSpriteSet(ParticleTypes.soulFireFlame, FlamethrowerParticle::Factory) } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt index 72169762d..2d2291c3f 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt @@ -18,7 +18,6 @@ package opekope2.avm_staff.internal.forge.item -import dev.architectury.registry.registries.RegistrySupplier import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.render.item.BuiltinModelItemRenderer import net.minecraft.client.render.model.json.ModelTransformationMode @@ -32,6 +31,7 @@ import net.minecraft.util.ActionResult import net.minecraft.util.Hand import net.minecraftforge.client.extensions.common.IClientItemExtensions import net.minecraftforge.common.extensions.IForgeItem +import net.minecraftforge.registries.RegistryObject import opekope2.avm_staff.api.item.StaffItem import opekope2.avm_staff.api.item.renderer.StaffRenderer import opekope2.avm_staff.util.blockEntityRenderDispatcher @@ -40,14 +40,12 @@ import opekope2.avm_staff.util.itemInStaff import opekope2.avm_staff.util.staffHandlerOrFallback import java.util.function.Consumer -class ForgeStaffItem(settings: Settings, repairIngredientSupplier: RegistrySupplier?) : +class ForgeStaffItem(settings: Settings, repairIngredientSupplier: RegistryObject?) : StaffItem(settings, repairIngredientSupplier), IForgeItem { override fun canDisableShield(stack: ItemStack, shield: ItemStack, entity: LivingEntity, attacker: LivingEntity) = disablesShield(stack, attacker.entityWorld, attacker, Hand.MAIN_HAND) || super.canDisableShield(stack, shield, entity, attacker) - override fun isRepairable(arg: ItemStack) = true - override fun onEntitySwing(stack: ItemStack, entity: LivingEntity) = !canSwingHand( stack, entity.entityWorld, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/ClientInitializer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/ClientInitializer.kt index 5315f4ad3..95ae84996 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/ClientInitializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/ClientInitializer.kt @@ -18,31 +18,32 @@ package opekope2.avm_staff.internal.initializer -import dev.architectury.registry.client.level.entity.EntityRendererRegistry -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment import net.minecraft.client.render.entity.EmptyEntityRenderer import net.minecraft.client.render.entity.TntEntityRenderer import net.minecraft.util.Identifier +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn +import net.minecraftforge.client.event.EntityRenderersEvent.RegisterRenderers import opekope2.avm_staff.api.entity.renderer.CakeEntityRenderer import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures import opekope2.avm_staff.content.EntityTypes import opekope2.avm_staff.internal.event_handler.KeyBindingHandler import opekope2.avm_staff.mixin.ISmithingTemplateItemAccessor import opekope2.avm_staff.util.MOD_ID +import thedarkcolour.kotlinforforge.forge.MOD_BUS -@Environment(EnvType.CLIENT) +@OnlyIn(Dist.CLIENT) object ClientInitializer { init { KeyBindingHandler - registerEntityRenderers() + MOD_BUS.addListener(::registerEntityRenderers) registerSmithingTableTextures() } - private fun registerEntityRenderers() { - EntityRendererRegistry.register(EntityTypes.IMPACT_TNT, ::TntEntityRenderer) - EntityRendererRegistry.register(EntityTypes.CAKE, ::CakeEntityRenderer) - EntityRendererRegistry.register(EntityTypes.CAMPFIRE_FLAME, ::EmptyEntityRenderer) + private fun registerEntityRenderers(event: RegisterRenderers) { + event.registerEntityRenderer(EntityTypes.impactTnt, ::TntEntityRenderer) + event.registerEntityRenderer(EntityTypes.cake, ::CakeEntityRenderer) + event.registerEntityRenderer(EntityTypes.campfireFlame, ::EmptyEntityRenderer) } private fun registerSmithingTableTextures() { diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt index 97aea63ac..14d4c707d 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/initializer/Initializer.kt @@ -48,10 +48,10 @@ object Initializer { } private fun initializeNetworking() { - AttackC2SPacket.registerReceiver() - InsertItemIntoStaffC2SPacket.registerReceiver() - RemoveItemFromStaffC2SPacket.registerReceiver() + AttackC2SPacket + InsertItemIntoStaffC2SPacket + RemoveItemFromStaffC2SPacket - MassDestructionS2CPacket.registerReceiver() + MassDestructionS2CPacket } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt index f505a11dc..70ef39b2b 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt @@ -16,13 +16,9 @@ * along with this mod. If not, see . */ -@file: OnlyIn(Dist.CLIENT) - package opekope2.avm_staff.internal.model import net.minecraft.client.item.ClampedModelPredicateProvider -import net.minecraft.client.item.ModelPredicateProvider -import net.minecraft.client.item.ModelPredicateProviderRegistry import net.minecraft.item.ItemStack import net.minecraft.util.Identifier import net.minecraftforge.api.distmarker.Dist @@ -32,7 +28,7 @@ import opekope2.avm_staff.api.registry.RegistryBase import opekope2.avm_staff.content.DataComponentTypes import opekope2.avm_staff.util.MOD_ID -@Environment(EnvType.CLIENT) +@OnlyIn(Dist.CLIENT) object ModelPredicates : RegistryBase() { init { register(Identifier.of(MOD_ID, "using_item")) { stack, _, entity, _ -> diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractMassDestructiveStaffHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractMassDestructiveStaffHandler.kt index f0b1917e2..e1252c8f9 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractMassDestructiveStaffHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/AbstractMassDestructiveStaffHandler.kt @@ -18,12 +18,12 @@ package opekope2.avm_staff.internal.staff.handler -import dev.architectury.event.EventResult import net.minecraft.entity.LivingEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.server.world.ServerWorld +import net.minecraft.util.ActionResult import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction @@ -48,9 +48,9 @@ internal abstract class AbstractMassDestructiveStaffHandler : StaffHandler() { target: BlockPos, side: Direction, hand: Hand - ): EventResult { - if (world.isClient) return EventResult.pass() - if (attacker is PlayerEntity && attacker.isAttackCoolingDown) return EventResult.pass() + ): ActionResult { + if (world.isClient) return ActionResult.PASS + if (attacker is PlayerEntity && attacker.isAttackCoolingDown) return ActionResult.PASS require(world is ServerWorld) val shapePredicate = createBlockDestructionShapePredicate(world, attacker, target) @@ -72,7 +72,7 @@ internal abstract class AbstractMassDestructiveStaffHandler : StaffHandler() { (attacker as? ServerPlayerEntity)?.incrementStaffItemUseStat(staffStack.itemInStaff!!) // "Mismatch in destroy block pos" in server logs if I interrupt on server but not on client side. Nothing bad should happen, right? - return EventResult.pass() + return ActionResult.PASS } protected abstract fun createBlockDestructionShapePredicate( diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt index 403f54fac..712813cc7 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/BellHandler.kt @@ -18,14 +18,6 @@ package opekope2.avm_staff.internal.staff.handler -import dev.architectury.event.EventResult -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment -import net.minecraft.client.render.RenderLayer -import net.minecraft.client.render.VertexConsumerProvider -import net.minecraft.client.render.block.entity.BellBlockEntityRenderer -import net.minecraft.client.render.model.json.ModelTransformationMode -import net.minecraft.client.util.math.MatrixStack import net.minecraft.component.type.AttributeModifierSlot import net.minecraft.entity.Entity import net.minecraft.entity.LivingEntity @@ -42,8 +34,6 @@ import net.minecraft.util.TypedActionResult import net.minecraft.util.math.Box import net.minecraft.world.World import net.minecraft.world.event.GameEvent -import net.minecraftforge.api.distmarker.Dist -import net.minecraftforge.api.distmarker.OnlyIn import opekope2.avm_staff.api.staff.StaffAttributeModifiersComponentBuilder import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.mixin.IBellBlockEntityAccessor diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt index 3685a2c18..709bae12f 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/CampfireHandler.kt @@ -29,8 +29,6 @@ import net.minecraft.util.Hand import net.minecraft.util.TypedActionResult import net.minecraft.util.math.MathHelper import net.minecraft.world.World -import net.minecraftforge.api.distmarker.Dist -import net.minecraftforge.api.distmarker.OnlyIn import net.minecraftforge.registries.RegistryObject import opekope2.avm_staff.api.entity.CampfireFlameEntity import opekope2.avm_staff.api.staff.StaffHandler @@ -80,7 +78,7 @@ internal class CampfireHandler(private val parameters: Parameters) : StaffHandle relativeRight * FLAMETHROWER_CONE_END_WIDTH, relativeUp * FLAMETHROWER_CONE_END_HEIGHT, 16, - parameters.particleEffectSupplier.key, + parameters.particleEffectSupplier.key!!, FLAMETHROWER_CONE_RAY_RESOLUTION, parameters.flammableBlockFireChance, parameters.nonFlammableBlockFireChance, @@ -138,7 +136,7 @@ internal class CampfireHandler(private val parameters: Parameters) : StaffHandle val attackFireSeconds: Float, val flameFireTicks: Int, val rocketThrust: Double, - val particleEffectSupplier: RegistrySupplier + val particleEffectSupplier: RegistryObject ) private companion object { diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt index e95b3306f..ae75399ac 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/handler/VanillaStaffHandlers.kt @@ -18,8 +18,6 @@ package opekope2.avm_staff.internal.staff.handler -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment import net.minecraft.block.Blocks import net.minecraft.item.BlockItem import net.minecraft.item.Items.* diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/BellStaffItemRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/BellStaffItemRenderer.kt index f3d36edaf..5ff75ecdf 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/BellStaffItemRenderer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/BellStaffItemRenderer.kt @@ -18,18 +18,18 @@ package opekope2.avm_staff.internal.staff.item_renderer -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment import net.minecraft.client.render.RenderLayer import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.render.block.entity.BellBlockEntityRenderer import net.minecraft.client.render.model.json.ModelTransformationMode import net.minecraft.client.util.math.MatrixStack import net.minecraft.item.ItemStack +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn import opekope2.avm_staff.api.item.renderer.StaffItemRenderer import opekope2.avm_staff.util.push -@Environment(EnvType.CLIENT) +@OnlyIn(Dist.CLIENT) class BellStaffItemRenderer : StaffItemRenderer() { private val bellModel = BellBlockEntityRenderer.getTexturedModelData().createModel().apply { setPivot(-8f, -12f, -8f) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/FurnaceStaffItemRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/FurnaceStaffItemRenderer.kt index 90690d05c..059d075cb 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/FurnaceStaffItemRenderer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/FurnaceStaffItemRenderer.kt @@ -18,8 +18,6 @@ package opekope2.avm_staff.internal.staff.item_renderer -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment import net.minecraft.block.AbstractFurnaceBlock import net.minecraft.block.Block import net.minecraft.block.BlockState @@ -27,11 +25,13 @@ import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.render.model.json.ModelTransformationMode import net.minecraft.client.util.math.MatrixStack import net.minecraft.item.ItemStack +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer import opekope2.avm_staff.api.item.renderer.StaffItemRenderer import opekope2.avm_staff.content.DataComponentTypes -@Environment(EnvType.CLIENT) +@OnlyIn(Dist.CLIENT) class FurnaceStaffItemRenderer(unlitState: BlockState, litState: BlockState) : StaffItemRenderer() { constructor(furnaceBlock: Block) : this( furnaceBlock.defaultState, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/LightningRodStaffItemRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/LightningRodStaffItemRenderer.kt index 06b1110c3..951f61ec4 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/LightningRodStaffItemRenderer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/LightningRodStaffItemRenderer.kt @@ -18,18 +18,18 @@ package opekope2.avm_staff.internal.staff.item_renderer -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment import net.minecraft.block.Blocks import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.render.model.json.ModelTransformationMode import net.minecraft.client.util.math.MatrixStack import net.minecraft.item.ItemStack +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer import opekope2.avm_staff.api.item.renderer.StaffItemRenderer import opekope2.avm_staff.util.push -@Environment(EnvType.CLIENT) +@OnlyIn(Dist.CLIENT) class LightningRodStaffItemRenderer : StaffItemRenderer() { private val lightningRodRenderer = BlockStateStaffItemRenderer(Blocks.LIGHTNING_ROD.defaultState) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/WitherSkeletonSkullStaffItemRenderer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/WitherSkeletonSkullStaffItemRenderer.kt index 22c0e7666..91532d089 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/WitherSkeletonSkullStaffItemRenderer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff/item_renderer/WitherSkeletonSkullStaffItemRenderer.kt @@ -18,8 +18,6 @@ package opekope2.avm_staff.internal.staff.item_renderer -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment import net.minecraft.block.AbstractSkullBlock import net.minecraft.block.Blocks import net.minecraft.client.render.VertexConsumerProvider @@ -28,10 +26,12 @@ import net.minecraft.client.render.entity.model.SkullEntityModel import net.minecraft.client.render.model.json.ModelTransformationMode import net.minecraft.client.util.math.MatrixStack import net.minecraft.item.ItemStack +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn import opekope2.avm_staff.api.item.renderer.StaffItemRenderer import opekope2.avm_staff.util.push -@Environment(EnvType.CLIENT) +@OnlyIn(Dist.CLIENT) class WitherSkeletonSkullStaffItemRenderer : StaffItemRenderer() { private val skullModel = SkullEntityModel.getSkullTexturedModelData().createModel() diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/MinecraftClientUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/MinecraftClientUtil.kt index 6ea2010c0..3c9929b6b 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/MinecraftClientUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/MinecraftClientUtil.kt @@ -17,12 +17,10 @@ */ @file: JvmName("MinecraftClientUtil") -@file: Environment(EnvType.CLIENT) +@file: OnlyIn(Dist.CLIENT) package opekope2.avm_staff.util -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment import net.minecraft.client.MinecraftClient import net.minecraft.client.option.GameOptions import net.minecraft.client.particle.ParticleManager @@ -30,6 +28,8 @@ import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher import net.minecraft.client.render.entity.model.EntityModelLoader import net.minecraft.client.render.item.ItemRenderer import net.minecraft.client.render.model.BakedModelManager +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn /** * @see MinecraftClient.bakedModelManager diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/RegistryUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/RegistryUtil.kt index 27d9256a3..7d9171b8d 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/RegistryUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/RegistryUtil.kt @@ -18,22 +18,43 @@ package opekope2.avm_staff.util -import dev.architectury.registry.registries.DeferredRegister -import dev.architectury.registry.registries.RegistrySupplier import net.minecraft.registry.Registry import net.minecraft.registry.RegistryKey import net.minecraft.util.Identifier +import net.minecraftforge.registries.DeferredRegister +import net.minecraftforge.registries.IForgeRegistry +import net.minecraftforge.registries.RegistryObject +import thedarkcolour.kotlinforforge.forge.MOD_BUS /** * Utility class to register content to Minecraft registries. * * @param TContent The type of the content to register - * @param modId The [namespace][Identifier.namespace] of the content to register. - * @param registry The registry to register the content in */ -abstract class RegistryUtil(modId: String, registry: RegistryKey>) : - RegistryKeyUtil(modId, registry) { - private val deferredRegister = DeferredRegister.create(modId, registry) +abstract class RegistryUtil : RegistryKeyUtil { + /** + * Creates a new [RegistryUtil] instance. + * + * @param TContent The type of the content to register + * @param modId The [namespace][Identifier.namespace] of the content to register. + * @param registry The registry to register the content in + */ + protected constructor(modId: String, registry: RegistryKey>) : super(modId, registry) { + this.deferredRegister = DeferredRegister.create(registry, modId) + } + + /** + * Creates a new [RegistryUtil] instance. + * + * @param TContent The type of the content to register + * @param modId The [namespace][Identifier.namespace] of the content to register. + * @param registry The registry to register the content in + */ + protected constructor(modId: String, registry: IForgeRegistry) : super(modId, registry.registryKey) { + this.deferredRegister = DeferredRegister.create(registry, modId) + } + + private val deferredRegister: DeferredRegister /** * Adds a content to be registered in a Minecraft registry using Architectury API. @@ -41,12 +62,12 @@ abstract class RegistryUtil(modId: String, registry: RegistryKey register(path: String, factory: (RegistryKey) -> T): RegistrySupplier = + protected fun register(path: String, factory: (RegistryKey) -> T): RegistryObject = deferredRegister.register(path) { factory(registryKey(path)) } /** * @suppress */ @JvmSynthetic - internal open fun register() = deferredRegister.register() + internal open fun register() = deferredRegister.register(MOD_BUS) } From c22685a7d598cc63c19c5ab2f9f9cdcb06c84522 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 1 Dec 2024 03:20:18 +0100 Subject: [PATCH 75/83] Bump version --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9b40535b2..621ce9081 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] java = "21" # Don't forget to update *.mixins.json kotlin = "2.0.0" -staff-mod = "0.19.1" +staff-mod = "0.20.0" architectury-plugin = "3.4-SNAPSHOT" architectury-loom = "1.7-SNAPSHOT" yarn = "1.21+build.9" From 5667f060f3b05e675506a5d51da80df1985d64a0 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 1 Dec 2024 03:30:09 +0100 Subject: [PATCH 76/83] Make Crown of King Orange curse-able --- .../data/minecraft/tags/item/enchantable/equippable.json | 6 ++++++ .../data/minecraft/tags/item/enchantable/vanishing.json | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/equippable.json diff --git a/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/equippable.json b/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/equippable.json new file mode 100644 index 000000000..fca333cf3 --- /dev/null +++ b/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/equippable.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "avm_staff:crown_of_king_orange" + ] +} diff --git a/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/vanishing.json b/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/vanishing.json index 641e9fc93..ca6d02fee 100644 --- a/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/vanishing.json +++ b/StaffMod/src/main/resources/data/minecraft/tags/item/enchantable/vanishing.json @@ -1,6 +1,7 @@ { "replace": false, "values": [ - "#avm_staff:staffs" + "#avm_staff:staffs", + "avm_staff:crown_of_king_orange" ] } From 12512f42f307a9b707138f281c1afde27ddf5756 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 1 Dec 2024 04:29:16 +0100 Subject: [PATCH 77/83] Fix Coronavirus advancement --- .../avm_staff/advancement/coronavirus.json | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/StaffMod/src/main/resources/data/avm_staff/advancement/coronavirus.json b/StaffMod/src/main/resources/data/avm_staff/advancement/coronavirus.json index 52578c5f1..a2bf12fcd 100644 --- a/StaffMod/src/main/resources/data/avm_staff/advancement/coronavirus.json +++ b/StaffMod/src/main/resources/data/avm_staff/advancement/coronavirus.json @@ -28,10 +28,12 @@ "equipment": { "head": { "items": "avm_staff:crown_of_king_orange", - "components": { - "minecraft:enchantments": { - "minecraft:binding_curse": 1 - } + "predicates": { + "minecraft:enchantments": [ + { + "enchantments": "minecraft:binding_curse" + } + ] } } } @@ -45,10 +47,12 @@ "equipment": { "head": { "items": "avm_staff:crown_of_king_orange", - "components": { - "minecraft:enchantments": { - "minecraft:binding_curse": 1 - } + "predicates": { + "minecraft:enchantments": [ + { + "enchantments": "minecraft:binding_curse" + } + ] } } } From e9e9ca8a691f9718dad75c45d50852269245b963 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 1 Dec 2024 04:29:56 +0100 Subject: [PATCH 78/83] Bump version --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 41ff52454..eb07f2fcd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] java = "21" # Don't forget to update *.mixins.json kotlin = "2.0.0" -staff-mod = "0.20.0" +staff-mod = "0.20.1" architectury-plugin = "3.4-SNAPSHOT" architectury-loom = "1.7-SNAPSHOT" yarn = "1.21+build.9" From 279038af26acd329dcb123f210e2d311115dd42f Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 1 Dec 2024 15:48:05 +0100 Subject: [PATCH 79/83] Fix staff jitter when it gets damaged --- .../opekope2/avm_staff/internal/model/ModelPredicates.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt index 481c6afc2..dd2398a04 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.kt @@ -32,7 +32,11 @@ import opekope2.avm_staff.util.MOD_ID object ModelPredicates : RegistryBase() { init { register(Identifier.of(MOD_ID, "using_item")) { stack, _, entity, _ -> - if (entity != null && entity.isUsingItem && ItemStack.areEqual(entity.activeItem, stack)) 1f + if (entity == null || !entity.isUsingItem) return@register 0f + // When the item's components get changed server-side, Minecraft client is just janky with references + val sameItem = ItemStack.areEqual(entity.activeItem, stack) || + ItemStack.areEqual(entity.getStackInHand(entity.activeHand), stack) + if (sameItem) 1f else 0f } register(Identifier.of(MOD_ID, "head"), matchStaffRendererPart(StaffRendererPartComponent.HEAD)) From d6bb75fa7c1b9038fcafd1959c06b97002514936 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 1 Dec 2024 15:57:05 +0100 Subject: [PATCH 80/83] Bump version --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index eb07f2fcd..307b08231 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] java = "21" # Don't forget to update *.mixins.json kotlin = "2.0.0" -staff-mod = "0.20.1" +staff-mod = "0.20.2" architectury-plugin = "3.4-SNAPSHOT" architectury-loom = "1.7-SNAPSHOT" yarn = "1.21+build.9" From c25a897a51d74abc8571e6191a5dd6c7407df696 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 1 Dec 2024 16:05:56 +0100 Subject: [PATCH 81/83] Don't save `avm_staff:rocket_mode` --- .../main/kotlin/opekope2/avm_staff/content/DataComponentTypes.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/DataComponentTypes.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/DataComponentTypes.kt index 0348adbf1..e58e70d13 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/DataComponentTypes.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/DataComponentTypes.kt @@ -71,7 +71,6 @@ object DataComponentTypes : RegistryUtil>(MOD_ID, RegistryKeys. @JvmField val ROCKET_MODE = register("rocket_mode") { ComponentType.builder() - .codec(MinecraftUnit.CODEC) .packetCodec(PacketCodec.unit(minecraftUnit)) .build() } From 658116f2d8cdaacff10aab524d7381c872e1ed13 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 1 Dec 2024 16:32:03 +0100 Subject: [PATCH 82/83] Revert "Don't save `avm_staff:rocket_mode`" This reverts commit c25a897a51d74abc8571e6191a5dd6c7407df696. --- .../main/kotlin/opekope2/avm_staff/content/DataComponentTypes.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/DataComponentTypes.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/DataComponentTypes.kt index e58e70d13..0348adbf1 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/content/DataComponentTypes.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/content/DataComponentTypes.kt @@ -71,6 +71,7 @@ object DataComponentTypes : RegistryUtil>(MOD_ID, RegistryKeys. @JvmField val ROCKET_MODE = register("rocket_mode") { ComponentType.builder() + .codec(MinecraftUnit.CODEC) .packetCodec(PacketCodec.unit(minecraftUnit)) .build() } From ac9821c06fd35121cfdc874e1169bd9852e72053 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 1 Dec 2024 16:36:09 +0100 Subject: [PATCH 83/83] Bump version --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 307b08231..b5a62be4f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] java = "21" # Don't forget to update *.mixins.json kotlin = "2.0.0" -staff-mod = "0.20.2" +staff-mod = "0.20.3" architectury-plugin = "3.4-SNAPSHOT" architectury-loom = "1.7-SNAPSHOT" yarn = "1.21+build.9"