From 7db936d9ee39f4c75b39a32681696ab4f5845007 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 30 Apr 2024 00:28:03 +0200 Subject: [PATCH 001/128] Check for staffs tag instead of staff item, when inserting or removing item to/from a staff --- .../avm_staff/internal/event_handler/NetworkHandler.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt index 838e75424..da205fca7 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt @@ -81,10 +81,10 @@ private fun findStaffStackAndItemSlot(player: PlayerEntity): Pair + mainStack.isIn(staffMod.staffsTag) && !offStack.isIn(staffMod.staffsTag) -> mainStack to PlayerInventory.OFF_HAND_SLOT - offStack.isOf(staffMod.staffItem) && !mainStack.isOf(staffMod.staffItem) -> + offStack.isIn(staffMod.staffsTag) && !mainStack.isIn(staffMod.staffsTag) -> offStack to player.inventory.selectedSlot else -> null @@ -96,8 +96,8 @@ private fun findStaffAndItemStack(player: PlayerEntity): Pair mainStack to offStack - offStack.isOf(staffMod.staffItem) && !mainStack.isOf(staffMod.staffItem) -> offStack to mainStack + mainStack.isIn(staffMod.staffsTag) && !offStack.isIn(staffMod.staffsTag) -> mainStack to offStack + offStack.isIn(staffMod.staffsTag) && !mainStack.isIn(staffMod.staffsTag) -> offStack to mainStack else -> null } } From 72b63b39b3ba59910b7d6f9bd732d126357bd0e5 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Wed, 1 May 2024 00:23:38 +0200 Subject: [PATCH 002/128] Reference StaffMod object directly when adding staff item to creative inventory --- .../opekope2/avm_staff/internal/forge/StaffModClient.kt | 5 ++--- .../opekope2/avm_staff/internal/neoforge/StaffModClient.kt | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt index 4acdef1b1..ad155af88 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt @@ -36,7 +36,6 @@ import opekope2.avm_staff.IStaffMod import opekope2.avm_staff.api.particle.FlamethrowerParticle import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING import opekope2.avm_staff.internal.event_handler.handleKeyBindings -import opekope2.avm_staff.internal.platform.forge.getStaffMod import opekope2.avm_staff.internal.registerModelPredicateProviders import thedarkcolour.kotlinforforge.forge.FORGE_BUS import thedarkcolour.kotlinforforge.forge.MOD_BUS @@ -60,13 +59,13 @@ object StaffModClient { if (event.tabKey === ItemGroups.TOOLS) { event.entries.putAfter( ItemStack(Items.NETHERITE_HOE), - ItemStack(getStaffMod().staffItem), + ItemStack(StaffMod.staffItem), PARENT_AND_SEARCH_TABS ) } else if (event.tabKey === ItemGroups.COMBAT) { event.entries.putAfter( ItemStack(Items.TRIDENT), - ItemStack(getStaffMod().staffItem), + ItemStack(StaffMod.staffItem), PARENT_AND_SEARCH_TABS ) } 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 19fe88898..015abbcb3 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 @@ -36,7 +36,6 @@ import opekope2.avm_staff.IStaffMod import opekope2.avm_staff.api.particle.FlamethrowerParticle import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING import opekope2.avm_staff.internal.event_handler.handleKeyBindings -import opekope2.avm_staff.internal.platform.neoforge.getStaffMod import opekope2.avm_staff.internal.registerModelPredicateProviders import thedarkcolour.kotlinforforge.neoforge.forge.FORGE_BUS import thedarkcolour.kotlinforforge.neoforge.forge.MOD_BUS @@ -60,13 +59,13 @@ object StaffModClient { if (event.tabKey === ItemGroups.TOOLS) { event.entries.putAfter( ItemStack(Items.NETHERITE_HOE), - ItemStack(getStaffMod().staffItem), + ItemStack(StaffMod.staffItem), PARENT_AND_SEARCH_TABS ) } else if (event.tabKey === ItemGroups.COMBAT) { event.entries.putAfter( ItemStack(Items.TRIDENT), - ItemStack(getStaffMod().staffItem), + ItemStack(StaffMod.staffItem), PARENT_AND_SEARCH_TABS ) } From 9d5c0d4264705055547051cb520bd266a0c6f2ac Mon Sep 17 00:00:00 2001 From: opekope2 Date: Wed, 1 May 2024 00:25:40 +0200 Subject: [PATCH 003/128] Query staffs tag instead of staff item in the remaining places --- .../java/opekope2/avm_staff/mixin/LivingEntityMixin.java | 2 +- .../avm_staff/internal/event_handler/StaffAttackHandler.kt | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/StaffMod/src/main/java/opekope2/avm_staff/mixin/LivingEntityMixin.java b/StaffMod/src/main/java/opekope2/avm_staff/mixin/LivingEntityMixin.java index ebed235ad..d68ba9481 100644 --- a/StaffMod/src/main/java/opekope2/avm_staff/mixin/LivingEntityMixin.java +++ b/StaffMod/src/main/java/opekope2/avm_staff/mixin/LivingEntityMixin.java @@ -38,7 +38,7 @@ public abstract class LivingEntityMixin { @Inject(method = "disablesShield", at = @At("HEAD"), cancellable = true) public void disableShield(CallbackInfoReturnable cir) { ItemStack mainHandStack = getMainHandStack(); - if (!mainHandStack.isOf(IStaffMod.get().getStaffItem())) return; + if (!mainHandStack.isIn(IStaffMod.get().getStaffsTag())) return; ItemStack itemInStaff = StaffUtil.getItemInStaff(mainHandStack); if (itemInStaff == null) return; diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt index 339969193..b71c4497b 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt @@ -41,7 +41,7 @@ fun attackBlock( direction: Direction ): ActionResult { val staffStack = player.getStackInHand(hand) - if (!staffStack.isOf(staffMod.staffItem)) return ActionResult.PASS + if (!staffStack.isIn(staffMod.staffsTag)) return ActionResult.PASS val itemInStaff = staffStack.itemInStaff ?: return ActionResult.PASS val staffHandler = itemInStaff.handlerOfItem ?: return ActionResult.PASS @@ -51,7 +51,7 @@ fun attackBlock( fun attackEntity(player: PlayerEntity, world: World, hand: Hand, target: Entity): ActionResult { val itemStack = player.getStackInHand(hand) - if (!itemStack.isOf(staffMod.staffItem)) return ActionResult.PASS + if (!itemStack.isIn(staffMod.staffsTag)) return ActionResult.PASS val itemInStaff = itemStack.itemInStaff ?: return ActionResult.PASS val staffHandler = itemInStaff.handlerOfItem ?: return ActionResult.PASS @@ -60,7 +60,7 @@ fun attackEntity(player: PlayerEntity, world: World, hand: Hand, target: Entity) } fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand): ActionResult { - if (!staffStack.isOf(staffMod.staffItem)) return ActionResult.PASS + if (!staffStack.isIn(staffMod.staffsTag)) return ActionResult.PASS val itemInStaff: ItemStack = staffStack.itemInStaff ?: return ActionResult.PASS val staffHandler = itemInStaff.handlerOfItem ?: return ActionResult.PASS From fcd3b92de7001358d4d47cae0c3347f69607f744 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Wed, 8 May 2024 01:02:59 +0200 Subject: [PATCH 004/128] Register staff item model suppliers in a separate method --- FabricMod/src/main/resources/fabric.mod.json | 4 + .../internal/forge/StaffModClient.kt | 2 + .../internal/neoforge/StaffModClient.kt | 2 + .../avm_staff/api/item/StaffItemHandler.kt | 38 +++-- .../model/UnbakedBlockStateModelSupplier.kt | 34 ---- .../staff_item_handler/BellBlockHandler.kt | 7 +- .../staff_item_handler/FurnaceHandler.kt | 17 +- .../staff_item_handler/LightningRodHandler.kt | 12 +- .../VanillaStaffItemHandlers.kt | 145 ++++++++++++------ .../WitherSkeletonSkullHandler.kt | 9 +- 10 files changed, 138 insertions(+), 132 deletions(-) delete mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/UnbakedBlockStateModelSupplier.kt diff --git a/FabricMod/src/main/resources/fabric.mod.json b/FabricMod/src/main/resources/fabric.mod.json index d3423993f..c90deeb12 100644 --- a/FabricMod/src/main/resources/fabric.mod.json +++ b/FabricMod/src/main/resources/fabric.mod.json @@ -34,6 +34,10 @@ { "adapter": "kotlin", "value": "opekope2.avm_staff.internal.fabric.StaffModClient" + }, + { + "adapter": "kotlin", + "value": "opekope2.avm_staff.internal.staff_item_handler.VanillaStaffItemHandlersKt::registerVanillaStaffItemRenderers" } ] }, diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt index ad155af88..6dcb81572 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt @@ -37,12 +37,14 @@ import opekope2.avm_staff.api.particle.FlamethrowerParticle import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING import opekope2.avm_staff.internal.event_handler.handleKeyBindings import opekope2.avm_staff.internal.registerModelPredicateProviders +import opekope2.avm_staff.internal.staff_item_handler.registerVanillaStaffItemRenderers import thedarkcolour.kotlinforforge.forge.FORGE_BUS import thedarkcolour.kotlinforforge.forge.MOD_BUS @OnlyIn(Dist.CLIENT) object StaffModClient { fun initializeClient() { + registerVanillaStaffItemRenderers() MOD_BUS.register(this) FORGE_BUS.register(javaClass) } 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 015abbcb3..fbc40d9ad 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 @@ -37,12 +37,14 @@ import opekope2.avm_staff.api.particle.FlamethrowerParticle import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING import opekope2.avm_staff.internal.event_handler.handleKeyBindings import opekope2.avm_staff.internal.registerModelPredicateProviders +import opekope2.avm_staff.internal.staff_item_handler.registerVanillaStaffItemRenderers import thedarkcolour.kotlinforforge.neoforge.forge.FORGE_BUS import thedarkcolour.kotlinforforge.neoforge.forge.MOD_BUS @OnlyIn(Dist.CLIENT) object StaffModClient { fun initializeClient() { + registerVanillaStaffItemRenderers() MOD_BUS.register(this) FORGE_BUS.addListener(::handleStaffKeybinding) } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt index 14c3bdf2f..1100b0a54 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt @@ -41,7 +41,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.IStaffMod import opekope2.avm_staff.api.item.model.IStaffItemUnbakedModel import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.attackSpeed @@ -418,34 +417,43 @@ abstract class StaffItemHandler { private val staffItemsHandlers = mutableMapOf() + @Environment(EnvType.CLIENT) private val staffItemModelProviders = mutableMapOf>() - @Suppress("RedundantGetter") // Force generate getter to annotate - @Environment(EnvType.CLIENT) - get() = field /** - * Registers a [StaffItemHandler] for the given [item ID][staffItem]. + * Registers a [StaffItemHandler] for the given [item ID][staffItem]. Call this from your common mod initializer. * * @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 - * @param staffItemModelSupplierFactory The staff item's unbaked model supplier's supplier. The nesting is needed - * to prevent loading client classes on the server * @return `true`, if the registration was successful, `false`, if the item was already registered */ @JvmStatic - fun register( - staffItem: Identifier, - handler: StaffItemHandler, - staffItemModelSupplierFactory: Supplier> - ): Boolean { + fun register(staffItem: Identifier, handler: StaffItemHandler): Boolean { if (staffItem in staffItemsHandlers) return false staffItemsHandlers[staffItem] = handler - if (IStaffMod.get().isPhysicalClient) { - staffItemModelProviders[staffItem] = staffItemModelSupplierFactory.get() - } + return true + } + + /** + * Registers an unbaked model supplier for a given [item ID][staffItem]. Call this from your client mod + * initializer. + * + * @param staffItemModelSupplier The staff item's unbaked model supplier + * @return `true`, if the registration was successful, `false`, if an unbaked model supplier for the item was + * already registered + */ + @JvmStatic + @Environment(EnvType.CLIENT) + fun registerModelSupplier( + staffItem: Identifier, + staffItemModelSupplier: Supplier + ): Boolean { + if (staffItem in staffItemModelProviders) return false + + staffItemModelProviders[staffItem] = staffItemModelSupplier return true } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/UnbakedBlockStateModelSupplier.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/UnbakedBlockStateModelSupplier.kt deleted file mode 100644 index 54e80322c..000000000 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/UnbakedBlockStateModelSupplier.kt +++ /dev/null @@ -1,34 +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.item.model - -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment -import net.minecraft.block.BlockState -import java.util.function.Supplier - -/** - * Convenience implementation of [Supplier] with the same parameters as [UnbakedBlockStateModel]. - * - * @param blockState The block state to bake - */ -@Environment(EnvType.CLIENT) -class UnbakedBlockStateModelSupplier(private val blockState: BlockState) : Supplier { - override fun get() = UnbakedBlockStateModel(blockState) -} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BellBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BellBlockHandler.kt index fba1168be..8ede9daed 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BellBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BellBlockHandler.kt @@ -55,7 +55,6 @@ import opekope2.avm_staff.util.getBakedQuads import opekope2.avm_staff.util.transform import org.joml.Vector3f import java.util.function.Function -import java.util.function.Supplier class BellBlockHandler : StaffItemHandler() { override fun use( @@ -97,7 +96,7 @@ class BellBlockHandler : StaffItemHandler() { } @Environment(EnvType.CLIENT) - private class BellUnbakedModel : IStaffItemUnbakedModel { + class BellUnbakedModel : IStaffItemUnbakedModel { override fun getModelDependencies() = setOf() override fun setParents(modelLoader: Function?) { @@ -152,9 +151,5 @@ class BellBlockHandler : StaffItemHandler() { EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(1.5) ) - - val modelSupplierFactory: Supplier> = Supplier { - Supplier(::BellUnbakedModel) - } } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt index b7dcd87bd..f9b3c3db8 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt @@ -60,7 +60,6 @@ import opekope2.avm_staff.api.item.model.IStaffItemUnbakedModel import opekope2.avm_staff.mixin.IAbstractFurnaceBlockEntityMixin import opekope2.avm_staff.util.* import java.util.function.Function -import java.util.function.Supplier import kotlin.jvm.optionals.getOrNull class FurnaceHandler( @@ -184,8 +183,13 @@ class FurnaceHandler( } @Environment(EnvType.CLIENT) - private class FurnaceUnbakedModel(private val unlitState: BlockState, private val litState: BlockState) : + class FurnaceUnbakedModel(private val unlitState: BlockState, private val litState: BlockState) : IStaffItemUnbakedModel { + constructor(furnaceBlock: Block) : this( + furnaceBlock.defaultState, + furnaceBlock.defaultState.with(AbstractFurnaceBlock.LIT, true) + ) + private val litStateId = BlockModels.getModelId(litState) private val unlitStateId = BlockModels.getModelId(unlitState) private val dependencies = setOf(litStateId, unlitStateId) @@ -243,14 +247,5 @@ class FurnaceHandler( EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(2.0) ) - - fun getModelSupplierFactory(furnaceBlock: Block): Supplier> = Supplier { - Supplier { - FurnaceUnbakedModel( - furnaceBlock.defaultState, - furnaceBlock.defaultState.with(AbstractFurnaceBlock.LIT, true) - ) - } - } } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/LightningRodHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/LightningRodHandler.kt index 721563364..263b715ff 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/LightningRodHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/LightningRodHandler.kt @@ -21,7 +21,6 @@ package opekope2.avm_staff.internal.staff_item_handler import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.minecraft.block.BlockState -import net.minecraft.block.Blocks import net.minecraft.client.render.block.BlockModels import net.minecraft.client.render.model.Baker import net.minecraft.client.render.model.ModelBakeSettings @@ -47,7 +46,6 @@ import opekope2.avm_staff.util.isItemCoolingDown import opekope2.avm_staff.util.transform import org.joml.Vector3f import java.util.function.Function -import java.util.function.Supplier class LightningRodHandler : StaffItemHandler() { override fun useOnBlock( @@ -84,7 +82,7 @@ class LightningRodHandler : StaffItemHandler() { } @Environment(EnvType.CLIENT) - private class LightningRodUnbakedModel(private val state: BlockState) : IStaffItemUnbakedModel { + class LightningRodUnbakedModel(private val state: BlockState) : IStaffItemUnbakedModel { private val stateId = BlockModels.getModelId(state) private val dependencies = setOf(stateId) @@ -117,12 +115,4 @@ class LightningRodHandler : StaffItemHandler() { ) } } - - companion object { - val modelSupplier: Supplier> = Supplier { - Supplier { - LightningRodUnbakedModel(Blocks.LIGHTNING_ROD.defaultState) - } - } - } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt index 968b98365..b8559c367 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt @@ -18,6 +18,8 @@ package opekope2.avm_staff.internal.staff_item_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.Item @@ -28,85 +30,134 @@ import net.minecraft.sound.SoundEvents import opekope2.avm_staff.IStaffMod import opekope2.avm_staff.api.item.StaffItemHandler import opekope2.avm_staff.api.item.model.IStaffItemUnbakedModel -import opekope2.avm_staff.api.item.model.UnbakedBlockStateModelSupplier +import opekope2.avm_staff.api.item.model.UnbakedBlockStateModel import java.util.function.Supplier -private fun Item.registerHandler( - handler: StaffItemHandler, - itemModelSupplierFactory: Supplier> -) { - StaffItemHandler.register(Registries.ITEM.getId(this), handler, itemModelSupplierFactory) -} - -private fun Item.registerHandler(handler: StaffItemHandler, staffItem: Block) { - registerHandler(handler) { UnbakedBlockStateModelSupplier(staffItem.defaultState) } +private fun Item.registerHandler(handler: StaffItemHandler) { + StaffItemHandler.register(Registries.ITEM.getId(this), handler) } @Suppress("unused") fun registerVanillaStaffItemHandlers() { - Items.ANVIL.registerHandler(AnvilHandler(Items.CHIPPED_ANVIL::getDefaultStack), ANVIL) - Items.CHIPPED_ANVIL.registerHandler(AnvilHandler(Items.DAMAGED_ANVIL::getDefaultStack), CHIPPED_ANVIL) - Items.DAMAGED_ANVIL.registerHandler(AnvilHandler { null }, DAMAGED_ANVIL) + Items.ANVIL.registerHandler(AnvilHandler(Items.CHIPPED_ANVIL::getDefaultStack)) + Items.CHIPPED_ANVIL.registerHandler(AnvilHandler(Items.DAMAGED_ANVIL::getDefaultStack)) + Items.DAMAGED_ANVIL.registerHandler(AnvilHandler { null }) - Items.BELL.registerHandler(BellBlockHandler(), BellBlockHandler.modelSupplierFactory) + Items.BELL.registerHandler(BellBlockHandler()) - Items.BONE_BLOCK.registerHandler(BoneBlockHandler(), BONE_BLOCK) + Items.BONE_BLOCK.registerHandler(BoneBlockHandler()) Items.CAMPFIRE.registerHandler( CampfireHandler( IStaffMod::flamethrowerParticleType, CampfireHandler.Properties(1 / 20.0, 5 / 20.0, 1, 0.1) - ), - CAMPFIRE + ) ) Items.SOUL_CAMPFIRE.registerHandler( CampfireHandler( IStaffMod::soulFlamethrowerParticleType, CampfireHandler.Properties(2 / 20.0, 10 / 20.0, 2, 0.12) - ), - SOUL_CAMPFIRE + ) ) Items.FURNACE.registerHandler( - FurnaceHandler(RecipeType.SMELTING, SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE), - FurnaceHandler.getModelSupplierFactory(FURNACE) + FurnaceHandler(RecipeType.SMELTING, SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE) ) Items.BLAST_FURNACE.registerHandler( - FurnaceHandler(RecipeType.BLASTING, SoundEvents.BLOCK_BLASTFURNACE_FIRE_CRACKLE), - FurnaceHandler.getModelSupplierFactory(BLAST_FURNACE) + FurnaceHandler(RecipeType.BLASTING, SoundEvents.BLOCK_BLASTFURNACE_FIRE_CRACKLE) ) Items.SMOKER.registerHandler( - FurnaceHandler(RecipeType.SMOKING, SoundEvents.BLOCK_SMOKER_SMOKE), - FurnaceHandler.getModelSupplierFactory(SMOKER) + FurnaceHandler(RecipeType.SMOKING, SoundEvents.BLOCK_SMOKER_SMOKE) ) - Items.LIGHTNING_ROD.registerHandler(LightningRodHandler(), LightningRodHandler.modelSupplier) + Items.LIGHTNING_ROD.registerHandler(LightningRodHandler()) - Items.MAGMA_BLOCK.registerHandler(MagmaBlockHandler(), MAGMA_BLOCK) + Items.MAGMA_BLOCK.registerHandler(MagmaBlockHandler()) - Items.SNOW_BLOCK.registerHandler(SnowBlockHandler(), SNOW_BLOCK) + Items.SNOW_BLOCK.registerHandler(SnowBlockHandler()) - Items.TNT.registerHandler(TntHandler(), TNT) + Items.TNT.registerHandler(TntHandler()) Items.WITHER_SKELETON_SKULL.registerHandler( - WitherSkeletonSkullHandler(), - WitherSkeletonSkullHandler.modelSupplierFactory + WitherSkeletonSkullHandler() ) - Items.WHITE_WOOL.registerHandler(WoolHandler(WHITE_WOOL, WHITE_CARPET), WHITE_WOOL) - Items.ORANGE_WOOL.registerHandler(WoolHandler(ORANGE_WOOL, ORANGE_CARPET), ORANGE_WOOL) - Items.MAGENTA_WOOL.registerHandler(WoolHandler(MAGENTA_WOOL, MAGENTA_CARPET), MAGENTA_WOOL) - Items.LIGHT_BLUE_WOOL.registerHandler(WoolHandler(LIGHT_BLUE_WOOL, LIGHT_BLUE_CARPET), LIGHT_BLUE_WOOL) - Items.YELLOW_WOOL.registerHandler(WoolHandler(YELLOW_WOOL, YELLOW_CARPET), YELLOW_WOOL) - Items.LIME_WOOL.registerHandler(WoolHandler(LIME_WOOL, LIME_CARPET), LIME_WOOL) - Items.PINK_WOOL.registerHandler(WoolHandler(PINK_WOOL, PINK_CARPET), PINK_WOOL) - Items.GRAY_WOOL.registerHandler(WoolHandler(GRAY_WOOL, GRAY_CARPET), GRAY_WOOL) - Items.LIGHT_GRAY_WOOL.registerHandler(WoolHandler(LIGHT_GRAY_WOOL, LIGHT_GRAY_CARPET), LIGHT_GRAY_WOOL) - Items.CYAN_WOOL.registerHandler(WoolHandler(CYAN_WOOL, CYAN_CARPET), CYAN_WOOL) - Items.PURPLE_WOOL.registerHandler(WoolHandler(PURPLE_WOOL, PURPLE_CARPET), PURPLE_WOOL) - Items.BLUE_WOOL.registerHandler(WoolHandler(BLUE_WOOL, BLUE_CARPET), BLUE_WOOL) - Items.BROWN_WOOL.registerHandler(WoolHandler(BROWN_WOOL, BROWN_CARPET), BROWN_WOOL) - Items.GREEN_WOOL.registerHandler(WoolHandler(GREEN_WOOL, GREEN_CARPET), GREEN_WOOL) - Items.RED_WOOL.registerHandler(WoolHandler(RED_WOOL, RED_CARPET), RED_WOOL) - Items.BLACK_WOOL.registerHandler(WoolHandler(BLACK_WOOL, BLACK_CARPET), BLACK_WOOL) + Items.WHITE_WOOL.registerHandler(WoolHandler(WHITE_WOOL, WHITE_CARPET)) + Items.ORANGE_WOOL.registerHandler(WoolHandler(ORANGE_WOOL, ORANGE_CARPET)) + Items.MAGENTA_WOOL.registerHandler(WoolHandler(MAGENTA_WOOL, MAGENTA_CARPET)) + Items.LIGHT_BLUE_WOOL.registerHandler(WoolHandler(LIGHT_BLUE_WOOL, LIGHT_BLUE_CARPET)) + Items.YELLOW_WOOL.registerHandler(WoolHandler(YELLOW_WOOL, YELLOW_CARPET)) + Items.LIME_WOOL.registerHandler(WoolHandler(LIME_WOOL, LIME_CARPET)) + Items.PINK_WOOL.registerHandler(WoolHandler(PINK_WOOL, PINK_CARPET)) + Items.GRAY_WOOL.registerHandler(WoolHandler(GRAY_WOOL, GRAY_CARPET)) + Items.LIGHT_GRAY_WOOL.registerHandler(WoolHandler(LIGHT_GRAY_WOOL, LIGHT_GRAY_CARPET)) + Items.CYAN_WOOL.registerHandler(WoolHandler(CYAN_WOOL, CYAN_CARPET)) + Items.PURPLE_WOOL.registerHandler(WoolHandler(PURPLE_WOOL, PURPLE_CARPET)) + Items.BLUE_WOOL.registerHandler(WoolHandler(BLUE_WOOL, BLUE_CARPET)) + Items.BROWN_WOOL.registerHandler(WoolHandler(BROWN_WOOL, BROWN_CARPET)) + Items.GREEN_WOOL.registerHandler(WoolHandler(GREEN_WOOL, GREEN_CARPET)) + Items.RED_WOOL.registerHandler(WoolHandler(RED_WOOL, RED_CARPET)) + Items.BLACK_WOOL.registerHandler(WoolHandler(BLACK_WOOL, BLACK_CARPET)) +} + +@Environment(EnvType.CLIENT) +private fun Item.registerModelSupplier(itemModelSupplier: Supplier) { + StaffItemHandler.registerModelSupplier(Registries.ITEM.getId(this), itemModelSupplier) +} + +@Environment(EnvType.CLIENT) +private fun Item.registerModelSupplier(staffItem: Block) { + registerModelSupplier { UnbakedBlockStateModel(staffItem.defaultState) } +} + +@Environment(EnvType.CLIENT) +fun registerVanillaStaffItemRenderers() { + Items.ANVIL.registerModelSupplier(ANVIL) + Items.CHIPPED_ANVIL.registerModelSupplier(CHIPPED_ANVIL) + Items.DAMAGED_ANVIL.registerModelSupplier(DAMAGED_ANVIL) + + Items.BELL.registerModelSupplier(BellBlockHandler::BellUnbakedModel) + + Items.BONE_BLOCK.registerModelSupplier(BONE_BLOCK) + + Items.CAMPFIRE.registerModelSupplier(CAMPFIRE) + Items.SOUL_CAMPFIRE.registerModelSupplier(SOUL_CAMPFIRE) + + Items.FURNACE.registerModelSupplier { + FurnaceHandler.FurnaceUnbakedModel(FURNACE) + } + Items.BLAST_FURNACE.registerModelSupplier { + FurnaceHandler.FurnaceUnbakedModel(BLAST_FURNACE) + } + Items.SMOKER.registerModelSupplier { + FurnaceHandler.FurnaceUnbakedModel(SMOKER) + } + + Items.LIGHTNING_ROD.registerModelSupplier { LightningRodHandler.LightningRodUnbakedModel(LIGHTNING_ROD.defaultState) } + + Items.MAGMA_BLOCK.registerModelSupplier(MAGMA_BLOCK) + + Items.SNOW_BLOCK.registerModelSupplier(SNOW_BLOCK) + + Items.TNT.registerModelSupplier(TNT) + + Items.WITHER_SKELETON_SKULL.registerModelSupplier(WitherSkeletonSkullHandler::WitherSkeletonSkullUnbakedModel) + + Items.WHITE_WOOL.registerModelSupplier(WHITE_WOOL) + Items.ORANGE_WOOL.registerModelSupplier(ORANGE_WOOL) + Items.MAGENTA_WOOL.registerModelSupplier(MAGENTA_WOOL) + Items.LIGHT_BLUE_WOOL.registerModelSupplier(LIGHT_BLUE_WOOL) + Items.YELLOW_WOOL.registerModelSupplier(YELLOW_WOOL) + Items.LIME_WOOL.registerModelSupplier(LIME_WOOL) + Items.PINK_WOOL.registerModelSupplier(PINK_WOOL) + Items.GRAY_WOOL.registerModelSupplier(GRAY_WOOL) + Items.LIGHT_GRAY_WOOL.registerModelSupplier(LIGHT_GRAY_WOOL) + Items.CYAN_WOOL.registerModelSupplier(CYAN_WOOL) + Items.PURPLE_WOOL.registerModelSupplier(PURPLE_WOOL) + Items.BLUE_WOOL.registerModelSupplier(BLUE_WOOL) + Items.BROWN_WOOL.registerModelSupplier(BROWN_WOOL) + Items.GREEN_WOOL.registerModelSupplier(GREEN_WOOL) + Items.RED_WOOL.registerModelSupplier(RED_WOOL) + Items.BLACK_WOOL.registerModelSupplier(BLACK_WOOL) + } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt index a84dc8068..72d47f25d 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt @@ -50,7 +50,6 @@ import opekope2.avm_staff.api.item.model.StaffItemBakedModel import opekope2.avm_staff.util.* import org.joml.Vector3f import java.util.function.Function -import java.util.function.Supplier class WitherSkeletonSkullHandler : StaffItemHandler() { override val maxUseTime = 20 @@ -123,7 +122,7 @@ class WitherSkeletonSkullHandler : StaffItemHandler() { } @Environment(EnvType.CLIENT) - private class WitherSkeletonSkullUnbakedModel : IStaffItemUnbakedModel { + class WitherSkeletonSkullUnbakedModel : IStaffItemUnbakedModel { override fun getModelDependencies() = setOf() override fun setParents(modelLoader: Function?) { @@ -175,10 +174,4 @@ class WitherSkeletonSkullHandler : StaffItemHandler() { ) } } - - companion object { - val modelSupplierFactory: Supplier> = Supplier { - Supplier(::WitherSkeletonSkullUnbakedModel) - } - } } From a5fd1b00ee5b9076f2c4262827487821bd4b7e1f Mon Sep 17 00:00:00 2001 From: opekope2 Date: Wed, 8 May 2024 01:05:13 +0200 Subject: [PATCH 005/128] Remove IStaffMod.isPhysicalClient --- .../kotlin/opekope2/avm_staff/internal/fabric/StaffMod.kt | 5 ----- .../kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt | 4 ---- .../kotlin/opekope2/avm_staff/internal/neoforge/StaffMod.kt | 4 ---- StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt | 5 ----- 4 files changed, 18 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 418d25290..19129eb75 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,13 +18,11 @@ package opekope2.avm_staff.internal.fabric -import net.fabricmc.api.EnvType import net.fabricmc.api.ModInitializer import net.fabricmc.fabric.api.event.player.AttackBlockCallback import net.fabricmc.fabric.api.event.player.AttackEntityCallback import net.fabricmc.fabric.api.item.v1.FabricItemSettings import net.fabricmc.fabric.api.particle.v1.FabricParticleTypes -import net.fabricmc.loader.api.FabricLoader import net.minecraft.entity.Entity import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.Item @@ -53,9 +51,6 @@ object StaffMod : ModInitializer, IStaffMod { FabricStaffItem(FabricItemSettings().maxCount(1)) ) - override val isPhysicalClient: Boolean - get() = FabricLoader.getInstance().environmentType == EnvType.CLIENT - override val staffsTag: TagKey = TagKey.of(RegistryKeys.ITEM, Identifier(MOD_ID, "staffs")) override val flamethrowerParticleType: DefaultParticleType = Registry.register( diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt index ed6cdc265..400d03b95 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt @@ -33,7 +33,6 @@ import opekope2.avm_staff.internal.forge.item.ForgeStaffItem import opekope2.avm_staff.internal.initializeNetworking import opekope2.avm_staff.internal.staff_item_handler.registerVanillaStaffItemHandlers import opekope2.avm_staff.util.MOD_ID -import thedarkcolour.kotlinforforge.forge.DIST import thedarkcolour.kotlinforforge.forge.MOD_BUS import thedarkcolour.kotlinforforge.forge.runWhenOn @@ -63,9 +62,6 @@ object StaffMod : IStaffMod { override val staffItem: StaffItem get() = STAFF_ITEM.get() - override val isPhysicalClient: Boolean - get() = DIST.isClient - override val staffsTag: TagKey = ItemTags.create(Identifier(MOD_ID, "staffs")) override val flamethrowerParticleType: DefaultParticleType 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 78185af3a..87991d517 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 @@ -33,7 +33,6 @@ import opekope2.avm_staff.internal.initializeNetworking import opekope2.avm_staff.internal.neoforge.item.NeoForgeStaffItem import opekope2.avm_staff.internal.staff_item_handler.registerVanillaStaffItemHandlers import opekope2.avm_staff.util.MOD_ID -import thedarkcolour.kotlinforforge.neoforge.forge.DIST import thedarkcolour.kotlinforforge.neoforge.forge.MOD_BUS import thedarkcolour.kotlinforforge.neoforge.forge.runWhenOn @@ -63,9 +62,6 @@ object StaffMod : IStaffMod { override val staffItem: StaffItem get() = STAFF_ITEM.get() - override val isPhysicalClient: Boolean - get() = DIST.isClient - override val staffsTag: TagKey = ItemTags.create(Identifier(MOD_ID, "staffs")) override val flamethrowerParticleType: DefaultParticleType diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt index f5bca0589..ad09e6c48 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt @@ -36,11 +36,6 @@ interface IStaffMod { */ val staffItem: StaffItem - /** - * Returns if Staff Mod is running on the physical client. - */ - val isPhysicalClient: Boolean - /** * Gets the [TagKey] containing all the staffs. */ From 56416276fd38ead7fee7f30ac798d0f60c27d226 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 9 May 2024 21:27:11 +0200 Subject: [PATCH 006/128] Rename VectorUtil to MathUtil --- .../opekope2/avm_staff/util/{VectorUtil.kt => MathUtil.kt} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename StaffMod/src/main/kotlin/opekope2/avm_staff/util/{VectorUtil.kt => MathUtil.kt} (98%) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/VectorUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/MathUtil.kt similarity index 98% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/util/VectorUtil.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/util/MathUtil.kt index cbf2db161..e43683fdc 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/VectorUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/MathUtil.kt @@ -16,7 +16,7 @@ * along with this mod. If not, see . */ -@file: JvmName("VectorUtil") +@file: JvmName("MathUtil") @file: Suppress("NOTHING_TO_INLINE") package opekope2.avm_staff.util From 59f5f101a36e10f693df4f72baccb4d1e9fc838e Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 9 May 2024 22:42:24 +0200 Subject: [PATCH 007/128] Add missing @Environment(CLIENT) --- .../opekope2/avm_staff/api/particle/FlamethrowerParticle.kt | 3 +++ .../opekope2/avm_staff/api/render/IQuadBakerVertexConsumer.kt | 3 +++ 2 files changed, 6 insertions(+) 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 098a100e3..fa328899c 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 @@ -18,6 +18,8 @@ package opekope2.avm_staff.api.particle +import net.fabricmc.api.EnvType +import net.fabricmc.api.Environment import net.minecraft.client.particle.* import net.minecraft.client.world.ClientWorld import net.minecraft.particle.DefaultParticleType @@ -37,6 +39,7 @@ import opekope2.avm_staff.mixin.IParticleMixin * @param velocityZ The Z component of the particle's velocity * @see FlamethrowerParticle.Factory */ +@Environment(EnvType.CLIENT) class FlamethrowerParticle( world: ClientWorld, x: Double, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/render/IQuadBakerVertexConsumer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/render/IQuadBakerVertexConsumer.kt index abd9812a4..a154b4ede 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/render/IQuadBakerVertexConsumer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/render/IQuadBakerVertexConsumer.kt @@ -18,6 +18,8 @@ package opekope2.avm_staff.api.render +import net.fabricmc.api.EnvType +import net.fabricmc.api.Environment import net.minecraft.client.render.VertexConsumer import net.minecraft.client.render.model.BakedQuad import net.minecraft.client.texture.Sprite @@ -25,6 +27,7 @@ import net.minecraft.client.texture.Sprite /** * A vertex consumer, which creates [BakedQuad]s. */ +@Environment(EnvType.CLIENT) interface IQuadBakerVertexConsumer : VertexConsumer { /** * Gets or sets the sprite used to create [BakedQuad]s. From 91db99286c6a31556c506ba5bcda6db389a17e2e Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 10 May 2024 23:36:49 +0200 Subject: [PATCH 008/128] Add model predicates for new staff renderer --- .../internal/fabric/StaffModClient.kt | 2 +- .../internal/forge/StaffModClient.kt | 4 +- .../internal/neoforge/StaffModClient.kt | 4 +- .../avm_staff/internal/Initializer.kt | 28 ---------- .../internal/model/ModelPredicates.kt | 51 +++++++++++++++++++ 5 files changed, 56 insertions(+), 33 deletions(-) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.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 a3bde36d5..b716691b0 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 @@ -37,8 +37,8 @@ import opekope2.avm_staff.api.particle.FlamethrowerParticle import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING import opekope2.avm_staff.internal.event_handler.handleKeyBindings import opekope2.avm_staff.internal.fabric.item.model.UnbakedFabricStaffItemModel -import opekope2.avm_staff.internal.registerModelPredicateProviders import opekope2.avm_staff.util.MOD_ID +import opekope2.avm_staff.internal.model.registerModelPredicateProviders @Suppress("unused") @Environment(EnvType.CLIENT) diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt index 6dcb81572..603d6aa13 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt @@ -36,7 +36,7 @@ import opekope2.avm_staff.IStaffMod import opekope2.avm_staff.api.particle.FlamethrowerParticle import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING import opekope2.avm_staff.internal.event_handler.handleKeyBindings -import opekope2.avm_staff.internal.registerModelPredicateProviders +import opekope2.avm_staff.internal.model.registerModelPredicateProviders import opekope2.avm_staff.internal.staff_item_handler.registerVanillaStaffItemRenderers import thedarkcolour.kotlinforforge.forge.FORGE_BUS import thedarkcolour.kotlinforforge.forge.MOD_BUS @@ -52,7 +52,7 @@ object StaffModClient { @SubscribeEvent fun initializeClient(event: FMLClientSetupEvent) { event.enqueueWork { - registerModelPredicateProviders(ModelPredicateProviderRegistry::register) + registerModelPredicateProviders(ModelPredicateProviderRegistry::registerGeneric) } } 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 fbc40d9ad..d65a7dc0d 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 @@ -36,7 +36,7 @@ import opekope2.avm_staff.IStaffMod import opekope2.avm_staff.api.particle.FlamethrowerParticle import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING import opekope2.avm_staff.internal.event_handler.handleKeyBindings -import opekope2.avm_staff.internal.registerModelPredicateProviders +import opekope2.avm_staff.internal.model.registerModelPredicateProviders import opekope2.avm_staff.internal.staff_item_handler.registerVanillaStaffItemRenderers import thedarkcolour.kotlinforforge.neoforge.forge.FORGE_BUS import thedarkcolour.kotlinforforge.neoforge.forge.MOD_BUS @@ -52,7 +52,7 @@ object StaffModClient { @SubscribeEvent fun initializeClient(event: FMLClientSetupEvent) { event.enqueueWork { - registerModelPredicateProviders(ModelPredicateProviderRegistry::register) + registerModelPredicateProviders(ModelPredicateProviderRegistry::registerGeneric) } } 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 6f98a13d4..d942012b1 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -18,43 +18,15 @@ package opekope2.avm_staff.internal -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment -import net.minecraft.client.item.ClampedModelPredicateProvider -import net.minecraft.client.world.ClientWorld -import net.minecraft.entity.LivingEntity -import net.minecraft.item.Item -import net.minecraft.item.ItemStack -import net.minecraft.util.Identifier -import opekope2.avm_staff.IStaffMod import opekope2.avm_staff.internal.event_handler.addBlockToStaff import opekope2.avm_staff.internal.event_handler.attack import opekope2.avm_staff.internal.event_handler.removeBlockFromStaff import opekope2.avm_staff.internal.networking.c2s.play.AddItemToStaffC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.RemoveItemFromStaffC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.StaffAttackC2SPacket -import opekope2.avm_staff.util.MOD_ID fun initializeNetworking() { AddItemToStaffC2SPacket.registerHandler(::addBlockToStaff) RemoveItemFromStaffC2SPacket.registerHandler(::removeBlockFromStaff) StaffAttackC2SPacket.registerHandler(::attack) } - -val USING_ITEM_PREDICATE = Identifier(MOD_ID, "using_item") - -@Suppress("UNUSED_PARAMETER") -@Environment(EnvType.CLIENT) -private fun usingItemPredicate(stack: ItemStack, world: ClientWorld?, entity: LivingEntity?, seed: Int): Float { - return if (entity != null && entity.isUsingItem) 1f else 0f -} - -// ModelPredicateProviderRegistry.register is private, so pass it from Fabric and Forge projects -@Environment(EnvType.CLIENT) -fun registerModelPredicateProviders(register: (Item, Identifier, ClampedModelPredicateProvider) -> Unit) { - register( - IStaffMod.get().staffItem, - USING_ITEM_PREDICATE, - ::usingItemPredicate - ) -} 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 new file mode 100644 index 000000000..06cca4413 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/model/ModelPredicates.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.model + +import net.fabricmc.api.EnvType +import net.fabricmc.api.Environment +import net.minecraft.client.item.ClampedModelPredicateProvider +import net.minecraft.item.ItemStack +import net.minecraft.util.Identifier +import opekope2.avm_staff.util.MOD_ID + +const val HEAD_SEED = -0b10011_10100_00001_00110_00110_00000 +const val ROD_TOP_SEED = -0b10011_10100_00001_00110_00110_00010 +const val ROD_BOTTOM_SEED = -0b10011_10100_00001_00110_00110_00011 + +// ModelPredicateProviderRegistry.register is private in common project +@Environment(EnvType.CLIENT) +fun registerModelPredicateProviders(register: (Identifier, ClampedModelPredicateProvider) -> Unit) { + register(Identifier(MOD_ID, "using_item")) { stack, _, entity, _ -> + if (entity != null && entity.isUsingItem && ItemStack.areEqual(entity.activeItem, stack)) 1f + else 0f + } + register(Identifier(MOD_ID, "head")) { _, _, _, seed -> + if (seed == HEAD_SEED) 1f + else 0f + } + register(Identifier(MOD_ID, "rod_top")) { _, _, _, seed -> + if (seed == ROD_TOP_SEED) 1f + else 0f + } + register(Identifier(MOD_ID, "rod_bottom")) { _, _, _, seed -> + if (seed == ROD_BOTTOM_SEED) 1f + else 0f + } +} From 75e73075fd2b8524493cbde63c96faf6ce1dae82 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 10 May 2024 23:50:00 +0200 Subject: [PATCH 009/128] Add a MatrixStack utility function --- .../main/kotlin/opekope2/avm_staff/util/MathUtil.kt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/MathUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/MathUtil.kt index e43683fdc..3e77f6a8b 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/MathUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/MathUtil.kt @@ -21,6 +21,7 @@ package opekope2.avm_staff.util +import net.minecraft.client.util.math.MatrixStack import net.minecraft.util.math.Vec3d import org.joml.Vector3f import org.joml.Vector3fc @@ -56,3 +57,15 @@ inline operator fun Vector3f.minusAssign(other: Vector3fc) { inline operator fun Vector3f.timesAssign(scalar: Float) { mul(scalar) } + +/** + * [Pushes][MatrixStack.push] to the given matrix stack, invokes [action], then [pops][MatrixStack.pop] from the given + * matrix stack. + * + * @param action The action to invoke between [MatrixStack.push] and [MatrixStack.pop] + */ +inline fun MatrixStack.push(action: MatrixStack.() -> Unit) { + push() + action() + pop() +} From e592fbba476804f93d09e09acf76a85d76a2f051 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 11 May 2024 02:23:24 +0200 Subject: [PATCH 010/128] Add new staff rendering API --- .../api/item/renderer/IStaffItemRenderer.kt | 91 ++++++++ .../api/item/renderer/StaffRenderer.kt | 210 ++++++++++++++++++ 2 files changed, 301 insertions(+) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/IStaffItemRenderer.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt 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/IStaffItemRenderer.kt new file mode 100644 index 000000000..14738ccdb --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/IStaffItemRenderer.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.api.item.renderer + +import net.fabricmc.api.EnvType +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.ItemStack +import net.minecraft.util.Identifier + +/** + * A renderer for an item, which can be placed into a staff. + * + * @see IStaffItemRenderer.register + */ +@Environment(EnvType.CLIENT) +fun interface IStaffItemRenderer { + /** + * Renders an item. + * + * @param staffStack The staff item stack + * @param mode The transformation the staff is rendered in. You likely want to pass + * [ModelTransformationMode.NONE] to rendering calls + * @param matrices Matrix stack for rendering calls + * @param vertexConsumers Vertex consumer provider for rendering calls + * @param light Light component for rendering calls + * @param overlay Overlay component for rendering calls + */ + fun renderItemInStaff( + staffStack: ItemStack, + mode: ModelTransformationMode, + matrices: MatrixStack, + vertexConsumers: VertexConsumerProvider, + light: Int, + overlay: Int + ) + + @Environment(EnvType.CLIENT) + companion object { + private val staffItemRenderers = mutableMapOf() + + /** + * Registers a renderer for a given [item ID][staffItem]. + * + * @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 + */ + @JvmStatic + fun register(staffItem: Identifier, renderer: IStaffItemRenderer): Boolean { + if (staffItem in staffItemRenderers) return false + + staffItemRenderers[staffItem] = renderer + return true + } + + /** + * Checks if a renderer for the [given item][staffItem] is registered. + * + * @param staffItem The item ID, which can be inserted into the staff + */ + @JvmStatic + operator fun contains(staffItem: Identifier): Boolean = staffItem in staffItemRenderers + + /** + * Gets the registered renderer for the [given item][staffItem] or `null`, if no renderer was registered. + * + * @param staffItem The item ID, which can be inserted into the staff + */ + @JvmStatic + operator fun get(staffItem: Identifier): IStaffItemRenderer? = staffItemRenderers[staffItem] + } +} 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 new file mode 100644 index 000000000..7830d344e --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/StaffRenderer.kt @@ -0,0 +1,210 @@ +/* + * 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.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.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 opekope2.avm_staff.internal.model.HEAD_SEED +import opekope2.avm_staff.internal.model.ROD_BOTTOM_SEED +import opekope2.avm_staff.internal.model.ROD_TOP_SEED +import opekope2.avm_staff.util.itemInStaff +import opekope2.avm_staff.util.push + +/** + * Builtin model item renderer for staffs. + * + * @param getStaffItem A supplier for the staff item to be rendered + */ +@Environment(EnvType.CLIENT) +class StaffRenderer(private val getStaffItem: () -> Item) { + /** + * Renders the staff. + * + * @param staffStack The staff item stack + * @param mode The transformation the staff is rendered in + * @param matrices Matrix stack for rendering calls + * @param vertexConsumers Vertex consumer provider for rendering calls + * @param light Light component for rendering calls + * @param overlay Overlay component for rendering calls + */ + fun renderStaff( + staffStack: ItemStack, + mode: ModelTransformationMode, + matrices: MatrixStack, + vertexConsumers: VertexConsumerProvider, + light: Int, + overlay: Int + ) { + when (mode) { + ModelTransformationMode.GUI -> renderInventoryStaff( + mode, staffStack, matrices, vertexConsumers, light, overlay + ) + + ModelTransformationMode.FIXED -> renderItemFrameStaff( + mode, staffStack, matrices, vertexConsumers, light, overlay + ) + + else -> renderFullStaff( + mode, staffStack, matrices, vertexConsumers, light, overlay + ) + } + } + + private fun renderFullStaff( + mode: ModelTransformationMode, + staffStack: ItemStack, + matrices: MatrixStack, + vertexConsumers: VertexConsumerProvider, + light: Int, + overlay: Int + ) { + matrices.push { + translate(0.5, 0.5, 0.5) + + // Head + push { + translate(0.0, 16.0 / 16.0, 0.0) + renderPart(this, vertexConsumers, light, overlay, HEAD_SEED) + + // Item + staffStack.itemInStaff?.let { itemInStaff -> + renderItem(mode, this, staffStack, itemInStaff, light, overlay, vertexConsumers) + } + } + + // Rod (top) + push { + translate(0.0, 2.0 / 16.0, 0.0) + renderPart(this, vertexConsumers, light, overlay, ROD_TOP_SEED) + } + + // Rod (bottom) + push { + translate(0.0, -12.0 / 16.0, 0.0) + renderPart(this, vertexConsumers, light, overlay, ROD_BOTTOM_SEED) + } + } + } + + private fun renderInventoryStaff( + mode: ModelTransformationMode, + staffStack: ItemStack, + matrices: MatrixStack, + vertexConsumers: VertexConsumerProvider, + light: Int, + overlay: Int + ) { + matrices.push { + translate(0.5, 0.5, 0.5) + + // Head + push { + renderPart(this, vertexConsumers, light, overlay, HEAD_SEED) + + // Item + staffStack.itemInStaff?.let { itemInStaff -> + renderItem(mode, this, staffStack, itemInStaff, light, overlay, vertexConsumers) + } + } + } + } + + private fun renderItemFrameStaff( + mode: ModelTransformationMode, + staffStack: ItemStack, + matrices: MatrixStack, + vertexConsumers: VertexConsumerProvider, + light: Int, + overlay: Int + ) { + matrices.push { + translate(0.5, 0.5, 0.5) + + // Head + push { + translate(0.0, 9.0 / 16.0, 0.0) + renderPart(this, vertexConsumers, light, overlay, HEAD_SEED) + + // Item + staffStack.itemInStaff?.let { itemInStaff -> + renderItem(mode, this, staffStack, itemInStaff, light, overlay, vertexConsumers) + } + } + + // Rod (top) + push { + translate(0.0, -5.0 / 16.0, 0.0) + renderPart(this, vertexConsumers, light, overlay, ROD_TOP_SEED) + } + } + } + + private fun renderItem( + mode: ModelTransformationMode, + matrices: MatrixStack, + staffStack: ItemStack, + itemStackInStaff: ItemStack, + light: Int, + overlay: Int, + vertexConsumers: VertexConsumerProvider + ) { + matrices.push { + scale(.5f, .5f, .5f) + translate(0.0, (-8.0 + 2.0) / 16.0, 0.0) + + val staffItemRenderer = IStaffItemRenderer[Registries.ITEM.getId(itemStackInStaff.item)] + if (staffItemRenderer != null) { + staffItemRenderer.renderItemInStaff(staffStack, mode, this, vertexConsumers, light, overlay) + } else { + val itemRenderer = MinecraftClient.getInstance().itemRenderer + + val model = MinecraftClient.getInstance().bakedModelManager.missingModel + itemRenderer.renderItem(itemStackInStaff, mode, false, this, vertexConsumers, light, overlay, model) + } + } + } + + private fun renderPart( + matrices: MatrixStack, + vertexConsumers: VertexConsumerProvider, + light: Int, + overlay: Int, + partSeed: Int + ) { + val itemRenderer = MinecraftClient.getInstance().itemRenderer + val modelManager = MinecraftClient.getInstance().bakedModelManager + val item = getStaffItem().defaultStack + + var model = itemRenderer.getModel(item, null, null, partSeed) + if (model.isBuiltin) { + model = modelManager.missingModel + } + + itemRenderer.renderItem( + item, ModelTransformationMode.NONE, false, matrices, vertexConsumers, light, overlay, model + ) + } +} From dace007074f91f0d84b99d9bf8d597847762d12c Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 11 May 2024 02:24:37 +0200 Subject: [PATCH 011/128] Add a staff item renderer for a constant block state --- .../renderer/BlockStateStaffItemRenderer.kt | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/BlockStateStaffItemRenderer.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 new file mode 100644 index 000000000..8763c83c6 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/renderer/BlockStateStaffItemRenderer.kt @@ -0,0 +1,53 @@ +/* + * 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.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.math.MatrixStack +import net.minecraft.item.ItemStack + +/** + * A [IStaffItemRenderer], always which renders a single block state. + * + * @param blockState The block state to render + */ +class BlockStateStaffItemRenderer(blockState: BlockState) : IStaffItemRenderer { + private val blockStateId = BlockModels.getModelId(blockState) + private val blockItem = blockState.block.asItem().defaultStack + + override fun renderItemInStaff( + staffStack: ItemStack, + mode: ModelTransformationMode, + matrices: MatrixStack, + vertexConsumers: VertexConsumerProvider, + light: Int, + overlay: Int + ) { + val itemRenderer = MinecraftClient.getInstance().itemRenderer + val modelManager = MinecraftClient.getInstance().bakedModelManager + val model = modelManager.getModel(blockStateId) + itemRenderer.renderItem( + blockItem, ModelTransformationMode.NONE, false, matrices, vertexConsumers, light, overlay, model + ) + } +} From 93e3b2f31ae62919dc5353c2f6242a6a6c166dde Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 11 May 2024 02:40:03 +0200 Subject: [PATCH 012/128] Migrate supported vanilla items to the new renderer --- .../staff_item_handler/BellBlockHandler.kt | 86 +++++---------- .../staff_item_handler/FurnaceHandler.kt | 68 ++++-------- .../staff_item_handler/LightningRodHandler.kt | 68 ++++-------- .../VanillaStaffItemHandlers.kt | 101 ++++++++---------- .../WitherSkeletonSkullHandler.kt | 97 ++++++----------- 5 files changed, 152 insertions(+), 268 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BellBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BellBlockHandler.kt index 8ede9daed..9cd6ba9ca 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BellBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BellBlockHandler.kt @@ -22,13 +22,11 @@ import com.google.common.collect.ImmutableMultimap import com.google.common.collect.Multimap 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.* -import net.minecraft.client.render.model.json.ModelOverrideList -import net.minecraft.client.render.model.json.ModelTransformation -import net.minecraft.client.render.model.json.Transformation -import net.minecraft.client.texture.Sprite -import net.minecraft.client.util.SpriteIdentifier +import net.minecraft.client.render.model.json.ModelTransformationMode +import net.minecraft.client.util.math.MatrixStack import net.minecraft.entity.Entity import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.LivingEntity @@ -41,20 +39,13 @@ import net.minecraft.sound.SoundCategory import net.minecraft.sound.SoundEvents import net.minecraft.util.ActionResult import net.minecraft.util.Hand -import net.minecraft.util.Identifier import net.minecraft.util.TypedActionResult -import net.minecraft.util.math.Direction import net.minecraft.world.World import opekope2.avm_staff.api.item.StaffItemHandler -import opekope2.avm_staff.api.item.model.IStaffItemBakedModel -import opekope2.avm_staff.api.item.model.IStaffItemUnbakedModel -import opekope2.avm_staff.api.item.model.StaffItemBakedModel +import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.attackSpeed -import opekope2.avm_staff.util.getBakedQuads -import opekope2.avm_staff.util.transform -import org.joml.Vector3f -import java.util.function.Function +import opekope2.avm_staff.util.push class BellBlockHandler : StaffItemHandler() { override fun use( @@ -96,51 +87,30 @@ class BellBlockHandler : StaffItemHandler() { } @Environment(EnvType.CLIENT) - class BellUnbakedModel : IStaffItemUnbakedModel { - override fun getModelDependencies() = setOf() + class BellStaffItemRenderer : IStaffItemRenderer { + private val bellModel = BellBlockEntityRenderer.getTexturedModelData().createModel().getChild("bell_body") - override fun setParents(modelLoader: Function?) { - } - - override fun bake( - baker: Baker, - textureGetter: Function, - rotationContainer: ModelBakeSettings, - modelId: Identifier, - transformation: Transformation - ): IStaffItemBakedModel { - val bellSprite = textureGetter.apply(BellBlockEntityRenderer.BELL_BODY_TEXTURE) - val bellModel = BellBlockEntityRenderer.getTexturedModelData().createModel().getChild("bell_body") - val quads = bellModel.getBakedQuads(bellSprite, bellTransformation) - val baked = BasicBakedModel( - quads, - createEmptyFaceQuads(), - true, - false, - false, - bellSprite, - ModelTransformation.NONE, - ModelOverrideList.EMPTY - ) - - return StaffItemBakedModel(baked.transform(null, transformation, textureGetter)) - } - - private companion object { - private val bellTransformation = Transformation( - Vector3f(), - Vector3f(-3.5f / 9f, -4f / 9f, -3.5f / 9f), - Vector3f(16f / 9f) - ) + override fun renderItemInStaff( + staffStack: ItemStack, + mode: ModelTransformationMode, + matrices: MatrixStack, + vertexConsumers: VertexConsumerProvider, + light: Int, + overlay: Int + ) { + matrices.push { + translate(-0.5, -5.0 / 16.0, -0.5) - private fun createEmptyFaceQuads(): Map> = mapOf( - Direction.DOWN to listOf(), - Direction.UP to listOf(), - Direction.NORTH to listOf(), - Direction.SOUTH to listOf(), - Direction.WEST to listOf(), - Direction.EAST to listOf(), - ) + 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_handler/FurnaceHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt index f9b3c3db8..c736d04c1 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt @@ -26,14 +26,9 @@ 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.block.BlockModels -import net.minecraft.client.render.model.BakedModel -import net.minecraft.client.render.model.Baker -import net.minecraft.client.render.model.ModelBakeSettings -import net.minecraft.client.render.model.UnbakedModel -import net.minecraft.client.render.model.json.Transformation -import net.minecraft.client.texture.Sprite -import net.minecraft.client.util.SpriteIdentifier +import net.minecraft.client.render.VertexConsumerProvider +import net.minecraft.client.render.model.json.ModelTransformationMode +import net.minecraft.client.util.math.MatrixStack import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.ItemEntity import net.minecraft.entity.LivingEntity @@ -50,16 +45,14 @@ import net.minecraft.server.world.ServerWorld import net.minecraft.sound.SoundCategory import net.minecraft.sound.SoundEvent import net.minecraft.util.Hand -import net.minecraft.util.Identifier import net.minecraft.util.TypedActionResult import net.minecraft.util.math.Box import net.minecraft.world.World import opekope2.avm_staff.api.item.StaffItemHandler -import opekope2.avm_staff.api.item.model.IStaffItemBakedModel -import opekope2.avm_staff.api.item.model.IStaffItemUnbakedModel +import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer +import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer import opekope2.avm_staff.mixin.IAbstractFurnaceBlockEntityMixin import opekope2.avm_staff.util.* -import java.util.function.Function import kotlin.jvm.optionals.getOrNull class FurnaceHandler( @@ -183,45 +176,28 @@ class FurnaceHandler( } @Environment(EnvType.CLIENT) - class FurnaceUnbakedModel(private val unlitState: BlockState, private val litState: BlockState) : - IStaffItemUnbakedModel { + class FurnaceStaffItemRenderer(unlitState: BlockState, litState: BlockState) : IStaffItemRenderer { constructor(furnaceBlock: Block) : this( furnaceBlock.defaultState, furnaceBlock.defaultState.with(AbstractFurnaceBlock.LIT, true) ) - private val litStateId = BlockModels.getModelId(litState) - private val unlitStateId = BlockModels.getModelId(unlitState) - private val dependencies = setOf(litStateId, unlitStateId) - - override fun getModelDependencies() = dependencies - - override fun setParents(modelLoader: Function?) { - } - - override fun bake( - baker: Baker, - textureGetter: Function, - rotationContainer: ModelBakeSettings, - modelId: Identifier, - transformation: Transformation - ): IStaffItemBakedModel? { - val unlitModel = baker.bake(unlitStateId, rotationContainer) ?: return null - val litModel = baker.bake(litStateId, rotationContainer) ?: return null - - return FurnaceBakedModel( - unlitModel.transform(unlitState, transformation, textureGetter), - litModel.transform(litState, transformation, textureGetter) - ) - } - } - - @Environment(EnvType.CLIENT) - private class FurnaceBakedModel(private val unlitModel: BakedModel, private val litModel: BakedModel) : - BakedModel by unlitModel, IStaffItemBakedModel { - override fun getModel(staffStack: ItemStack): BakedModel { - return if (staffStack.nbt?.getBoolean(LIT_KEY) == true) litModel - else unlitModel + 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 (staffStack.nbt?.getBoolean(LIT_KEY) == true) litRenderer + else unlitRenderer + + renderer.renderItemInStaff(staffStack, mode, matrices, vertexConsumers, light, overlay) } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/LightningRodHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/LightningRodHandler.kt index 263b715ff..5ed98044c 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/LightningRodHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/LightningRodHandler.kt @@ -20,32 +20,24 @@ package opekope2.avm_staff.internal.staff_item_handler import net.fabricmc.api.EnvType import net.fabricmc.api.Environment -import net.minecraft.block.BlockState -import net.minecraft.client.render.block.BlockModels -import net.minecraft.client.render.model.Baker -import net.minecraft.client.render.model.ModelBakeSettings -import net.minecraft.client.render.model.UnbakedModel -import net.minecraft.client.render.model.json.Transformation -import net.minecraft.client.texture.Sprite -import net.minecraft.client.util.SpriteIdentifier +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.entity.EntityType import net.minecraft.entity.LivingEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack import net.minecraft.util.ActionResult import net.minecraft.util.Hand -import net.minecraft.util.Identifier import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction import net.minecraft.world.World import opekope2.avm_staff.api.item.StaffItemHandler -import opekope2.avm_staff.api.item.model.IStaffItemBakedModel -import opekope2.avm_staff.api.item.model.IStaffItemUnbakedModel -import opekope2.avm_staff.api.item.model.StaffItemBakedModel +import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer +import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer import opekope2.avm_staff.util.isItemCoolingDown -import opekope2.avm_staff.util.transform -import org.joml.Vector3f -import java.util.function.Function +import opekope2.avm_staff.util.push class LightningRodHandler : StaffItemHandler() { override fun useOnBlock( @@ -82,37 +74,21 @@ class LightningRodHandler : StaffItemHandler() { } @Environment(EnvType.CLIENT) - class LightningRodUnbakedModel(private val state: BlockState) : IStaffItemUnbakedModel { - private val stateId = BlockModels.getModelId(state) - private val dependencies = setOf(stateId) - - override fun getModelDependencies() = dependencies - - override fun setParents(modelLoader: Function?) { - } - - override fun bake( - baker: Baker, - textureGetter: Function, - rotationContainer: ModelBakeSettings, - modelId: Identifier, - transformation: Transformation - ): IStaffItemBakedModel? { - val baked = baker.bake(stateId, rotationContainer) ?: return null - - return StaffItemBakedModel( - baked - .transform(state, lightningRodTransformation, textureGetter) - .transform(state, transformation, textureGetter) - ) - } - - private companion object { - private val lightningRodTransformation = Transformation( - Vector3f(), - Vector3f(-1f / 14f, 10f / 7f, -1f / 14f), - Vector3f(8f / 7f) - ) + 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 { + translate(0.0, 22.0 / 16.0, 0.0) + lightningRodRenderer.renderItemInStaff(staffStack, mode, matrices, vertexConsumers, light, overlay) + } } } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt index b8559c367..ebe35f390 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt @@ -29,9 +29,8 @@ import net.minecraft.registry.Registries import net.minecraft.sound.SoundEvents import opekope2.avm_staff.IStaffMod import opekope2.avm_staff.api.item.StaffItemHandler -import opekope2.avm_staff.api.item.model.IStaffItemUnbakedModel -import opekope2.avm_staff.api.item.model.UnbakedBlockStateModel -import java.util.function.Supplier +import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer +import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer private fun Item.registerHandler(handler: StaffItemHandler) { StaffItemHandler.register(Registries.ITEM.getId(this), handler) @@ -101,63 +100,57 @@ fun registerVanillaStaffItemHandlers() { } @Environment(EnvType.CLIENT) -private fun Item.registerModelSupplier(itemModelSupplier: Supplier) { - StaffItemHandler.registerModelSupplier(Registries.ITEM.getId(this), itemModelSupplier) +private fun Item.registerStaffItemRenderer(renderer: IStaffItemRenderer) { + IStaffItemRenderer.register(Registries.ITEM.getId(this), renderer) } @Environment(EnvType.CLIENT) -private fun Item.registerModelSupplier(staffItem: Block) { - registerModelSupplier { UnbakedBlockStateModel(staffItem.defaultState) } +private fun Item.registerStaffItemRenderer(staffItem: Block) { + registerStaffItemRenderer(BlockStateStaffItemRenderer(staffItem.defaultState)) } @Environment(EnvType.CLIENT) fun registerVanillaStaffItemRenderers() { - Items.ANVIL.registerModelSupplier(ANVIL) - Items.CHIPPED_ANVIL.registerModelSupplier(CHIPPED_ANVIL) - Items.DAMAGED_ANVIL.registerModelSupplier(DAMAGED_ANVIL) - - Items.BELL.registerModelSupplier(BellBlockHandler::BellUnbakedModel) - - Items.BONE_BLOCK.registerModelSupplier(BONE_BLOCK) - - Items.CAMPFIRE.registerModelSupplier(CAMPFIRE) - Items.SOUL_CAMPFIRE.registerModelSupplier(SOUL_CAMPFIRE) - - Items.FURNACE.registerModelSupplier { - FurnaceHandler.FurnaceUnbakedModel(FURNACE) - } - Items.BLAST_FURNACE.registerModelSupplier { - FurnaceHandler.FurnaceUnbakedModel(BLAST_FURNACE) - } - Items.SMOKER.registerModelSupplier { - FurnaceHandler.FurnaceUnbakedModel(SMOKER) - } - - Items.LIGHTNING_ROD.registerModelSupplier { LightningRodHandler.LightningRodUnbakedModel(LIGHTNING_ROD.defaultState) } - - Items.MAGMA_BLOCK.registerModelSupplier(MAGMA_BLOCK) - - Items.SNOW_BLOCK.registerModelSupplier(SNOW_BLOCK) - - Items.TNT.registerModelSupplier(TNT) - - Items.WITHER_SKELETON_SKULL.registerModelSupplier(WitherSkeletonSkullHandler::WitherSkeletonSkullUnbakedModel) - - Items.WHITE_WOOL.registerModelSupplier(WHITE_WOOL) - Items.ORANGE_WOOL.registerModelSupplier(ORANGE_WOOL) - Items.MAGENTA_WOOL.registerModelSupplier(MAGENTA_WOOL) - Items.LIGHT_BLUE_WOOL.registerModelSupplier(LIGHT_BLUE_WOOL) - Items.YELLOW_WOOL.registerModelSupplier(YELLOW_WOOL) - Items.LIME_WOOL.registerModelSupplier(LIME_WOOL) - Items.PINK_WOOL.registerModelSupplier(PINK_WOOL) - Items.GRAY_WOOL.registerModelSupplier(GRAY_WOOL) - Items.LIGHT_GRAY_WOOL.registerModelSupplier(LIGHT_GRAY_WOOL) - Items.CYAN_WOOL.registerModelSupplier(CYAN_WOOL) - Items.PURPLE_WOOL.registerModelSupplier(PURPLE_WOOL) - Items.BLUE_WOOL.registerModelSupplier(BLUE_WOOL) - Items.BROWN_WOOL.registerModelSupplier(BROWN_WOOL) - Items.GREEN_WOOL.registerModelSupplier(GREEN_WOOL) - Items.RED_WOOL.registerModelSupplier(RED_WOOL) - Items.BLACK_WOOL.registerModelSupplier(BLACK_WOOL) + Items.ANVIL.registerStaffItemRenderer(ANVIL) + Items.CHIPPED_ANVIL.registerStaffItemRenderer(CHIPPED_ANVIL) + Items.DAMAGED_ANVIL.registerStaffItemRenderer(DAMAGED_ANVIL) + + Items.BELL.registerStaffItemRenderer(BellBlockHandler.BellStaffItemRenderer()) + + Items.BONE_BLOCK.registerStaffItemRenderer(BONE_BLOCK) + + Items.CAMPFIRE.registerStaffItemRenderer(CAMPFIRE) + Items.SOUL_CAMPFIRE.registerStaffItemRenderer(SOUL_CAMPFIRE) + + Items.FURNACE.registerStaffItemRenderer(FurnaceHandler.FurnaceStaffItemRenderer(FURNACE)) + Items.BLAST_FURNACE.registerStaffItemRenderer(FurnaceHandler.FurnaceStaffItemRenderer(BLAST_FURNACE)) + Items.SMOKER.registerStaffItemRenderer(FurnaceHandler.FurnaceStaffItemRenderer(SMOKER)) + + Items.LIGHTNING_ROD.registerStaffItemRenderer(LightningRodHandler.LightningRodStaffItemRenderer()) + + Items.MAGMA_BLOCK.registerStaffItemRenderer(MAGMA_BLOCK) + + Items.SNOW_BLOCK.registerStaffItemRenderer(SNOW_BLOCK) + + Items.TNT.registerStaffItemRenderer(TNT) + + Items.WITHER_SKELETON_SKULL.registerStaffItemRenderer(WitherSkeletonSkullHandler.WitherSkeletonSkullStaffItemRenderer()) + + Items.WHITE_WOOL.registerStaffItemRenderer(WHITE_WOOL) + Items.ORANGE_WOOL.registerStaffItemRenderer(ORANGE_WOOL) + Items.MAGENTA_WOOL.registerStaffItemRenderer(MAGENTA_WOOL) + Items.LIGHT_BLUE_WOOL.registerStaffItemRenderer(LIGHT_BLUE_WOOL) + Items.YELLOW_WOOL.registerStaffItemRenderer(YELLOW_WOOL) + Items.LIME_WOOL.registerStaffItemRenderer(LIME_WOOL) + Items.PINK_WOOL.registerStaffItemRenderer(PINK_WOOL) + Items.GRAY_WOOL.registerStaffItemRenderer(GRAY_WOOL) + Items.LIGHT_GRAY_WOOL.registerStaffItemRenderer(LIGHT_GRAY_WOOL) + Items.CYAN_WOOL.registerStaffItemRenderer(CYAN_WOOL) + Items.PURPLE_WOOL.registerStaffItemRenderer(PURPLE_WOOL) + Items.BLUE_WOOL.registerStaffItemRenderer(BLUE_WOOL) + Items.BROWN_WOOL.registerStaffItemRenderer(BROWN_WOOL) + Items.GREEN_WOOL.registerStaffItemRenderer(GREEN_WOOL) + Items.RED_WOOL.registerStaffItemRenderer(RED_WOOL) + Items.BLACK_WOOL.registerStaffItemRenderer(BLACK_WOOL) } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt index 72d47f25d..6435b3fd9 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt @@ -20,14 +20,13 @@ package opekope2.avm_staff.internal.staff_item_handler 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.* -import net.minecraft.client.render.model.json.ModelOverrideList -import net.minecraft.client.render.model.json.ModelTransformation -import net.minecraft.client.render.model.json.Transformation -import net.minecraft.client.texture.Sprite -import net.minecraft.client.texture.SpriteAtlasTexture -import net.minecraft.client.util.SpriteIdentifier +import net.minecraft.client.render.model.json.ModelTransformationMode +import net.minecraft.client.util.math.MatrixStack import net.minecraft.entity.Entity import net.minecraft.entity.LivingEntity import net.minecraft.entity.effect.StatusEffectInstance @@ -37,19 +36,13 @@ import net.minecraft.entity.projectile.WitherSkullEntity import net.minecraft.item.ItemStack import net.minecraft.util.ActionResult import net.minecraft.util.Hand -import net.minecraft.util.Identifier import net.minecraft.util.TypedActionResult -import net.minecraft.util.math.Direction import net.minecraft.world.Difficulty import net.minecraft.world.World import net.minecraft.world.WorldEvents import opekope2.avm_staff.api.item.StaffItemHandler -import opekope2.avm_staff.api.item.model.IStaffItemBakedModel -import opekope2.avm_staff.api.item.model.IStaffItemUnbakedModel -import opekope2.avm_staff.api.item.model.StaffItemBakedModel +import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer import opekope2.avm_staff.util.* -import org.joml.Vector3f -import java.util.function.Function class WitherSkeletonSkullHandler : StaffItemHandler() { override val maxUseTime = 20 @@ -122,56 +115,32 @@ class WitherSkeletonSkullHandler : StaffItemHandler() { } @Environment(EnvType.CLIENT) - class WitherSkeletonSkullUnbakedModel : IStaffItemUnbakedModel { - override fun getModelDependencies() = setOf() - - override fun setParents(modelLoader: Function?) { - } - - override fun bake( - baker: Baker, - textureGetter: Function, - rotationContainer: ModelBakeSettings, - modelId: Identifier, - transformation: Transformation - ): IStaffItemBakedModel { - val skullSprite = textureGetter.apply(WITHER_SKELETON_SKULL_TEXTURE) - val skullModel = SkullEntityModel.getSkullTexturedModelData().createModel().getChild("head") - val quads = skullModel.getBakedQuads(skullSprite, skullTransformation) - val baked = BasicBakedModel( - quads, - createEmptyFaceQuads(), - true, - false, - false, - skullSprite, - ModelTransformation.NONE, - ModelOverrideList.EMPTY - ) - - return StaffItemBakedModel(baked.transform(null, transformation, textureGetter)) - } - - private companion object { - private val WITHER_SKELETON_SKULL_TEXTURE = SpriteIdentifier( - SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, - Identifier("entity/skeleton/wither_skeleton") - ) - - private val skullTransformation = Transformation( - Vector3f(0f, 0f, 180f), - Vector3f(.5f, 0f, .5f), - Vector3f(2f) - ) - - private fun createEmptyFaceQuads(): Map> = mapOf( - Direction.DOWN to listOf(), - Direction.UP to listOf(), - Direction.NORTH to listOf(), - Direction.SOUTH to listOf(), - Direction.WEST to listOf(), - Direction.EAST to listOf(), - ) + class WitherSkeletonSkullStaffItemRenderer : IStaffItemRenderer { + private val skullModel = SkullEntityModel.getSkullTexturedModelData().createModel().getChild("head") + + override fun renderItemInStaff( + staffStack: ItemStack, + mode: ModelTransformationMode, + matrices: MatrixStack, + vertexConsumers: VertexConsumerProvider, + light: Int, + overlay: Int + ) { + matrices.push { + scale(-1f, -1f, 1f) + translate(0.0, 8.0 / 16.0, 0.0) + scale(2f, 2f, 2f) + skullModel.render( + matrices, + vertexConsumers.getBuffer( + SkullBlockEntityRenderer.getRenderLayer( + (Blocks.WITHER_SKELETON_SKULL as AbstractSkullBlock).skullType, null + ) + ), + light, + overlay + ) + } } } } From c5c86cb62b4bd101221182b9a09bee118b3421ca Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 11 May 2024 02:58:08 +0200 Subject: [PATCH 013/128] Remove old model-based renderer --- .../internal/fabric/StaffModClient.kt | 22 ------- .../item/model/BakedFabricStaffItemModel.kt | 53 --------------- .../item/model/UnbakedFabricStaffItemModel.kt | 50 --------------- .../forge/ModelLoaderBakerImplMixin.java | 58 ----------------- .../item/model/BakedForgeStaffItemModel.kt | 58 ----------------- .../item/model/UnbakedForgeStaffItemModel.kt | 50 --------------- .../resources/avm_staff_forge.mixins.json | 3 +- .../neoforge/ModelLoaderBakerImplMixin.java | 58 ----------------- .../item/model/BakedNeoForgeStaffItemModel.kt | 58 ----------------- .../model/UnbakedNeoForgeStaffItemModel.kt | 50 --------------- .../resources/avm_staff_neoforge.mixins.json | 3 +- .../avm_staff/api/item/StaffItemHandler.kt | 35 ---------- .../api/item/model/IStaffItemBakedModel.kt | 35 ---------- .../api/item/model/IStaffItemUnbakedModel.kt | 64 ------------------- .../api/item/model/StaffItemBakedModel.kt | 31 --------- .../api/item/model/UnbakedBlockStateModel.kt | 61 ------------------ .../item/model/UnbakedStaffItemModel.kt | 60 ----------------- 17 files changed, 2 insertions(+), 747 deletions(-) delete mode 100644 FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/model/BakedFabricStaffItemModel.kt delete mode 100644 FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/model/UnbakedFabricStaffItemModel.kt delete mode 100644 ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ModelLoaderBakerImplMixin.java delete mode 100644 ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/model/BakedForgeStaffItemModel.kt delete mode 100644 ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/model/UnbakedForgeStaffItemModel.kt delete mode 100644 NeoForgeMod/src/main/java/opekope2/avm_staff/mixin/neoforge/ModelLoaderBakerImplMixin.java delete mode 100644 NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/model/BakedNeoForgeStaffItemModel.kt delete mode 100644 NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/model/UnbakedNeoForgeStaffItemModel.kt delete mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/IStaffItemBakedModel.kt delete mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/IStaffItemUnbakedModel.kt delete mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/StaffItemBakedModel.kt delete mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/UnbakedBlockStateModel.kt delete mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/internal/item/model/UnbakedStaffItemModel.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 b716691b0..65a48723b 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 @@ -23,21 +23,15 @@ import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper -import net.fabricmc.fabric.api.client.model.loading.v1.ModelLoadingPlugin -import net.fabricmc.fabric.api.client.model.loading.v1.ModelModifier import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents import net.minecraft.client.item.ModelPredicateProviderRegistry -import net.minecraft.client.render.model.UnbakedModel -import net.minecraft.client.render.model.json.JsonUnbakedModel import net.minecraft.item.ItemGroups import net.minecraft.item.Items import opekope2.avm_staff.IStaffMod import opekope2.avm_staff.api.particle.FlamethrowerParticle import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING import opekope2.avm_staff.internal.event_handler.handleKeyBindings -import opekope2.avm_staff.internal.fabric.item.model.UnbakedFabricStaffItemModel -import opekope2.avm_staff.util.MOD_ID import opekope2.avm_staff.internal.model.registerModelPredicateProviders @Suppress("unused") @@ -51,8 +45,6 @@ object StaffModClient : ClientModInitializer { entries.addAfter(Items.TRIDENT, StaffMod.staffItem) } - ModelLoadingPlugin.register(::modelLoadingPlugin) - KeyBindingHelper.registerKeyBinding(ADD_REMOVE_KEYBINDING) ClientTickEvents.END_CLIENT_TICK.register(::handleKeyBindings) @@ -68,18 +60,4 @@ object StaffModClient : ClientModInitializer { registerModelPredicateProviders(ModelPredicateProviderRegistry::register) } - - private fun modelLoadingPlugin(pluginContext: ModelLoadingPlugin.Context) { - pluginContext.modifyModelBeforeBake().register(::modifyModelBeforeBake) - } - - private fun modifyModelBeforeBake(model: UnbakedModel, context: ModelModifier.BeforeBake.Context): UnbakedModel { - if (context.id().namespace != MOD_ID) return model - - return when (context.id().path) { - // TODO hardcoded paths - "staff", "item/staff_in_use" -> UnbakedFabricStaffItemModel(model as JsonUnbakedModel) // FIXME - else -> model - } - } } diff --git a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/model/BakedFabricStaffItemModel.kt b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/model/BakedFabricStaffItemModel.kt deleted file mode 100644 index d8ba1c49c..000000000 --- a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/model/BakedFabricStaffItemModel.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * AvM Staff Mod - * Copyright (c) 2023-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.fabric.item.model - -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment -import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel -import net.fabricmc.fabric.api.renderer.v1.render.RenderContext -import net.minecraft.client.render.model.BakedModel -import net.minecraft.item.ItemStack -import net.minecraft.registry.Registries -import net.minecraft.util.Identifier -import net.minecraft.util.math.random.Random -import opekope2.avm_staff.api.item.model.IStaffItemBakedModel -import opekope2.avm_staff.util.isItemInStaff -import opekope2.avm_staff.util.itemInStaff -import java.util.function.Supplier - -@Environment(EnvType.CLIENT) -class BakedFabricStaffItemModel( - original: BakedModel, - private val itemModels: Map, - private val missingModel: BakedModel -) : BakedModel by original { - override fun emitItemQuads(stack: ItemStack, randomSupplier: Supplier, context: RenderContext) { - super.emitItemQuads(stack, randomSupplier, context) - - if (!stack.isItemInStaff) return - - val itemStack = stack.itemInStaff ?: return - - val model = itemModels[Registries.ITEM.getId(itemStack.item)]?.getModel(stack) ?: missingModel - (model as FabricBakedModel).emitItemQuads(stack, randomSupplier, context) - } - - override fun isVanillaAdapter() = false -} diff --git a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/model/UnbakedFabricStaffItemModel.kt b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/model/UnbakedFabricStaffItemModel.kt deleted file mode 100644 index ec53b66ba..000000000 --- a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/model/UnbakedFabricStaffItemModel.kt +++ /dev/null @@ -1,50 +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.fabric.item.model - -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment -import net.minecraft.client.render.model.BakedModel -import net.minecraft.client.render.model.Baker -import net.minecraft.client.render.model.ModelBakeSettings -import net.minecraft.client.render.model.ModelLoader -import net.minecraft.client.render.model.json.JsonUnbakedModel -import net.minecraft.client.texture.Sprite -import net.minecraft.client.util.SpriteIdentifier -import net.minecraft.util.Identifier -import opekope2.avm_staff.api.item.model.IStaffItemBakedModel -import opekope2.avm_staff.internal.item.model.UnbakedStaffItemModel -import java.util.function.Function - -@Environment(EnvType.CLIENT) -class UnbakedFabricStaffItemModel(private val original: JsonUnbakedModel) : UnbakedStaffItemModel(original) { - override fun bake( - baker: Baker, - textureGetter: Function, - rotationContainer: ModelBakeSettings, - modelId: Identifier, - itemModels: Map - ): BakedModel? { - return BakedFabricStaffItemModel( - original.bake(baker, textureGetter, rotationContainer, modelId) ?: return null, - itemModels, - baker.bake(ModelLoader.MISSING_ID, rotationContainer)!! - ) - } -} diff --git a/ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ModelLoaderBakerImplMixin.java b/ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ModelLoaderBakerImplMixin.java deleted file mode 100644 index b8aa98105..000000000 --- a/ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ModelLoaderBakerImplMixin.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * AvM Staff Mod - * Copyright (c) 2016-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.forge; - -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import net.minecraft.client.render.model.Baker; -import net.minecraft.client.render.model.UnbakedModel; -import net.minecraft.client.render.model.json.JsonUnbakedModel; -import net.minecraft.util.Identifier; -import opekope2.avm_staff.internal.forge.item.model.UnbakedForgeStaffItemModel; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Coerce; - -import static opekope2.avm_staff.util.Constants.MOD_ID; - -// Forge geometry loaders are way more difficult, than porting a Fabric mixin -@Mixin(targets = "net/minecraft/client/render/model/ModelLoader$BakerImpl") -public class ModelLoaderBakerImplMixin { - // Change method to directly call Staff Mod instead of an exposed event - // Ignore this error, IntelliJ/mcdev is not looking at the correct jar - @WrapOperation( - method = "bake(Lnet/minecraft/util/Identifier;Lnet/minecraft/client/render/model/ModelBakeSettings;Ljava/util/function/Function;)Lnet/minecraft/client/render/model/BakedModel;", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/render/model/ModelLoader$BakerImpl;getOrLoadModel(Lnet/minecraft/util/Identifier;)Lnet/minecraft/client/render/model/UnbakedModel;" - ) - ) - private UnbakedModel modifyUnbakedModel(@Coerce Baker thiz, Identifier id, Operation original) { - UnbakedModel model = original.call(thiz, id); - if (!MOD_ID.equals(id.getNamespace())) return model; - - return switch (id.getPath()) { - // TODO hardcoded paths - case "staff", "item/staff_in_use" -> new UnbakedForgeStaffItemModel((JsonUnbakedModel) model); // FIXME - default -> model; - }; - } - - // Remove unused mixins: invokeModifyAfterBake -} diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/model/BakedForgeStaffItemModel.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/model/BakedForgeStaffItemModel.kt deleted file mode 100644 index fdb7cb8c5..000000000 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/model/BakedForgeStaffItemModel.kt +++ /dev/null @@ -1,58 +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.forge.item.model - -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.util.Identifier -import net.minecraftforge.api.distmarker.Dist -import net.minecraftforge.api.distmarker.OnlyIn -import net.minecraftforge.client.model.BakedModelWrapper -import net.minecraftforge.registries.ForgeRegistries -import opekope2.avm_staff.api.item.model.IStaffItemBakedModel -import opekope2.avm_staff.util.isItemInStaff -import opekope2.avm_staff.util.itemInStaff - -@OnlyIn(Dist.CLIENT) -class BakedForgeStaffItemModel( - original: BakedModel, - private val itemModels: Map, - private val missingModel: BakedModel -) : BakedModelWrapper(original) { - override fun applyTransform( - cameraTransformType: ModelTransformationMode, - poseStack: MatrixStack, - applyLeftHandTransform: Boolean - ): BakedModel { - // BakedModelWrapper delegates this to the original model, which returns the original model instead of this - super.applyTransform(cameraTransformType, poseStack, applyLeftHandTransform) - return this - } - - override fun getRenderPasses(stack: ItemStack, fabulous: Boolean): MutableList { - if (!stack.isItemInStaff) return mutableListOf(this) - - val itemStack = stack.itemInStaff ?: return mutableListOf(this) - - val model = itemModels[ForgeRegistries.ITEMS.getKey(itemStack.item)]?.getModel(stack) ?: missingModel - return mutableListOf(this, model) - } -} diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/model/UnbakedForgeStaffItemModel.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/model/UnbakedForgeStaffItemModel.kt deleted file mode 100644 index a0c0d16a9..000000000 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/model/UnbakedForgeStaffItemModel.kt +++ /dev/null @@ -1,50 +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.forge.item.model - -import net.minecraft.client.render.model.BakedModel -import net.minecraft.client.render.model.Baker -import net.minecraft.client.render.model.ModelBakeSettings -import net.minecraft.client.render.model.ModelLoader -import net.minecraft.client.render.model.json.JsonUnbakedModel -import net.minecraft.client.texture.Sprite -import net.minecraft.client.util.SpriteIdentifier -import net.minecraft.util.Identifier -import net.minecraftforge.api.distmarker.Dist -import net.minecraftforge.api.distmarker.OnlyIn -import opekope2.avm_staff.api.item.model.IStaffItemBakedModel -import opekope2.avm_staff.internal.item.model.UnbakedStaffItemModel -import java.util.function.Function - -@OnlyIn(Dist.CLIENT) -class UnbakedForgeStaffItemModel(private val original: JsonUnbakedModel) : UnbakedStaffItemModel(original) { - override fun bake( - baker: Baker, - textureGetter: Function, - rotationContainer: ModelBakeSettings, - modelId: Identifier, - itemModels: Map - ): BakedModel? { - return BakedForgeStaffItemModel( - original.bake(baker, original, textureGetter, rotationContainer, modelId, true) ?: return null, - itemModels, - baker.bake(ModelLoader.MISSING_ID, rotationContainer, textureGetter)!! - ) - } -} diff --git a/ForgeMod/src/main/resources/avm_staff_forge.mixins.json b/ForgeMod/src/main/resources/avm_staff_forge.mixins.json index 59b98338a..910fab075 100644 --- a/ForgeMod/src/main/resources/avm_staff_forge.mixins.json +++ b/ForgeMod/src/main/resources/avm_staff_forge.mixins.json @@ -7,8 +7,7 @@ "defaultRequire": 1 }, "client": [ - "ClientPlayerInteractionManagerMixin", - "ModelLoaderBakerImplMixin" + "ClientPlayerInteractionManagerMixin" ], "mixins": [ "ServerPlayerEntityMixin", diff --git a/NeoForgeMod/src/main/java/opekope2/avm_staff/mixin/neoforge/ModelLoaderBakerImplMixin.java b/NeoForgeMod/src/main/java/opekope2/avm_staff/mixin/neoforge/ModelLoaderBakerImplMixin.java deleted file mode 100644 index 44426b237..000000000 --- a/NeoForgeMod/src/main/java/opekope2/avm_staff/mixin/neoforge/ModelLoaderBakerImplMixin.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * AvM Staff Mod - * Copyright (c) 2016-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.neoforge; - -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import net.minecraft.client.render.model.Baker; -import net.minecraft.client.render.model.UnbakedModel; -import net.minecraft.client.render.model.json.JsonUnbakedModel; -import net.minecraft.util.Identifier; -import opekope2.avm_staff.internal.neoforge.item.model.UnbakedNeoForgeStaffItemModel; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Coerce; - -import static opekope2.avm_staff.util.Constants.MOD_ID; - -// Forge geometry loaders are way more difficult, than porting a Fabric mixin -@Mixin(targets = "net/minecraft/client/render/model/ModelLoader$BakerImpl") -public class ModelLoaderBakerImplMixin { - // Change method to directly call Staff Mod instead of an exposed event - // Ignore this error, IntelliJ/mcdev is not looking at the correct jar - @WrapOperation( - method = "bake(Lnet/minecraft/util/Identifier;Lnet/minecraft/client/render/model/ModelBakeSettings;Ljava/util/function/Function;)Lnet/minecraft/client/render/model/BakedModel;", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/render/model/ModelLoader$BakerImpl;getOrLoadModel(Lnet/minecraft/util/Identifier;)Lnet/minecraft/client/render/model/UnbakedModel;" - ) - ) - private UnbakedModel modifyUnbakedModel(@Coerce Baker thiz, Identifier id, Operation original) { - UnbakedModel model = original.call(thiz, id); - if (!MOD_ID.equals(id.getNamespace())) return model; - - return switch (id.getPath()) { - // TODO hardcoded paths - case "staff", "item/staff_in_use" -> new UnbakedNeoForgeStaffItemModel((JsonUnbakedModel) model); // FIXME - default -> model; - }; - } - - // Remove unused mixins: invokeModifyAfterBake -} diff --git a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/model/BakedNeoForgeStaffItemModel.kt b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/model/BakedNeoForgeStaffItemModel.kt deleted file mode 100644 index 7218e3f4d..000000000 --- a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/model/BakedNeoForgeStaffItemModel.kt +++ /dev/null @@ -1,58 +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.neoforge.item.model - -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 net.minecraft.util.Identifier -import net.neoforged.api.distmarker.Dist -import net.neoforged.api.distmarker.OnlyIn -import net.neoforged.neoforge.client.model.BakedModelWrapper -import opekope2.avm_staff.api.item.model.IStaffItemBakedModel -import opekope2.avm_staff.util.isItemInStaff -import opekope2.avm_staff.util.itemInStaff - -@OnlyIn(Dist.CLIENT) -class BakedNeoForgeStaffItemModel( - original: BakedModel, - private val itemModels: Map, - private val missingModel: BakedModel -) : BakedModelWrapper(original) { - override fun applyTransform( - cameraTransformType: ModelTransformationMode, - poseStack: MatrixStack, - applyLeftHandTransform: Boolean - ): BakedModel { - // BakedModelWrapper delegates this to the original model, which returns the original model instead of this - super.applyTransform(cameraTransformType, poseStack, applyLeftHandTransform) - return this - } - - override fun getRenderPasses(stack: ItemStack, fabulous: Boolean): MutableList { - if (!stack.isItemInStaff) return mutableListOf(this) - - val itemStack = stack.itemInStaff ?: return mutableListOf(this) - - val model = itemModels[Registries.ITEM.getId(itemStack.item)]?.getModel(stack) ?: missingModel - return mutableListOf(this, model) - } -} diff --git a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/model/UnbakedNeoForgeStaffItemModel.kt b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/model/UnbakedNeoForgeStaffItemModel.kt deleted file mode 100644 index 6f7ae6ae9..000000000 --- a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/model/UnbakedNeoForgeStaffItemModel.kt +++ /dev/null @@ -1,50 +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.neoforge.item.model - -import net.minecraft.client.render.model.BakedModel -import net.minecraft.client.render.model.Baker -import net.minecraft.client.render.model.ModelBakeSettings -import net.minecraft.client.render.model.ModelLoader -import net.minecraft.client.render.model.json.JsonUnbakedModel -import net.minecraft.client.texture.Sprite -import net.minecraft.client.util.SpriteIdentifier -import net.minecraft.util.Identifier -import net.neoforged.api.distmarker.Dist -import net.neoforged.api.distmarker.OnlyIn -import opekope2.avm_staff.api.item.model.IStaffItemBakedModel -import opekope2.avm_staff.internal.item.model.UnbakedStaffItemModel -import java.util.function.Function - -@OnlyIn(Dist.CLIENT) -class UnbakedNeoForgeStaffItemModel(private val original: JsonUnbakedModel) : UnbakedStaffItemModel(original) { - override fun bake( - baker: Baker, - textureGetter: Function, - rotationContainer: ModelBakeSettings, - modelId: Identifier, - itemModels: Map - ): BakedModel? { - return BakedNeoForgeStaffItemModel( - original.bake(baker, original, textureGetter, rotationContainer, modelId, true) ?: return null, - itemModels, - baker.bake(ModelLoader.MISSING_ID, rotationContainer, textureGetter)!! - ) - } -} diff --git a/NeoForgeMod/src/main/resources/avm_staff_neoforge.mixins.json b/NeoForgeMod/src/main/resources/avm_staff_neoforge.mixins.json index 8a0cf73be..9f766346d 100644 --- a/NeoForgeMod/src/main/resources/avm_staff_neoforge.mixins.json +++ b/NeoForgeMod/src/main/resources/avm_staff_neoforge.mixins.json @@ -7,8 +7,7 @@ "defaultRequire": 1 }, "client": [ - "ClientPlayerInteractionManagerMixin", - "ModelLoaderBakerImplMixin" + "ClientPlayerInteractionManagerMixin" ], "mixins": [ "ServerPlayerEntityMixin", diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt index 1100b0a54..465e97388 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt @@ -20,8 +20,6 @@ package opekope2.avm_staff.api.item import com.google.common.collect.ImmutableMultimap import com.google.common.collect.Multimap -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment import net.minecraft.advancement.criterion.Criteria import net.minecraft.entity.Entity import net.minecraft.entity.EquipmentSlot @@ -41,10 +39,8 @@ 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.item.model.IStaffItemUnbakedModel import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.attackSpeed -import java.util.function.Supplier /** * Provides functionality for a staff, when an item is inserted into it. @@ -417,9 +413,6 @@ abstract class StaffItemHandler { private val staffItemsHandlers = mutableMapOf() - @Environment(EnvType.CLIENT) - private val staffItemModelProviders = mutableMapOf>() - /** * Registers a [StaffItemHandler] for the given [item ID][staffItem]. Call this from your common mod initializer. * @@ -437,26 +430,6 @@ abstract class StaffItemHandler { return true } - /** - * Registers an unbaked model supplier for a given [item ID][staffItem]. Call this from your client mod - * initializer. - * - * @param staffItemModelSupplier The staff item's unbaked model supplier - * @return `true`, if the registration was successful, `false`, if an unbaked model supplier for the item was - * already registered - */ - @JvmStatic - @Environment(EnvType.CLIENT) - fun registerModelSupplier( - staffItem: Identifier, - staffItemModelSupplier: Supplier - ): Boolean { - if (staffItem in staffItemModelProviders) return false - - staffItemModelProviders[staffItem] = staffItemModelSupplier - return true - } - /** * Checks, if a staff item handler for the [given item][staffItem] is registered. * @@ -473,13 +446,5 @@ abstract class StaffItemHandler { */ @JvmStatic operator fun get(staffItem: Identifier): StaffItemHandler? = staffItemsHandlers[staffItem] - - /** - * @suppress - */ - @Environment(EnvType.CLIENT) - internal fun iterateStaffItemModelProviders(): Iterator>> { - return staffItemModelProviders.iterator() - } } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/IStaffItemBakedModel.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/IStaffItemBakedModel.kt deleted file mode 100644 index 7883468e4..000000000 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/IStaffItemBakedModel.kt +++ /dev/null @@ -1,35 +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.item.model - -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment -import net.minecraft.client.render.model.BakedModel -import net.minecraft.item.ItemStack - -/** - * A [BakedModel] of an item, which can be placed into the staff. - */ -@Environment(EnvType.CLIENT) -interface IStaffItemBakedModel : BakedModel { - /** - * Gets a model for the given [staff item stack][staffStack]. - */ - fun getModel(staffStack: ItemStack): BakedModel = this -} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/IStaffItemUnbakedModel.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/IStaffItemUnbakedModel.kt deleted file mode 100644 index 4e765fc5a..000000000 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/IStaffItemUnbakedModel.kt +++ /dev/null @@ -1,64 +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.item.model - -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment -import net.minecraft.client.render.model.BakedModel -import net.minecraft.client.render.model.Baker -import net.minecraft.client.render.model.ModelBakeSettings -import net.minecraft.client.render.model.UnbakedModel -import net.minecraft.client.render.model.json.Transformation -import net.minecraft.client.texture.Sprite -import net.minecraft.client.util.SpriteIdentifier -import net.minecraft.util.Identifier -import opekope2.avm_staff.api.item.StaffItemHandler -import java.util.function.Function - -/** - * An [UnbakedModel] of an item, which can be placed into a staff. - * - * @see StaffItemHandler.register - */ -@Environment(EnvType.CLIENT) -interface IStaffItemUnbakedModel : UnbakedModel { - override fun bake( - baker: Baker, - textureGetter: Function, - rotationContainer: ModelBakeSettings, - modelId: Identifier - ): BakedModel? = bake(baker, textureGetter, rotationContainer, modelId, Transformation.IDENTITY) - - /** - * Bakes the item model. - * - * @param baker The baker used to load and bake additional models - * @param textureGetter Function to get a [Sprite] from a [SpriteIdentifier] - * @param rotationContainer The model rotation container - * @param modelId The identifier of the staff model being baked. This is not the ID of the item in the staff - * @param transformation The transformation, which transforms the item into the staff - */ - fun bake( - baker: Baker, - textureGetter: Function, - rotationContainer: ModelBakeSettings, - modelId: Identifier, - transformation: Transformation - ): IStaffItemBakedModel? -} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/StaffItemBakedModel.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/StaffItemBakedModel.kt deleted file mode 100644 index 8effd7b5d..000000000 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/StaffItemBakedModel.kt +++ /dev/null @@ -1,31 +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.item.model - -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment -import net.minecraft.client.render.model.BakedModel - -/** - * Default implementation of [IStaffItemBakedModel], which returns itself as a model for each block state. - * - * @param blockStateModel The model of a block state. [BakedModel] implementation is delegated to it - */ -@Environment(EnvType.CLIENT) -class StaffItemBakedModel(blockStateModel: BakedModel) : BakedModel by blockStateModel, IStaffItemBakedModel diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/UnbakedBlockStateModel.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/UnbakedBlockStateModel.kt deleted file mode 100644 index ee8075a30..000000000 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/UnbakedBlockStateModel.kt +++ /dev/null @@ -1,61 +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.item.model - -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment -import net.minecraft.block.BlockState -import net.minecraft.client.render.block.BlockModels -import net.minecraft.client.render.model.Baker -import net.minecraft.client.render.model.ModelBakeSettings -import net.minecraft.client.render.model.UnbakedModel -import net.minecraft.client.render.model.json.Transformation -import net.minecraft.client.texture.Sprite -import net.minecraft.client.util.SpriteIdentifier -import net.minecraft.util.Identifier -import opekope2.avm_staff.util.transform -import java.util.function.Function - -/** - * Default implementation of [IStaffItemUnbakedModel]. - * - * @param blockState The block state to bake - */ -@Environment(EnvType.CLIENT) -class UnbakedBlockStateModel(private val blockState: BlockState) : IStaffItemUnbakedModel { - private val blockStateId = BlockModels.getModelId(blockState) - private val dependencies = setOf(blockStateId) - - override fun getModelDependencies() = dependencies - - override fun setParents(modelLoader: Function?) { - } - - override fun bake( - baker: Baker, - textureGetter: Function, - rotationContainer: ModelBakeSettings, - modelId: Identifier, - transformation: Transformation - ): IStaffItemBakedModel? { - val baked = baker.bake(blockStateId, rotationContainer) ?: return null - - return StaffItemBakedModel(baked.transform(blockState, transformation, textureGetter)) - } -} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/item/model/UnbakedStaffItemModel.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/item/model/UnbakedStaffItemModel.kt deleted file mode 100644 index 6ba3a765b..000000000 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/item/model/UnbakedStaffItemModel.kt +++ /dev/null @@ -1,60 +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.item.model - -import net.minecraft.client.render.model.BakedModel -import net.minecraft.client.render.model.Baker -import net.minecraft.client.render.model.ModelBakeSettings -import net.minecraft.client.render.model.UnbakedModel -import net.minecraft.client.render.model.json.JsonUnbakedModel -import net.minecraft.client.texture.Sprite -import net.minecraft.client.util.SpriteIdentifier -import net.minecraft.util.Identifier -import opekope2.avm_staff.api.item.StaffItemHandler -import opekope2.avm_staff.api.item.model.IStaffItemBakedModel -import opekope2.avm_staff.util.TRANSFORM_INTO_STAFF -import java.util.function.Function - -abstract class UnbakedStaffItemModel(private val original: JsonUnbakedModel) : UnbakedModel by original { - abstract fun bake( - baker: Baker, - textureGetter: Function, - rotationContainer: ModelBakeSettings, - modelId: Identifier, - itemModels: Map - ): BakedModel? - - override fun bake( - baker: Baker, - textureGetter: Function, - rotationContainer: ModelBakeSettings, - modelId: Identifier - ): BakedModel? { - val itemModels = mutableMapOf() - - for ((id, modelSupplier) in StaffItemHandler.iterateStaffItemModelProviders()) { - val unbaked = modelSupplier.get() - // TODO cache baked model, because it will be baked each time UnbakedStaffItemModel is baked. Maybe use resource loader - val baked = unbaked.bake(baker, textureGetter, rotationContainer, modelId, TRANSFORM_INTO_STAFF) - itemModels[id] = baked ?: continue - } - - return bake(baker, textureGetter, rotationContainer, modelId, itemModels) - } -} From 7e512c48d4598e5fa2f012050f3c760d97479987 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 11 May 2024 02:59:29 +0200 Subject: [PATCH 014/128] Remove redundant model utilities --- .../opekope2/avm_staff/util/ModelUtil.kt | 143 ------------------ 1 file changed, 143 deletions(-) delete mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/util/ModelUtil.kt diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/ModelUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/ModelUtil.kt deleted file mode 100644 index 273ec783d..000000000 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/ModelUtil.kt +++ /dev/null @@ -1,143 +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("ModelUtil") - -package opekope2.avm_staff.util - -import net.minecraft.block.BlockState -import net.minecraft.client.model.ModelPart -import net.minecraft.client.render.LightmapTextureManager -import net.minecraft.client.render.model.BakedModel -import net.minecraft.client.render.model.BakedQuad -import net.minecraft.client.render.model.BasicBakedModel -import net.minecraft.client.render.model.UnbakedModel -import net.minecraft.client.render.model.json.Transformation -import net.minecraft.client.texture.MissingSprite -import net.minecraft.client.texture.Sprite -import net.minecraft.client.texture.SpriteAtlasTexture -import net.minecraft.client.util.SpriteIdentifier -import net.minecraft.client.util.math.MatrixStack -import net.minecraft.util.math.Direction -import net.minecraft.util.math.random.Random -import opekope2.avm_staff.internal.platform.getQuadBakerVertexConsumer -import org.joml.Vector3f -import java.util.function.Consumer -import java.util.function.Function - -/** - * The transform of an item in the default position of the staff. - */ -@JvmField -val TRANSFORM_INTO_STAFF = Transformation( - Vector3f(), - Vector3f((16f - 7f) / 16f / 2f, 22f / 16f, (16f - 7f) / 16f / 2f), - Vector3f(7f / 16f) -) - -private val cullFaces = arrayOf(*Direction.values(), null) - -/** - * Creates a new transformed model. - * - * @param blockState Passed to [BakedModel.getQuads] - * @param transformation The transformation to apply to the model - * @param textureGetter Function from [UnbakedModel.bake] used to obtain the missing sprite - */ -fun BakedModel.transform( - blockState: BlockState?, - transformation: Transformation, - textureGetter: Function -): BakedModel { - val matrices = MatrixStack() - transformation.apply(false, matrices) - val random = Random.create() - val missingSprite = textureGetter.apply( - SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, MissingSprite.getMissingSpriteId()) - ) - - val quads = mutableMapOf>() - for (cullFace in cullFaces) { - val cullQuads = quads.getOrPut(cullFace, ::mutableListOf) - val vertexConsumer = getQuadBakerVertexConsumer(missingSprite, cullQuads::add) - - random.setSeed(42L) - for (quad in getQuads(blockState, cullFace, random)) { - vertexConsumer.sprite = quad.sprite - vertexConsumer.quad( - matrices.peek(), - quad, - 1f, - 1f, - 1f, - LightmapTextureManager.pack(blockState?.luminance ?: 0, 0), - 0 // Overlay is ignored - ) - } - } - - return BasicBakedModel( - quads.remove(null)!!, - quads, - useAmbientOcclusion(), - isSideLit, - hasDepth(), - particleSprite, - this.transformation, - overrides - ) -} - -/** - * Renders the model to [BakedQuad]s. - * - * @param sprite The sprite of the model part - * @param luminance The luminance of the model. Must be in range `[0,15]` - * @param transformation The transformation to apply to the model part while rendering - */ -@JvmOverloads -fun ModelPart.getBakedQuads( - sprite: Sprite, - transformation: Transformation = Transformation.IDENTITY, - luminance: Int = 0 -): MutableList { - val quads = mutableListOf() - getBakedQuads(quads::add, sprite, transformation, luminance) - return quads -} - -/** - * Renders the model to [BakedQuad]s. - * - * @param bakedQuadConsumer The consumer of the output quads - * @param sprite The sprite of the model part - * @param transformation The transformation to apply to the model part while rendering - * @param luminance The luminance of the model. Must be in range `[0,15]` - */ -@JvmOverloads -fun ModelPart.getBakedQuads( - bakedQuadConsumer: Consumer, - sprite: Sprite, - transformation: Transformation = Transformation.IDENTITY, - luminance: Int = 0 -) { - val vertexConsumer = sprite.getTextureSpecificVertexConsumer(getQuadBakerVertexConsumer(sprite, bakedQuadConsumer)) - val matrices = MatrixStack() - transformation.apply(false, matrices) - render(matrices, vertexConsumer, LightmapTextureManager.pack(luminance, 0), 0) // Overlay is ignored -} From d184cd4ff10f9a9ff902ea4a25961ff2de90d3ac Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 11 May 2024 03:01:35 +0200 Subject: [PATCH 015/128] Remove redundant RenderPlatform --- .../platform/fabric/RenderPlatformImpl.kt | 91 ------------------- .../platform/forge/RenderPlatformImpl.kt | 50 ---------- .../platform/neoforge/RenderPlatformImpl.kt | 50 ---------- .../internal/platform/RenderPlatform.kt | 33 ------- 4 files changed, 224 deletions(-) delete mode 100644 FabricMod/src/main/kotlin/opekope2/avm_staff/internal/platform/fabric/RenderPlatformImpl.kt delete mode 100644 ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/platform/forge/RenderPlatformImpl.kt delete mode 100644 NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/platform/neoforge/RenderPlatformImpl.kt delete mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/internal/platform/RenderPlatform.kt diff --git a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/platform/fabric/RenderPlatformImpl.kt b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/platform/fabric/RenderPlatformImpl.kt deleted file mode 100644 index ccbceffbc..000000000 --- a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/platform/fabric/RenderPlatformImpl.kt +++ /dev/null @@ -1,91 +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("RenderPlatformImpl") - -package opekope2.avm_staff.internal.platform.fabric - -import net.fabricmc.fabric.api.renderer.v1.RendererAccess -import net.minecraft.client.render.VertexConsumer -import net.minecraft.client.render.model.BakedQuad -import net.minecraft.client.texture.Sprite -import opekope2.avm_staff.api.render.IQuadBakerVertexConsumer -import java.util.function.Consumer - -fun getQuadBakerVertexConsumer(sprite: Sprite, bakedQuadConsumer: Consumer): IQuadBakerVertexConsumer { - return FabricQuadBakerVertexConsumer(sprite, bakedQuadConsumer) -} - -private class FabricQuadBakerVertexConsumer( - override var sprite: Sprite, - private val bakedQuadConsumer: Consumer -) : IQuadBakerVertexConsumer { - private val meshBuilder = renderer.meshBuilder() - private var emitter = meshBuilder.emitter - private var vertex = 0 - - override fun vertex(x: Double, y: Double, z: Double): VertexConsumer { - emitter.pos(vertex, x.toFloat(), y.toFloat(), z.toFloat()) - return this - } - - override fun color(red: Int, green: Int, blue: Int, alpha: Int): VertexConsumer { - emitter.color(vertex, (alpha shl 24) or (red shl 16) or (green shl 8) or blue) - return this - } - - override fun texture(u: Float, v: Float): VertexConsumer { - emitter.uv(vertex, u, v) - return this - } - - override fun overlay(u: Int, v: Int): VertexConsumer { - // Not supported by Fabric Rendering API - return this - } - - override fun light(u: Int, v: Int): VertexConsumer { - emitter.lightmap(vertex, u or (v shl 16)) - return this - } - - override fun normal(x: Float, y: Float, z: Float): VertexConsumer { - emitter.normal(vertex, x, y, z) - return this - } - - override fun next() { - if (++vertex != 4) return - - bakedQuadConsumer.accept(emitter.toBakedQuad(sprite)) - - vertex = 0 - emitter = meshBuilder.emitter - } - - override fun fixedColor(red: Int, green: Int, blue: Int, alpha: Int) { - } - - override fun unfixColor() { - } - - private companion object { - private val renderer = RendererAccess.INSTANCE.renderer - ?: throw IllegalStateException("No Fabric renderer is available") - } -} diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/platform/forge/RenderPlatformImpl.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/platform/forge/RenderPlatformImpl.kt deleted file mode 100644 index d85a36465..000000000 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/platform/forge/RenderPlatformImpl.kt +++ /dev/null @@ -1,50 +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("RenderPlatformImpl") - -package opekope2.avm_staff.internal.platform.forge - -import net.minecraft.client.render.VertexConsumer -import net.minecraft.client.render.model.BakedQuad -import net.minecraft.client.texture.Sprite -import net.minecraftforge.client.model.pipeline.QuadBakingVertexConsumer -import opekope2.avm_staff.api.render.IQuadBakerVertexConsumer -import java.util.function.Consumer - -fun getQuadBakerVertexConsumer(sprite: Sprite, bakedQuadConsumer: Consumer): IQuadBakerVertexConsumer { - return ForgeQuadBakerVertexConsumer(QuadBakingVertexConsumer(bakedQuadConsumer), sprite) -} - -private class ForgeQuadBakerVertexConsumer(private val wrapped: QuadBakingVertexConsumer, sprite: Sprite) : - VertexConsumer by wrapped, IQuadBakerVertexConsumer { - override var sprite: Sprite = sprite - set(value) { - field = value - wrapped.setSprite(value) - } - - init { - this.sprite = sprite // Call the setter instead of setting the field - } - - override fun overlay(u: Int, v: Int): VertexConsumer { - // Not supported by Fabric Rendering API, override as NO-OP for parity - return this - } -} diff --git a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/platform/neoforge/RenderPlatformImpl.kt b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/platform/neoforge/RenderPlatformImpl.kt deleted file mode 100644 index 7eeb568e1..000000000 --- a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/platform/neoforge/RenderPlatformImpl.kt +++ /dev/null @@ -1,50 +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("RenderPlatformImpl") - -package opekope2.avm_staff.internal.platform.neoforge - -import net.minecraft.client.render.VertexConsumer -import net.minecraft.client.render.model.BakedQuad -import net.minecraft.client.texture.Sprite -import net.neoforged.neoforge.client.model.pipeline.QuadBakingVertexConsumer -import opekope2.avm_staff.api.render.IQuadBakerVertexConsumer -import java.util.function.Consumer - -fun getQuadBakerVertexConsumer(sprite: Sprite, bakedQuadConsumer: Consumer): IQuadBakerVertexConsumer { - return ForgeQuadBakerVertexConsumer(QuadBakingVertexConsumer(bakedQuadConsumer), sprite) -} - -private class ForgeQuadBakerVertexConsumer(private val wrapped: QuadBakingVertexConsumer, sprite: Sprite) : - VertexConsumer by wrapped, IQuadBakerVertexConsumer { - override var sprite: Sprite = sprite - set(value) { - field = value - wrapped.setSprite(value) - } - - init { - this.sprite = sprite // Call the setter instead of setting the field - } - - override fun overlay(u: Int, v: Int): VertexConsumer { - // Not supported by Fabric Rendering API, override as NO-OP for parity - return this - } -} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/platform/RenderPlatform.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/platform/RenderPlatform.kt deleted file mode 100644 index 85addd5eb..000000000 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/platform/RenderPlatform.kt +++ /dev/null @@ -1,33 +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("RenderPlatform") - -package opekope2.avm_staff.internal.platform - -import dev.architectury.injectables.annotations.ExpectPlatform -import net.minecraft.client.render.model.BakedQuad -import net.minecraft.client.texture.Sprite -import opekope2.avm_staff.api.render.IQuadBakerVertexConsumer -import java.util.function.Consumer - -@ExpectPlatform -@Suppress("UNUSED_PARAMETER") -fun getQuadBakerVertexConsumer(sprite: Sprite, bakedQuadConsumer: Consumer): IQuadBakerVertexConsumer { - throw AssertionError() -} From 30a9ec03943acd14682b94fc14da5364d1f502a4 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 13 May 2024 00:26:51 +0200 Subject: [PATCH 016/128] Prefix IImpactTnt methods with staffMod$ Provide better Kotlin integration via extension property --- .../avm_staff/api/entity/IImpactTnt.java | 8 ++-- .../avm_staff/mixin/TntEntityMixin.java | 12 +++--- .../avm_staff/api/entity/ImpactTntUtil.kt | 38 +++++++++++++++++++ .../internal/staff_item_handler/TntHandler.kt | 5 +-- 4 files changed, 50 insertions(+), 13 deletions(-) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntUtil.kt diff --git a/StaffMod/src/main/java/opekope2/avm_staff/api/entity/IImpactTnt.java b/StaffMod/src/main/java/opekope2/avm_staff/api/entity/IImpactTnt.java index b842cfc7a..541598196 100644 --- a/StaffMod/src/main/java/opekope2/avm_staff/api/entity/IImpactTnt.java +++ b/StaffMod/src/main/java/opekope2/avm_staff/api/entity/IImpactTnt.java @@ -28,16 +28,16 @@ */ public interface IImpactTnt { /** - * Returns if the current TNT explodes, when it collides. + * Returns if the current TNT explodes, when it collides with a block or entity. */ - boolean explodesOnImpact(); + boolean staffMod$explodesOnImpact(); /** - * Configures the current TNT to explode or not, when it collides. + * Configures the current TNT to explode or not, when it collides with a block or entity. * * @param explode Whether to explode on collision */ - void explodeOnImpact(boolean explode); + void staffMod$explodeOnImpact(boolean explode); /** * NBT Key for TNT's explodes on impact property. diff --git a/StaffMod/src/main/java/opekope2/avm_staff/mixin/TntEntityMixin.java b/StaffMod/src/main/java/opekope2/avm_staff/mixin/TntEntityMixin.java index e369e74e0..6a314900e 100644 --- a/StaffMod/src/main/java/opekope2/avm_staff/mixin/TntEntityMixin.java +++ b/StaffMod/src/main/java/opekope2/avm_staff/mixin/TntEntityMixin.java @@ -49,13 +49,13 @@ private void initDataTracker(CallbackInfo ci) { @Inject(method = "writeCustomDataToNbt", at = @At("TAIL")) private void writeCustomDataToNbt(NbtCompound nbt, CallbackInfo ci) { - nbt.putBoolean(EXPLODES_ON_IMPACT_NBT_KEY, explodesOnImpact()); + nbt.putBoolean(EXPLODES_ON_IMPACT_NBT_KEY, staffMod$explodesOnImpact()); } @Inject(method = "readCustomDataFromNbt", at = @At("TAIL")) private void readCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) { if (nbt.contains(EXPLODES_ON_IMPACT_NBT_KEY, NbtElement.BYTE_TYPE)) { - explodeOnImpact(nbt.getBoolean(EXPLODES_ON_IMPACT_NBT_KEY)); + staffMod$explodeOnImpact(nbt.getBoolean(EXPLODES_ON_IMPACT_NBT_KEY)); } } @@ -68,7 +68,7 @@ private void readCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) { ) ) private void explodeOnImpact(CallbackInfo ci) { - if (!explodesOnImpact()) return; + if (!staffMod$explodesOnImpact()) return; boolean explode = horizontalCollision || verticalCollision; if (!explode) { @@ -76,7 +76,7 @@ private void explodeOnImpact(CallbackInfo ci) { explode = !collisions.isEmpty(); for (Entity collider : collisions) { - if (collider instanceof TntEntity tnt && ((IImpactTnt) tnt).explodesOnImpact()) { + if (collider instanceof TntEntity tnt && ((IImpactTnt) tnt).staffMod$explodesOnImpact()) { // Force explode other TNT, because the current TNT gets discarded before the other TNT gets processed tnt.setFuse(0); } @@ -93,12 +93,12 @@ private void explodeOnImpact(CallbackInfo ci) { } @Override - public boolean explodesOnImpact() { + public boolean staffMod$explodesOnImpact() { return dataTracker.get(EXPLODES_ON_IMPACT); } @Override - public void explodeOnImpact(boolean explode) { + public void staffMod$explodeOnImpact(boolean explode) { dataTracker.set(EXPLODES_ON_IMPACT, explode); } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntUtil.kt new file mode 100644 index 000000000..a07c379cf --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntUtil.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 . + */ + +@file: JvmSynthetic + +package opekope2.avm_staff.api.entity + +import net.minecraft.entity.TntEntity + +/** + * Kotlin utility to get or set a TNT to explode when it collides with a block or entity. + * + * @see IImpactTnt + */ +inline var TntEntity.explodesOnImpact: Boolean + get() { + this as IImpactTnt + return `staffMod$explodesOnImpact`() + } + set(value) { + this as IImpactTnt + `staffMod$explodeOnImpact`(value) + } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/TntHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/TntHandler.kt index f1113e73f..1d9a9b073 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/TntHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/TntHandler.kt @@ -28,7 +28,7 @@ import net.minecraft.util.ActionResult import net.minecraft.util.Hand import net.minecraft.world.World import net.minecraft.world.event.GameEvent -import opekope2.avm_staff.api.entity.IImpactTnt +import opekope2.avm_staff.api.entity.explodesOnImpact import opekope2.avm_staff.api.item.StaffItemHandler import opekope2.avm_staff.util.* @@ -48,8 +48,7 @@ class TntHandler : StaffItemHandler() { world.spawnEntity( TntEntity(world, x, y, z, attacker).apply { velocity = attacker.rotationVector + attacker.velocity - @Suppress("KotlinConstantConditions") // IImpactTnt is ducked into TntEntity - (this as IImpactTnt).explodeOnImpact(true) + explodesOnImpact = true world.playSound(null, x, y, z, SoundEvents.ENTITY_TNT_PRIMED, SoundCategory.BLOCKS, 1.0f, 1.0f) world.emitGameEvent(attacker, GameEvent.PRIME_FUSE, pos) } From f488fbd1402977e1e389f597f23bde57049ea492 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 13 May 2024 00:41:00 +0200 Subject: [PATCH 017/128] Add option to add temporary data to active item --- .../api/item/IActiveItemTempDataHolder.java | 39 +++++++++++++++++++ .../avm_staff/mixin/LivingEntityMixin.java | 27 ++++++++++++- .../api/item/ActiveItemTempDataHolderUtil.kt | 39 +++++++++++++++++++ 3 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 StaffMod/src/main/java/opekope2/avm_staff/api/item/IActiveItemTempDataHolder.java create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/ActiveItemTempDataHolderUtil.kt diff --git a/StaffMod/src/main/java/opekope2/avm_staff/api/item/IActiveItemTempDataHolder.java b/StaffMod/src/main/java/opekope2/avm_staff/api/item/IActiveItemTempDataHolder.java new file mode 100644 index 000000000..5728da9a5 --- /dev/null +++ b/StaffMod/src/main/java/opekope2/avm_staff/api/item/IActiveItemTempDataHolder.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.api.item; + +import org.jetbrains.annotations.Nullable; + +/** + * Holder of a temporary data while an entity is using an item. To be used by the item class being used on server side. + */ +public interface IActiveItemTempDataHolder { + /** + * Gets the temporary data associated with the entity. + */ + @Nullable + Object staffMod$getActiveItemTempData(); + + /** + * Associates a temporary data with an entity, overwriting previous data. + * + * @param value The data to associate + */ + void staffMod$setActiveItemTempData(@Nullable Object value); +} diff --git a/StaffMod/src/main/java/opekope2/avm_staff/mixin/LivingEntityMixin.java b/StaffMod/src/main/java/opekope2/avm_staff/mixin/LivingEntityMixin.java index d68ba9481..2fc3b7260 100644 --- a/StaffMod/src/main/java/opekope2/avm_staff/mixin/LivingEntityMixin.java +++ b/StaffMod/src/main/java/opekope2/avm_staff/mixin/LivingEntityMixin.java @@ -21,17 +21,25 @@ import net.minecraft.entity.LivingEntity; import net.minecraft.item.ItemStack; import opekope2.avm_staff.IStaffMod; +import opekope2.avm_staff.api.item.IActiveItemTempDataHolder; import opekope2.avm_staff.api.item.IDisablesShield; import opekope2.avm_staff.api.item.StaffItemHandler; import opekope2.avm_staff.util.StaffUtil; +import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(LivingEntity.class) -public abstract class LivingEntityMixin { +public abstract class LivingEntityMixin implements IActiveItemTempDataHolder { + @Unique + @Nullable + private Object staffMod$activeItemTempData; + @Shadow public abstract ItemStack getMainHandStack(); @@ -48,4 +56,21 @@ public void disableShield(CallbackInfoReturnable cir) { cir.setReturnValue(true); } } + + // Only invoke on server + @Inject(method = "clearActiveItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;setLivingFlag(IZ)V")) + public void clearActiveItem(CallbackInfo ci) { + staffMod$setActiveItemTempData(null); + } + + @Nullable + @Override + public Object staffMod$getActiveItemTempData() { + return staffMod$activeItemTempData; + } + + @Override + public void staffMod$setActiveItemTempData(@Nullable Object value) { + staffMod$activeItemTempData = value; + } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/ActiveItemTempDataHolderUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/ActiveItemTempDataHolderUtil.kt new file mode 100644 index 000000000..79d7a4c2c --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/ActiveItemTempDataHolderUtil.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 . + */ + +@file: JvmSynthetic + +package opekope2.avm_staff.api.item + +import net.minecraft.entity.LivingEntity + +/** + * Kotlin utility to get or set the temporary data associated with an entity. To be used by the item class being used on + * server side. + * + * @see IActiveItemTempDataHolder + */ +inline var LivingEntity.activeItemTempData: Any? + get() { + this as IActiveItemTempDataHolder + return `staffMod$getActiveItemTempData`() + } + set(value) { + this as IActiveItemTempDataHolder + `staffMod$setActiveItemTempData`(value) + } From 79fed60f8cd01767cef23b90680ea76dc6c88e8a Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 13 May 2024 00:42:58 +0200 Subject: [PATCH 018/128] Fix furnace staff rendering & packet spam --- .../staff_item_handler/FurnaceHandler.kt | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt index c736d04c1..96ebe3091 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt @@ -49,6 +49,7 @@ import net.minecraft.util.TypedActionResult import net.minecraft.util.math.Box import net.minecraft.world.World import opekope2.avm_staff.api.item.StaffItemHandler +import opekope2.avm_staff.api.item.activeItemTempData import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer import opekope2.avm_staff.mixin.IAbstractFurnaceBlockEntityMixin @@ -67,9 +68,11 @@ class FurnaceHandler( user: PlayerEntity, hand: Hand ): TypedActionResult { - staffStack.getOrCreateNbt().apply { - putBoolean(LIT_KEY, true) - putInt(BURN_TIME_KEY, 0) + if (world.isClient) { + // Visual only + staffStack.orCreateNbt.putBoolean(LIT_KEY, true) + } else { + user.activeItemTempData = BurnTimeTempData(0) } user.setCurrentHand(hand) @@ -86,12 +89,11 @@ class FurnaceHandler( return } - val nbt = staffStack.getOrCreateNbt() - var burnTime = nbt.getInt(BURN_TIME_KEY) - nbt.putInt(BURN_TIME_KEY, burnTime + 1) + val burnTimeData = user.activeItemTempData as BurnTimeTempData + burnTimeData.burnTime++ val stackToSmelt = itemToSmelt?.stack ?: return - if (burnTime < stackToSmelt.count) return + if (burnTimeData.burnTime < stackToSmelt.count) return val inventory = ItemEntityInventory(itemToSmelt) val recipe = world.recipeManager.getFirstMatch(recipeType, inventory, world).getOrNull()?.value ?: return @@ -105,11 +107,9 @@ class FurnaceHandler( stackToSmelt.count, recipe.experience ) - - burnTime -= stackToSmelt.count - nbt.putInt(BURN_TIME_KEY, burnTime + 1) - itemToSmelt.discard() + + burnTimeData.burnTime -= stackToSmelt.count } private fun findItemToSmelt( @@ -139,9 +139,11 @@ class FurnaceHandler( } override fun onStoppedUsing(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - staffStack.getOrCreateNbt().apply { - remove(LIT_KEY) - remove(BURN_TIME_KEY) + if (world.isClient) { + // Visual only + staffStack.nbt?.remove(LIT_KEY) + } else { + user.activeItemTempData = null } } @@ -201,6 +203,9 @@ class FurnaceHandler( } } + @Environment(EnvType.CLIENT) + private data class BurnTimeTempData(var burnTime: Int) + private class ItemEntityInventory(private val itemEntity: ItemEntity) : SingleStackInventory { override fun getStack(): ItemStack = itemEntity.stack @@ -215,7 +220,6 @@ class FurnaceHandler( companion object { private const val LIT_KEY = "Lit" - private const val BURN_TIME_KEY = "BurnTime" private val SMELTING_VOLUME = Box(-0.5, -0.5, -0.5, 0.5, 0.5, 0.5).contract(0.25 / 2) private val ATTRIBUTE_MODIFIERS = ImmutableMultimap.of( EntityAttributes.GENERIC_ATTACK_DAMAGE, From 5ec3e481eaf507b1d07b0bf2c143e04352282873 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 13 May 2024 02:43:13 +0200 Subject: [PATCH 019/128] Fix jittery staff movement in 3rd person while holding RMB --- .../avm_staff/mixin/BipedEntityModelMixin.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) 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 ba0e666ee..5f1205421 100644 --- a/StaffMod/src/main/java/opekope2/avm_staff/mixin/BipedEntityModelMixin.java +++ b/StaffMod/src/main/java/opekope2/avm_staff/mixin/BipedEntityModelMixin.java @@ -25,7 +25,6 @@ import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -46,24 +45,23 @@ public abstract class BipedEntityModelMixin { @Final public ModelPart rightArm; - @Unique - private float staffMod$degToRad(float degrees) { - return degrees * (float) Math.PI / 180f; - } + @Shadow + @Final + public ModelPart head; @Inject(method = "positionLeftArm", at = @At("TAIL")) private void positionLeftArm(LivingEntity entity, CallbackInfo ci) { if (leftArmPose == BipedEntityModel.ArmPose.ITEM && entity.getActiveItem().isIn(IStaffMod.get().getStaffsTag())) { - leftArm.yaw = staffMod$degToRad(entity.headYaw - entity.bodyYaw); - leftArm.pitch = staffMod$degToRad(entity.getPitch() - 90f); + leftArm.yaw = head.yaw; + leftArm.pitch = head.pitch - 0.5f * (float) Math.PI; } } @Inject(method = "positionRightArm", at = @At("TAIL")) private void positionRightArm(LivingEntity entity, CallbackInfo ci) { if (rightArmPose == BipedEntityModel.ArmPose.ITEM && entity.getActiveItem().isIn(IStaffMod.get().getStaffsTag())) { - rightArm.yaw = staffMod$degToRad(entity.headYaw - entity.bodyYaw); - rightArm.pitch = staffMod$degToRad(entity.getPitch() - 90f); + rightArm.yaw = head.yaw; + rightArm.pitch = head.pitch - 0.5f * (float) Math.PI; } } } From 02c11185ca5cd85594ec426bb5a538cae5460941 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 13 May 2024 03:08:26 +0200 Subject: [PATCH 020/128] Make StaffRenderer singleton as per Neo/Forge docs --- .../api/item/renderer/StaffRenderer.kt | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) 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 7830d344e..b1fcbf381 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 @@ -24,7 +24,6 @@ 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 -import net.minecraft.item.Item import net.minecraft.item.ItemStack import net.minecraft.registry.Registries import opekope2.avm_staff.internal.model.HEAD_SEED @@ -35,11 +34,9 @@ import opekope2.avm_staff.util.push /** * Builtin model item renderer for staffs. - * - * @param getStaffItem A supplier for the staff item to be rendered */ @Environment(EnvType.CLIENT) -class StaffRenderer(private val getStaffItem: () -> Item) { +object StaffRenderer { /** * Renders the staff. * @@ -87,7 +84,7 @@ class StaffRenderer(private val getStaffItem: () -> Item) { // Head push { translate(0.0, 16.0 / 16.0, 0.0) - renderPart(this, vertexConsumers, light, overlay, HEAD_SEED) + renderPart(staffStack, this, vertexConsumers, light, overlay, HEAD_SEED) // Item staffStack.itemInStaff?.let { itemInStaff -> @@ -98,13 +95,13 @@ class StaffRenderer(private val getStaffItem: () -> Item) { // Rod (top) push { translate(0.0, 2.0 / 16.0, 0.0) - renderPart(this, vertexConsumers, light, overlay, ROD_TOP_SEED) + renderPart(staffStack, this, vertexConsumers, light, overlay, ROD_TOP_SEED) } // Rod (bottom) push { translate(0.0, -12.0 / 16.0, 0.0) - renderPart(this, vertexConsumers, light, overlay, ROD_BOTTOM_SEED) + renderPart(staffStack, this, vertexConsumers, light, overlay, ROD_BOTTOM_SEED) } } } @@ -122,7 +119,7 @@ class StaffRenderer(private val getStaffItem: () -> Item) { // Head push { - renderPart(this, vertexConsumers, light, overlay, HEAD_SEED) + renderPart(staffStack, this, vertexConsumers, light, overlay, HEAD_SEED) // Item staffStack.itemInStaff?.let { itemInStaff -> @@ -146,7 +143,7 @@ class StaffRenderer(private val getStaffItem: () -> Item) { // Head push { translate(0.0, 9.0 / 16.0, 0.0) - renderPart(this, vertexConsumers, light, overlay, HEAD_SEED) + renderPart(staffStack, this, vertexConsumers, light, overlay, HEAD_SEED) // Item staffStack.itemInStaff?.let { itemInStaff -> @@ -157,7 +154,7 @@ class StaffRenderer(private val getStaffItem: () -> Item) { // Rod (top) push { translate(0.0, -5.0 / 16.0, 0.0) - renderPart(this, vertexConsumers, light, overlay, ROD_TOP_SEED) + renderPart(staffStack, this, vertexConsumers, light, overlay, ROD_TOP_SEED) } } } @@ -188,6 +185,7 @@ class StaffRenderer(private val getStaffItem: () -> Item) { } private fun renderPart( + staffStack: ItemStack, matrices: MatrixStack, vertexConsumers: VertexConsumerProvider, light: Int, @@ -196,15 +194,14 @@ class StaffRenderer(private val getStaffItem: () -> Item) { ) { val itemRenderer = MinecraftClient.getInstance().itemRenderer val modelManager = MinecraftClient.getInstance().bakedModelManager - val item = getStaffItem().defaultStack - var model = itemRenderer.getModel(item, null, null, partSeed) + var model = itemRenderer.getModel(staffStack, null, null, partSeed) if (model.isBuiltin) { model = modelManager.missingModel } itemRenderer.renderItem( - item, ModelTransformationMode.NONE, false, matrices, vertexConsumers, light, overlay, model + staffStack, ModelTransformationMode.NONE, false, matrices, vertexConsumers, light, overlay, model ) } } From 327edba2dafe2bf40516c382f8596a437a1126c1 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 14 May 2024 18:30:59 +0200 Subject: [PATCH 021/128] Move StaffModPlatform one package up Also thanks git for being retarded with rename detection --- .../avm_staff/internal/fabric}/StaffModPlatformImpl.kt | 3 +-- .../opekope2/avm_staff/internal/forge}/StaffModPlatformImpl.kt | 3 +-- .../internal/{platform => }/neoforge/StaffModPlatformImpl.kt | 3 +-- StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt | 2 +- .../avm_staff/internal/{platform => }/StaffModPlatform.kt | 2 +- 5 files changed, 5 insertions(+), 8 deletions(-) rename {ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/platform/forge => FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric}/StaffModPlatformImpl.kt (89%) rename {FabricMod/src/main/kotlin/opekope2/avm_staff/internal/platform/fabric => ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge}/StaffModPlatformImpl.kt (88%) rename NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/{platform => }/neoforge/StaffModPlatformImpl.kt (88%) rename StaffMod/src/main/kotlin/opekope2/avm_staff/internal/{platform => }/StaffModPlatform.kt (95%) diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/platform/forge/StaffModPlatformImpl.kt b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModPlatformImpl.kt similarity index 89% rename from ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/platform/forge/StaffModPlatformImpl.kt rename to FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModPlatformImpl.kt index df3e0f312..90ddeee73 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/platform/forge/StaffModPlatformImpl.kt +++ b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModPlatformImpl.kt @@ -18,9 +18,8 @@ @file: JvmName("StaffModPlatformImpl") -package opekope2.avm_staff.internal.platform.forge +package opekope2.avm_staff.internal.fabric import opekope2.avm_staff.IStaffMod -import opekope2.avm_staff.internal.forge.StaffMod fun getStaffMod(): IStaffMod = StaffMod diff --git a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/platform/fabric/StaffModPlatformImpl.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModPlatformImpl.kt similarity index 88% rename from FabricMod/src/main/kotlin/opekope2/avm_staff/internal/platform/fabric/StaffModPlatformImpl.kt rename to ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModPlatformImpl.kt index eec850632..7a98cbc94 100644 --- a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/platform/fabric/StaffModPlatformImpl.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModPlatformImpl.kt @@ -18,9 +18,8 @@ @file: JvmName("StaffModPlatformImpl") -package opekope2.avm_staff.internal.platform.fabric +package opekope2.avm_staff.internal.forge import opekope2.avm_staff.IStaffMod -import opekope2.avm_staff.internal.fabric.StaffMod fun getStaffMod(): IStaffMod = StaffMod diff --git a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/platform/neoforge/StaffModPlatformImpl.kt b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModPlatformImpl.kt similarity index 88% rename from NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/platform/neoforge/StaffModPlatformImpl.kt rename to NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModPlatformImpl.kt index 9c17cf228..61c0e0e99 100644 --- a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/platform/neoforge/StaffModPlatformImpl.kt +++ b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModPlatformImpl.kt @@ -18,9 +18,8 @@ @file: JvmName("StaffModPlatformImpl") -package opekope2.avm_staff.internal.platform.neoforge +package opekope2.avm_staff.internal.neoforge import opekope2.avm_staff.IStaffMod -import opekope2.avm_staff.internal.neoforge.StaffMod fun getStaffMod(): IStaffMod = StaffMod diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt index ad09e6c48..efabb7343 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt @@ -23,7 +23,7 @@ import net.minecraft.item.Item import net.minecraft.particle.DefaultParticleType import net.minecraft.registry.tag.TagKey import opekope2.avm_staff.api.item.StaffItem -import opekope2.avm_staff.internal.platform.getStaffMod +import opekope2.avm_staff.internal.getStaffMod /** * A non-loader-specific interface of the Staff Mod. diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/platform/StaffModPlatform.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/StaffModPlatform.kt similarity index 95% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/internal/platform/StaffModPlatform.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/internal/StaffModPlatform.kt index 373279657..6ce5963fa 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/platform/StaffModPlatform.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/StaffModPlatform.kt @@ -18,7 +18,7 @@ @file: JvmName("StaffModPlatform") -package opekope2.avm_staff.internal.platform +package opekope2.avm_staff.internal import dev.architectury.injectables.annotations.ExpectPlatform import opekope2.avm_staff.IStaffMod From fc4c0e69c4f6c2c55fe2a136330186beea879d29 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 16 May 2024 00:08:36 +0200 Subject: [PATCH 022/128] Make item position in staff customizable --- .../api/item/renderer/StaffRenderer.kt | 21 ++++++++++++------- .../internal/model/ModelPredicates.kt | 5 +++++ 2 files changed, 19 insertions(+), 7 deletions(-) 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 b1fcbf381..b50ac9f54 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 @@ -22,11 +22,13 @@ 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 import net.minecraft.client.util.math.MatrixStack import net.minecraft.item.ItemStack import net.minecraft.registry.Registries import opekope2.avm_staff.internal.model.HEAD_SEED +import opekope2.avm_staff.internal.model.ITEM_SEED import opekope2.avm_staff.internal.model.ROD_BOTTOM_SEED import opekope2.avm_staff.internal.model.ROD_TOP_SEED import opekope2.avm_staff.util.itemInStaff @@ -169,8 +171,7 @@ object StaffRenderer { vertexConsumers: VertexConsumerProvider ) { matrices.push { - scale(.5f, .5f, .5f) - translate(0.0, (-8.0 + 2.0) / 16.0, 0.0) + safeGetModel(staffStack, ITEM_SEED).transformation.fixed.apply(false, this) val staffItemRenderer = IStaffItemRenderer[Registries.ITEM.getId(itemStackInStaff.item)] if (staffItemRenderer != null) { @@ -193,15 +194,21 @@ object StaffRenderer { partSeed: Int ) { val itemRenderer = MinecraftClient.getInstance().itemRenderer - val modelManager = MinecraftClient.getInstance().bakedModelManager - var model = itemRenderer.getModel(staffStack, null, null, partSeed) - if (model.isBuiltin) { - model = modelManager.missingModel - } + val model = safeGetModel(staffStack, partSeed) itemRenderer.renderItem( staffStack, ModelTransformationMode.NONE, false, matrices, vertexConsumers, light, overlay, model ) } + + private fun safeGetModel(staffStack: ItemStack, partSeed: Int): BakedModel { + val itemRenderer = MinecraftClient.getInstance().itemRenderer + + val model = itemRenderer.getModel(staffStack, null, null, partSeed) + + // Prevent StackOverflowError if an override is missing + return if (!model.isBuiltin) model + else MinecraftClient.getInstance().bakedModelManager.missingModel + } } 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 06cca4413..cb8a500e7 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 @@ -26,6 +26,7 @@ import net.minecraft.util.Identifier import opekope2.avm_staff.util.MOD_ID const val HEAD_SEED = -0b10011_10100_00001_00110_00110_00000 +const val ITEM_SEED = -0b10011_10100_00001_00110_00110_00001 const val ROD_TOP_SEED = -0b10011_10100_00001_00110_00110_00010 const val ROD_BOTTOM_SEED = -0b10011_10100_00001_00110_00110_00011 @@ -40,6 +41,10 @@ fun registerModelPredicateProviders(register: (Identifier, ClampedModelPredicate if (seed == HEAD_SEED) 1f else 0f } + register(Identifier(MOD_ID, "item")) { _, _, _, seed -> + if (seed == ITEM_SEED) 1f + else 0f + } register(Identifier(MOD_ID, "rod_top")) { _, _, _, seed -> if (seed == ROD_TOP_SEED) 1f else 0f From a9b39b6cf0efa009e42e9b0067a127b07f669343 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 17 May 2024 00:40:14 +0200 Subject: [PATCH 023/128] Add new staff items, models and textures Remove old staff --- .../avm_staff/internal/fabric/StaffMod.kt | 26 ++++- .../internal/fabric/StaffModClient.kt | 15 +-- .../avm_staff/internal/forge/StaffMod.kt | 27 ++++- .../internal/forge/StaffModClient.kt | 17 --- .../internal/forge/item/ForgeStaffItem.kt | 31 +++++ .../avm_staff/internal/neoforge/StaffMod.kt | 27 ++++- .../internal/neoforge/StaffModClient.kt | 17 --- .../neoforge/item/NeoForgeStaffItem.kt | 31 +++++ .../kotlin/opekope2/avm_staff/IStaffMod.kt | 27 ++++- .../assets/avm_staff/lang/en_us.json | 7 +- .../models/item/faint_royal_staff.json | 45 ++++++++ .../models/item/faint_royal_staff/head.json | 92 +++++++++++++++ .../models/item/faint_royal_staff/item.json | 9 ++ .../item/faint_royal_staff/rod_bottom.json | 7 ++ .../item/faint_royal_staff/rod_top.json | 7 ++ .../models/item/faint_royal_staff_head.json | 4 + .../models/item/faint_staff_rod.json | 55 +++++++++ .../avm_staff/models/item/royal_staff.json | 46 ++++++++ .../models/item/royal_staff/head.json | 7 ++ .../models/item/royal_staff/item.json | 9 ++ .../item/royal_staff/point_forward.json | 26 +++++ .../models/item/royal_staff/rod_bottom.json | 7 ++ .../models/item/royal_staff/rod_top.json | 7 ++ .../assets/avm_staff/models/item/staff.json | 108 ------------------ .../textures/item/faint_royal_staff/head.png | Bin 0 -> 519 bytes .../item/faint_royal_staff/rod_bottom.png | Bin 0 -> 321 bytes .../item/faint_royal_staff/rod_top.png | Bin 0 -> 341 bytes .../textures/item/faint_staff_rod.png | Bin 0 -> 375 bytes .../textures/item/royal_staff/head.png | Bin 0 -> 600 bytes .../textures/item/royal_staff/rod_bottom.png | Bin 0 -> 376 bytes .../textures/item/royal_staff/rod_top.png | Bin 0 -> 347 bytes .../assets/avm_staff/textures/item/staff.png | Bin 970 -> 0 bytes .../data/avm_staff/tags/items/staffs.json | 2 +- 33 files changed, 488 insertions(+), 168 deletions(-) create mode 100644 StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff.json create mode 100644 StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff/head.json create mode 100644 StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff/item.json create mode 100644 StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff/rod_bottom.json create mode 100644 StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff/rod_top.json create mode 100644 StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff_head.json create mode 100644 StaffMod/src/main/resources/assets/avm_staff/models/item/faint_staff_rod.json create mode 100644 StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff.json create mode 100644 StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff/head.json create mode 100644 StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff/item.json create mode 100644 StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff/point_forward.json create mode 100644 StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff/rod_bottom.json create mode 100644 StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff/rod_top.json delete mode 100644 StaffMod/src/main/resources/assets/avm_staff/models/item/staff.json create mode 100644 StaffMod/src/main/resources/assets/avm_staff/textures/item/faint_royal_staff/head.png create mode 100644 StaffMod/src/main/resources/assets/avm_staff/textures/item/faint_royal_staff/rod_bottom.png create mode 100644 StaffMod/src/main/resources/assets/avm_staff/textures/item/faint_royal_staff/rod_top.png create mode 100644 StaffMod/src/main/resources/assets/avm_staff/textures/item/faint_staff_rod.png create mode 100644 StaffMod/src/main/resources/assets/avm_staff/textures/item/royal_staff/head.png create mode 100644 StaffMod/src/main/resources/assets/avm_staff/textures/item/royal_staff/rod_bottom.png create mode 100644 StaffMod/src/main/resources/assets/avm_staff/textures/item/royal_staff/rod_top.png delete mode 100644 StaffMod/src/main/resources/assets/avm_staff/textures/item/staff.png 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 19129eb75..49fe86646 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 @@ -21,7 +21,6 @@ package opekope2.avm_staff.internal.fabric import net.fabricmc.api.ModInitializer import net.fabricmc.fabric.api.event.player.AttackBlockCallback import net.fabricmc.fabric.api.event.player.AttackEntityCallback -import net.fabricmc.fabric.api.item.v1.FabricItemSettings import net.fabricmc.fabric.api.particle.v1.FabricParticleTypes import net.minecraft.entity.Entity import net.minecraft.entity.player.PlayerEntity @@ -31,6 +30,7 @@ import net.minecraft.registry.Registries import net.minecraft.registry.Registry import net.minecraft.registry.RegistryKeys import net.minecraft.registry.tag.TagKey +import net.minecraft.resource.featuretoggle.FeatureFlags import net.minecraft.util.ActionResult import net.minecraft.util.Hand import net.minecraft.util.Identifier @@ -45,10 +45,28 @@ import opekope2.avm_staff.util.MOD_ID @Suppress("unused") object StaffMod : ModInitializer, IStaffMod { - override val staffItem: StaffItem = Registry.register( + override val faintStaffRodItem: Item = Registry.register( Registries.ITEM, - Identifier(MOD_ID, "staff"), - FabricStaffItem(FabricItemSettings().maxCount(1)) + Identifier(MOD_ID, "faint_staff_rod"), + Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21)) + ) + + override val faintRoyalStaffHeadItem: Item = Registry.register( + Registries.ITEM, + Identifier(MOD_ID, "faint_royal_staff_head"), + Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21)) + ) + + override val faintRoyalStaffItem: Item = Registry.register( + Registries.ITEM, + Identifier(MOD_ID, "faint_royal_staff"), + Item(Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21)) + ) + + override val royalStaffItem: StaffItem = Registry.register( + Registries.ITEM, + Identifier(MOD_ID, "royal_staff"), + FabricStaffItem(Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21)) ) override val staffsTag: TagKey = TagKey.of(RegistryKeys.ITEM, Identifier(MOD_ID, "staffs")) 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 65a48723b..0938bcec9 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 @@ -24,11 +24,10 @@ import net.fabricmc.api.Environment import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry -import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents +import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry import net.minecraft.client.item.ModelPredicateProviderRegistry -import net.minecraft.item.ItemGroups -import net.minecraft.item.Items import opekope2.avm_staff.IStaffMod +import opekope2.avm_staff.api.item.renderer.StaffRenderer import opekope2.avm_staff.api.particle.FlamethrowerParticle import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING import opekope2.avm_staff.internal.event_handler.handleKeyBindings @@ -38,13 +37,6 @@ import opekope2.avm_staff.internal.model.registerModelPredicateProviders @Environment(EnvType.CLIENT) object StaffModClient : ClientModInitializer { override fun onInitializeClient() { - ItemGroupEvents.modifyEntriesEvent(ItemGroups.TOOLS).register { entries -> - entries.addAfter(Items.NETHERITE_HOE, StaffMod.staffItem) - } - ItemGroupEvents.modifyEntriesEvent(ItemGroups.COMBAT).register { entries -> - entries.addAfter(Items.TRIDENT, StaffMod.staffItem) - } - KeyBindingHelper.registerKeyBinding(ADD_REMOVE_KEYBINDING) ClientTickEvents.END_CLIENT_TICK.register(::handleKeyBindings) @@ -59,5 +51,8 @@ object StaffModClient : ClientModInitializer { ) registerModelPredicateProviders(ModelPredicateProviderRegistry::register) + + BuiltinItemRendererRegistry.INSTANCE.register(StaffMod.faintRoyalStaffItem, StaffRenderer::renderStaff) + BuiltinItemRendererRegistry.INSTANCE.register(StaffMod.royalStaffItem, StaffRenderer::renderStaff) } } diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt index 400d03b95..a45f747a5 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt @@ -22,6 +22,7 @@ import net.minecraft.item.Item import net.minecraft.particle.DefaultParticleType import net.minecraft.registry.tag.ItemTags import net.minecraft.registry.tag.TagKey +import net.minecraft.resource.featuretoggle.FeatureFlags import net.minecraft.util.Identifier import net.minecraftforge.api.distmarker.Dist import net.minecraftforge.fml.common.Mod @@ -40,7 +41,18 @@ import thedarkcolour.kotlinforforge.forge.runWhenOn object StaffMod : IStaffMod { private val ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MOD_ID) - private val STAFF_ITEM = ITEMS.register("staff") { ForgeStaffItem(Item.Settings().maxCount(1)) } + private val FAINT_STAFF_ROD_ITEM = ITEMS.register("faint_staff_rod") { + Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21)) + } + private val FAINT_ROYAL_STAFF_HEAD_ITEM = ITEMS.register("faint_royal_staff_head") { + Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21)) + } + private val FAINT_ROYAL_STAFF_ITEM = ITEMS.register("faint_royal_staff") { + Item(Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21)) + } + private val ROYAL_STAFF_ITEM = ITEMS.register("royal_staff") { + ForgeStaffItem(Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21)) + } private val PARTICLE_TYPES = DeferredRegister.create(ForgeRegistries.PARTICLE_TYPES, MOD_ID) @@ -59,8 +71,17 @@ object StaffMod : IStaffMod { runWhenOn(Dist.CLIENT, StaffModClient::initializeClient) } - override val staffItem: StaffItem - get() = STAFF_ITEM.get() + override val faintStaffRodItem: Item + get() = FAINT_STAFF_ROD_ITEM.get() + + override val faintRoyalStaffHeadItem: Item + get() = FAINT_ROYAL_STAFF_HEAD_ITEM.get() + + override val faintRoyalStaffItem: Item + get() = FAINT_ROYAL_STAFF_ITEM.get() + + override val royalStaffItem: StaffItem + get() = ROYAL_STAFF_ITEM.get() override val staffsTag: TagKey = ItemTags.create(Identifier(MOD_ID, "staffs")) diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt index 603d6aa13..301b0f304 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt @@ -20,10 +20,6 @@ package opekope2.avm_staff.internal.forge import net.minecraft.client.MinecraftClient import net.minecraft.client.item.ModelPredicateProviderRegistry -import net.minecraft.item.ItemGroup.StackVisibility.PARENT_AND_SEARCH_TABS -import net.minecraft.item.ItemGroups -import net.minecraft.item.ItemStack -import net.minecraft.item.Items import net.minecraftforge.api.distmarker.Dist import net.minecraftforge.api.distmarker.OnlyIn import net.minecraftforge.client.event.RegisterKeyMappingsEvent @@ -58,19 +54,6 @@ object StaffModClient { @SubscribeEvent fun addItemsToItemGroups(event: BuildCreativeModeTabContentsEvent) { - if (event.tabKey === ItemGroups.TOOLS) { - event.entries.putAfter( - ItemStack(Items.NETHERITE_HOE), - ItemStack(StaffMod.staffItem), - PARENT_AND_SEARCH_TABS - ) - } else if (event.tabKey === ItemGroups.COMBAT) { - event.entries.putAfter( - ItemStack(Items.TRIDENT), - ItemStack(StaffMod.staffItem), - PARENT_AND_SEARCH_TABS - ) - } } @SubscribeEvent diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt index 7b8a4594d..9441cb2a9 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt @@ -19,15 +19,23 @@ package opekope2.avm_staff.internal.forge.item import com.google.common.collect.Multimap +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 +import net.minecraft.client.util.math.MatrixStack import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.attribute.EntityAttribute import net.minecraft.entity.attribute.EntityAttributeModifier import net.minecraft.item.Item import net.minecraft.item.ItemStack +import net.minecraftforge.client.extensions.common.IClientItemExtensions import net.minecraftforge.common.extensions.IForgeItem import opekope2.avm_staff.api.item.StaffItem +import opekope2.avm_staff.api.item.renderer.StaffRenderer import opekope2.avm_staff.util.handlerOfItemOrFallback import opekope2.avm_staff.util.itemInStaff +import java.util.function.Consumer class ForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IForgeItem { override fun getAttributeModifiers( @@ -52,4 +60,27 @@ class ForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IForgeItem return if (oldHandler !== newHandler) true else oldHandler.allowReequipAnimation(oldStack, newStack, slotChanged) } + + // Calm down IDEA, this is beyond your understanding + override fun initializeClient(consumer: Consumer) { + consumer.accept(object : IClientItemExtensions { + override fun getCustomRenderer() = Renderer + }) + } + + private object Renderer : BuiltinModelItemRenderer( + MinecraftClient.getInstance().blockEntityRenderDispatcher, + MinecraftClient.getInstance().entityModelLoader + ) { + override fun render( + stack: ItemStack, + mode: ModelTransformationMode, + matrices: MatrixStack, + vertexConsumers: VertexConsumerProvider, + light: Int, + overlay: Int + ) { + StaffRenderer.renderStaff(stack, mode, matrices, vertexConsumers, light, overlay) + } + } } 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 87991d517..97ebd5765 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 @@ -23,6 +23,7 @@ import net.minecraft.particle.DefaultParticleType import net.minecraft.registry.Registries import net.minecraft.registry.tag.ItemTags import net.minecraft.registry.tag.TagKey +import net.minecraft.resource.featuretoggle.FeatureFlags import net.minecraft.util.Identifier import net.neoforged.api.distmarker.Dist import net.neoforged.fml.common.Mod @@ -40,7 +41,18 @@ import thedarkcolour.kotlinforforge.neoforge.forge.runWhenOn object StaffMod : IStaffMod { private val ITEMS = DeferredRegister.create(Registries.ITEM, MOD_ID) - private val STAFF_ITEM = ITEMS.register("staff") { -> NeoForgeStaffItem(Item.Settings().maxCount(1)) } + private val FAINT_STAFF_ROD_ITEM = ITEMS.register("faint_staff_rod") { -> + Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21)) + } + private val FAINT_ROYAL_STAFF_HEAD_ITEM = ITEMS.register("faint_royal_staff_head") { -> + Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21)) + } + private val FAINT_ROYAL_STAFF_ITEM = ITEMS.register("faint_royal_staff") { -> + Item(Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21)) + } + private val ROYAL_STAFF_ITEM = ITEMS.register("royal_staff") { -> + NeoForgeStaffItem(Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21)) + } private val PARTICLE_TYPES = DeferredRegister.create(Registries.PARTICLE_TYPE, MOD_ID) @@ -59,8 +71,17 @@ object StaffMod : IStaffMod { runWhenOn(Dist.CLIENT, StaffModClient::initializeClient) } - override val staffItem: StaffItem - get() = STAFF_ITEM.get() + override val faintStaffRodItem: Item + get() = FAINT_STAFF_ROD_ITEM.get() + + override val faintRoyalStaffHeadItem: Item + get() = FAINT_ROYAL_STAFF_HEAD_ITEM.get() + + override val faintRoyalStaffItem: Item + get() = FAINT_ROYAL_STAFF_ITEM.get() + + override val royalStaffItem: StaffItem + get() = ROYAL_STAFF_ITEM.get() override val staffsTag: TagKey = ItemTags.create(Identifier(MOD_ID, "staffs")) 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 d65a7dc0d..a84bd9d15 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 @@ -20,10 +20,6 @@ package opekope2.avm_staff.internal.neoforge import net.minecraft.client.MinecraftClient import net.minecraft.client.item.ModelPredicateProviderRegistry -import net.minecraft.item.ItemGroup.StackVisibility.PARENT_AND_SEARCH_TABS -import net.minecraft.item.ItemGroups -import net.minecraft.item.ItemStack -import net.minecraft.item.Items import net.neoforged.api.distmarker.Dist import net.neoforged.api.distmarker.OnlyIn import net.neoforged.bus.api.SubscribeEvent @@ -58,19 +54,6 @@ object StaffModClient { @SubscribeEvent fun addItemsToItemGroups(event: BuildCreativeModeTabContentsEvent) { - if (event.tabKey === ItemGroups.TOOLS) { - event.entries.putAfter( - ItemStack(Items.NETHERITE_HOE), - ItemStack(StaffMod.staffItem), - PARENT_AND_SEARCH_TABS - ) - } else if (event.tabKey === ItemGroups.COMBAT) { - event.entries.putAfter( - ItemStack(Items.TRIDENT), - ItemStack(StaffMod.staffItem), - PARENT_AND_SEARCH_TABS - ) - } } @SubscribeEvent 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 da9d0893b..dae01250f 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 @@ -19,15 +19,23 @@ package opekope2.avm_staff.internal.neoforge.item import com.google.common.collect.Multimap +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 +import net.minecraft.client.util.math.MatrixStack import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.attribute.EntityAttribute import net.minecraft.entity.attribute.EntityAttributeModifier import net.minecraft.item.Item import net.minecraft.item.ItemStack +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.handlerOfItemOrFallback import opekope2.avm_staff.util.itemInStaff +import java.util.function.Consumer class NeoForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IItemExtension { override fun getAttributeModifiers( @@ -52,4 +60,27 @@ class NeoForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IItemExt return if (oldHandler !== newHandler) true else oldHandler.allowReequipAnimation(oldStack, newStack, slotChanged) } + + // Calm down IDEA, this is beyond your understanding + override fun initializeClient(consumer: Consumer) { + consumer.accept(object : IClientItemExtensions { + override fun getCustomRenderer() = Renderer + }) + } + + private object Renderer : BuiltinModelItemRenderer( + MinecraftClient.getInstance().blockEntityRenderDispatcher, + MinecraftClient.getInstance().entityModelLoader + ) { + override fun render( + stack: ItemStack, + mode: ModelTransformationMode, + matrices: MatrixStack, + vertexConsumers: VertexConsumerProvider, + light: Int, + overlay: Int + ) { + StaffRenderer.renderStaff(stack, mode, matrices, vertexConsumers, light, overlay) + } + } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt index efabb7343..1b8daeaf7 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt @@ -30,11 +30,32 @@ import opekope2.avm_staff.internal.getStaffMod */ interface IStaffMod { /** - * Gets the Staff item registered in Minecraft. + * Gets `avm_staff:faint_staff_rod` item registered in Minecraft. * - * Due to how Forge registries work, *always* use this getter instead of storing the result. + * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. + */ + val faintStaffRodItem: Item + + /** + * Gets `avm_staff:faint_royal_staff_head` item registered in Minecraft. + * + * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. + */ + val faintRoyalStaffHeadItem: Item + + /** + * Gets `avm_staff:faint_royal_staff` item registered in Minecraft. + * + * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. + */ + val faintRoyalStaffItem: Item + + /** + * Gets `avm_staff:royal_staff` item registered in Minecraft. + * + * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. */ - val staffItem: StaffItem + val royalStaffItem: StaffItem /** * Gets the [TagKey] containing all the staffs. 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 cf4061fc5..9ba4dee16 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,6 +1,9 @@ { - "item.avm_staff.staff": "Staff", - "item.avm_staff.staff.with_item": "Staff with %s", + "item.avm_staff.faint_staff_rod": "Faint staff rod", + "item.avm_staff.faint_royal_staff_head": "Faint royal staff head", + "item.avm_staff.faint_royal_staff": "Faint royal staff", + "item.avm_staff.royal_staff": "Royal staff", + "item.avm_staff.royal_staff.with_item": "Royal staff with %s", "key.categories.avm_staff": "Staff Mod", "key.avm_staff.add_remove_staff_block": "Add/remove staff block" } diff --git a/StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff.json b/StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff.json new file mode 100644 index 000000000..ba43a8616 --- /dev/null +++ b/StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff.json @@ -0,0 +1,45 @@ +{ + "credit": "Made with Blockbench", + "parent": "minecraft:builtin/entity", + "overrides": [ + {"predicate": {"avm_staff:head": 1}, "model": "avm_staff:item/faint_royal_staff/head"}, + {"predicate": {"avm_staff:item": 1}, "model": "avm_staff:item/faint_royal_staff/item"}, + {"predicate": {"avm_staff:rod_top": 1}, "model": "avm_staff:item/faint_royal_staff/rod_top"}, + {"predicate": {"avm_staff:rod_bottom": 1}, "model": "avm_staff:item/faint_royal_staff/rod_bottom"} + ], + "display": { + "thirdperson_righthand": { + "rotation": [0, 90, 0], + "translation": [0, 5.4, 0], + "scale": [0.85, 0.85, 0.85] + }, + "thirdperson_lefthand": { + "rotation": [0, 90, 0], + "translation": [0, 5.4, 0], + "scale": [0.85, 0.85, 0.85] + }, + "firstperson_righthand": { + "rotation": [-25, 90, 0], + "translation": [1.13, 0.71, 2.29], + "scale": [0.68, 0.68, 0.68] + }, + "firstperson_lefthand": { + "rotation": [0, 90, -25], + "translation": [1.13, 0.71, 2.29], + "scale": [0.68, 0.68, 0.68] + }, + "ground": { + "rotation": [90, 45, -90], + "translation": [0, 6, 0], + "scale": [0.5, 0.5, 0.5] + }, + "gui": { + "rotation": [30, 45, 0], + "translation": [0, 3, 0], + "scale": [1.25, 1.25, 1.25] + }, + "fixed": { + "rotation": [90, -45, 90] + } + } +} \ No newline at end of file diff --git a/StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff/head.json b/StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff/head.json new file mode 100644 index 000000000..b8186dabd --- /dev/null +++ b/StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff/head.json @@ -0,0 +1,92 @@ +{ + "credit": "Made with Blockbench", + "texture_size": [32, 32], + "textures": { + "particle": "avm_staff:item/faint_royal_staff/head", + "head": "avm_staff:item/faint_royal_staff/head" + }, + "elements": [ + { + "from": [7, 10, 7], + "to": [9, 12, 9], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 11, 8]}, + "faces": { + "north": {"uv": [8, 2, 10, 4], "texture": "#head"}, + "east": {"uv": [14, 2, 16, 4], "texture": "#head"}, + "south": {"uv": [12, 2, 14, 4], "texture": "#head"}, + "west": {"uv": [10, 2, 12, 4], "texture": "#head"}, + "up": {"uv": [12, 0, 14, 2], "texture": "#head"} + } + }, + { + "from": [7, 9, 7], + "to": [9, 10, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 9.5, 8]}, + "faces": { + "north": {"uv": [0, 3, 1, 5], "rotation": 90, "texture": "#head"}, + "east": {"uv": [1, 5, 7, 6], "rotation": 180, "texture": "#head"}, + "south": {"uv": [7, 3, 8, 5], "rotation": 270, "texture": "#head"}, + "west": {"uv": [1, 2, 7, 3], "texture": "#head"}, + "up": {"uv": [1, 0, 7, 2], "rotation": 90, "texture": "#head"}, + "down": {"uv": [1, 3, 7, 5], "rotation": 270, "texture": "#head"} + } + }, + { + "from": [7, 1, 12], + "to": [9, 9, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 5, 8]}, + "faces": { + "north": {"uv": [8, 4, 10, 12], "texture": "#head"}, + "east": {"uv": [13, 4, 14, 12], "texture": "#head"}, + "south": {"uv": [11, 4, 13, 12], "texture": "#head"}, + "west": {"uv": [10, 4, 11, 12], "texture": "#head"} + } + }, + { + "from": [7, 0, 7], + "to": [9, 1, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 0.5, 8]}, + "faces": { + "north": {"uv": [0, 9, 1, 11], "rotation": 90, "texture": "#head"}, + "east": {"uv": [1, 11, 7, 12], "rotation": 180, "texture": "#head"}, + "south": {"uv": [7, 9, 8, 11], "rotation": 270, "texture": "#head"}, + "west": {"uv": [1, 8, 7, 9], "texture": "#head"}, + "up": {"uv": [1, 6, 7, 8], "rotation": 90, "texture": "#head"}, + "down": {"uv": [1, 9, 7, 11], "rotation": 270, "texture": "#head"} + } + } + ], + "gui_light": "front", + "display": { + "thirdperson_righthand": { + "translation": [0, -0.5, -1.25], + "scale": [0.55, 0.55, 0.55] + }, + "thirdperson_lefthand": { + "translation": [0, -0.5, -1.25], + "scale": [0.55, 0.55, 0.55] + }, + "firstperson_righthand": { + "rotation": [-25, 0, 0], + "translation": [-0.37, 3.2, 1.13], + "scale": [0.68, 0.68, 0.68] + }, + "firstperson_lefthand": { + "rotation": [-25, 0, 0], + "translation": [-0.37, 3.2, 1.13], + "scale": [0.68, 0.68, 0.68] + }, + "ground": { + "translation": [0, 2, -1], + "scale": [0.5, 0.5, 0.5] + }, + "gui": { + "rotation": [0, 90, 0], + "translation": [0, 2, 0] + }, + "fixed": { + "rotation": [0, -90, 0], + "translation": [0, 2, 0] + } + } +} \ No newline at end of file diff --git a/StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff/item.json b/StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff/item.json new file mode 100644 index 000000000..0878ced6b --- /dev/null +++ b/StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff/item.json @@ -0,0 +1,9 @@ +{ + "credit": "Made with Blockbench", + "display": { + "fixed": { + "translation": [0, -3, 0], + "scale": [0.5, 0.5, 0.5] + } + } +} \ No newline at end of file diff --git a/StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff/rod_bottom.json b/StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff/rod_bottom.json new file mode 100644 index 000000000..20155a93f --- /dev/null +++ b/StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff/rod_bottom.json @@ -0,0 +1,7 @@ +{ + "credit": "Made with Blockbench", + "parent": "avm_staff:item/faint_staff_rod", + "textures": { + "rod": "avm_staff:item/faint_royal_staff/rod_bottom" + } +} \ No newline at end of file diff --git a/StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff/rod_top.json b/StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff/rod_top.json new file mode 100644 index 000000000..7ea8a216b --- /dev/null +++ b/StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff/rod_top.json @@ -0,0 +1,7 @@ +{ + "credit": "Made with Blockbench", + "parent": "avm_staff:item/faint_staff_rod", + "textures": { + "rod": "avm_staff:item/faint_royal_staff/rod_top" + } +} \ No newline at end of file diff --git a/StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff_head.json b/StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff_head.json new file mode 100644 index 000000000..057711595 --- /dev/null +++ b/StaffMod/src/main/resources/assets/avm_staff/models/item/faint_royal_staff_head.json @@ -0,0 +1,4 @@ +{ + "credit": "Made with Blockbench", + "parent": "avm_staff:item/faint_royal_staff/head" +} \ No newline at end of file diff --git a/StaffMod/src/main/resources/assets/avm_staff/models/item/faint_staff_rod.json b/StaffMod/src/main/resources/assets/avm_staff/models/item/faint_staff_rod.json new file mode 100644 index 000000000..f81a4f47e --- /dev/null +++ b/StaffMod/src/main/resources/assets/avm_staff/models/item/faint_staff_rod.json @@ -0,0 +1,55 @@ +{ + "credit": "Made with Blockbench", + "texture_size": [32, 32], + "textures": { + "particle": "avm_staff:item/faint_staff_rod", + "rod": "avm_staff:item/faint_staff_rod" + }, + "elements": [ + { + "from": [7, 0, 7], + "to": [9, 14, 9], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 7, 8]}, + "faces": { + "north": {"uv": [0, 2, 2, 16], "texture": "#rod"}, + "east": {"uv": [6, 2, 8, 16], "texture": "#rod"}, + "south": {"uv": [4, 2, 6, 16], "texture": "#rod"}, + "west": {"uv": [2, 2, 4, 16], "texture": "#rod"}, + "up": {"uv": [4, 0, 6, 2], "texture": "#rod"}, + "down": {"uv": [2, 0, 4, 2], "texture": "#rod"} + } + } + ], + "gui_light": "front", + "display": { + "thirdperson_righthand": { + "translation": [0, 3, 1], + "scale": [0.55, 0.55, 0.55] + }, + "thirdperson_lefthand": { + "translation": [0, 3, 1], + "scale": [0.55, 0.55, 0.55] + }, + "firstperson_righthand": { + "rotation": [0, -90, 25], + "translation": [1.13, 3.2, 1.13], + "scale": [0.68, 0.68, 0.68] + }, + "firstperson_lefthand": { + "rotation": [0, -90, 25], + "translation": [1.13, 3.2, 1.13], + "scale": [0.68, 0.68, 0.68] + }, + "ground": { + "translation": [0, 2, 0], + "scale": [0.5, 0.5, 0.5] + }, + "gui": { + "translation": [0, 1, 0] + }, + "fixed": { + "rotation": [0, 180, 0], + "translation": [0, 1, 0] + } + } +} \ No newline at end of file diff --git a/StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff.json b/StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff.json new file mode 100644 index 000000000..6bc726f20 --- /dev/null +++ b/StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff.json @@ -0,0 +1,46 @@ +{ + "credit": "Made with Blockbench", + "parent": "minecraft:builtin/entity", + "overrides": [ + {"predicate": {"avm_staff:using_item": 1}, "model": "avm_staff:item/royal_staff/point_forward"}, + {"predicate": {"avm_staff:head": 1}, "model": "avm_staff:item/royal_staff/head"}, + {"predicate": {"avm_staff:item": 1}, "model": "avm_staff:item/royal_staff/item"}, + {"predicate": {"avm_staff:rod_top": 1}, "model": "avm_staff:item/royal_staff/rod_top"}, + {"predicate": {"avm_staff:rod_bottom": 1}, "model": "avm_staff:item/royal_staff/rod_bottom"} + ], + "display": { + "thirdperson_righthand": { + "rotation": [0, 90, 0], + "translation": [0, 5.4, 0], + "scale": [0.85, 0.85, 0.85] + }, + "thirdperson_lefthand": { + "rotation": [0, 90, 0], + "translation": [0, 5.4, 0], + "scale": [0.85, 0.85, 0.85] + }, + "firstperson_righthand": { + "rotation": [-25, 90, 0], + "translation": [1.13, 0.71, 2.29], + "scale": [0.68, 0.68, 0.68] + }, + "firstperson_lefthand": { + "rotation": [0, 90, -25], + "translation": [1.13, 0.71, 2.29], + "scale": [0.68, 0.68, 0.68] + }, + "ground": { + "rotation": [90, 45, -90], + "translation": [0, 6, 0], + "scale": [0.5, 0.5, 0.5] + }, + "gui": { + "rotation": [30, 45, 0], + "translation": [0, 3, 0], + "scale": [1.25, 1.25, 1.25] + }, + "fixed": { + "rotation": [90, -45, 90] + } + } +} \ No newline at end of file diff --git a/StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff/head.json b/StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff/head.json new file mode 100644 index 000000000..5efafb67f --- /dev/null +++ b/StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff/head.json @@ -0,0 +1,7 @@ +{ + "credit": "Made with Blockbench", + "parent": "avm_staff:item/faint_royal_staff/head", + "textures": { + "head": "avm_staff:item/royal_staff/head" + } +} \ No newline at end of file diff --git a/StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff/item.json b/StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff/item.json new file mode 100644 index 000000000..0878ced6b --- /dev/null +++ b/StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff/item.json @@ -0,0 +1,9 @@ +{ + "credit": "Made with Blockbench", + "display": { + "fixed": { + "translation": [0, -3, 0], + "scale": [0.5, 0.5, 0.5] + } + } +} \ No newline at end of file diff --git a/StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff/point_forward.json b/StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff/point_forward.json new file mode 100644 index 000000000..e6595007c --- /dev/null +++ b/StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff/point_forward.json @@ -0,0 +1,26 @@ +{ + "credit": "Made with Blockbench", + "parent": "avm_staff:item/faint_royal_staff", + "display": { + "thirdperson_righthand": { + "rotation": [-75, 90, 0], + "translation": [0, -1.12, -7.28], + "scale": [0.85, 0.85, 0.85] + }, + "thirdperson_lefthand": { + "rotation": [-75, 90, 0], + "translation": [0, -1.12, -7.28], + "scale": [0.85, 0.85, 0.85] + }, + "firstperson_righthand": { + "rotation": [-180, 70, 105], + "translation": [-2.86, 3.98, 0.74], + "scale": [0.68, 0.68, 0.68] + }, + "firstperson_lefthand": { + "rotation": [-180, 70, 105], + "translation": [-2.86, 3.96, 0.74], + "scale": [0.68, 0.68, 0.68] + } + } +} \ No newline at end of file diff --git a/StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff/rod_bottom.json b/StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff/rod_bottom.json new file mode 100644 index 000000000..8da8c3361 --- /dev/null +++ b/StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff/rod_bottom.json @@ -0,0 +1,7 @@ +{ + "credit": "Made with Blockbench", + "parent": "avm_staff:item/faint_staff_rod", + "textures": { + "rod": "avm_staff:item/royal_staff/rod_bottom" + } +} \ No newline at end of file diff --git a/StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff/rod_top.json b/StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff/rod_top.json new file mode 100644 index 000000000..19c8ec946 --- /dev/null +++ b/StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff/rod_top.json @@ -0,0 +1,7 @@ +{ + "credit": "Made with Blockbench", + "parent": "avm_staff:item/faint_staff_rod", + "textures": { + "rod": "avm_staff:item/royal_staff/rod_top" + } +} \ No newline at end of file diff --git a/StaffMod/src/main/resources/assets/avm_staff/models/item/staff.json b/StaffMod/src/main/resources/assets/avm_staff/models/item/staff.json deleted file mode 100644 index b5a1f4477..000000000 --- a/StaffMod/src/main/resources/assets/avm_staff/models/item/staff.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "credit": "Made with Blockbench", - "texture_size": [32, 32], - "textures": { - "particle": "avm_staff:item/staff", - "staff": "avm_staff:item/staff" - }, - "elements": [ - { - "from": [7, 30, 7], - "to": [9, 32, 9], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 31, 8]}, - "faces": { - "north": {"uv": [5, 2.5, 6, 3.5], "texture": "#staff"}, - "east": {"uv": [8, 2.5, 9, 3.5], "texture": "#staff"}, - "south": {"uv": [7, 2.5, 8, 3.5], "texture": "#staff"}, - "west": {"uv": [6, 2.5, 7, 3.5], "texture": "#staff"}, - "up": {"uv": [6, 1.5, 7, 2.5], "texture": "#staff"} - } - }, - { - "from": [7, 29, 7], - "to": [9, 30, 12.5], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 29.5, 8]}, - "faces": { - "north": {"uv": [5, 6, 6, 6.5], "texture": "#staff"}, - "east": {"uv": [9.75, 6, 12.5, 6.5], "texture": "#staff"}, - "south": {"uv": [8.75, 6, 9.75, 6.5], "texture": "#staff"}, - "west": {"uv": [6, 6, 8.75, 6.5], "texture": "#staff"}, - "up": {"uv": [6, 5, 8.75, 6], "rotation": 90, "texture": "#staff"}, - "down": {"uv": [6, 6.5, 8.75, 7.5], "rotation": 270, "texture": "#staff"} - } - }, - { - "from": [7, 22, 11.5], - "to": [9, 29, 12.5], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 25.5, 8]}, - "faces": { - "north": {"uv": [7.25, 8.5, 8.25, 12], "texture": "#staff"}, - "east": {"uv": [6.75, 8.5, 7.25, 12], "texture": "#staff"}, - "south": {"uv": [8.75, 8.5, 9.75, 12], "texture": "#staff"}, - "west": {"uv": [8.25, 8.5, 8.75, 12], "texture": "#staff"} - } - }, - { - "from": [7, 21, 7], - "to": [9, 22, 12.5], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 21.5, 8]}, - "faces": { - "north": {"uv": [5, 14.5, 6, 15], "texture": "#staff"}, - "east": {"uv": [8.75, 13.5, 6, 13], "texture": "#staff"}, - "south": {"uv": [8.75, 14.5, 9.75, 15], "texture": "#staff"}, - "west": {"uv": [6, 14.5, 8.75, 15], "texture": "#staff"}, - "up": {"uv": [6, 13.5, 8.75, 14.5], "rotation": 90, "texture": "#staff"}, - "down": {"uv": [6, 15, 8.75, 16], "rotation": 270, "texture": "#staff"} - } - }, - { - "from": [7, -8, 7], - "to": [9, 21, 9], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 6.5, 8]}, - "faces": { - "north": {"uv": [0, 0.5, 1, 15], "texture": "#staff"}, - "east": {"uv": [3, 0.5, 4, 15], "texture": "#staff"}, - "south": {"uv": [2, 0.5, 3, 15], "texture": "#staff"}, - "west": {"uv": [1, 0.5, 2, 15], "texture": "#staff"}, - "down": {"uv": [1, 15, 2, 16], "texture": "#staff"} - } - } - ], - "gui_light": "front", - "overrides": [ - {"predicate": {"avm_staff:using_item": 1}, "model": "avm_staff:item/staff_in_use"} - ], - "display": { - "thirdperson_righthand": { - "rotation": [0, 90, 0], - "translation": [0, 2, 0], - "scale": [0.85, 0.85, 0.85] - }, - "thirdperson_lefthand": { - "rotation": [0, 90, 0], - "translation": [0, 2, 0], - "scale": [0.85, 0.85, 0.85] - }, - "firstperson_righthand": { - "rotation": [-25, 90, 0], - "translation": [1.13, -1.8, 3.46], - "scale": [0.68, 0.68, 0.68] - }, - "firstperson_lefthand": { - "rotation": [0, 90, -25], - "translation": [1.13, -1.8, 3.46], - "scale": [0.68, 0.68, 0.68] - }, - "ground": { - "rotation": [90, 45, -90], - "translation": [-1.75, 6, 0], - "scale": [0.5, 0.5, 0.5] - }, - "gui": { - "rotation": [90, 45, -90] - }, - "fixed": { - "rotation": [90, -45, 90] - } - } -} \ No newline at end of file diff --git a/StaffMod/src/main/resources/assets/avm_staff/textures/item/faint_royal_staff/head.png b/StaffMod/src/main/resources/assets/avm_staff/textures/item/faint_royal_staff/head.png new file mode 100644 index 0000000000000000000000000000000000000000..cfc250ba590229bfd5944fd338247da1a59809a0 GIT binary patch literal 519 zcmV+i0{H!jP)g@IflONX4G3j+(v4YR(8ewh2vu zfq^F>HQ4cUY{w449a)yuv)K%kQcR~)T(4KSkmot1l*FlEKnPJ&N}c;g`okn2kH*7QO;c>QTL1`J6J7n z6i`Zm5P~?4!8yljwZiFi3SJX4CtU|zD2f6Aa6X^G7;Dx^k^n#xy~$((04U3{iQHzh zY4?F{^=m_qQlN>B$0HbHPCXxt4u=E5y*fiS>XWS3>)Lg4pN3}b165Ud_W@02BQ|A& z4m^7e%~N)XgCfu+_bEaQL|{Ij4?6HUv%t)&?=5%-J|_at-h!7M5JJ?pW;6sLM7>-t zUw1&aVcc&*$cre7B9vu`s;VC9X}NC6EeC>Kwive=HlgJZyi=lP}#>AFFO{|#e5#d#UiEk#H>V94z zhikX3T@khQmPl$bqxTp*9QxP9uNh-M_}7Fqv4u^ z1+F3rM1lV!u&%4oaLvI2SD^)#WicAAIauH-qJS2d=h-F-=q3rTJ2O!Hb0DN<>z$&{$fi(o?|I{}J3v9(Ga5x+$1>YPjuoY1t3PgcX nV87o_3cfj5U@M|P6o>-9Re_GVIX_Eb00000NkvXXu0mjfXxEce literal 0 HcmV?d00001 diff --git a/StaffMod/src/main/resources/assets/avm_staff/textures/item/faint_staff_rod.png b/StaffMod/src/main/resources/assets/avm_staff/textures/item/faint_staff_rod.png new file mode 100644 index 0000000000000000000000000000000000000000..af9d015195e4ca34137ecbf058df0a6a18984326 GIT binary patch literal 375 zcmV--0f_#IP)U5JewZx&+~h#;#LQQ8*W%C1=SIc5jd}hv5JbH77tww2?yUY=s4EH5du4lwa`} zVV(yUL%=L~p1+k+06ZQK0MaxCpss7mvJB?W_#~X)P)cEpacqpiTI;wh%QfH6Zq?Nm z(%Q_1jC^-#<(3y*!NI|N-0jK6IyH9 zwgnKgmp~lHXstOOj~HWkKA$4?%`S=}01k%(08;iASY?%uz#0PcZz^SPfvw^M_WS*$ zAZ2fXt@06Y0VI!uR|A$49_*psK3Lj-Ui@PLHsO1@VkQ(k^o-t`F6KZRLXo;+ zy8Z+JvE~}Be!3YW@Y0YH@Mj(X;PcmRWW;gi&+F!!%e-kJZ6sEl`!f$uzZa3;$aCQ@ z=FkElZ6werSI|0b;P%dmJ=gd%5edjJA_eOV?olli**r@!Nwb$C?L75-mbr_Y534#L zRzEBt%WV>cEcxvYzoS|xO4q4C|1$oeVZ5x)IEFNm^OJW0B_u|kOdqT#KnHv#+=Q>J z11U~5MaL=Qg*t&v+mMe^bgUxjjDXmJDn$q(O40G_9I2ywIf31|3)s2F=z@QN-O0eF zU9dHQwp|NCVx)k!T?@|Y$J-O2G7QoQ$}b{PCsS_@ck&p$fK>&B2{K zGOd?^I*uZ$_lJYfYY2)jqAJmfzi9^VIEtuFU#ZPZDb`)kae7+E>EUDReZX!*$y)w4 m3=yD%O{I8`J@(jRTl@i0EFWDAp7$*P00003`JOr=AM2#N*_LZ_obhk~P!(MkJ50{({Xj*cSeBuepwbFS zP!X;}o1=Fw-hF|H+&kTK-{tPP%k()=5_GnCyV(K&Op6T6^D*c$06?53I37oi`VA$n zI?-;nu(`4-c+h27U+c`rV8A%4@_aNZ-OV6BUSL{e(l}0&`OO!pFa`2bBejho!x30NMRu#rI7c=Xv8POh$j zMKADMjwZJ>f$|n{nn*X&Wn%&R0(HNDGu+tWWi$Hl_5uLV;mgMxQn&1?z2I_m*(5Uy WFzvCZ(DRZ20000b;z6o&sq5u%POh!8M9Bmz=Ysa6LDdI1j9qjc;km>6?{jFqQIC_~t)Do3D08w;DI z=2^<(e~Ev;`1yOzivt*Xd)Z%hxc~r^m4s|+h%^HL$ficoo&s|XMUgqN%LVfF{AR9G z(VkrHkI-qhJ9KjbWhJ$-Y-;7N$Ibw{Z@v{Pd>oD{uoWwmm4rw$T*pP4Y45*(7Nnkt zx~j}-ZT;N~vP0IJ;i%VQ@S!GR6|ufL#Dt9E9d z=wT;-k9jwCKXb%?CxFDft7Vldto+CkT>?~v<$}geHanN!Etf7mfWw3cJ1jiF4+0cr zf-%t8$;L}=uOOMl_a*@3UaxoJd9MKEnP>R-h~1zdKoB4Z5Cnv>6sEV^2_=q`=BaJ{ z;KxqUa{~Cm+Z8*Rl;+D$u^R%i9AykNcCv{O=p*D52>=pG+_{7f0|BeaMe|waL07-( zPLg0==#aX~(OkrTYm2JmB}4rS1lMPC%pim;DDQ>|`6v1KO6l8!VDw z7(#&A-SJ%^7x=nQg+(1el*1n+kj`vbiG z!2}t+o4djMX3;+n*e#cs8Kp5H!VU*I1ibcuQNJ4$9^kbHjQZW6)USWPALcW+-RIF^ z;6wlkh1r=TRyH?0Ulk&B4-c&mgZbBZdqZj4FN510x!c#%GbGuq+hhR4^xn|*eBk;7 sdwP7Xn4AOCCn&bVE@F5X8TCHFf9ep914RWhQUCw|07*qoM6N<$f;d^kwg3PC diff --git a/StaffMod/src/main/resources/data/avm_staff/tags/items/staffs.json b/StaffMod/src/main/resources/data/avm_staff/tags/items/staffs.json index 8d8e67097..d252465a6 100644 --- a/StaffMod/src/main/resources/data/avm_staff/tags/items/staffs.json +++ b/StaffMod/src/main/resources/data/avm_staff/tags/items/staffs.json @@ -1,6 +1,6 @@ { "replace": false, "values": [ - "avm_staff:staff" + "avm_staff:royal_staff" ] } From 4232acde4d0f79cb87d708d753f23c6e488eb8f0 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 17 May 2024 01:04:09 +0200 Subject: [PATCH 024/128] Update add/remove staff item translation --- StaffMod/src/main/resources/assets/avm_staff/lang/en_us.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 9ba4dee16..2259d5d75 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 @@ -5,5 +5,5 @@ "item.avm_staff.royal_staff": "Royal staff", "item.avm_staff.royal_staff.with_item": "Royal staff with %s", "key.categories.avm_staff": "Staff Mod", - "key.avm_staff.add_remove_staff_block": "Add/remove staff block" + "key.avm_staff.add_remove_staff_block": "Add/remove staff item" } From 0c7bcbf70cf1ab0a167173ae1d5e7d6ddca25ce6 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 17 May 2024 01:06:54 +0200 Subject: [PATCH 025/128] Update StaffItem KDoc --- .../src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 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 cb1e352b6..c8b916cc9 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 @@ -37,8 +37,8 @@ import java.util.stream.Stream /** * Staff item dispatching functionality to [StaffItemHandler] without loader specific functionality. - * Implementing `FabricItem` or `IForgeItem` (on the appropriate loader) is highly recommended when extending the class - * to pass loader-specific functionality to [StaffItemHandler]. + * Implementing loader-specific interfaces is highly recommended when extending the class to pass loader-specific + * functionality to [StaffItemHandler]. */ abstract class StaffItem(settings: Settings) : Item(settings) { override fun onItemEntityDestroyed(entity: ItemEntity) { From f8cdb5ec5dab65f84923d41634aea3ac46ef9cbd Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 17 May 2024 21:32:42 +0200 Subject: [PATCH 026/128] Refactor StaffMod API Move content registration to common project using Architectury API --- .../avm_staff/internal/fabric/StaffMod.kt | 53 +-------- .../internal/fabric/StaffModClient.kt | 13 ++- .../internal/fabric/StaffModPlatformImpl.kt | 6 +- FabricMod/src/main/resources/fabric.mod.json | 4 + .../avm_staff/internal/forge/StaffMod.kt | 68 +---------- .../internal/forge/StaffModClient.kt | 7 +- .../internal/forge/StaffModPlatformImpl.kt | 6 +- .../avm_staff/internal/neoforge/StaffMod.kt | 67 +---------- .../internal/neoforge/StaffModClient.kt | 7 +- .../internal/neoforge/StaffModPlatformImpl.kt | 6 +- .../mixin/BipedEntityModelMixin.java | 6 +- .../avm_staff/mixin/LivingEntityMixin.java | 4 +- .../kotlin/opekope2/avm_staff/IStaffMod.kt | 90 --------------- .../kotlin/opekope2/avm_staff/api/StaffMod.kt | 107 ++++++++++++++++++ .../api/particle/FlamethrowerParticle.kt | 6 +- .../avm_staff/internal/Initializer.kt | 4 + .../avm_staff/internal/StaffModPlatform.kt | 5 +- .../internal/event_handler/NetworkHandler.kt | 12 +- .../event_handler/StaffAttackHandler.kt | 10 +- .../staff_item_handler/CampfireHandler.kt | 8 +- .../VanillaStaffItemHandlers.kt | 13 +-- .../main/resources/avm_staff.accesswidener | 5 +- 22 files changed, 184 insertions(+), 323 deletions(-) delete mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.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 49fe86646..53327b949 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 @@ -21,68 +21,17 @@ package opekope2.avm_staff.internal.fabric import net.fabricmc.api.ModInitializer import net.fabricmc.fabric.api.event.player.AttackBlockCallback import net.fabricmc.fabric.api.event.player.AttackEntityCallback -import net.fabricmc.fabric.api.particle.v1.FabricParticleTypes import net.minecraft.entity.Entity import net.minecraft.entity.player.PlayerEntity -import net.minecraft.item.Item -import net.minecraft.particle.DefaultParticleType -import net.minecraft.registry.Registries -import net.minecraft.registry.Registry -import net.minecraft.registry.RegistryKeys -import net.minecraft.registry.tag.TagKey -import net.minecraft.resource.featuretoggle.FeatureFlags import net.minecraft.util.ActionResult import net.minecraft.util.Hand -import net.minecraft.util.Identifier import net.minecraft.util.hit.EntityHitResult import net.minecraft.world.World -import opekope2.avm_staff.IStaffMod -import opekope2.avm_staff.api.item.StaffItem import opekope2.avm_staff.internal.event_handler.attackBlock import opekope2.avm_staff.internal.event_handler.attackEntity -import opekope2.avm_staff.internal.fabric.item.FabricStaffItem -import opekope2.avm_staff.util.MOD_ID @Suppress("unused") -object StaffMod : ModInitializer, IStaffMod { - override val faintStaffRodItem: Item = Registry.register( - Registries.ITEM, - Identifier(MOD_ID, "faint_staff_rod"), - Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21)) - ) - - override val faintRoyalStaffHeadItem: Item = Registry.register( - Registries.ITEM, - Identifier(MOD_ID, "faint_royal_staff_head"), - Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21)) - ) - - override val faintRoyalStaffItem: Item = Registry.register( - Registries.ITEM, - Identifier(MOD_ID, "faint_royal_staff"), - Item(Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21)) - ) - - override val royalStaffItem: StaffItem = Registry.register( - Registries.ITEM, - Identifier(MOD_ID, "royal_staff"), - FabricStaffItem(Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21)) - ) - - override val staffsTag: TagKey = TagKey.of(RegistryKeys.ITEM, Identifier(MOD_ID, "staffs")) - - override val flamethrowerParticleType: DefaultParticleType = Registry.register( - Registries.PARTICLE_TYPE, - Identifier(MOD_ID, "flame"), - FabricParticleTypes.simple() - ) - - override val soulFlamethrowerParticleType: DefaultParticleType = Registry.register( - Registries.PARTICLE_TYPE, - Identifier(MOD_ID, "soul_fire_flame"), - FabricParticleTypes.simple() - ) - +object StaffMod : ModInitializer { override fun onInitialize() { AttackBlockCallback.EVENT.register(::attackBlock) AttackEntityCallback.EVENT.register(::handleEntityAttackEvent) 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 0938bcec9..0c82ab2aa 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 @@ -26,9 +26,12 @@ import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry import net.minecraft.client.item.ModelPredicateProviderRegistry -import opekope2.avm_staff.IStaffMod +import opekope2.avm_staff.api.faintRoyalStaffItem +import opekope2.avm_staff.api.flamethrowerParticleType import opekope2.avm_staff.api.item.renderer.StaffRenderer import opekope2.avm_staff.api.particle.FlamethrowerParticle +import opekope2.avm_staff.api.royalStaffItem +import opekope2.avm_staff.api.soulFlamethrowerParticleType import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING import opekope2.avm_staff.internal.event_handler.handleKeyBindings import opekope2.avm_staff.internal.model.registerModelPredicateProviders @@ -42,17 +45,17 @@ object StaffModClient : ClientModInitializer { ClientTickEvents.END_CLIENT_TICK.register(::handleKeyBindings) ParticleFactoryRegistry.getInstance().register( - IStaffMod.get().flamethrowerParticleType, + flamethrowerParticleType.get(), FlamethrowerParticle::Factory ) ParticleFactoryRegistry.getInstance().register( - IStaffMod.get().soulFlamethrowerParticleType, + soulFlamethrowerParticleType.get(), FlamethrowerParticle::Factory ) registerModelPredicateProviders(ModelPredicateProviderRegistry::register) - BuiltinItemRendererRegistry.INSTANCE.register(StaffMod.faintRoyalStaffItem, StaffRenderer::renderStaff) - BuiltinItemRendererRegistry.INSTANCE.register(StaffMod.royalStaffItem, StaffRenderer::renderStaff) + BuiltinItemRendererRegistry.INSTANCE.register(faintRoyalStaffItem.get(), StaffRenderer::renderStaff) + BuiltinItemRendererRegistry.INSTANCE.register(royalStaffItem.get(), StaffRenderer::renderStaff) } } diff --git a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModPlatformImpl.kt b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModPlatformImpl.kt index 90ddeee73..86c8652e8 100644 --- a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModPlatformImpl.kt +++ b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModPlatformImpl.kt @@ -20,6 +20,8 @@ package opekope2.avm_staff.internal.fabric -import opekope2.avm_staff.IStaffMod +import net.minecraft.item.Item +import opekope2.avm_staff.api.item.StaffItem +import opekope2.avm_staff.internal.fabric.item.FabricStaffItem -fun getStaffMod(): IStaffMod = StaffMod +fun createStaffItem(settings: Item.Settings): StaffItem = FabricStaffItem(settings) diff --git a/FabricMod/src/main/resources/fabric.mod.json b/FabricMod/src/main/resources/fabric.mod.json index c90deeb12..fb4633192 100644 --- a/FabricMod/src/main/resources/fabric.mod.json +++ b/FabricMod/src/main/resources/fabric.mod.json @@ -21,6 +21,10 @@ "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" diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt index a45f747a5..e1afe877b 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt @@ -18,81 +18,23 @@ package opekope2.avm_staff.internal.forge -import net.minecraft.item.Item -import net.minecraft.particle.DefaultParticleType -import net.minecraft.registry.tag.ItemTags -import net.minecraft.registry.tag.TagKey -import net.minecraft.resource.featuretoggle.FeatureFlags -import net.minecraft.util.Identifier +import dev.architectury.platform.forge.EventBuses import net.minecraftforge.api.distmarker.Dist import net.minecraftforge.fml.common.Mod -import net.minecraftforge.registries.DeferredRegister -import net.minecraftforge.registries.ForgeRegistries -import opekope2.avm_staff.IStaffMod -import opekope2.avm_staff.api.item.StaffItem -import opekope2.avm_staff.internal.forge.item.ForgeStaffItem import opekope2.avm_staff.internal.initializeNetworking +import opekope2.avm_staff.internal.registerContent import opekope2.avm_staff.internal.staff_item_handler.registerVanillaStaffItemHandlers import opekope2.avm_staff.util.MOD_ID import thedarkcolour.kotlinforforge.forge.MOD_BUS import thedarkcolour.kotlinforforge.forge.runWhenOn @Mod(MOD_ID) -object StaffMod : IStaffMod { - private val ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MOD_ID) - - private val FAINT_STAFF_ROD_ITEM = ITEMS.register("faint_staff_rod") { - Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21)) - } - private val FAINT_ROYAL_STAFF_HEAD_ITEM = ITEMS.register("faint_royal_staff_head") { - Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21)) - } - private val FAINT_ROYAL_STAFF_ITEM = ITEMS.register("faint_royal_staff") { - Item(Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21)) - } - private val ROYAL_STAFF_ITEM = ITEMS.register("royal_staff") { - ForgeStaffItem(Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21)) - } - - private val PARTICLE_TYPES = DeferredRegister.create(ForgeRegistries.PARTICLE_TYPES, MOD_ID) - - private val FLAMETHROWER_PARTICLE_TYPE = PARTICLE_TYPES.register("flame") { - DefaultParticleType(false) - } - - private val SOUL_FLAMETHROWER_PARTICLE_TYPE = PARTICLE_TYPES.register("soul_fire_flame") { - DefaultParticleType(false) - } - +object StaffMod { init { - initialize() + EventBuses.registerModEventBus(MOD_ID, MOD_BUS) + registerContent() initializeNetworking() registerVanillaStaffItemHandlers() runWhenOn(Dist.CLIENT, StaffModClient::initializeClient) } - - override val faintStaffRodItem: Item - get() = FAINT_STAFF_ROD_ITEM.get() - - override val faintRoyalStaffHeadItem: Item - get() = FAINT_ROYAL_STAFF_HEAD_ITEM.get() - - override val faintRoyalStaffItem: Item - get() = FAINT_ROYAL_STAFF_ITEM.get() - - override val royalStaffItem: StaffItem - get() = ROYAL_STAFF_ITEM.get() - - override val staffsTag: TagKey = ItemTags.create(Identifier(MOD_ID, "staffs")) - - override val flamethrowerParticleType: DefaultParticleType - get() = FLAMETHROWER_PARTICLE_TYPE.get() - - override val soulFlamethrowerParticleType: DefaultParticleType - get() = SOUL_FLAMETHROWER_PARTICLE_TYPE.get() - - private fun initialize() { - ITEMS.register(MOD_BUS) - PARTICLE_TYPES.register(MOD_BUS) - } } diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt index 301b0f304..cefc1b187 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt @@ -28,8 +28,9 @@ import net.minecraftforge.event.BuildCreativeModeTabContentsEvent import net.minecraftforge.event.TickEvent import net.minecraftforge.eventbus.api.SubscribeEvent import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent -import opekope2.avm_staff.IStaffMod +import opekope2.avm_staff.api.flamethrowerParticleType import opekope2.avm_staff.api.particle.FlamethrowerParticle +import opekope2.avm_staff.api.soulFlamethrowerParticleType import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING import opekope2.avm_staff.internal.event_handler.handleKeyBindings import opekope2.avm_staff.internal.model.registerModelPredicateProviders @@ -58,8 +59,8 @@ object StaffModClient { @SubscribeEvent fun registerParticleProviders(event: RegisterParticleProvidersEvent) { - event.registerSpriteSet(IStaffMod.get().flamethrowerParticleType, FlamethrowerParticle::Factory) - event.registerSpriteSet(IStaffMod.get().soulFlamethrowerParticleType, FlamethrowerParticle::Factory) + event.registerSpriteSet(flamethrowerParticleType.get(), FlamethrowerParticle::Factory) + event.registerSpriteSet(soulFlamethrowerParticleType.get(), FlamethrowerParticle::Factory) } @SubscribeEvent diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModPlatformImpl.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModPlatformImpl.kt index 7a98cbc94..355a6cb6a 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModPlatformImpl.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModPlatformImpl.kt @@ -20,6 +20,8 @@ package opekope2.avm_staff.internal.forge -import opekope2.avm_staff.IStaffMod +import net.minecraft.item.Item +import opekope2.avm_staff.api.item.StaffItem +import opekope2.avm_staff.internal.forge.item.ForgeStaffItem -fun getStaffMod(): IStaffMod = StaffMod +fun createStaffItem(settings: Item.Settings): StaffItem = ForgeStaffItem(settings) 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 97ebd5765..88076cdc5 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,81 +18,20 @@ package opekope2.avm_staff.internal.neoforge -import net.minecraft.item.Item -import net.minecraft.particle.DefaultParticleType -import net.minecraft.registry.Registries -import net.minecraft.registry.tag.ItemTags -import net.minecraft.registry.tag.TagKey -import net.minecraft.resource.featuretoggle.FeatureFlags -import net.minecraft.util.Identifier import net.neoforged.api.distmarker.Dist import net.neoforged.fml.common.Mod -import net.neoforged.neoforge.registries.DeferredRegister -import opekope2.avm_staff.IStaffMod -import opekope2.avm_staff.api.item.StaffItem import opekope2.avm_staff.internal.initializeNetworking -import opekope2.avm_staff.internal.neoforge.item.NeoForgeStaffItem +import opekope2.avm_staff.internal.registerContent import opekope2.avm_staff.internal.staff_item_handler.registerVanillaStaffItemHandlers import opekope2.avm_staff.util.MOD_ID -import thedarkcolour.kotlinforforge.neoforge.forge.MOD_BUS import thedarkcolour.kotlinforforge.neoforge.forge.runWhenOn @Mod(MOD_ID) -object StaffMod : IStaffMod { - private val ITEMS = DeferredRegister.create(Registries.ITEM, MOD_ID) - - private val FAINT_STAFF_ROD_ITEM = ITEMS.register("faint_staff_rod") { -> - Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21)) - } - private val FAINT_ROYAL_STAFF_HEAD_ITEM = ITEMS.register("faint_royal_staff_head") { -> - Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21)) - } - private val FAINT_ROYAL_STAFF_ITEM = ITEMS.register("faint_royal_staff") { -> - Item(Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21)) - } - private val ROYAL_STAFF_ITEM = ITEMS.register("royal_staff") { -> - NeoForgeStaffItem(Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21)) - } - - private val PARTICLE_TYPES = DeferredRegister.create(Registries.PARTICLE_TYPE, MOD_ID) - - private val FLAMETHROWER_PARTICLE_TYPE = PARTICLE_TYPES.register("flame") { -> - DefaultParticleType(false) - } - - private val SOUL_FLAMETHROWER_PARTICLE_TYPE = PARTICLE_TYPES.register("soul_fire_flame") { -> - DefaultParticleType(false) - } - +object StaffMod { init { - initialize() + registerContent() initializeNetworking() registerVanillaStaffItemHandlers() runWhenOn(Dist.CLIENT, StaffModClient::initializeClient) } - - override val faintStaffRodItem: Item - get() = FAINT_STAFF_ROD_ITEM.get() - - override val faintRoyalStaffHeadItem: Item - get() = FAINT_ROYAL_STAFF_HEAD_ITEM.get() - - override val faintRoyalStaffItem: Item - get() = FAINT_ROYAL_STAFF_ITEM.get() - - override val royalStaffItem: StaffItem - get() = ROYAL_STAFF_ITEM.get() - - override val staffsTag: TagKey = ItemTags.create(Identifier(MOD_ID, "staffs")) - - override val flamethrowerParticleType: DefaultParticleType - get() = FLAMETHROWER_PARTICLE_TYPE.get() - - override val soulFlamethrowerParticleType: DefaultParticleType - get() = SOUL_FLAMETHROWER_PARTICLE_TYPE.get() - - private fun initialize() { - ITEMS.register(MOD_BUS) - PARTICLE_TYPES.register(MOD_BUS) - } } 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 a84bd9d15..35f317a01 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 @@ -28,8 +28,9 @@ import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent import net.neoforged.neoforge.client.event.RegisterParticleProvidersEvent import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent import net.neoforged.neoforge.event.TickEvent -import opekope2.avm_staff.IStaffMod +import opekope2.avm_staff.api.flamethrowerParticleType import opekope2.avm_staff.api.particle.FlamethrowerParticle +import opekope2.avm_staff.api.soulFlamethrowerParticleType import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING import opekope2.avm_staff.internal.event_handler.handleKeyBindings import opekope2.avm_staff.internal.model.registerModelPredicateProviders @@ -58,8 +59,8 @@ object StaffModClient { @SubscribeEvent fun registerParticleProviders(event: RegisterParticleProvidersEvent) { - event.registerSpriteSet(IStaffMod.get().flamethrowerParticleType, FlamethrowerParticle::Factory) - event.registerSpriteSet(IStaffMod.get().soulFlamethrowerParticleType, FlamethrowerParticle::Factory) + event.registerSpriteSet(flamethrowerParticleType.get(), FlamethrowerParticle::Factory) + event.registerSpriteSet(soulFlamethrowerParticleType.get(), FlamethrowerParticle::Factory) } @SubscribeEvent diff --git a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModPlatformImpl.kt b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModPlatformImpl.kt index 61c0e0e99..b2e37f8c0 100644 --- a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModPlatformImpl.kt +++ b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModPlatformImpl.kt @@ -20,6 +20,8 @@ package opekope2.avm_staff.internal.neoforge -import opekope2.avm_staff.IStaffMod +import net.minecraft.item.Item +import opekope2.avm_staff.api.item.StaffItem +import opekope2.avm_staff.internal.neoforge.item.NeoForgeStaffItem -fun getStaffMod(): IStaffMod = StaffMod +fun createStaffItem(settings: Item.Settings): StaffItem = NeoForgeStaffItem(settings) 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 5f1205421..6977c47bf 100644 --- a/StaffMod/src/main/java/opekope2/avm_staff/mixin/BipedEntityModelMixin.java +++ b/StaffMod/src/main/java/opekope2/avm_staff/mixin/BipedEntityModelMixin.java @@ -21,7 +21,7 @@ import net.minecraft.client.model.ModelPart; import net.minecraft.client.render.entity.model.BipedEntityModel; import net.minecraft.entity.LivingEntity; -import opekope2.avm_staff.IStaffMod; +import opekope2.avm_staff.api.StaffMod; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -51,7 +51,7 @@ public abstract class BipedEntityModelMixin { @Inject(method = "positionLeftArm", at = @At("TAIL")) private void positionLeftArm(LivingEntity entity, CallbackInfo ci) { - if (leftArmPose == BipedEntityModel.ArmPose.ITEM && entity.getActiveItem().isIn(IStaffMod.get().getStaffsTag())) { + if (leftArmPose == BipedEntityModel.ArmPose.ITEM && entity.getActiveItem().isIn(StaffMod.getStaffsTag())) { leftArm.yaw = head.yaw; leftArm.pitch = head.pitch - 0.5f * (float) Math.PI; } @@ -59,7 +59,7 @@ private void positionLeftArm(LivingEntity entity, CallbackInfo ci) { @Inject(method = "positionRightArm", at = @At("TAIL")) private void positionRightArm(LivingEntity entity, CallbackInfo ci) { - if (rightArmPose == BipedEntityModel.ArmPose.ITEM && entity.getActiveItem().isIn(IStaffMod.get().getStaffsTag())) { + if (rightArmPose == BipedEntityModel.ArmPose.ITEM && entity.getActiveItem().isIn(StaffMod.getStaffsTag())) { rightArm.yaw = head.yaw; rightArm.pitch = head.pitch - 0.5f * (float) Math.PI; } diff --git a/StaffMod/src/main/java/opekope2/avm_staff/mixin/LivingEntityMixin.java b/StaffMod/src/main/java/opekope2/avm_staff/mixin/LivingEntityMixin.java index 2fc3b7260..03518db01 100644 --- a/StaffMod/src/main/java/opekope2/avm_staff/mixin/LivingEntityMixin.java +++ b/StaffMod/src/main/java/opekope2/avm_staff/mixin/LivingEntityMixin.java @@ -20,7 +20,7 @@ import net.minecraft.entity.LivingEntity; import net.minecraft.item.ItemStack; -import opekope2.avm_staff.IStaffMod; +import opekope2.avm_staff.api.StaffMod; import opekope2.avm_staff.api.item.IActiveItemTempDataHolder; import opekope2.avm_staff.api.item.IDisablesShield; import opekope2.avm_staff.api.item.StaffItemHandler; @@ -46,7 +46,7 @@ public abstract class LivingEntityMixin implements IActiveItemTempDataHolder { @Inject(method = "disablesShield", at = @At("HEAD"), cancellable = true) public void disableShield(CallbackInfoReturnable cir) { ItemStack mainHandStack = getMainHandStack(); - if (!mainHandStack.isIn(IStaffMod.get().getStaffsTag())) return; + if (!mainHandStack.isIn(StaffMod.getStaffsTag())) return; ItemStack itemInStaff = StaffUtil.getItemInStaff(mainHandStack); if (itemInStaff == null) return; diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt deleted file mode 100644 index 1b8daeaf7..000000000 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt +++ /dev/null @@ -1,90 +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 - -import net.minecraft.client.particle.ParticleManager -import net.minecraft.item.Item -import net.minecraft.particle.DefaultParticleType -import net.minecraft.registry.tag.TagKey -import opekope2.avm_staff.api.item.StaffItem -import opekope2.avm_staff.internal.getStaffMod - -/** - * A non-loader-specific interface of the Staff Mod. - */ -interface IStaffMod { - /** - * Gets `avm_staff:faint_staff_rod` item registered in Minecraft. - * - * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. - */ - val faintStaffRodItem: Item - - /** - * Gets `avm_staff:faint_royal_staff_head` item registered in Minecraft. - * - * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. - */ - val faintRoyalStaffHeadItem: Item - - /** - * Gets `avm_staff:faint_royal_staff` item registered in Minecraft. - * - * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. - */ - val faintRoyalStaffItem: Item - - /** - * Gets `avm_staff:royal_staff` item registered in Minecraft. - * - * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. - */ - val royalStaffItem: StaffItem - - /** - * Gets the [TagKey] containing all the staffs. - */ - val staffsTag: TagKey - - /** - * Gets the flamethrower's flame particle type. - * - * Due to how Forge registries work, *always* use this getter instead of storing the result. - * - * @see ParticleManager.addParticle - */ - val flamethrowerParticleType: DefaultParticleType - - /** - * Gets the soul fire flamethrower's flame particle type. - * - * Due to how Forge registries work, *always* use this getter instead of storing the result. - * - * @see ParticleManager.addParticle - */ - val soulFlamethrowerParticleType: DefaultParticleType - - companion object Holder { - /** - * Gets the currently running loader-specific Staff Mod instance. - */ - @JvmStatic - fun get(): IStaffMod = getStaffMod() - } -} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt new file mode 100644 index 000000000..83bfc3074 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -0,0 +1,107 @@ +/* + * 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") + +package opekope2.avm_staff.api + +import dev.architectury.registry.registries.DeferredRegister +import dev.architectury.registry.registries.RegistrySupplier +import net.minecraft.client.particle.ParticleManager +import net.minecraft.item.Item +import net.minecraft.particle.DefaultParticleType +import net.minecraft.registry.RegistryKeys +import net.minecraft.registry.tag.TagKey +import net.minecraft.resource.featuretoggle.FeatureFlags +import net.minecraft.util.Identifier +import opekope2.avm_staff.api.item.StaffItem +import opekope2.avm_staff.internal.createStaffItem +import opekope2.avm_staff.util.MOD_ID + +private val ITEMS = DeferredRegister.create(MOD_ID, RegistryKeys.ITEM) +private val PARTICLE_TYPES = DeferredRegister.create(MOD_ID, RegistryKeys.PARTICLE_TYPE) + +/** + * Gets `avm_staff:faint_staff_rod` item registered in Minecraft. + * + * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. + */ +val faintStaffRodItem: RegistrySupplier = ITEMS.register("faint_staff_rod") { + Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21)) +} + +/** + * Gets `avm_staff:faint_royal_staff_head` item registered in Minecraft. + * + * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. + */ +val faintRoyalStaffHeadItem: RegistrySupplier = ITEMS.register("faint_royal_staff_head") { + Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21)) +} + +/** + * Gets `avm_staff:faint_royal_staff` item registered in Minecraft. + * + * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. + */ +val faintRoyalStaffItem: RegistrySupplier = ITEMS.register("faint_royal_staff") { + Item(Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21)) +} + +/** + * Gets `avm_staff:royal_staff` item registered in Minecraft. + * + * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. + */ +val royalStaffItem: RegistrySupplier = ITEMS.register("royal_staff") { + createStaffItem(Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21)) +} + +/** + * Gets the [TagKey] containing all the staffs. + */ +val staffsTag: TagKey = TagKey.of(RegistryKeys.ITEM, Identifier(MOD_ID, "staffs")) + +/** + * Gets the flamethrower's flame particle type. + * + * Due to how Forge registries work, *always* use this getter instead of storing the result. + * + * @see ParticleManager.addParticle + */ +val flamethrowerParticleType: RegistrySupplier = + PARTICLE_TYPES.register("flame") { DefaultParticleType(false) } + +/** + * Gets the soul fire flamethrower's flame particle type. + * + * Due to how Forge registries work, *always* use this getter instead of storing the result. + * + * @see ParticleManager.addParticle + */ +val soulFlamethrowerParticleType: RegistrySupplier = + PARTICLE_TYPES.register("soul_fire_flame") { DefaultParticleType(false) } + +/** + * @suppress + */ +@JvmSynthetic +internal fun registerContent() { + ITEMS.register() + PARTICLE_TYPES.register() +} 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 fa328899c..0525cf955 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,7 +24,8 @@ import net.minecraft.client.particle.* import net.minecraft.client.world.ClientWorld import net.minecraft.particle.DefaultParticleType import net.minecraft.util.math.BlockPos -import opekope2.avm_staff.IStaffMod +import opekope2.avm_staff.api.flamethrowerParticleType +import opekope2.avm_staff.api.soulFlamethrowerParticleType import opekope2.avm_staff.mixin.IParticleMixin /** @@ -106,7 +107,8 @@ class FlamethrowerParticle( * Factory class for [FlamethrowerParticle], intended to register in Minecraft instead of direct consumption. * * @param spriteProvider Flame sprite provider - * @see IStaffMod.flamethrowerParticleType + * @see flamethrowerParticleType + * @see soulFlamethrowerParticleType * @see ParticleManager.addParticle */ class Factory(private val spriteProvider: SpriteProvider) : ParticleFactory { 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 d942012b1..0b4d3fcb4 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -25,6 +25,10 @@ import opekope2.avm_staff.internal.networking.c2s.play.AddItemToStaffC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.RemoveItemFromStaffC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.StaffAttackC2SPacket +fun registerContent() { + opekope2.avm_staff.api.registerContent() +} + fun initializeNetworking() { AddItemToStaffC2SPacket.registerHandler(::addBlockToStaff) RemoveItemFromStaffC2SPacket.registerHandler(::removeBlockFromStaff) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/StaffModPlatform.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/StaffModPlatform.kt index 6ce5963fa..2b83a7cb4 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/StaffModPlatform.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/StaffModPlatform.kt @@ -21,9 +21,10 @@ package opekope2.avm_staff.internal import dev.architectury.injectables.annotations.ExpectPlatform -import opekope2.avm_staff.IStaffMod +import net.minecraft.item.Item +import opekope2.avm_staff.api.item.StaffItem @ExpectPlatform -fun getStaffMod(): IStaffMod { +fun createStaffItem(settings: Item.Settings): StaffItem { throw AssertionError() } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt index da205fca7..52fa2f4a1 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt @@ -24,7 +24,7 @@ import net.minecraft.entity.player.PlayerInventory import net.minecraft.item.ItemStack import net.minecraft.util.ActionResult import net.minecraft.util.Hand -import opekope2.avm_staff.IStaffMod +import opekope2.avm_staff.api.staffsTag import opekope2.avm_staff.internal.networking.c2s.play.AddItemToStaffC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.RemoveItemFromStaffC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.StaffAttackC2SPacket @@ -32,8 +32,6 @@ import opekope2.avm_staff.util.hasHandlerOfItem import opekope2.avm_staff.util.isItemInStaff import opekope2.avm_staff.util.itemInStaff -private val staffMod: IStaffMod = IStaffMod.get() - @Suppress("UNUSED_PARAMETER") fun addBlockToStaff(packet: AddItemToStaffC2SPacket, context: PacketContext) { val player = context.player @@ -81,10 +79,10 @@ private fun findStaffStackAndItemSlot(player: PlayerEntity): Pair + mainStack.isIn(staffsTag) && !offStack.isIn(staffsTag) -> mainStack to PlayerInventory.OFF_HAND_SLOT - offStack.isIn(staffMod.staffsTag) && !mainStack.isIn(staffMod.staffsTag) -> + offStack.isIn(staffsTag) && !mainStack.isIn(staffsTag) -> offStack to player.inventory.selectedSlot else -> null @@ -96,8 +94,8 @@ private fun findStaffAndItemStack(player: PlayerEntity): Pair mainStack to offStack - offStack.isIn(staffMod.staffsTag) && !mainStack.isIn(staffMod.staffsTag) -> offStack to mainStack + mainStack.isIn(staffsTag) && !offStack.isIn(staffsTag) -> mainStack to offStack + offStack.isIn(staffsTag) && !mainStack.isIn(staffsTag) -> offStack to mainStack else -> null } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt index b71c4497b..45b56b62e 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt @@ -27,12 +27,10 @@ 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.IStaffMod +import opekope2.avm_staff.api.staffsTag import opekope2.avm_staff.util.handlerOfItem import opekope2.avm_staff.util.itemInStaff -private val staffMod = IStaffMod.get() - fun attackBlock( player: PlayerEntity, world: World, @@ -41,7 +39,7 @@ fun attackBlock( direction: Direction ): ActionResult { val staffStack = player.getStackInHand(hand) - if (!staffStack.isIn(staffMod.staffsTag)) return ActionResult.PASS + if (!staffStack.isIn(staffsTag)) return ActionResult.PASS val itemInStaff = staffStack.itemInStaff ?: return ActionResult.PASS val staffHandler = itemInStaff.handlerOfItem ?: return ActionResult.PASS @@ -51,7 +49,7 @@ fun attackBlock( fun attackEntity(player: PlayerEntity, world: World, hand: Hand, target: Entity): ActionResult { val itemStack = player.getStackInHand(hand) - if (!itemStack.isIn(staffMod.staffsTag)) return ActionResult.PASS + if (!itemStack.isIn(staffsTag)) return ActionResult.PASS val itemInStaff = itemStack.itemInStaff ?: return ActionResult.PASS val staffHandler = itemInStaff.handlerOfItem ?: return ActionResult.PASS @@ -60,7 +58,7 @@ fun attackEntity(player: PlayerEntity, world: World, hand: Hand, target: Entity) } fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand): ActionResult { - if (!staffStack.isIn(staffMod.staffsTag)) return ActionResult.PASS + if (!staffStack.isIn(staffsTag)) return ActionResult.PASS val itemInStaff: ItemStack = staffStack.itemInStaff ?: return ActionResult.PASS val staffHandler = itemInStaff.handlerOfItem ?: return ActionResult.PASS diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/CampfireHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/CampfireHandler.kt index e2fbe0703..b4067b9cd 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/CampfireHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/CampfireHandler.kt @@ -19,6 +19,7 @@ package opekope2.avm_staff.internal.staff_item_handler 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.* @@ -29,7 +30,7 @@ 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.ParticleEffect +import net.minecraft.particle.DefaultParticleType import net.minecraft.server.MinecraftServer import net.minecraft.state.property.Properties.LIT import net.minecraft.util.Hand @@ -43,13 +44,12 @@ 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.IStaffMod import opekope2.avm_staff.api.item.StaffItemHandler import opekope2.avm_staff.mixin.IEntityMixin import opekope2.avm_staff.util.* class CampfireHandler( - private val particleEffectGetter: (IStaffMod) -> ParticleEffect, + private val particleEffectSupplier: RegistrySupplier, private val properties: Properties ) : StaffItemHandler() { override val maxUseTime: Int @@ -133,7 +133,7 @@ class CampfireHandler( val particleSpeed = targetDirection.normalize() * FLAME_SPEED * (0.9 + Math.random() * 0.2) particleManager.addParticle( - particleEffectGetter(IStaffMod.get()), + particleEffectSupplier.get(), origin.x, origin.y, origin.z, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt index ebe35f390..2db18a21e 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt @@ -27,10 +27,11 @@ import net.minecraft.item.Items import net.minecraft.recipe.RecipeType import net.minecraft.registry.Registries import net.minecraft.sound.SoundEvents -import opekope2.avm_staff.IStaffMod +import opekope2.avm_staff.api.flamethrowerParticleType import opekope2.avm_staff.api.item.StaffItemHandler import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer +import opekope2.avm_staff.api.soulFlamethrowerParticleType private fun Item.registerHandler(handler: StaffItemHandler) { StaffItemHandler.register(Registries.ITEM.getId(this), handler) @@ -47,16 +48,10 @@ fun registerVanillaStaffItemHandlers() { Items.BONE_BLOCK.registerHandler(BoneBlockHandler()) Items.CAMPFIRE.registerHandler( - CampfireHandler( - IStaffMod::flamethrowerParticleType, - CampfireHandler.Properties(1 / 20.0, 5 / 20.0, 1, 0.1) - ) + CampfireHandler(flamethrowerParticleType, CampfireHandler.Properties(1 / 20.0, 5 / 20.0, 1, 0.1)) ) Items.SOUL_CAMPFIRE.registerHandler( - CampfireHandler( - IStaffMod::soulFlamethrowerParticleType, - CampfireHandler.Properties(2 / 20.0, 10 / 20.0, 2, 0.12) - ) + CampfireHandler(soulFlamethrowerParticleType, CampfireHandler.Properties(2 / 20.0, 10 / 20.0, 2, 0.12)) ) Items.FURNACE.registerHandler( diff --git a/StaffMod/src/main/resources/avm_staff.accesswidener b/StaffMod/src/main/resources/avm_staff.accesswidener index 51740a8ee..422052a07 100644 --- a/StaffMod/src/main/resources/avm_staff.accesswidener +++ b/StaffMod/src/main/resources/avm_staff.accesswidener @@ -1,4 +1,5 @@ accessWidener v2 named -accessible field net/minecraft/item/Item ATTACK_DAMAGE_MODIFIER_ID Ljava/util/UUID; -accessible field net/minecraft/item/Item ATTACK_SPEED_MODIFIER_ID Ljava/util/UUID; +accessible field net/minecraft/item/Item ATTACK_DAMAGE_MODIFIER_ID Ljava/util/UUID; +accessible field net/minecraft/item/Item ATTACK_SPEED_MODIFIER_ID Ljava/util/UUID; +accessible method net/minecraft/particle/DefaultParticleType (Z)V From e71102d1d61765e5f7275eea7d658b298d9a909f Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 17 May 2024 22:59:35 +0200 Subject: [PATCH 027/128] Add Neo/Forge Item classes to render non-functional staff items as staffs --- .../internal/forge/item/ForgeStaffItem.kt | 2 +- .../forge/item/ForgeStaffRendererItem.kt | 31 +++++++++++++++++++ .../neoforge/item/NeoForgeStaffItem.kt | 2 +- .../item/NeoForgeStaffRendererItem.kt | 31 +++++++++++++++++++ 4 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffRendererItem.kt create mode 100644 NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/NeoForgeStaffRendererItem.kt diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt index 9441cb2a9..80f7064a3 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt @@ -68,7 +68,7 @@ class ForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IForgeItem }) } - private object Renderer : BuiltinModelItemRenderer( + object Renderer : BuiltinModelItemRenderer( MinecraftClient.getInstance().blockEntityRenderDispatcher, MinecraftClient.getInstance().entityModelLoader ) { diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffRendererItem.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffRendererItem.kt new file mode 100644 index 000000000..ee6b15920 --- /dev/null +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffRendererItem.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.internal.forge.item + +import net.minecraft.item.Item +import net.minecraftforge.client.extensions.common.IClientItemExtensions +import java.util.function.Consumer + +class ForgeStaffRendererItem(settings: Settings) : Item(settings) { + override fun initializeClient(consumer: Consumer) { + consumer.accept(object : IClientItemExtensions { + override fun getCustomRenderer() = ForgeStaffItem.Renderer + }) + } +} 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 dae01250f..2cc2a0e9f 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 @@ -68,7 +68,7 @@ class NeoForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IItemExt }) } - private object Renderer : BuiltinModelItemRenderer( + object Renderer : BuiltinModelItemRenderer( MinecraftClient.getInstance().blockEntityRenderDispatcher, MinecraftClient.getInstance().entityModelLoader ) { diff --git a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/NeoForgeStaffRendererItem.kt b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/NeoForgeStaffRendererItem.kt new file mode 100644 index 000000000..1b0c9963e --- /dev/null +++ b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/NeoForgeStaffRendererItem.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.internal.neoforge.item + +import net.minecraft.item.Item +import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions +import java.util.function.Consumer + +class NeoForgeStaffRendererItem(settings: Settings) : Item(settings) { + override fun initializeClient(consumer: Consumer) { + consumer.accept(object : IClientItemExtensions { + override fun getCustomRenderer() = NeoForgeStaffItem.Renderer + }) + } +} From 6cdee009388d7d20f21ee6ea5711e2fcf786b105 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 17 May 2024 23:01:35 +0200 Subject: [PATCH 028/128] Automatically register FabricStaffItem for custom rendering Just like on Neo/Forge --- .../avm_staff/internal/fabric/StaffModClient.kt | 2 -- .../avm_staff/internal/fabric/item/FabricStaffItem.kt | 10 ++++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) 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 0c82ab2aa..a70781e79 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 @@ -30,7 +30,6 @@ import opekope2.avm_staff.api.faintRoyalStaffItem import opekope2.avm_staff.api.flamethrowerParticleType import opekope2.avm_staff.api.item.renderer.StaffRenderer import opekope2.avm_staff.api.particle.FlamethrowerParticle -import opekope2.avm_staff.api.royalStaffItem import opekope2.avm_staff.api.soulFlamethrowerParticleType import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING import opekope2.avm_staff.internal.event_handler.handleKeyBindings @@ -56,6 +55,5 @@ object StaffModClient : ClientModInitializer { registerModelPredicateProviders(ModelPredicateProviderRegistry::register) BuiltinItemRendererRegistry.INSTANCE.register(faintRoyalStaffItem.get(), StaffRenderer::renderStaff) - BuiltinItemRendererRegistry.INSTANCE.register(royalStaffItem.get(), StaffRenderer::renderStaff) } } 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 18c31282f..b227b96da 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 @@ -19,7 +19,10 @@ package opekope2.avm_staff.internal.fabric.item import com.google.common.collect.Multimap +import net.fabricmc.api.EnvType +import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry import net.fabricmc.fabric.api.item.v1.FabricItem +import net.fabricmc.loader.api.FabricLoader import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.attribute.EntityAttribute import net.minecraft.entity.attribute.EntityAttributeModifier @@ -28,10 +31,17 @@ import net.minecraft.item.Item import net.minecraft.item.ItemStack 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.handlerOfItemOrFallback import opekope2.avm_staff.util.itemInStaff class FabricStaffItem(settings: Item.Settings) : StaffItem(settings), FabricItem { + init { + if (FabricLoader.getInstance().environmentType == EnvType.CLIENT) { + BuiltinItemRendererRegistry.INSTANCE.register(this, StaffRenderer::renderStaff) + } + } + override fun allowNbtUpdateAnimation( player: PlayerEntity, hand: Hand, From 724cfd725092537ffcf377e731f510ce18833e59 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 17 May 2024 23:04:04 +0200 Subject: [PATCH 029/128] Fix faint royal staff not rendering on Neo/Forge --- .../avm_staff/internal/fabric/StaffModClient.kt | 5 ----- .../internal/fabric/StaffModPlatformImpl.kt | 13 +++++++++++++ .../internal/forge/StaffModPlatformImpl.kt | 4 ++++ .../internal/neoforge/StaffModPlatformImpl.kt | 4 ++++ .../main/kotlin/opekope2/avm_staff/api/StaffMod.kt | 3 ++- .../opekope2/avm_staff/internal/StaffModPlatform.kt | 8 +++++--- 6 files changed, 28 insertions(+), 9 deletions(-) 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 a70781e79..3fd85ec9e 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 @@ -24,11 +24,8 @@ import net.fabricmc.api.Environment import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry -import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry import net.minecraft.client.item.ModelPredicateProviderRegistry -import opekope2.avm_staff.api.faintRoyalStaffItem import opekope2.avm_staff.api.flamethrowerParticleType -import opekope2.avm_staff.api.item.renderer.StaffRenderer import opekope2.avm_staff.api.particle.FlamethrowerParticle import opekope2.avm_staff.api.soulFlamethrowerParticleType import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING @@ -53,7 +50,5 @@ object StaffModClient : ClientModInitializer { ) registerModelPredicateProviders(ModelPredicateProviderRegistry::register) - - BuiltinItemRendererRegistry.INSTANCE.register(faintRoyalStaffItem.get(), StaffRenderer::renderStaff) } } diff --git a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModPlatformImpl.kt b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModPlatformImpl.kt index 86c8652e8..5c9336f8e 100644 --- a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModPlatformImpl.kt +++ b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModPlatformImpl.kt @@ -17,11 +17,24 @@ */ @file: JvmName("StaffModPlatformImpl") +@file: Suppress("unused") package opekope2.avm_staff.internal.fabric +import net.fabricmc.api.EnvType +import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry +import net.fabricmc.loader.api.FabricLoader import net.minecraft.item.Item import opekope2.avm_staff.api.item.StaffItem +import opekope2.avm_staff.api.item.renderer.StaffRenderer import opekope2.avm_staff.internal.fabric.item.FabricStaffItem fun createStaffItem(settings: Item.Settings): StaffItem = FabricStaffItem(settings) + +fun createStaffRendererItem(settings: Item.Settings): Item { + return Item(settings).also { item -> + if (FabricLoader.getInstance().environmentType == EnvType.CLIENT) { + BuiltinItemRendererRegistry.INSTANCE.register(item, StaffRenderer::renderStaff) + } + } +} diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModPlatformImpl.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModPlatformImpl.kt index 355a6cb6a..2d6ea5708 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModPlatformImpl.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModPlatformImpl.kt @@ -17,11 +17,15 @@ */ @file: JvmName("StaffModPlatformImpl") +@file: Suppress("unused") package opekope2.avm_staff.internal.forge import net.minecraft.item.Item import opekope2.avm_staff.api.item.StaffItem import opekope2.avm_staff.internal.forge.item.ForgeStaffItem +import opekope2.avm_staff.internal.forge.item.ForgeStaffRendererItem fun createStaffItem(settings: Item.Settings): StaffItem = ForgeStaffItem(settings) + +fun createStaffRendererItem(settings: Item.Settings): Item = ForgeStaffRendererItem(settings) diff --git a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModPlatformImpl.kt b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModPlatformImpl.kt index b2e37f8c0..5b9318d1d 100644 --- a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModPlatformImpl.kt +++ b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModPlatformImpl.kt @@ -17,11 +17,15 @@ */ @file: JvmName("StaffModPlatformImpl") +@file: Suppress("unused") package opekope2.avm_staff.internal.neoforge import net.minecraft.item.Item import opekope2.avm_staff.api.item.StaffItem import opekope2.avm_staff.internal.neoforge.item.NeoForgeStaffItem +import opekope2.avm_staff.internal.neoforge.item.NeoForgeStaffRendererItem fun createStaffItem(settings: Item.Settings): StaffItem = NeoForgeStaffItem(settings) + +fun createStaffRendererItem(settings: Item.Settings): Item = NeoForgeStaffRendererItem(settings) 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 83bfc3074..25b6cbbc6 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -31,6 +31,7 @@ import net.minecraft.resource.featuretoggle.FeatureFlags import net.minecraft.util.Identifier import opekope2.avm_staff.api.item.StaffItem import opekope2.avm_staff.internal.createStaffItem +import opekope2.avm_staff.internal.createStaffRendererItem import opekope2.avm_staff.util.MOD_ID private val ITEMS = DeferredRegister.create(MOD_ID, RegistryKeys.ITEM) @@ -60,7 +61,7 @@ val faintRoyalStaffHeadItem: RegistrySupplier = ITEMS.register("faint_roya * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. */ val faintRoyalStaffItem: RegistrySupplier = ITEMS.register("faint_royal_staff") { - Item(Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21)) + createStaffRendererItem(Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21)) } /** diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/StaffModPlatform.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/StaffModPlatform.kt index 2b83a7cb4..6bda69f2d 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/StaffModPlatform.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/StaffModPlatform.kt @@ -17,6 +17,7 @@ */ @file: JvmName("StaffModPlatform") +@file: Suppress("UNUSED_PARAMETER") package opekope2.avm_staff.internal @@ -25,6 +26,7 @@ import net.minecraft.item.Item import opekope2.avm_staff.api.item.StaffItem @ExpectPlatform -fun createStaffItem(settings: Item.Settings): StaffItem { - throw AssertionError() -} +fun createStaffItem(settings: Item.Settings): StaffItem = throw AssertionError() + +@ExpectPlatform +fun createStaffRendererItem(settings: Item.Settings): Item = throw AssertionError() From 89ebeafb65192ebb43da5af2d4ca4457a641af70 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 17 May 2024 23:10:30 +0200 Subject: [PATCH 030/128] Add Staff Mod item group --- .../kotlin/opekope2/avm_staff/api/StaffMod.kt | 28 ++++++++++++++++--- .../VanillaStaffItemHandlers.kt | 5 +++- .../assets/avm_staff/lang/en_us.json | 3 +- 3 files changed, 30 insertions(+), 6 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 25b6cbbc6..d13ad7ff2 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -20,21 +20,27 @@ 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.client.particle.ParticleManager import net.minecraft.item.Item +import net.minecraft.item.ItemGroup +import net.minecraft.item.Items import net.minecraft.particle.DefaultParticleType import net.minecraft.registry.RegistryKeys import net.minecraft.registry.tag.TagKey import net.minecraft.resource.featuretoggle.FeatureFlags +import net.minecraft.text.Text import net.minecraft.util.Identifier import opekope2.avm_staff.api.item.StaffItem import opekope2.avm_staff.internal.createStaffItem import opekope2.avm_staff.internal.createStaffRendererItem import opekope2.avm_staff.util.MOD_ID +import opekope2.avm_staff.util.itemInStaff private val ITEMS = DeferredRegister.create(MOD_ID, RegistryKeys.ITEM) +private val ITEM_GROUPS = DeferredRegister.create(MOD_ID, RegistryKeys.ITEM_GROUP) private val PARTICLE_TYPES = DeferredRegister.create(MOD_ID, RegistryKeys.PARTICLE_TYPE) /** @@ -43,7 +49,7 @@ private val PARTICLE_TYPES = DeferredRegister.create(MOD_ID, RegistryKeys.PARTIC * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. */ val faintStaffRodItem: RegistrySupplier = ITEMS.register("faint_staff_rod") { - Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21)) + Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21).`arch$tab`(staffModItemGroup)) } /** @@ -52,7 +58,7 @@ val faintStaffRodItem: RegistrySupplier = ITEMS.register("faint_staff_rod" * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. */ val faintRoyalStaffHeadItem: RegistrySupplier = ITEMS.register("faint_royal_staff_head") { - Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21)) + Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21).`arch$tab`(staffModItemGroup)) } /** @@ -61,7 +67,9 @@ val faintRoyalStaffHeadItem: RegistrySupplier = ITEMS.register("faint_roya * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. */ val faintRoyalStaffItem: RegistrySupplier = ITEMS.register("faint_royal_staff") { - createStaffRendererItem(Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21)) + createStaffRendererItem( + Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21).`arch$tab`(staffModItemGroup) + ) } /** @@ -70,7 +78,7 @@ val faintRoyalStaffItem: RegistrySupplier = ITEMS.register("faint_royal_st * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. */ val royalStaffItem: RegistrySupplier = ITEMS.register("royal_staff") { - createStaffItem(Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21)) + createStaffItem(Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21).`arch$tab`(staffModItemGroup)) } /** @@ -78,6 +86,17 @@ val royalStaffItem: RegistrySupplier = ITEMS.register("royal_staff") */ val staffsTag: TagKey = TagKey.of(RegistryKeys.ITEM, Identifier(MOD_ID, "staffs")) +/** + * Gets Staff Mod's item group. + */ +val staffModItemGroup: RegistrySupplier = ITEM_GROUPS.register("avm_staff_items") { + CreativeTabRegistry.create(Text.translatable("itemGroup.avm_staff_items")) { + royalStaffItem.get().defaultStack.apply { + itemInStaff = Items.COMMAND_BLOCK.defaultStack + } + } +} + /** * Gets the flamethrower's flame particle type. * @@ -104,5 +123,6 @@ val soulFlamethrowerParticleType: RegistrySupplier = @JvmSynthetic internal fun registerContent() { ITEMS.register() + ITEM_GROUPS.register() PARTICLE_TYPES.register() } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt index 2db18a21e..7e3995029 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt @@ -54,6 +54,8 @@ fun registerVanillaStaffItemHandlers() { CampfireHandler(soulFlamethrowerParticleType, CampfireHandler.Properties(2 / 20.0, 10 / 20.0, 2, 0.12)) ) + // TODO command block + Items.FURNACE.registerHandler( FurnaceHandler(RecipeType.SMELTING, SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE) ) @@ -117,6 +119,8 @@ fun registerVanillaStaffItemRenderers() { Items.CAMPFIRE.registerStaffItemRenderer(CAMPFIRE) Items.SOUL_CAMPFIRE.registerStaffItemRenderer(SOUL_CAMPFIRE) + Items.COMMAND_BLOCK.registerStaffItemRenderer(COMMAND_BLOCK) + Items.FURNACE.registerStaffItemRenderer(FurnaceHandler.FurnaceStaffItemRenderer(FURNACE)) Items.BLAST_FURNACE.registerStaffItemRenderer(FurnaceHandler.FurnaceStaffItemRenderer(BLAST_FURNACE)) Items.SMOKER.registerStaffItemRenderer(FurnaceHandler.FurnaceStaffItemRenderer(SMOKER)) @@ -147,5 +151,4 @@ fun registerVanillaStaffItemRenderers() { Items.GREEN_WOOL.registerStaffItemRenderer(GREEN_WOOL) Items.RED_WOOL.registerStaffItemRenderer(RED_WOOL) Items.BLACK_WOOL.registerStaffItemRenderer(BLACK_WOOL) - } 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 2259d5d75..23fcbfab0 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 @@ -5,5 +5,6 @@ "item.avm_staff.royal_staff": "Royal staff", "item.avm_staff.royal_staff.with_item": "Royal staff with %s", "key.categories.avm_staff": "Staff Mod", - "key.avm_staff.add_remove_staff_block": "Add/remove staff item" + "key.avm_staff.add_remove_staff_block": "Add/remove staff item", + "itemGroup.avm_staff_items": "Staff Mod" } From 08d22b3be8399bd03fd0a1841a062ac3264c791d Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 18 May 2024 15:57:25 +0200 Subject: [PATCH 031/128] Add rarity to staff items --- .../main/kotlin/opekope2/avm_staff/api/StaffMod.kt | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 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 d13ad7ff2..acccbb2d6 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -33,6 +33,7 @@ import net.minecraft.registry.tag.TagKey import net.minecraft.resource.featuretoggle.FeatureFlags import net.minecraft.text.Text import net.minecraft.util.Identifier +import net.minecraft.util.Rarity import opekope2.avm_staff.api.item.StaffItem import opekope2.avm_staff.internal.createStaffItem import opekope2.avm_staff.internal.createStaffRendererItem @@ -58,7 +59,10 @@ val faintStaffRodItem: RegistrySupplier = ITEMS.register("faint_staff_rod" * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. */ val faintRoyalStaffHeadItem: RegistrySupplier = ITEMS.register("faint_royal_staff_head") { - Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21).`arch$tab`(staffModItemGroup)) + Item( + Item.Settings().maxCount(16).rarity(Rarity.RARE).requires(FeatureFlags.UPDATE_1_21) + .`arch$tab`(staffModItemGroup) + ) } /** @@ -68,7 +72,8 @@ val faintRoyalStaffHeadItem: RegistrySupplier = ITEMS.register("faint_roya */ val faintRoyalStaffItem: RegistrySupplier = ITEMS.register("faint_royal_staff") { createStaffRendererItem( - Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21).`arch$tab`(staffModItemGroup) + Item.Settings().maxCount(1).rarity(Rarity.RARE).requires(FeatureFlags.UPDATE_1_21) + .`arch$tab`(staffModItemGroup) ) } @@ -78,7 +83,10 @@ val faintRoyalStaffItem: RegistrySupplier = ITEMS.register("faint_royal_st * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. */ val royalStaffItem: RegistrySupplier = ITEMS.register("royal_staff") { - createStaffItem(Item.Settings().maxCount(1).requires(FeatureFlags.UPDATE_1_21).`arch$tab`(staffModItemGroup)) + createStaffItem( + Item.Settings().maxCount(1).rarity(Rarity.EPIC).requires(FeatureFlags.UPDATE_1_21) + .`arch$tab`(staffModItemGroup) + ) } /** From c4c0eee4c08a7c39fc89ecada91adeb33fb34900 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 18 May 2024 18:40:00 +0200 Subject: [PATCH 032/128] Add Crown of King Orange --- .../mixin/fabric/PiglinBrainMixin.java | 41 ++++++++++++ .../internal/fabric/StaffModPlatformImpl.kt | 3 + .../resources/avm_staff_fabric.mixins.json | 12 ++++ FabricMod/src/main/resources/fabric.mod.json | 7 +- .../avm_staff/internal/forge/StaffMod.kt | 2 + .../internal/forge/StaffModPlatformImpl.kt | 4 ++ .../internal/forge/item/ForgeCrownItem.kt | 31 +++++++++ .../avm_staff/internal/neoforge/StaffMod.kt | 2 + .../internal/neoforge/StaffModPlatformImpl.kt | 4 ++ .../neoforge/item/NeoForgeCrownItem.kt | 31 +++++++++ .../kotlin/opekope2/avm_staff/api/StaffMod.kt | 14 ++++ .../opekope2/avm_staff/api/item/CrownItem.kt | 49 ++++++++++++++ .../avm_staff/internal/Initializer.kt | 15 +++++ .../avm_staff/internal/StaffModPlatform.kt | 4 ++ .../assets/avm_staff/lang/en_us.json | 1 + .../models/item/crown_of_king_orange.json | 62 ++++++++++++++++++ .../textures/item/crown_of_king_orange.png | Bin 0 -> 147 bytes 17 files changed, 281 insertions(+), 1 deletion(-) create mode 100644 FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/PiglinBrainMixin.java create mode 100644 FabricMod/src/main/resources/avm_staff_fabric.mixins.json create mode 100644 ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeCrownItem.kt create mode 100644 NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/NeoForgeCrownItem.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/CrownItem.kt create mode 100644 StaffMod/src/main/resources/assets/avm_staff/models/item/crown_of_king_orange.json create mode 100644 StaffMod/src/main/resources/assets/avm_staff/textures/item/crown_of_king_orange.png diff --git a/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/PiglinBrainMixin.java b/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/PiglinBrainMixin.java new file mode 100644 index 000000000..5485a962e --- /dev/null +++ b/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/PiglinBrainMixin.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.fabric; + +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.mob.PiglinBrain; +import net.minecraft.item.ItemStack; +import opekope2.avm_staff.api.item.CrownItem; +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(PiglinBrain.class) +public abstract class PiglinBrainMixin { + @Inject(method = "wearsGoldArmor", at = @At("HEAD"), cancellable = true) + private static void wearsGoldArmor(LivingEntity entity, CallbackInfoReturnable cir) { + for (ItemStack armorStack : entity.getArmorItems()) { + if (armorStack.getItem() instanceof CrownItem) { + cir.setReturnValue(true); + return; + } + } + } +} diff --git a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModPlatformImpl.kt b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModPlatformImpl.kt index 5c9336f8e..6df8cd726 100644 --- a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModPlatformImpl.kt +++ b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/StaffModPlatformImpl.kt @@ -25,6 +25,7 @@ import net.fabricmc.api.EnvType import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry import net.fabricmc.loader.api.FabricLoader import net.minecraft.item.Item +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.fabric.item.FabricStaffItem @@ -38,3 +39,5 @@ fun createStaffRendererItem(settings: Item.Settings): Item { } } } + +fun createCrownItem(settings: Item.Settings): CrownItem = CrownItem(settings) diff --git a/FabricMod/src/main/resources/avm_staff_fabric.mixins.json b/FabricMod/src/main/resources/avm_staff_fabric.mixins.json new file mode 100644 index 000000000..eecc989aa --- /dev/null +++ b/FabricMod/src/main/resources/avm_staff_fabric.mixins.json @@ -0,0 +1,12 @@ +{ + "required": true, + "package": "opekope2.avm_staff.mixin.fabric", + "compatibilityLevel": "JAVA_17", + "minVersion": "0.8", + "injectors": { + "defaultRequire": 1 + }, + "mixins": [ + "PiglinBrainMixin" + ] +} diff --git a/FabricMod/src/main/resources/fabric.mod.json b/FabricMod/src/main/resources/fabric.mod.json index fb4633192..41a5ec7ac 100644 --- a/FabricMod/src/main/resources/fabric.mod.json +++ b/FabricMod/src/main/resources/fabric.mod.json @@ -29,6 +29,10 @@ "adapter": "kotlin", "value": "opekope2.avm_staff.internal.InitializerKt::initializeNetworking" }, + { + "adapter": "kotlin", + "value": "opekope2.avm_staff.internal.InitializerKt::modifyLootTables" + }, { "adapter": "kotlin", "value": "opekope2.avm_staff.internal.staff_item_handler.VanillaStaffItemHandlersKt::registerVanillaStaffItemHandlers" @@ -46,7 +50,8 @@ ] }, "mixins": [ - "avm_staff.mixins.json" + "avm_staff.mixins.json", + "avm_staff_fabric.mixins.json" ], "depends": { "fabric-api": ">=$fabric_api", diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt index e1afe877b..a827ff2d3 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt @@ -22,6 +22,7 @@ import dev.architectury.platform.forge.EventBuses import net.minecraftforge.api.distmarker.Dist import net.minecraftforge.fml.common.Mod import opekope2.avm_staff.internal.initializeNetworking +import opekope2.avm_staff.internal.modifyLootTables import opekope2.avm_staff.internal.registerContent import opekope2.avm_staff.internal.staff_item_handler.registerVanillaStaffItemHandlers import opekope2.avm_staff.util.MOD_ID @@ -34,6 +35,7 @@ object StaffMod { EventBuses.registerModEventBus(MOD_ID, MOD_BUS) registerContent() initializeNetworking() + modifyLootTables() registerVanillaStaffItemHandlers() runWhenOn(Dist.CLIENT, StaffModClient::initializeClient) } diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModPlatformImpl.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModPlatformImpl.kt index 2d6ea5708..7db0c701b 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModPlatformImpl.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModPlatformImpl.kt @@ -22,10 +22,14 @@ package opekope2.avm_staff.internal.forge import net.minecraft.item.Item +import opekope2.avm_staff.api.item.CrownItem import opekope2.avm_staff.api.item.StaffItem +import opekope2.avm_staff.internal.forge.item.ForgeCrownItem import opekope2.avm_staff.internal.forge.item.ForgeStaffItem import opekope2.avm_staff.internal.forge.item.ForgeStaffRendererItem fun createStaffItem(settings: Item.Settings): StaffItem = ForgeStaffItem(settings) fun createStaffRendererItem(settings: Item.Settings): Item = ForgeStaffRendererItem(settings) + +fun createCrownItem(settings: Item.Settings): CrownItem = ForgeCrownItem(settings) diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeCrownItem.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeCrownItem.kt new file mode 100644 index 000000000..aaab164ca --- /dev/null +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeCrownItem.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.internal.forge.item + +import net.minecraft.entity.LivingEntity +import net.minecraft.item.Item +import net.minecraft.item.ItemStack +import net.minecraftforge.common.extensions.IForgeItem +import opekope2.avm_staff.api.item.CrownItem + +class ForgeCrownItem(settings: Item.Settings) : CrownItem(settings), IForgeItem { + override fun isRepairable(arg: ItemStack?) = false + + override fun makesPiglinsNeutral(stack: ItemStack, wearer: LivingEntity?) = stack.item is CrownItem +} 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 88076cdc5..aef7c3763 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 @@ -21,6 +21,7 @@ package opekope2.avm_staff.internal.neoforge import net.neoforged.api.distmarker.Dist import net.neoforged.fml.common.Mod import opekope2.avm_staff.internal.initializeNetworking +import opekope2.avm_staff.internal.modifyLootTables import opekope2.avm_staff.internal.registerContent import opekope2.avm_staff.internal.staff_item_handler.registerVanillaStaffItemHandlers import opekope2.avm_staff.util.MOD_ID @@ -31,6 +32,7 @@ object StaffMod { init { registerContent() initializeNetworking() + modifyLootTables() registerVanillaStaffItemHandlers() runWhenOn(Dist.CLIENT, StaffModClient::initializeClient) } diff --git a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModPlatformImpl.kt b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModPlatformImpl.kt index 5b9318d1d..70e059ca2 100644 --- a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModPlatformImpl.kt +++ b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/StaffModPlatformImpl.kt @@ -22,10 +22,14 @@ package opekope2.avm_staff.internal.neoforge import net.minecraft.item.Item +import opekope2.avm_staff.api.item.CrownItem import opekope2.avm_staff.api.item.StaffItem +import opekope2.avm_staff.internal.neoforge.item.NeoForgeCrownItem import opekope2.avm_staff.internal.neoforge.item.NeoForgeStaffItem import opekope2.avm_staff.internal.neoforge.item.NeoForgeStaffRendererItem fun createStaffItem(settings: Item.Settings): StaffItem = NeoForgeStaffItem(settings) fun createStaffRendererItem(settings: Item.Settings): Item = NeoForgeStaffRendererItem(settings) + +fun createCrownItem(settings: Item.Settings): CrownItem = NeoForgeCrownItem(settings) diff --git a/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/NeoForgeCrownItem.kt b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/NeoForgeCrownItem.kt new file mode 100644 index 000000000..7859e88b5 --- /dev/null +++ b/NeoForgeMod/src/main/kotlin/opekope2/avm_staff/internal/neoforge/item/NeoForgeCrownItem.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.internal.neoforge.item + +import net.minecraft.entity.LivingEntity +import net.minecraft.item.Item +import net.minecraft.item.ItemStack +import net.neoforged.neoforge.common.extensions.IItemExtension +import opekope2.avm_staff.api.item.CrownItem + +class NeoForgeCrownItem(settings: Item.Settings) : CrownItem(settings), IItemExtension { + override fun isRepairable(arg: ItemStack) = false + + override fun makesPiglinsNeutral(stack: ItemStack, wearer: LivingEntity) = stack.item is CrownItem +} 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 acccbb2d6..863991dd2 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -34,7 +34,9 @@ import net.minecraft.resource.featuretoggle.FeatureFlags import net.minecraft.text.Text import net.minecraft.util.Identifier import net.minecraft.util.Rarity +import opekope2.avm_staff.api.item.CrownItem import opekope2.avm_staff.api.item.StaffItem +import opekope2.avm_staff.internal.createCrownItem import opekope2.avm_staff.internal.createStaffItem import opekope2.avm_staff.internal.createStaffRendererItem import opekope2.avm_staff.util.MOD_ID @@ -89,6 +91,18 @@ val royalStaffItem: RegistrySupplier = ITEMS.register("royal_staff") ) } +/** + * Gets `avm_staff:crown_of_king_orange` item registered in Minecraft. + * + * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. + */ +val crownOfKingOrangeItem: RegistrySupplier = ITEMS.register("crown_of_king_orange") { + createCrownItem( + Item.Settings().maxCount(1).rarity(Rarity.UNCOMMON).requires(FeatureFlags.UPDATE_1_21) + .`arch$tab`(staffModItemGroup) + ) +} + /** * Gets the [TagKey] containing all the staffs. */ diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/CrownItem.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/CrownItem.kt new file mode 100644 index 000000000..d110d7df7 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/CrownItem.kt @@ -0,0 +1,49 @@ +/* + * 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 + +import net.minecraft.block.DispenserBlock +import net.minecraft.entity.EquipmentSlot +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.ArmorItem +import net.minecraft.item.Equipment +import net.minecraft.item.Item +import net.minecraft.item.ItemStack +import net.minecraft.sound.SoundEvent +import net.minecraft.sound.SoundEvents +import net.minecraft.util.Hand +import net.minecraft.util.TypedActionResult +import net.minecraft.world.World + +/** + * A crown, which makes piglins neutral when worn, just like gold armor. + */ +open class CrownItem(settings: Settings) : Item(settings), Equipment { + init { + DispenserBlock.registerBehavior(this, ArmorItem.DISPENSER_BEHAVIOR) + } + + override fun use(world: World, user: PlayerEntity, hand: Hand): TypedActionResult { + return equipAndSwap(this, world, user, hand) + } + + override fun getEquipSound(): SoundEvent = SoundEvents.ITEM_ARMOR_EQUIP_GOLD + + override fun getSlotType(): EquipmentSlot = EquipmentSlot.HEAD +} 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 0b4d3fcb4..1256948a9 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -18,6 +18,11 @@ package opekope2.avm_staff.internal +import dev.architectury.event.events.common.LootEvent +import net.minecraft.loot.LootPool +import net.minecraft.loot.entry.ItemEntry +import net.minecraft.util.Identifier +import opekope2.avm_staff.api.crownOfKingOrangeItem import opekope2.avm_staff.internal.event_handler.addBlockToStaff import opekope2.avm_staff.internal.event_handler.attack import opekope2.avm_staff.internal.event_handler.removeBlockFromStaff @@ -34,3 +39,13 @@ fun initializeNetworking() { RemoveItemFromStaffC2SPacket.registerHandler(::removeBlockFromStaff) StaffAttackC2SPacket.registerHandler(::attack) } + +private val TREASURE_BASTION_CHEST_LOOT = Identifier("chests/bastion_treasure") + +fun modifyLootTables() { + LootEvent.MODIFY_LOOT_TABLE.register(LootEvent.ModifyLootTable { _, lootTableId, context, builtin -> + if (builtin && lootTableId == TREASURE_BASTION_CHEST_LOOT) { + context.addPool(LootPool.builder().with(ItemEntry.builder(crownOfKingOrangeItem.get()))) + } + }) +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/StaffModPlatform.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/StaffModPlatform.kt index 6bda69f2d..19af7e540 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/StaffModPlatform.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/StaffModPlatform.kt @@ -23,6 +23,7 @@ package opekope2.avm_staff.internal import dev.architectury.injectables.annotations.ExpectPlatform import net.minecraft.item.Item +import opekope2.avm_staff.api.item.CrownItem import opekope2.avm_staff.api.item.StaffItem @ExpectPlatform @@ -30,3 +31,6 @@ fun createStaffItem(settings: Item.Settings): StaffItem = throw AssertionError() @ExpectPlatform fun createStaffRendererItem(settings: Item.Settings): Item = throw AssertionError() + +@ExpectPlatform +fun createCrownItem(settings: Item.Settings): CrownItem = throw AssertionError() 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 23fcbfab0..17628aa1a 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 @@ "item.avm_staff.faint_royal_staff": "Faint royal staff", "item.avm_staff.royal_staff": "Royal staff", "item.avm_staff.royal_staff.with_item": "Royal staff with %s", + "item.avm_staff.crown_of_king_orange": "Crown of King Orange", "key.categories.avm_staff": "Staff Mod", "key.avm_staff.add_remove_staff_block": "Add/remove staff item", "itemGroup.avm_staff_items": "Staff Mod" diff --git a/StaffMod/src/main/resources/assets/avm_staff/models/item/crown_of_king_orange.json b/StaffMod/src/main/resources/assets/avm_staff/models/item/crown_of_king_orange.json new file mode 100644 index 000000000..8faf74524 --- /dev/null +++ b/StaffMod/src/main/resources/assets/avm_staff/models/item/crown_of_king_orange.json @@ -0,0 +1,62 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "particle": "avm_staff:item/crown_of_king_orange", + "crown": "avm_staff:item/crown_of_king_orange" + }, + "elements": [ + { + "from": [4, 0, 4], + "to": [12, 12, 12], + "faces": { + "north": {"uv": [0, 0, 8, 12], "texture": "#crown"}, + "east": {"uv": [0, 0, 8, 12], "texture": "#crown"}, + "south": {"uv": [0, 0, 8, 12], "texture": "#crown"}, + "west": {"uv": [0, 0, 8, 12], "texture": "#crown"} + } + }, + { + "name": "cube inverted", + "from": [12, 12, 12], + "to": [4, 0, 4], + "faces": { + "north": {"uv": [0, 12, 8, 0], "texture": "#crown"}, + "east": {"uv": [0, 12, 8, 0], "texture": "#crown"}, + "south": {"uv": [0, 12, 8, 0], "texture": "#crown"}, + "west": {"uv": [0, 12, 8, 0], "texture": "#crown"} + } + } + ], + "gui_light": "front", + "display": { + "thirdperson_righthand": { + "translation": [0, 3, 1], + "scale": [0.55, 0.55, 0.55] + }, + "thirdperson_lefthand": { + "translation": [0, 3, 1], + "scale": [0.55, 0.55, 0.55] + }, + "firstperson_righthand": { + "rotation": [0, -90, 25], + "translation": [1.13, 3.2, 1.13], + "scale": [0.68, 0.68, 0.68] + }, + "firstperson_lefthand": { + "rotation": [0, -90, 25], + "translation": [1.13, 3.2, 1.13], + "scale": [0.68, 0.68, 0.68] + }, + "ground": { + "translation": [0, 2, 0], + "scale": [0.5, 0.5, 0.5] + }, + "gui": { + "rotation": [30, 225, 0], + "translation": [0, 1.75, 0] + }, + "head": { + "translation": [0, 14.5, 0] + } + } +} \ No newline at end of file diff --git a/StaffMod/src/main/resources/assets/avm_staff/textures/item/crown_of_king_orange.png b/StaffMod/src/main/resources/assets/avm_staff/textures/item/crown_of_king_orange.png new file mode 100644 index 0000000000000000000000000000000000000000..4b9a08358dd23c0a8e8ea9d47b740cda35c8a416 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJC{Gv1kcif|lMiw-7;>;&zf$ry ze8Rjl-|Z$@^Jt_zdnqJ&<;3zBM!ToGZBFeoTIBZrmYzTNluJphQxy*AJ1powFn_Ui vX+xH2V>YYKZvX0(nctrZJ1{V^FffQIFSYu@@ZefC&=v+yS3j3^P6 literal 0 HcmV?d00001 From 099b85fbbebd491df943916027fe186aaf484b29 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 18 May 2024 22:21:43 +0200 Subject: [PATCH 033/128] Fix right click holding with staffs Off-hand items will no longer be activated --- .../avm_staff/internal/staff_item_handler/CampfireHandler.kt | 2 +- .../avm_staff/internal/staff_item_handler/FurnaceHandler.kt | 2 +- .../avm_staff/internal/staff_item_handler/MagmaBlockHandler.kt | 2 +- .../avm_staff/internal/staff_item_handler/SnowBlockHandler.kt | 2 +- .../internal/staff_item_handler/WitherSkeletonSkullHandler.kt | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/CampfireHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/CampfireHandler.kt index b4067b9cd..61f0d6e23 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/CampfireHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/CampfireHandler.kt @@ -64,7 +64,7 @@ class CampfireHandler( staffStack.getOrCreateNbt().putBoolean(ROCKET_MODE_KEY, user.isSneaking && !user.isOnGround) user.setCurrentHand(hand) - return TypedActionResult.pass(staffStack) + return TypedActionResult.consume(staffStack) } override fun usageTick(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt index 96ebe3091..a7e2671d2 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt @@ -76,7 +76,7 @@ class FurnaceHandler( } user.setCurrentHand(hand) - return TypedActionResult.pass(staffStack) + return TypedActionResult.consume(staffStack) } override fun usageTick(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/MagmaBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/MagmaBlockHandler.kt index 48270d6a6..687cdcf1a 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/MagmaBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/MagmaBlockHandler.kt @@ -47,7 +47,7 @@ class MagmaBlockHandler : StaffItemHandler() { hand: Hand ): TypedActionResult { user.setCurrentHand(hand) - return TypedActionResult.pass(staffStack) + return TypedActionResult.consume(staffStack) } override fun usageTick(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/SnowBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/SnowBlockHandler.kt index 19b780446..b1e6fd56b 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/SnowBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/SnowBlockHandler.kt @@ -40,7 +40,7 @@ class SnowBlockHandler : StaffItemHandler() { hand: Hand ): TypedActionResult { user.setCurrentHand(hand) - return TypedActionResult.pass(staffStack) + return TypedActionResult.consume(staffStack) } override fun usageTick(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt index 6435b3fd9..a64638652 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt @@ -54,7 +54,7 @@ class WitherSkeletonSkullHandler : StaffItemHandler() { hand: Hand ): TypedActionResult { user.setCurrentHand(hand) - return TypedActionResult.pass(staffStack) + return TypedActionResult.consume(staffStack) } override fun usageTick(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { From b8574535fa5cd0c49871d97df97711a9cbe38002 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 18 May 2024 22:36:29 +0200 Subject: [PATCH 034/128] Show lightning rod inside staff when in inventory or item frame --- .../internal/staff_item_handler/LightningRodHandler.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/LightningRodHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/LightningRodHandler.kt index 5ed98044c..590cf0b51 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/LightningRodHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/LightningRodHandler.kt @@ -86,7 +86,9 @@ class LightningRodHandler : StaffItemHandler() { overlay: Int ) { matrices.push { - translate(0.0, 22.0 / 16.0, 0.0) + if (mode != ModelTransformationMode.GUI && mode != ModelTransformationMode.FIXED) { + translate(0f, 22f / 16f, 0f) + } lightningRodRenderer.renderItemInStaff(staffStack, mode, matrices, vertexConsumers, light, overlay) } } From c4ede5fdba13589103f4dfbebdbcc4e124cd8cc9 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 19 May 2024 00:29:22 +0200 Subject: [PATCH 035/128] Make bell bigger in the staff --- .../internal/staff_item_handler/BellBlockHandler.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BellBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BellBlockHandler.kt index 9cd6ba9ca..76e7d70f0 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BellBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BellBlockHandler.kt @@ -88,7 +88,9 @@ class BellBlockHandler : StaffItemHandler() { @Environment(EnvType.CLIENT) class BellStaffItemRenderer : IStaffItemRenderer { - private val bellModel = BellBlockEntityRenderer.getTexturedModelData().createModel().getChild("bell_body") + private val bellModel = BellBlockEntityRenderer.getTexturedModelData().createModel().apply { + setPivot(-8f, -12f, -8f) + } override fun renderItemInStaff( staffStack: ItemStack, @@ -99,7 +101,8 @@ class BellBlockHandler : StaffItemHandler() { overlay: Int ) { matrices.push { - translate(-0.5, -5.0 / 16.0, -0.5) + scale(16f / 9f, 16f / 9f, 16f / 9f) + translate(0f, 2f / 9f, 0f) bellModel.render( matrices, From f00b5d42328b33e51deac32934ebe0649db85675 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 19 May 2024 00:29:53 +0200 Subject: [PATCH 036/128] Adjust wither skeleton skull rendering --- .../internal/staff_item_handler/WitherSkeletonSkullHandler.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt index a64638652..f8264bfc5 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt @@ -116,7 +116,7 @@ class WitherSkeletonSkullHandler : StaffItemHandler() { @Environment(EnvType.CLIENT) class WitherSkeletonSkullStaffItemRenderer : IStaffItemRenderer { - private val skullModel = SkullEntityModel.getSkullTexturedModelData().createModel().getChild("head") + private val skullModel = SkullEntityModel.getSkullTexturedModelData().createModel() override fun renderItemInStaff( staffStack: ItemStack, @@ -128,7 +128,7 @@ class WitherSkeletonSkullHandler : StaffItemHandler() { ) { matrices.push { scale(-1f, -1f, 1f) - translate(0.0, 8.0 / 16.0, 0.0) + translate(0f, 8f / 16f, 0f) scale(2f, 2f, 2f) skullModel.render( matrices, From d5953b223afcab6ad0c06e5f458ad96e36386ba5 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 19 May 2024 00:31:12 +0200 Subject: [PATCH 037/128] Make piglins admire Crown of King Orange --- .../avm_staff/api/item/renderer/StaffRenderer.kt | 16 ++++++++-------- .../data/minecraft/tags/items/piglin_loved.json | 6 ++++++ 2 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 StaffMod/src/main/resources/data/minecraft/tags/items/piglin_loved.json 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 b50ac9f54..67de4639d 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 @@ -81,11 +81,11 @@ object StaffRenderer { overlay: Int ) { matrices.push { - translate(0.5, 0.5, 0.5) + translate(0.5f, 0.5f, 0.5f) // Head push { - translate(0.0, 16.0 / 16.0, 0.0) + translate(0f, 16f / 16f, 0f) renderPart(staffStack, this, vertexConsumers, light, overlay, HEAD_SEED) // Item @@ -96,13 +96,13 @@ object StaffRenderer { // Rod (top) push { - translate(0.0, 2.0 / 16.0, 0.0) + translate(0f, 2f / 16f, 0f) renderPart(staffStack, this, vertexConsumers, light, overlay, ROD_TOP_SEED) } // Rod (bottom) push { - translate(0.0, -12.0 / 16.0, 0.0) + translate(0f, -12f / 16f, 0f) renderPart(staffStack, this, vertexConsumers, light, overlay, ROD_BOTTOM_SEED) } } @@ -117,7 +117,7 @@ object StaffRenderer { overlay: Int ) { matrices.push { - translate(0.5, 0.5, 0.5) + translate(0.5f, 0.5f, 0.5f) // Head push { @@ -140,11 +140,11 @@ object StaffRenderer { overlay: Int ) { matrices.push { - translate(0.5, 0.5, 0.5) + translate(0.5f, 0.5f, 0.5f) // Head push { - translate(0.0, 9.0 / 16.0, 0.0) + translate(0f, 9f / 16f, 0f) renderPart(staffStack, this, vertexConsumers, light, overlay, HEAD_SEED) // Item @@ -155,7 +155,7 @@ object StaffRenderer { // Rod (top) push { - translate(0.0, -5.0 / 16.0, 0.0) + translate(0f, -5f / 16f, 0f) renderPart(staffStack, this, vertexConsumers, light, overlay, ROD_TOP_SEED) } } diff --git a/StaffMod/src/main/resources/data/minecraft/tags/items/piglin_loved.json b/StaffMod/src/main/resources/data/minecraft/tags/items/piglin_loved.json new file mode 100644 index 000000000..fca333cf3 --- /dev/null +++ b/StaffMod/src/main/resources/data/minecraft/tags/items/piglin_loved.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "avm_staff:crown_of_king_orange" + ] +} From dbd3d22735a6ba8ed461193e6a745e41c56c812b Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 19 May 2024 17:31:06 +0200 Subject: [PATCH 038/128] Use Neo/Forge API for shield disabling Move related mixin to Fabric project --- .../mixin/fabric/LivingEntityMixin.java | 51 +++++++++++++++++++ .../resources/avm_staff_fabric.mixins.json | 1 + .../internal/forge/item/ForgeStaffItem.kt | 13 +++++ .../neoforge/item/NeoForgeStaffItem.kt | 13 +++++ .../avm_staff/mixin/LivingEntityMixin.java | 24 --------- 5 files changed, 78 insertions(+), 24 deletions(-) create mode 100644 FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/LivingEntityMixin.java diff --git a/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/LivingEntityMixin.java b/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/LivingEntityMixin.java new file mode 100644 index 000000000..f3df171a4 --- /dev/null +++ b/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/LivingEntityMixin.java @@ -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.mixin.fabric; + +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.ItemStack; +import opekope2.avm_staff.api.StaffMod; +import opekope2.avm_staff.api.item.IDisablesShield; +import opekope2.avm_staff.api.item.StaffItemHandler; +import opekope2.avm_staff.util.StaffUtil; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(LivingEntity.class) +public abstract class LivingEntityMixin { + @Shadow + public abstract ItemStack getMainHandStack(); + + @Inject(method = "disablesShield", at = @At("HEAD"), cancellable = true) + public void disableShield(CallbackInfoReturnable cir) { + ItemStack mainHandStack = getMainHandStack(); + if (!mainHandStack.isIn(StaffMod.getStaffsTag())) return; + + ItemStack itemInStaff = StaffUtil.getItemInStaff(mainHandStack); + if (itemInStaff == null) return; + + StaffItemHandler handlerOfItem = StaffUtil.getHandlerOfItem(itemInStaff); + if (handlerOfItem instanceof IDisablesShield) { + cir.setReturnValue(true); + } + } +} diff --git a/FabricMod/src/main/resources/avm_staff_fabric.mixins.json b/FabricMod/src/main/resources/avm_staff_fabric.mixins.json index eecc989aa..e7a5a8961 100644 --- a/FabricMod/src/main/resources/avm_staff_fabric.mixins.json +++ b/FabricMod/src/main/resources/avm_staff_fabric.mixins.json @@ -7,6 +7,7 @@ "defaultRequire": 1 }, "mixins": [ + "LivingEntityMixin", "PiglinBrainMixin" ] } diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt index 80f7064a3..0d28950c4 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt @@ -25,12 +25,14 @@ import net.minecraft.client.render.item.BuiltinModelItemRenderer import net.minecraft.client.render.model.json.ModelTransformationMode import net.minecraft.client.util.math.MatrixStack import net.minecraft.entity.EquipmentSlot +import net.minecraft.entity.LivingEntity import net.minecraft.entity.attribute.EntityAttribute import net.minecraft.entity.attribute.EntityAttributeModifier import net.minecraft.item.Item import net.minecraft.item.ItemStack import net.minecraftforge.client.extensions.common.IClientItemExtensions import net.minecraftforge.common.extensions.IForgeItem +import opekope2.avm_staff.api.item.IDisablesShield import opekope2.avm_staff.api.item.StaffItem import opekope2.avm_staff.api.item.renderer.StaffRenderer import opekope2.avm_staff.util.handlerOfItemOrFallback @@ -45,6 +47,17 @@ class ForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IForgeItem return stack.itemInStaff.handlerOfItemOrFallback.getAttributeModifiers(stack, slot) } + @Suppress("RemoveExplicitSuperQualifier") // Required because StaffItem apparently also has canDisableShield + override fun canDisableShield( + stack: ItemStack, + shield: ItemStack?, + entity: LivingEntity?, + attacker: LivingEntity? + ): Boolean { + return stack.itemInStaff.handlerOfItemOrFallback is IDisablesShield || + super.canDisableShield(stack, shield, entity, attacker) + } + override fun isRepairable(arg: ItemStack): Boolean { return false } 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 2cc2a0e9f..ff0f61bc9 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 @@ -25,12 +25,14 @@ import net.minecraft.client.render.item.BuiltinModelItemRenderer import net.minecraft.client.render.model.json.ModelTransformationMode import net.minecraft.client.util.math.MatrixStack import net.minecraft.entity.EquipmentSlot +import net.minecraft.entity.LivingEntity import net.minecraft.entity.attribute.EntityAttribute import net.minecraft.entity.attribute.EntityAttributeModifier import net.minecraft.item.Item import net.minecraft.item.ItemStack import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions import net.neoforged.neoforge.common.extensions.IItemExtension +import opekope2.avm_staff.api.item.IDisablesShield import opekope2.avm_staff.api.item.StaffItem import opekope2.avm_staff.api.item.renderer.StaffRenderer import opekope2.avm_staff.util.handlerOfItemOrFallback @@ -45,6 +47,17 @@ class NeoForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IItemExt return stack.itemInStaff.handlerOfItemOrFallback.getAttributeModifiers(stack, slot) } + @Suppress("RemoveExplicitSuperQualifier") // Required because StaffItem apparently also has canDisableShield + override fun canDisableShield( + stack: ItemStack, + shield: ItemStack, + entity: LivingEntity, + attacker: LivingEntity + ): Boolean { + return stack.itemInStaff.handlerOfItemOrFallback is IDisablesShield || + super.canDisableShield(stack, shield, entity, attacker) + } + override fun isRepairable(arg: ItemStack): Boolean { return false } diff --git a/StaffMod/src/main/java/opekope2/avm_staff/mixin/LivingEntityMixin.java b/StaffMod/src/main/java/opekope2/avm_staff/mixin/LivingEntityMixin.java index 03518db01..82f9306bb 100644 --- a/StaffMod/src/main/java/opekope2/avm_staff/mixin/LivingEntityMixin.java +++ b/StaffMod/src/main/java/opekope2/avm_staff/mixin/LivingEntityMixin.java @@ -19,20 +19,13 @@ package opekope2.avm_staff.mixin; import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import opekope2.avm_staff.api.StaffMod; import opekope2.avm_staff.api.item.IActiveItemTempDataHolder; -import opekope2.avm_staff.api.item.IDisablesShield; -import opekope2.avm_staff.api.item.StaffItemHandler; -import opekope2.avm_staff.util.StaffUtil; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(LivingEntity.class) public abstract class LivingEntityMixin implements IActiveItemTempDataHolder { @@ -40,23 +33,6 @@ public abstract class LivingEntityMixin implements IActiveItemTempDataHolder { @Nullable private Object staffMod$activeItemTempData; - @Shadow - public abstract ItemStack getMainHandStack(); - - @Inject(method = "disablesShield", at = @At("HEAD"), cancellable = true) - public void disableShield(CallbackInfoReturnable cir) { - ItemStack mainHandStack = getMainHandStack(); - if (!mainHandStack.isIn(StaffMod.getStaffsTag())) return; - - ItemStack itemInStaff = StaffUtil.getItemInStaff(mainHandStack); - if (itemInStaff == null) return; - - StaffItemHandler handlerOfItem = StaffUtil.getHandlerOfItem(itemInStaff); - if (handlerOfItem instanceof IDisablesShield) { - cir.setReturnValue(true); - } - } - // Only invoke on server @Inject(method = "clearActiveItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;setLivingFlag(IZ)V")) public void clearActiveItem(CallbackInfo ci) { From d1a67dc0e4ff7dfde132a64ee68c121f824ef978 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 19 May 2024 18:56:37 +0200 Subject: [PATCH 039/128] Refactor StaffItemHandler.attackEntity Less is more, remove unused functionality Use Item APIs on Neo/Forge Get rid of unnecessary mixins --- .../avm_staff/internal/fabric/StaffMod.kt | 17 +++++-- .../mixin/forge/ServerPlayerEntityMixin.java | 41 ---------------- .../internal/forge/item/ForgeStaffItem.kt | 9 ++++ .../resources/avm_staff_forge.mixins.json | 1 - .../neoforge/ServerPlayerEntityMixin.java | 41 ---------------- .../neoforge/item/NeoForgeStaffItem.kt | 9 ++++ .../resources/avm_staff_neoforge.mixins.json | 1 - .../avm_staff/mixin/MinecraftClientMixin.java | 49 ------------------- .../avm_staff/api/item/StaffItemHandler.kt | 38 ++++---------- .../event_handler/StaffAttackHandler.kt | 11 ----- .../staff_item_handler/AnvilHandler.kt | 8 +-- .../staff_item_handler/BellBlockHandler.kt | 6 +-- .../staff_item_handler/MagmaBlockHandler.kt | 5 +- .../WitherSkeletonSkullHandler.kt | 5 +- 14 files changed, 54 insertions(+), 187 deletions(-) delete mode 100644 ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ServerPlayerEntityMixin.java delete mode 100644 NeoForgeMod/src/main/java/opekope2/avm_staff/mixin/neoforge/ServerPlayerEntityMixin.java 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 53327b949..3783c82dc 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 @@ -27,8 +27,10 @@ import net.minecraft.util.ActionResult import net.minecraft.util.Hand import net.minecraft.util.hit.EntityHitResult import net.minecraft.world.World +import opekope2.avm_staff.api.staffsTag import opekope2.avm_staff.internal.event_handler.attackBlock -import opekope2.avm_staff.internal.event_handler.attackEntity +import opekope2.avm_staff.util.handlerOfItem +import opekope2.avm_staff.util.itemInStaff @Suppress("unused") object StaffMod : ModInitializer { @@ -37,15 +39,22 @@ object StaffMod : ModInitializer { AttackEntityCallback.EVENT.register(::handleEntityAttackEvent) } + @Suppress("UNUSED_PARAMETER") private fun handleEntityAttackEvent( player: PlayerEntity, world: World, hand: Hand, target: Entity, - @Suppress("UNUSED_PARAMETER") hit: EntityHitResult? + hit: EntityHitResult? ): ActionResult { - if (world.isClient) return ActionResult.PASS // Handled with mixin + val itemStack = player.getStackInHand(hand) + if (!itemStack.isIn(staffsTag)) return ActionResult.PASS - return attackEntity(player, world, hand, target) + val itemInStaff = itemStack.itemInStaff ?: return ActionResult.PASS + val staffHandler = itemInStaff.handlerOfItem ?: return ActionResult.PASS + + val result = staffHandler.attackEntity(itemStack, world, player, target, hand) + return if (result.interruptsFurtherEvaluation()) ActionResult.SUCCESS + else ActionResult.PASS } } diff --git a/ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ServerPlayerEntityMixin.java b/ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ServerPlayerEntityMixin.java deleted file mode 100644 index e2c32284c..000000000 --- a/ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ServerPlayerEntityMixin.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package opekope2.avm_staff.mixin.forge; - -import net.minecraft.entity.Entity; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; -import opekope2.avm_staff.internal.event_handler.StaffAttackHandlerKt; -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.CallbackInfo; - -@Mixin(ServerPlayerEntity.class) -public class ServerPlayerEntityMixin { - // Change method to directly call Staff Mod instead of an exposed event - @Inject(method = "attack", at = @At("HEAD"), cancellable = true) - public void onPlayerInteractEntity(Entity target, CallbackInfo info) { - ServerPlayerEntity player = (ServerPlayerEntity) (Object) this; - ActionResult result = StaffAttackHandlerKt.attackEntity(player, player.getEntityWorld(), Hand.MAIN_HAND, target); - - if (result != ActionResult.PASS) { - info.cancel(); - } - } -} diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt index 0d28950c4..1536d4f28 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt @@ -24,12 +24,15 @@ import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.render.item.BuiltinModelItemRenderer import net.minecraft.client.render.model.json.ModelTransformationMode import net.minecraft.client.util.math.MatrixStack +import net.minecraft.entity.Entity import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.LivingEntity import net.minecraft.entity.attribute.EntityAttribute import net.minecraft.entity.attribute.EntityAttributeModifier +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.Item import net.minecraft.item.ItemStack +import net.minecraft.util.Hand import net.minecraftforge.client.extensions.common.IClientItemExtensions import net.minecraftforge.common.extensions.IForgeItem import opekope2.avm_staff.api.item.IDisablesShield @@ -62,6 +65,12 @@ class ForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IForgeItem return false } + override fun onLeftClickEntity(stack: ItemStack, player: PlayerEntity, entity: Entity): Boolean { + return stack.itemInStaff.handlerOfItemOrFallback.attackEntity( + stack, player.entityWorld, player, entity, Hand.MAIN_HAND + ).interruptsFurtherEvaluation() + } + override fun shouldCauseReequipAnimation( oldStack: ItemStack, newStack: ItemStack, diff --git a/ForgeMod/src/main/resources/avm_staff_forge.mixins.json b/ForgeMod/src/main/resources/avm_staff_forge.mixins.json index 910fab075..925498177 100644 --- a/ForgeMod/src/main/resources/avm_staff_forge.mixins.json +++ b/ForgeMod/src/main/resources/avm_staff_forge.mixins.json @@ -10,7 +10,6 @@ "ClientPlayerInteractionManagerMixin" ], "mixins": [ - "ServerPlayerEntityMixin", "ServerPlayerInteractionManagerMixin" ] } diff --git a/NeoForgeMod/src/main/java/opekope2/avm_staff/mixin/neoforge/ServerPlayerEntityMixin.java b/NeoForgeMod/src/main/java/opekope2/avm_staff/mixin/neoforge/ServerPlayerEntityMixin.java deleted file mode 100644 index e6d66146a..000000000 --- a/NeoForgeMod/src/main/java/opekope2/avm_staff/mixin/neoforge/ServerPlayerEntityMixin.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package opekope2.avm_staff.mixin.neoforge; - -import net.minecraft.entity.Entity; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; -import opekope2.avm_staff.internal.event_handler.StaffAttackHandlerKt; -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.CallbackInfo; - -@Mixin(ServerPlayerEntity.class) -public class ServerPlayerEntityMixin { - // Change method to directly call Staff Mod instead of an exposed event - @Inject(method = "attack", at = @At("HEAD"), cancellable = true) - public void onPlayerInteractEntity(Entity target, CallbackInfo info) { - ServerPlayerEntity player = (ServerPlayerEntity) (Object) this; - ActionResult result = StaffAttackHandlerKt.attackEntity(player, player.getEntityWorld(), Hand.MAIN_HAND, target); - - if (result != ActionResult.PASS) { - info.cancel(); - } - } -} 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 ff0f61bc9..79cd72860 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 @@ -24,12 +24,15 @@ import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.render.item.BuiltinModelItemRenderer import net.minecraft.client.render.model.json.ModelTransformationMode import net.minecraft.client.util.math.MatrixStack +import net.minecraft.entity.Entity import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.LivingEntity import net.minecraft.entity.attribute.EntityAttribute import net.minecraft.entity.attribute.EntityAttributeModifier +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.Item import net.minecraft.item.ItemStack +import net.minecraft.util.Hand import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions import net.neoforged.neoforge.common.extensions.IItemExtension import opekope2.avm_staff.api.item.IDisablesShield @@ -62,6 +65,12 @@ class NeoForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IItemExt return false } + override fun onLeftClickEntity(stack: ItemStack, player: PlayerEntity, entity: Entity): Boolean { + return stack.itemInStaff.handlerOfItemOrFallback.attackEntity( + stack, player.entityWorld, player, entity, Hand.MAIN_HAND + ).interruptsFurtherEvaluation() + } + override fun shouldCauseReequipAnimation( oldStack: ItemStack, newStack: ItemStack, diff --git a/NeoForgeMod/src/main/resources/avm_staff_neoforge.mixins.json b/NeoForgeMod/src/main/resources/avm_staff_neoforge.mixins.json index 9f766346d..ff97af424 100644 --- a/NeoForgeMod/src/main/resources/avm_staff_neoforge.mixins.json +++ b/NeoForgeMod/src/main/resources/avm_staff_neoforge.mixins.json @@ -10,7 +10,6 @@ "ClientPlayerInteractionManagerMixin" ], "mixins": [ - "ServerPlayerEntityMixin", "ServerPlayerInteractionManagerMixin" ] } diff --git a/StaffMod/src/main/java/opekope2/avm_staff/mixin/MinecraftClientMixin.java b/StaffMod/src/main/java/opekope2/avm_staff/mixin/MinecraftClientMixin.java index fd7cc2bf9..483e6ac78 100644 --- a/StaffMod/src/main/java/opekope2/avm_staff/mixin/MinecraftClientMixin.java +++ b/StaffMod/src/main/java/opekope2/avm_staff/mixin/MinecraftClientMixin.java @@ -19,16 +19,11 @@ package opekope2.avm_staff.mixin; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.world.ClientWorld; -import net.minecraft.entity.Entity; import net.minecraft.item.ItemStack; -import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; -import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.util.hit.HitResult; import opekope2.avm_staff.internal.event_handler.StaffAttackHandlerKt; import opekope2.avm_staff.internal.networking.c2s.play.StaffAttackC2SPacket; import org.jetbrains.annotations.Nullable; @@ -37,9 +32,6 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -import java.util.Objects; @Mixin(MinecraftClient.class) public abstract class MinecraftClientMixin { @@ -51,47 +43,6 @@ public abstract class MinecraftClientMixin { @Nullable public ClientWorld world; - @Shadow - @Nullable - public HitResult crosshairTarget; - - @Shadow - @Nullable - public abstract ClientPlayNetworkHandler getNetworkHandler(); - - // Because Fabric API can't not swing hand (it always swings hand) - @Inject( - method = "doAttack", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;attackEntity(Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/entity/Entity;)V" - ), - locals = LocalCapture.CAPTURE_FAILHARD, - cancellable = true - ) - private void handleEntityAttack(CallbackInfoReturnable cir) { - assert player != null; - assert world != null; - assert crosshairTarget != null; - - Entity target = ((EntityHitResult) crosshairTarget).getEntity(); - ActionResult result = StaffAttackHandlerKt.attackEntity(player, world, Hand.MAIN_HAND, target); - switch (result) { - case SUCCESS -> { - Objects.requireNonNull(getNetworkHandler()) - .sendPacket(PlayerInteractEntityC2SPacket.attack(target, player.isSneaking())); - player.swingHand(Hand.MAIN_HAND); - cir.setReturnValue(false); - } - case CONSUME, CONSUME_PARTIAL -> { - Objects.requireNonNull(getNetworkHandler()) - .sendPacket(PlayerInteractEntityC2SPacket.attack(target, player.isSneaking())); - cir.setReturnValue(false); - } - case FAIL -> cir.setReturnValue(false); - } - } - @Inject( method = "doAttack", at = @At( diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt index 465e97388..b8593bc12 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt @@ -20,6 +20,7 @@ package opekope2.avm_staff.api.item import com.google.common.collect.ImmutableMultimap import com.google.common.collect.Multimap +import dev.architectury.event.EventResult import net.minecraft.advancement.criterion.Criteria import net.minecraft.entity.Entity import net.minecraft.entity.EquipmentSlot @@ -306,34 +307,15 @@ abstract class StaffItemHandler { } /** - * Called on both the client by Staff Mod and the server by Fabric API (Fabric) or Staff Mod (Forge), when an entity - * attacks an entity with a staff. + * Called on both the client by Fabric/Neo/Forge API and the server by Fabric/Neo/Forge API, when an entity attacks + * an entity with a staff. * - * On the logical client, the return values have the following meaning: + * The return values have the following meaning: * - * - SUCCESS: - * Cancel vanilla entity attack, - * send a packet to the server, - * and swing hand. - * This doesn't reset the entity attack cooldown - * - CONSUME, CONSUME_PARTIAL: - * Cancel vanilla entity attack, - * send a packet to the server, - * and don't swing hand. - * This doesn't reset the entity attack cooldown - * - PASS: Let Minecraft handle vanilla entity attack - * - FAIL: - * Cancel vanilla entity attack, - * don't send a packet to the server, - * and don't swing hand. - * This doesn't reset the entity attack cooldown - * - * On the logical server, the return values have the following meaning (if used by player): - * - * - SUCCESS, CONSUME, CONSUME_PARTIAL, FAIL: Cancel vanilla entity attack, don't attack the entity - * - PASS: Let Minecraft handle vanilla entity attack - * - * On the logical server, the return values are processed by the caller code (if the attacker is not a player). + * - [EventResult.interrupt], [EventResult.interruptTrue], [EventResult.interruptFalse], [EventResult.interruptDefault]: + * Cancels vanilla entity attack, and on the logical client, sends a packet to the server. + * - [EventResult.pass]: + * Lets Minecraft handle vanilla entity attack. * * @param staffStack The item stack used to perform the action * @param world The world the [attacker] is in @@ -347,8 +329,8 @@ abstract class StaffItemHandler { attacker: LivingEntity, target: Entity, hand: Hand - ): ActionResult { - return ActionResult.PASS + ): EventResult { + return EventResult.pass() } /** diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt index 45b56b62e..ac730ed39 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt @@ -18,7 +18,6 @@ package opekope2.avm_staff.internal.event_handler -import net.minecraft.entity.Entity import net.minecraft.entity.LivingEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack @@ -47,16 +46,6 @@ fun attackBlock( return staffHandler.attackBlock(staffStack, world, player, target, direction, hand) } -fun attackEntity(player: PlayerEntity, world: World, hand: Hand, target: Entity): ActionResult { - val itemStack = player.getStackInHand(hand) - if (!itemStack.isIn(staffsTag)) return ActionResult.PASS - - val itemInStaff = itemStack.itemInStaff ?: return ActionResult.PASS - val staffHandler = itemInStaff.handlerOfItem ?: return ActionResult.PASS - - return staffHandler.attackEntity(itemStack, world, player, target, hand) -} - fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand): ActionResult { if (!staffStack.isIn(staffsTag)) return ActionResult.PASS diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/AnvilHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/AnvilHandler.kt index 512efa24d..8ac22c883 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/AnvilHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/AnvilHandler.kt @@ -20,6 +20,7 @@ package opekope2.avm_staff.internal.staff_item_handler import com.google.common.collect.ImmutableMultimap import com.google.common.collect.Multimap +import dev.architectury.event.EventResult import net.minecraft.entity.Entity import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.LivingEntity @@ -28,7 +29,6 @@ import net.minecraft.entity.attribute.EntityAttributeModifier import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.util.ActionResult import net.minecraft.util.Hand import net.minecraft.world.World import net.minecraft.world.WorldEvents @@ -46,8 +46,8 @@ class AnvilHandler(private val damagedStackFactory: () -> ItemStack?) : StaffIte attacker: LivingEntity, target: Entity, hand: Hand - ): ActionResult { - if (world.isClient) return ActionResult.PASS + ): EventResult { + if (world.isClient) return EventResult.pass() var broke = false if (attacker is PlayerEntity && !attacker.abilities.creativeMode && attacker.random.nextFloat() < 0.12F) { @@ -63,7 +63,7 @@ class AnvilHandler(private val damagedStackFactory: () -> ItemStack?) : StaffIte 0 ) - return ActionResult.PASS + return EventResult.pass() } override fun getAttributeModifiers( diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BellBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BellBlockHandler.kt index 76e7d70f0..1f22049a3 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BellBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BellBlockHandler.kt @@ -20,6 +20,7 @@ package opekope2.avm_staff.internal.staff_item_handler import com.google.common.collect.ImmutableMultimap import com.google.common.collect.Multimap +import dev.architectury.event.EventResult import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.minecraft.client.render.RenderLayer @@ -37,7 +38,6 @@ import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack import net.minecraft.sound.SoundCategory import net.minecraft.sound.SoundEvents -import net.minecraft.util.ActionResult import net.minecraft.util.Hand import net.minecraft.util.TypedActionResult import net.minecraft.world.World @@ -65,7 +65,7 @@ class BellBlockHandler : StaffItemHandler() { attacker: LivingEntity, target: Entity, hand: Hand - ): ActionResult { + ): EventResult { world.playSound( target as? PlayerEntity, target.blockPos, @@ -75,7 +75,7 @@ class BellBlockHandler : StaffItemHandler() { 1f ) - return ActionResult.PASS + return EventResult.pass() } override fun getAttributeModifiers( diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/MagmaBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/MagmaBlockHandler.kt index 687cdcf1a..7ec51fe97 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/MagmaBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/MagmaBlockHandler.kt @@ -20,6 +20,7 @@ package opekope2.avm_staff.internal.staff_item_handler import com.google.common.collect.ImmutableMultimap import com.google.common.collect.Multimap +import dev.architectury.event.EventResult import net.minecraft.entity.Entity import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.LivingEntity @@ -68,12 +69,12 @@ class MagmaBlockHandler : StaffItemHandler() { attacker: LivingEntity, target: Entity, hand: Hand - ): ActionResult { + ): EventResult { if (!world.isClient) { target.setOnFireFor(8) // TODO duration } - return ActionResult.PASS + return EventResult.pass() } private fun shootFireball(world: World, user: LivingEntity) { diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt index f8264bfc5..47a39046e 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt @@ -18,6 +18,7 @@ package opekope2.avm_staff.internal.staff_item_handler +import dev.architectury.event.EventResult import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.minecraft.block.AbstractSkullBlock @@ -92,7 +93,7 @@ class WitherSkeletonSkullHandler : StaffItemHandler() { attacker: LivingEntity, target: Entity, hand: Hand - ): ActionResult { + ): EventResult { if (!world.isClient) { if (world.difficulty.id >= Difficulty.NORMAL.id) { if (target is LivingEntity && !target.isInvulnerableTo(world.damageSources.wither())) { @@ -102,7 +103,7 @@ class WitherSkeletonSkullHandler : StaffItemHandler() { } } - return super.attackEntity(staffStack, world, attacker, target, hand) + return EventResult.pass() } override fun onStoppedUsing(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { From 5a376b09529a13d35dd09af56d0ea1fdd88d57a4 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 20 May 2024 00:45:22 +0200 Subject: [PATCH 040/128] Refactor StaffItemHandler.attackBlock Migrate to Architectury API from mixins --- .../avm_staff/internal/fabric/StaffMod.kt | 3 -- FabricMod/src/main/resources/fabric.mod.json | 2 +- .../avm_staff/internal/forge/StaffMod.kt | 4 +- .../avm_staff/internal/neoforge/StaffMod.kt | 4 +- .../avm_staff/api/item/StaffItemHandler.kt | 39 ++++--------------- .../avm_staff/internal/Initializer.kt | 5 ++- .../event_handler/StaffAttackHandler.kt | 19 ++++----- 7 files changed, 25 insertions(+), 51 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 3783c82dc..b0dec02ca 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 @@ -19,7 +19,6 @@ package opekope2.avm_staff.internal.fabric import net.fabricmc.api.ModInitializer -import net.fabricmc.fabric.api.event.player.AttackBlockCallback import net.fabricmc.fabric.api.event.player.AttackEntityCallback import net.minecraft.entity.Entity import net.minecraft.entity.player.PlayerEntity @@ -28,14 +27,12 @@ import net.minecraft.util.Hand import net.minecraft.util.hit.EntityHitResult import net.minecraft.world.World import opekope2.avm_staff.api.staffsTag -import opekope2.avm_staff.internal.event_handler.attackBlock import opekope2.avm_staff.util.handlerOfItem import opekope2.avm_staff.util.itemInStaff @Suppress("unused") object StaffMod : ModInitializer { override fun onInitialize() { - AttackBlockCallback.EVENT.register(::attackBlock) AttackEntityCallback.EVENT.register(::handleEntityAttackEvent) } diff --git a/FabricMod/src/main/resources/fabric.mod.json b/FabricMod/src/main/resources/fabric.mod.json index 41a5ec7ac..6cafec937 100644 --- a/FabricMod/src/main/resources/fabric.mod.json +++ b/FabricMod/src/main/resources/fabric.mod.json @@ -31,7 +31,7 @@ }, { "adapter": "kotlin", - "value": "opekope2.avm_staff.internal.InitializerKt::modifyLootTables" + "value": "opekope2.avm_staff.internal.InitializerKt::subscribeToEvents" }, { "adapter": "kotlin", diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt index a827ff2d3..bbfd1c9cb 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt @@ -22,9 +22,9 @@ import dev.architectury.platform.forge.EventBuses import net.minecraftforge.api.distmarker.Dist import net.minecraftforge.fml.common.Mod import opekope2.avm_staff.internal.initializeNetworking -import opekope2.avm_staff.internal.modifyLootTables import opekope2.avm_staff.internal.registerContent import opekope2.avm_staff.internal.staff_item_handler.registerVanillaStaffItemHandlers +import opekope2.avm_staff.internal.subscribeToEvents import opekope2.avm_staff.util.MOD_ID import thedarkcolour.kotlinforforge.forge.MOD_BUS import thedarkcolour.kotlinforforge.forge.runWhenOn @@ -35,7 +35,7 @@ object StaffMod { EventBuses.registerModEventBus(MOD_ID, MOD_BUS) registerContent() initializeNetworking() - modifyLootTables() + subscribeToEvents() registerVanillaStaffItemHandlers() runWhenOn(Dist.CLIENT, StaffModClient::initializeClient) } 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 aef7c3763..3bc2453d0 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 @@ -21,9 +21,9 @@ package opekope2.avm_staff.internal.neoforge import net.neoforged.api.distmarker.Dist import net.neoforged.fml.common.Mod import opekope2.avm_staff.internal.initializeNetworking -import opekope2.avm_staff.internal.modifyLootTables import opekope2.avm_staff.internal.registerContent import opekope2.avm_staff.internal.staff_item_handler.registerVanillaStaffItemHandlers +import opekope2.avm_staff.internal.subscribeToEvents import opekope2.avm_staff.util.MOD_ID import thedarkcolour.kotlinforforge.neoforge.forge.runWhenOn @@ -32,7 +32,7 @@ object StaffMod { init { registerContent() initializeNetworking() - modifyLootTables() + subscribeToEvents() registerVanillaStaffItemHandlers() runWhenOn(Dist.CLIENT, StaffModClient::initializeClient) } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt index b8593bc12..e31f39be2 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt @@ -256,37 +256,14 @@ abstract class StaffItemHandler { } /** - * Called on both the client and the server by Fabric API (Fabric) or Staff Mod (Forge),when an entity attacks a - * block with a staff. + * Called on both the client and the server by Architectury API, when an entity attacks a block with a staff. * - * On the logical client, the return values have the following meaning: - * - * - SUCCESS: - * Cancel vanilla block breaking, - * send a packet to the server, - * spawn block breaking particles, - * and swing hand. - * This doesn't reset the block breaking cooldown - * - CONSUME, CONSUME_PARTIAL: - * Cancel vanilla block breaking, - * send a packet to the server, - * don't spawn block breaking particles, - * and don't swing hand. - * This doesn't reset the block breaking cooldown - * - PASS: Let Minecraft handle vanilla block breaking - * - FAIL: - * Cancel vanilla block breaking, - * don't send a packet to the server, - * don't spawn block breaking particles, - * and don't swing hand. - * This doesn't reset the block breaking cooldown - * - * On the logical server, the return values have the following meaning (if used by player): - * - * - SUCCESS, CONSUME, CONSUME_PARTIAL, FAIL: Cancel vanilla block breaking, and notify the client - * - PASS: Let Minecraft handle vanilla block breaking + * The return values have the following meaning: * - * On the logical server, the return values are processed by the caller code (if the attacker is not a player). + * - [EventResult.interruptTrue], [EventResult.interruptTrue]: + * Cancels vanilla block breaking, and on the logical client, sends a packet to the server. + * - [EventResult.interruptDefault], [EventResult.pass]: + * Lets Minecraft handle vanilla block breaking. * * @param staffStack The item stack used to perform the action * @param world The world the [attacker] is in @@ -302,8 +279,8 @@ abstract class StaffItemHandler { target: BlockPos, side: Direction, hand: Hand - ): ActionResult { - return ActionResult.PASS + ): EventResult { + return EventResult.pass() } /** 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 1256948a9..e31ee38fa 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -18,6 +18,7 @@ package opekope2.avm_staff.internal +import dev.architectury.event.events.common.InteractionEvent import dev.architectury.event.events.common.LootEvent import net.minecraft.loot.LootPool import net.minecraft.loot.entry.ItemEntry @@ -25,6 +26,7 @@ import net.minecraft.util.Identifier import opekope2.avm_staff.api.crownOfKingOrangeItem import opekope2.avm_staff.internal.event_handler.addBlockToStaff import opekope2.avm_staff.internal.event_handler.attack +import opekope2.avm_staff.internal.event_handler.attackBlock import opekope2.avm_staff.internal.event_handler.removeBlockFromStaff import opekope2.avm_staff.internal.networking.c2s.play.AddItemToStaffC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.RemoveItemFromStaffC2SPacket @@ -42,7 +44,8 @@ fun initializeNetworking() { private val TREASURE_BASTION_CHEST_LOOT = Identifier("chests/bastion_treasure") -fun modifyLootTables() { +fun subscribeToEvents() { + InteractionEvent.LEFT_CLICK_BLOCK.register(::attackBlock) LootEvent.MODIFY_LOOT_TABLE.register(LootEvent.ModifyLootTable { _, lootTableId, context, builtin -> if (builtin && lootTableId == TREASURE_BASTION_CHEST_LOOT) { context.addPool(LootPool.builder().with(ItemEntry.builder(crownOfKingOrangeItem.get()))) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt index ac730ed39..264433215 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt @@ -18,6 +18,7 @@ package opekope2.avm_staff.internal.event_handler +import dev.architectury.event.EventResult import net.minecraft.entity.LivingEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack @@ -30,20 +31,16 @@ import opekope2.avm_staff.api.staffsTag import opekope2.avm_staff.util.handlerOfItem import opekope2.avm_staff.util.itemInStaff -fun attackBlock( - player: PlayerEntity, - world: World, - hand: Hand, - target: BlockPos, - direction: Direction -): ActionResult { +fun attackBlock(player: PlayerEntity, hand: Hand, target: BlockPos, direction: Direction): EventResult { val staffStack = player.getStackInHand(hand) - if (!staffStack.isIn(staffsTag)) return ActionResult.PASS + if (!staffStack.isIn(staffsTag)) return EventResult.pass() - val itemInStaff = staffStack.itemInStaff ?: return ActionResult.PASS - val staffHandler = itemInStaff.handlerOfItem ?: return ActionResult.PASS + val itemInStaff = staffStack.itemInStaff ?: return EventResult.pass() + val staffHandler = itemInStaff.handlerOfItem ?: return EventResult.pass() - return staffHandler.attackBlock(staffStack, world, player, target, direction, hand) + val result = staffHandler.attackBlock(staffStack, player.entityWorld, player, target, direction, hand) + return if (result.isFalse) EventResult.interruptTrue() // Force Fabric to send packet for Neo/Forge parity + else result } fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand): ActionResult { From d16815ef5ffe4a7a8a3b2330013f0fe206311993 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 20 May 2024 00:46:47 +0200 Subject: [PATCH 041/128] Remove mixins from NeoForge project --- NeoForgeMod/Fabric.license | 201 ------------------ NeoForgeMod/build.gradle.kts | 2 - .../ClientPlayerInteractionManagerMixin.java | 85 -------- .../ServerPlayerInteractionManagerMixin.java | 76 ------- .../src/main/resources/META-INF/mods.toml | 3 - .../resources/avm_staff_neoforge.mixins.json | 15 -- 6 files changed, 382 deletions(-) delete mode 100644 NeoForgeMod/Fabric.license delete mode 100644 NeoForgeMod/src/main/java/opekope2/avm_staff/mixin/neoforge/ClientPlayerInteractionManagerMixin.java delete mode 100644 NeoForgeMod/src/main/java/opekope2/avm_staff/mixin/neoforge/ServerPlayerInteractionManagerMixin.java delete mode 100644 NeoForgeMod/src/main/resources/avm_staff_neoforge.mixins.json diff --git a/NeoForgeMod/Fabric.license b/NeoForgeMod/Fabric.license deleted file mode 100644 index 8dada3eda..000000000 --- a/NeoForgeMod/Fabric.license +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/NeoForgeMod/build.gradle.kts b/NeoForgeMod/build.gradle.kts index 0ebdc4f15..0e498fea9 100644 --- a/NeoForgeMod/build.gradle.kts +++ b/NeoForgeMod/build.gradle.kts @@ -80,7 +80,6 @@ tasks { from(rootDir.resolve("COPYING")) from(rootDir.resolve("COPYING.LESSER")) - from(projectDir.resolve("Fabric.license")) } remapJar { @@ -91,7 +90,6 @@ tasks { from(rootDir.resolve("COPYING")) from(rootDir.resolve("COPYING.LESSER")) - from(projectDir.resolve("Fabric.license")) } sourcesJar { diff --git a/NeoForgeMod/src/main/java/opekope2/avm_staff/mixin/neoforge/ClientPlayerInteractionManagerMixin.java b/NeoForgeMod/src/main/java/opekope2/avm_staff/mixin/neoforge/ClientPlayerInteractionManagerMixin.java deleted file mode 100644 index 763950019..000000000 --- a/NeoForgeMod/src/main/java/opekope2/avm_staff/mixin/neoforge/ClientPlayerInteractionManagerMixin.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package opekope2.avm_staff.mixin.neoforge; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayerInteractionManager; -import net.minecraft.client.network.SequencedPacketCreator; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.world.GameMode; -import opekope2.avm_staff.internal.event_handler.StaffAttackHandlerKt; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(ClientPlayerInteractionManager.class) -public abstract class ClientPlayerInteractionManagerMixin { - @Shadow - @Final - private MinecraftClient client; - - @Shadow - private GameMode gameMode; - - @Shadow - protected abstract void sendSequencedPacket(ClientWorld clientWorld, SequencedPacketCreator supplier); - - // Change method to directly call Staff Mod instead of an exposed event - @Inject( - method = "attackBlock", - at = @At(value = "INVOKE", target = "Lnet/minecraft/world/GameMode;isCreative()Z", ordinal = 0), - cancellable = true - ) - private void attackBlock(BlockPos pos, Direction direction, CallbackInfoReturnable info) { - assert client.player != null; - assert client.world != null; - - ActionResult result = StaffAttackHandlerKt.attackBlock(client.player, client.world, Hand.MAIN_HAND, pos, direction); - - if (result != ActionResult.PASS) { - // Returning true will spawn particles and trigger the animation of the hand -> only for SUCCESS. - info.setReturnValue(result == ActionResult.SUCCESS); - - // We also need to let the server process the action if it's accepted. - if (result.isAccepted()) { - sendSequencedPacket(client.world, id -> new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.START_DESTROY_BLOCK, pos, direction, id)); - } - } - } - - @Inject( - method = "updateBlockBreakingProgress", - at = @At(value = "INVOKE", target = "Lnet/minecraft/world/GameMode;isCreative()Z", ordinal = 0), - cancellable = true - ) - private void updateBlockBreakingProgress(BlockPos pos, Direction direction, CallbackInfoReturnable info) { - if (gameMode.isCreative()) { - attackBlock(pos, direction, info); - } - } - - // Inline fabric_fireAttackBlockCallback - // Remove unused mixins: fabric$onBlockBroken, interactBlock, interactItem, attackEntity -} diff --git a/NeoForgeMod/src/main/java/opekope2/avm_staff/mixin/neoforge/ServerPlayerInteractionManagerMixin.java b/NeoForgeMod/src/main/java/opekope2/avm_staff/mixin/neoforge/ServerPlayerInteractionManagerMixin.java deleted file mode 100644 index db7780495..000000000 --- a/NeoForgeMod/src/main/java/opekope2/avm_staff/mixin/neoforge/ServerPlayerInteractionManagerMixin.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package opekope2.avm_staff.mixin.neoforge; - -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.network.listener.ClientPlayPacketListener; -import net.minecraft.network.packet.Packet; -import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; -import net.minecraft.network.packet.s2c.play.BlockUpdateS2CPacket; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.network.ServerPlayerInteractionManager; -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; -import opekope2.avm_staff.internal.event_handler.StaffAttackHandlerKt; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ServerPlayerInteractionManager.class) -public abstract class ServerPlayerInteractionManagerMixin { - @Shadow - protected ServerWorld world; - - @Shadow - @Final - protected ServerPlayerEntity player; - - // Change method to directly call Staff Mod instead of an exposed event - @Inject(at = @At("HEAD"), method = "processBlockBreakingAction", cancellable = true) - public void startBlockBreak(BlockPos pos, PlayerActionC2SPacket.Action playerAction, Direction direction, int worldHeight, int i, CallbackInfo info) { - if (playerAction != PlayerActionC2SPacket.Action.START_DESTROY_BLOCK) return; - - ActionResult result = StaffAttackHandlerKt.attackBlock(player, world, Hand.MAIN_HAND, pos, direction); - - if (result == ActionResult.PASS) return; - - // The client might have broken the block on its side, so make sure to let it know. - this.player.networkHandler.sendPacket(new BlockUpdateS2CPacket(world, pos)); - - if (world.getBlockState(pos).hasBlockEntity()) { - BlockEntity blockEntity = world.getBlockEntity(pos); - - if (blockEntity != null) { - Packet updatePacket = blockEntity.toUpdatePacket(); - - if (updatePacket != null) { - this.player.networkHandler.sendPacket(updatePacket); - } - } - } - - info.cancel(); - } - - // Remove unused mixins: interactBlock, interactItem, breakBlock, onBlockBroken -} diff --git a/NeoForgeMod/src/main/resources/META-INF/mods.toml b/NeoForgeMod/src/main/resources/META-INF/mods.toml index 51f87f9e8..341408eb3 100644 --- a/NeoForgeMod/src/main/resources/META-INF/mods.toml +++ b/NeoForgeMod/src/main/resources/META-INF/mods.toml @@ -18,9 +18,6 @@ displayURL = "https://opekope2.dev/StaffMod" [[mixins]] config = "avm_staff.mixins.json" -[[mixins]] -config = "avm_staff_neoforge.mixins.json" - [[dependencies.avm_staff]] modId = "neoforge" type = "required" diff --git a/NeoForgeMod/src/main/resources/avm_staff_neoforge.mixins.json b/NeoForgeMod/src/main/resources/avm_staff_neoforge.mixins.json deleted file mode 100644 index ff97af424..000000000 --- a/NeoForgeMod/src/main/resources/avm_staff_neoforge.mixins.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "required": true, - "package": "opekope2.avm_staff.mixin.neoforge", - "compatibilityLevel": "JAVA_17", - "minVersion": "0.8", - "injectors": { - "defaultRequire": 1 - }, - "client": [ - "ClientPlayerInteractionManagerMixin" - ], - "mixins": [ - "ServerPlayerInteractionManagerMixin" - ] -} From 3970c8763053d14a6209ea89552afb043c33f984 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 20 May 2024 00:47:20 +0200 Subject: [PATCH 042/128] Remove mixins from Forge project --- ForgeMod/Fabric.license | 201 ------------------ ForgeMod/build.gradle.kts | 3 - .../ClientPlayerInteractionManagerMixin.java | 85 -------- .../ServerPlayerInteractionManagerMixin.java | 76 ------- .../resources/avm_staff_forge.mixins.json | 15 -- 5 files changed, 380 deletions(-) delete mode 100644 ForgeMod/Fabric.license delete mode 100644 ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ClientPlayerInteractionManagerMixin.java delete mode 100644 ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ServerPlayerInteractionManagerMixin.java delete mode 100644 ForgeMod/src/main/resources/avm_staff_forge.mixins.json diff --git a/ForgeMod/Fabric.license b/ForgeMod/Fabric.license deleted file mode 100644 index 8dada3eda..000000000 --- a/ForgeMod/Fabric.license +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/ForgeMod/build.gradle.kts b/ForgeMod/build.gradle.kts index 984d42fb1..2adc8f2b4 100644 --- a/ForgeMod/build.gradle.kts +++ b/ForgeMod/build.gradle.kts @@ -56,7 +56,6 @@ loom { extraAccessWideners.add(loom.accessWidenerPath.get().asFile.name) mixinConfig("avm_staff.mixins.json") - mixinConfig("avm_staff_forge.mixins.json") } mods { @@ -95,7 +94,6 @@ tasks { from(rootDir.resolve("COPYING")) from(rootDir.resolve("COPYING.LESSER")) - from(projectDir.resolve("Fabric.license")) } remapJar { @@ -106,7 +104,6 @@ tasks { from(rootDir.resolve("COPYING")) from(rootDir.resolve("COPYING.LESSER")) - from(projectDir.resolve("Fabric.license")) } sourcesJar { diff --git a/ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ClientPlayerInteractionManagerMixin.java b/ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ClientPlayerInteractionManagerMixin.java deleted file mode 100644 index 1ebb471b0..000000000 --- a/ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ClientPlayerInteractionManagerMixin.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package opekope2.avm_staff.mixin.forge; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayerInteractionManager; -import net.minecraft.client.network.SequencedPacketCreator; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.world.GameMode; -import opekope2.avm_staff.internal.event_handler.StaffAttackHandlerKt; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(ClientPlayerInteractionManager.class) -public abstract class ClientPlayerInteractionManagerMixin { - @Shadow - @Final - private MinecraftClient client; - - @Shadow - private GameMode gameMode; - - @Shadow - protected abstract void sendSequencedPacket(ClientWorld clientWorld, SequencedPacketCreator supplier); - - // Change method to directly call Staff Mod instead of an exposed event - @Inject( - method = "attackBlock", - at = @At(value = "INVOKE", target = "Lnet/minecraft/world/GameMode;isCreative()Z", ordinal = 0), - cancellable = true - ) - private void attackBlock(BlockPos pos, Direction direction, CallbackInfoReturnable info) { - assert client.player != null; - assert client.world != null; - - ActionResult result = StaffAttackHandlerKt.attackBlock(client.player, client.world, Hand.MAIN_HAND, pos, direction); - - if (result != ActionResult.PASS) { - // Returning true will spawn particles and trigger the animation of the hand -> only for SUCCESS. - info.setReturnValue(result == ActionResult.SUCCESS); - - // We also need to let the server process the action if it's accepted. - if (result.isAccepted()) { - sendSequencedPacket(client.world, id -> new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.START_DESTROY_BLOCK, pos, direction, id)); - } - } - } - - @Inject( - method = "updateBlockBreakingProgress", - at = @At(value = "INVOKE", target = "Lnet/minecraft/world/GameMode;isCreative()Z", ordinal = 0), - cancellable = true - ) - private void updateBlockBreakingProgress(BlockPos pos, Direction direction, CallbackInfoReturnable info) { - if (gameMode.isCreative()) { - attackBlock(pos, direction, info); - } - } - - // Inline fabric_fireAttackBlockCallback - // Remove unused mixins: fabric$onBlockBroken, interactBlock, interactItem, attackEntity -} diff --git a/ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ServerPlayerInteractionManagerMixin.java b/ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ServerPlayerInteractionManagerMixin.java deleted file mode 100644 index 65c0e7ad2..000000000 --- a/ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ServerPlayerInteractionManagerMixin.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package opekope2.avm_staff.mixin.forge; - -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.network.listener.ClientPlayPacketListener; -import net.minecraft.network.packet.Packet; -import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; -import net.minecraft.network.packet.s2c.play.BlockUpdateS2CPacket; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.network.ServerPlayerInteractionManager; -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; -import opekope2.avm_staff.internal.event_handler.StaffAttackHandlerKt; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ServerPlayerInteractionManager.class) -public abstract class ServerPlayerInteractionManagerMixin { - @Shadow - protected ServerWorld world; - - @Shadow - @Final - protected ServerPlayerEntity player; - - // Change method to directly call Staff Mod instead of an exposed event - @Inject(at = @At("HEAD"), method = "processBlockBreakingAction", cancellable = true) - public void startBlockBreak(BlockPos pos, PlayerActionC2SPacket.Action playerAction, Direction direction, int worldHeight, int i, CallbackInfo info) { - if (playerAction != PlayerActionC2SPacket.Action.START_DESTROY_BLOCK) return; - - ActionResult result = StaffAttackHandlerKt.attackBlock(player, world, Hand.MAIN_HAND, pos, direction); - - if (result == ActionResult.PASS) return; - - // The client might have broken the block on its side, so make sure to let it know. - this.player.networkHandler.sendPacket(new BlockUpdateS2CPacket(world, pos)); - - if (world.getBlockState(pos).hasBlockEntity()) { - BlockEntity blockEntity = world.getBlockEntity(pos); - - if (blockEntity != null) { - Packet updatePacket = blockEntity.toUpdatePacket(); - - if (updatePacket != null) { - this.player.networkHandler.sendPacket(updatePacket); - } - } - } - - info.cancel(); - } - - // Remove unused mixins: interactBlock, interactItem, breakBlock, onBlockBroken -} diff --git a/ForgeMod/src/main/resources/avm_staff_forge.mixins.json b/ForgeMod/src/main/resources/avm_staff_forge.mixins.json deleted file mode 100644 index 925498177..000000000 --- a/ForgeMod/src/main/resources/avm_staff_forge.mixins.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "required": true, - "package": "opekope2.avm_staff.mixin.forge", - "compatibilityLevel": "JAVA_17", - "minVersion": "0.8", - "injectors": { - "defaultRequire": 1 - }, - "client": [ - "ClientPlayerInteractionManagerMixin" - ], - "mixins": [ - "ServerPlayerInteractionManagerMixin" - ] -} From 0266deb253569da955cf41f076292d9cda718685 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 20 May 2024 01:11:44 +0200 Subject: [PATCH 043/128] Refactor StaffItemHandler.attack Migrate to Architectury API from mixin Fix AttackC2SPacket channel ID --- .../avm_staff/mixin/MinecraftClientMixin.java | 75 ------------------- .../avm_staff/api/item/StaffItemHandler.kt | 23 +----- .../avm_staff/internal/Initializer.kt | 10 +-- .../internal/event_handler/NetworkHandler.kt | 15 ++-- .../event_handler/StaffAttackHandler.kt | 16 ++-- ...fAttackC2SPacket.kt => AttackC2SPacket.kt} | 14 ++-- .../staff_item_handler/MagmaBlockHandler.kt | 4 +- .../staff_item_handler/SnowBlockHandler.kt | 4 +- .../internal/staff_item_handler/TntHandler.kt | 7 +- .../WitherSkeletonSkullHandler.kt | 6 +- .../src/main/resources/avm_staff.mixins.json | 3 +- 11 files changed, 40 insertions(+), 137 deletions(-) delete mode 100644 StaffMod/src/main/java/opekope2/avm_staff/mixin/MinecraftClientMixin.java rename StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/{StaffAttackC2SPacket.kt => AttackC2SPacket.kt} (76%) diff --git a/StaffMod/src/main/java/opekope2/avm_staff/mixin/MinecraftClientMixin.java b/StaffMod/src/main/java/opekope2/avm_staff/mixin/MinecraftClientMixin.java deleted file mode 100644 index 483e6ac78..000000000 --- a/StaffMod/src/main/java/opekope2/avm_staff/mixin/MinecraftClientMixin.java +++ /dev/null @@ -1,75 +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.mixin; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; -import opekope2.avm_staff.internal.event_handler.StaffAttackHandlerKt; -import opekope2.avm_staff.internal.networking.c2s.play.StaffAttackC2SPacket; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(MinecraftClient.class) -public abstract class MinecraftClientMixin { - @Shadow - @Nullable - public ClientPlayerEntity player; - - @Shadow - @Nullable - public ClientWorld world; - - @Inject( - method = "doAttack", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;hasLimitedAttackSpeed()Z", - ordinal = 1 - ), - cancellable = true - ) - private void handleAttack(CallbackInfoReturnable cir) { - assert player != null; - assert world != null; - - ItemStack stackInHand = player.getStackInHand(Hand.MAIN_HAND); - - ActionResult result = StaffAttackHandlerKt.attack(stackInHand, world, player, Hand.MAIN_HAND); - switch (result) { - case SUCCESS -> { - new StaffAttackC2SPacket().send(); - player.swingHand(Hand.MAIN_HAND); - cir.setReturnValue(false); - } - case CONSUME, CONSUME_PARTIAL -> { - new StaffAttackC2SPacket().send(); - cir.setReturnValue(false); - } - case FAIL -> cir.setReturnValue(false); - } - } -} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt index e31f39be2..afc3d0bb6 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt @@ -228,32 +228,15 @@ abstract class StaffItemHandler { } /** - * Called on both the client and the server by Staff Mod, when an entity attacks nothing (left clicks on air) with - * a staff. - * - * On the logical client, the return values have the following meaning: - * - * - SUCCESS: send a packet to the server, and swing hand. This doesn't reset attack cooldown - * - CONSUME, CONSUME_PARTIAL: send a packet to the server, and don't swing hand. This doesn't reset attack cooldown - * - PASS: Let Minecraft handle vanilla attack - * - FAIL: don't send a packet to the server, and don't swing hand. This doesn't reset attack cooldown - * - * On the logical server, the return value is ignored (if used by player) or processed by the caller code - * (if the attacker is not a player). + * Called on both the client by Architectury API and the server by Staff Mod, when an entity attacks thin air with a + * staff. * * @param staffStack The item stack used to perform the action * @param world The world the [attacker] is in * @param attacker The entity, which attacked with the staff * @param hand The hand of the [attacker], in which the [staff][staffStack] is */ - open fun attack( - staffStack: ItemStack, - world: World, - attacker: LivingEntity, - hand: Hand - ): ActionResult { - return ActionResult.PASS - } + open fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand) {} /** * Called on both the client and the server by Architectury API, when an entity attacks a block with a staff. 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 e31ee38fa..b4b0a6d9c 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -24,13 +24,10 @@ import net.minecraft.loot.LootPool import net.minecraft.loot.entry.ItemEntry import net.minecraft.util.Identifier import opekope2.avm_staff.api.crownOfKingOrangeItem -import opekope2.avm_staff.internal.event_handler.addBlockToStaff -import opekope2.avm_staff.internal.event_handler.attack -import opekope2.avm_staff.internal.event_handler.attackBlock -import opekope2.avm_staff.internal.event_handler.removeBlockFromStaff +import opekope2.avm_staff.internal.event_handler.* import opekope2.avm_staff.internal.networking.c2s.play.AddItemToStaffC2SPacket +import opekope2.avm_staff.internal.networking.c2s.play.AttackC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.RemoveItemFromStaffC2SPacket -import opekope2.avm_staff.internal.networking.c2s.play.StaffAttackC2SPacket fun registerContent() { opekope2.avm_staff.api.registerContent() @@ -39,13 +36,14 @@ fun registerContent() { fun initializeNetworking() { AddItemToStaffC2SPacket.registerHandler(::addBlockToStaff) RemoveItemFromStaffC2SPacket.registerHandler(::removeBlockFromStaff) - StaffAttackC2SPacket.registerHandler(::attack) + AttackC2SPacket.registerHandler(::attack) } private val TREASURE_BASTION_CHEST_LOOT = Identifier("chests/bastion_treasure") fun subscribeToEvents() { InteractionEvent.LEFT_CLICK_BLOCK.register(::attackBlock) + InteractionEvent.CLIENT_LEFT_CLICK_AIR.register(::clientAttack) LootEvent.MODIFY_LOOT_TABLE.register(LootEvent.ModifyLootTable { _, lootTableId, context, builtin -> if (builtin && lootTableId == TREASURE_BASTION_CHEST_LOOT) { context.addPool(LootPool.builder().with(ItemEntry.builder(crownOfKingOrangeItem.get()))) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt index 52fa2f4a1..7b94c0686 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt @@ -22,12 +22,11 @@ import dev.architectury.networking.NetworkManager.PacketContext import net.minecraft.entity.player.PlayerEntity import net.minecraft.entity.player.PlayerInventory import net.minecraft.item.ItemStack -import net.minecraft.util.ActionResult -import net.minecraft.util.Hand import opekope2.avm_staff.api.staffsTag import opekope2.avm_staff.internal.networking.c2s.play.AddItemToStaffC2SPacket +import opekope2.avm_staff.internal.networking.c2s.play.AttackC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.RemoveItemFromStaffC2SPacket -import opekope2.avm_staff.internal.networking.c2s.play.StaffAttackC2SPacket +import opekope2.avm_staff.util.handlerOfItem import opekope2.avm_staff.util.hasHandlerOfItem import opekope2.avm_staff.util.isItemInStaff import opekope2.avm_staff.util.itemInStaff @@ -59,12 +58,16 @@ fun removeBlockFromStaff(packet: RemoveItemFromStaffC2SPacket, context: PacketCo } } -@Suppress("UNUSED_PARAMETER") -fun attack(packet: StaffAttackC2SPacket, context: PacketContext): ActionResult { +fun attack(packet: AttackC2SPacket, context: PacketContext) { val player = context.player val staffStack = player.mainHandStack - return attack(staffStack, player.world, player, Hand.MAIN_HAND) + if (!staffStack.isIn(staffsTag)) return + + val itemInStaff: ItemStack = staffStack.itemInStaff ?: return + val staffHandler = itemInStaff.handlerOfItem ?: return + + staffHandler.attack(staffStack, player.entityWorld, player, packet.hand) } private fun ItemStack.canAccept(other: ItemStack, maxCountPerStack: Int): Boolean { diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt index 264433215..175766b0a 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt @@ -19,15 +19,13 @@ package opekope2.avm_staff.internal.event_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.util.ActionResult 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.staffsTag +import opekope2.avm_staff.internal.networking.c2s.play.AttackC2SPacket import opekope2.avm_staff.util.handlerOfItem import opekope2.avm_staff.util.itemInStaff @@ -43,11 +41,13 @@ fun attackBlock(player: PlayerEntity, hand: Hand, target: BlockPos, direction: D else result } -fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand): ActionResult { - if (!staffStack.isIn(staffsTag)) return ActionResult.PASS +fun clientAttack(player: PlayerEntity, hand: Hand) { + val staffStack = player.getStackInHand(hand) + if (!staffStack.isIn(staffsTag)) return - val itemInStaff: ItemStack = staffStack.itemInStaff ?: return ActionResult.PASS - val staffHandler = itemInStaff.handlerOfItem ?: return ActionResult.PASS + val itemInStaff: ItemStack = staffStack.itemInStaff ?: return + val staffHandler = itemInStaff.handlerOfItem ?: return - return staffHandler.attack(staffStack, world, attacker, hand) + staffHandler.attack(staffStack, player.entityWorld, player, hand) + AttackC2SPacket(hand).send() } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/StaffAttackC2SPacket.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/AttackC2SPacket.kt similarity index 76% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/StaffAttackC2SPacket.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/AttackC2SPacket.kt index fb79dbeac..728da0e00 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/StaffAttackC2SPacket.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/AttackC2SPacket.kt @@ -22,23 +22,25 @@ import dev.architectury.networking.NetworkChannel import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.minecraft.network.PacketByteBuf +import net.minecraft.util.Hand import net.minecraft.util.Identifier import opekope2.avm_staff.internal.networking.IPacket import opekope2.avm_staff.internal.networking.PacketRegistrar import opekope2.avm_staff.util.MOD_ID -class StaffAttackC2SPacket() : IPacket { - constructor(@Suppress("UNUSED_PARAMETER") buf: PacketByteBuf) : this() +class AttackC2SPacket(val hand: Hand) : IPacket { + constructor(buf: PacketByteBuf) : this(buf.readEnumConstant(Hand::class.java)) override fun write(buf: PacketByteBuf) { + buf.writeEnumConstant(hand) } @Environment(EnvType.CLIENT) fun send() = channel.sendToServer(this) - companion object : PacketRegistrar( - NetworkChannel.create(Identifier(MOD_ID, "remove_item_from_staff")), - StaffAttackC2SPacket::class.java, - ::StaffAttackC2SPacket + companion object : PacketRegistrar( + NetworkChannel.create(Identifier(MOD_ID, "attack")), + AttackC2SPacket::class.java, + ::AttackC2SPacket ) } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/MagmaBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/MagmaBlockHandler.kt index 7ec51fe97..4cda3155a 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/MagmaBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/MagmaBlockHandler.kt @@ -30,7 +30,6 @@ 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.util.ActionResult import net.minecraft.util.Hand import net.minecraft.util.TypedActionResult import net.minecraft.world.World @@ -57,10 +56,9 @@ class MagmaBlockHandler : StaffItemHandler() { } } - override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand): ActionResult { + override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand) { shootFireball(world, attacker) (attacker as? PlayerEntity)?.resetLastAttackedTicks() - return ActionResult.SUCCESS } override fun attackEntity( diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/SnowBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/SnowBlockHandler.kt index b1e6fd56b..4cf6ed547 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/SnowBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/SnowBlockHandler.kt @@ -23,7 +23,6 @@ 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.ActionResult import net.minecraft.util.Hand import net.minecraft.util.TypedActionResult import net.minecraft.world.World @@ -47,10 +46,9 @@ class SnowBlockHandler : StaffItemHandler() { throwSnowball(world, user) } - override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand): ActionResult { + override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand) { throwSnowball(world, attacker) (attacker as? PlayerEntity)?.resetLastAttackedTicks() - return ActionResult.SUCCESS } private fun throwSnowball(world: World, user: LivingEntity) { diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/TntHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/TntHandler.kt index 1d9a9b073..4492048c9 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/TntHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/TntHandler.kt @@ -33,10 +33,9 @@ import opekope2.avm_staff.api.item.StaffItemHandler import opekope2.avm_staff.util.* class TntHandler : StaffItemHandler() { - override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand): ActionResult { - return shootTnt(world, attacker).also { - (attacker as? PlayerEntity)?.resetLastAttackedTicks() - } + override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand) { + shootTnt(world, attacker) + (attacker as? PlayerEntity)?.resetLastAttackedTicks() } private fun shootTnt(world: World, attacker: LivingEntity): ActionResult { diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt index 47a39046e..52f49e3ef 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt @@ -35,7 +35,6 @@ 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.util.ActionResult import net.minecraft.util.Hand import net.minecraft.util.TypedActionResult import net.minecraft.world.Difficulty @@ -64,12 +63,11 @@ class WitherSkeletonSkullHandler : StaffItemHandler() { } } - override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand): ActionResult { - if (attacker is PlayerEntity && attacker.itemCooldownManager.isCoolingDown(staffStack.item)) return ActionResult.FAIL + override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand) { + if (attacker is PlayerEntity && attacker.itemCooldownManager.isCoolingDown(staffStack.item)) return shootSkull(world, attacker, false) (attacker as? PlayerEntity)?.resetLastAttackedTicks() - return ActionResult.SUCCESS } private fun shootSkull(world: World, user: LivingEntity, charged: Boolean) { diff --git a/StaffMod/src/main/resources/avm_staff.mixins.json b/StaffMod/src/main/resources/avm_staff.mixins.json index 58c443522..3e4a91b2b 100644 --- a/StaffMod/src/main/resources/avm_staff.mixins.json +++ b/StaffMod/src/main/resources/avm_staff.mixins.json @@ -9,8 +9,7 @@ "client": [ "BipedEntityModelMixin", "IMinecraftClientMixin", - "IParticleMixin", - "MinecraftClientMixin" + "IParticleMixin" ], "mixins": [ "IAbstractFurnaceBlockEntityMixin", From 30d35b2aac7aa851bc1e401adad722de600e018d Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 20 May 2024 01:46:37 +0200 Subject: [PATCH 044/128] Replace @Invokers with access wideners --- .../IAbstractFurnaceBlockEntityMixin.java | 33 ------------------- .../avm_staff/mixin/IEntityMixin.java | 30 ----------------- .../staff_item_handler/CampfireHandler.kt | 4 +-- .../staff_item_handler/FurnaceHandler.kt | 4 +-- .../main/resources/avm_staff.accesswidener | 8 +++-- .../src/main/resources/avm_staff.mixins.json | 2 -- 6 files changed, 8 insertions(+), 73 deletions(-) delete mode 100644 StaffMod/src/main/java/opekope2/avm_staff/mixin/IAbstractFurnaceBlockEntityMixin.java delete mode 100644 StaffMod/src/main/java/opekope2/avm_staff/mixin/IEntityMixin.java diff --git a/StaffMod/src/main/java/opekope2/avm_staff/mixin/IAbstractFurnaceBlockEntityMixin.java b/StaffMod/src/main/java/opekope2/avm_staff/mixin/IAbstractFurnaceBlockEntityMixin.java deleted file mode 100644 index e5837d923..000000000 --- a/StaffMod/src/main/java/opekope2/avm_staff/mixin/IAbstractFurnaceBlockEntityMixin.java +++ /dev/null @@ -1,33 +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.mixin; - -import net.minecraft.block.entity.AbstractFurnaceBlockEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.Vec3d; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -@Mixin(AbstractFurnaceBlockEntity.class) -public interface IAbstractFurnaceBlockEntityMixin { - @Invoker - static void invokeDropExperience(ServerWorld world, Vec3d pos, int multiplier, float experience) { - throw new AssertionError(); - } -} diff --git a/StaffMod/src/main/java/opekope2/avm_staff/mixin/IEntityMixin.java b/StaffMod/src/main/java/opekope2/avm_staff/mixin/IEntityMixin.java deleted file mode 100644 index 382d74c25..000000000 --- a/StaffMod/src/main/java/opekope2/avm_staff/mixin/IEntityMixin.java +++ /dev/null @@ -1,30 +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.mixin; - -import net.minecraft.entity.Entity; -import net.minecraft.util.math.Vec3d; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -@Mixin(Entity.class) -public interface IEntityMixin { - @Invoker - Vec3d invokeGetRotationVector(float pitch, float yaw); -} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/CampfireHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/CampfireHandler.kt index 61f0d6e23..9fce78fe9 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/CampfireHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/CampfireHandler.kt @@ -45,7 +45,6 @@ import net.minecraft.world.RaycastContext import net.minecraft.world.World import net.minecraft.world.event.GameEvent import opekope2.avm_staff.api.item.StaffItemHandler -import opekope2.avm_staff.mixin.IEntityMixin import opekope2.avm_staff.util.* class CampfireHandler( @@ -73,8 +72,7 @@ class CampfireHandler( val forward = user.rotationVector val origin = user.approximateStaffTipPosition val target = origin + forward * FLAME_MAX_DISTANCE - val relativeRight = - (user as IEntityMixin).invokeGetRotationVector(0f, MathHelper.wrapDegrees(user.yaw + 90f)).normalize() + val relativeRight = user.getRotationVector(0f, MathHelper.wrapDegrees(user.yaw + 90f)).normalize() val relativeUp = relativeRight.crossProduct(forward).normalize() if (world.isClient) { diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt index a7e2671d2..fe6d06288 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt @@ -25,6 +25,7 @@ import net.fabricmc.api.Environment import net.minecraft.block.AbstractFurnaceBlock import net.minecraft.block.Block import net.minecraft.block.BlockState +import net.minecraft.block.entity.AbstractFurnaceBlockEntity import net.minecraft.client.MinecraftClient import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.render.model.json.ModelTransformationMode @@ -52,7 +53,6 @@ import opekope2.avm_staff.api.item.StaffItemHandler import opekope2.avm_staff.api.item.activeItemTempData import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer -import opekope2.avm_staff.mixin.IAbstractFurnaceBlockEntityMixin import opekope2.avm_staff.util.* import kotlin.jvm.optionals.getOrNull @@ -101,7 +101,7 @@ class FurnaceHandler( val (vx, vy, vz) = itemToSmelt.velocity world.spawnEntity(ItemEntity(world, itemToSmelt.x, itemToSmelt.y, itemToSmelt.z, resultItem, vx, vy, vz)) - IAbstractFurnaceBlockEntityMixin.invokeDropExperience( + AbstractFurnaceBlockEntity.dropExperience( world as ServerWorld, itemToSmelt.pos, stackToSmelt.count, diff --git a/StaffMod/src/main/resources/avm_staff.accesswidener b/StaffMod/src/main/resources/avm_staff.accesswidener index 422052a07..43b92e859 100644 --- a/StaffMod/src/main/resources/avm_staff.accesswidener +++ b/StaffMod/src/main/resources/avm_staff.accesswidener @@ -1,5 +1,7 @@ accessWidener v2 named -accessible field net/minecraft/item/Item ATTACK_DAMAGE_MODIFIER_ID Ljava/util/UUID; -accessible field net/minecraft/item/Item ATTACK_SPEED_MODIFIER_ID Ljava/util/UUID; -accessible method net/minecraft/particle/DefaultParticleType (Z)V +accessible field net/minecraft/item/Item ATTACK_DAMAGE_MODIFIER_ID Ljava/util/UUID; +accessible field net/minecraft/item/Item ATTACK_SPEED_MODIFIER_ID Ljava/util/UUID; +accessible method net/minecraft/particle/DefaultParticleType (Z)V +accessible method net/minecraft/block/entity/AbstractFurnaceBlockEntity dropExperience (Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/util/math/Vec3d;IF)V +accessible method net/minecraft/entity/Entity getRotationVector (FF)Lnet/minecraft/util/math/Vec3d; diff --git a/StaffMod/src/main/resources/avm_staff.mixins.json b/StaffMod/src/main/resources/avm_staff.mixins.json index 3e4a91b2b..3b6edd1f4 100644 --- a/StaffMod/src/main/resources/avm_staff.mixins.json +++ b/StaffMod/src/main/resources/avm_staff.mixins.json @@ -12,8 +12,6 @@ "IParticleMixin" ], "mixins": [ - "IAbstractFurnaceBlockEntityMixin", - "IEntityMixin", "LivingEntityMixin", "TntEntityMixin" ] From 41983293368f14ed958d6a595a6928ed949939fd Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 20 May 2024 01:49:27 +0200 Subject: [PATCH 045/128] Extract modifyLootTables from subscribeToEvents --- .../avm_staff/internal/Initializer.kt | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 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 b4b0a6d9c..e9abe9d10 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -20,6 +20,7 @@ package opekope2.avm_staff.internal import dev.architectury.event.events.common.InteractionEvent import dev.architectury.event.events.common.LootEvent +import net.minecraft.loot.LootManager import net.minecraft.loot.LootPool import net.minecraft.loot.entry.ItemEntry import net.minecraft.util.Identifier @@ -41,12 +42,20 @@ fun initializeNetworking() { private val TREASURE_BASTION_CHEST_LOOT = Identifier("chests/bastion_treasure") +@Suppress("UNUSED_PARAMETER") +fun modifyLootTables( + lootManager: LootManager?, + lootTableId: Identifier, + context: LootEvent.LootTableModificationContext, + builtin: Boolean +) { + if (builtin && lootTableId == TREASURE_BASTION_CHEST_LOOT) { + context.addPool(LootPool.builder().with(ItemEntry.builder(crownOfKingOrangeItem.get()))) + } +} + fun subscribeToEvents() { InteractionEvent.LEFT_CLICK_BLOCK.register(::attackBlock) InteractionEvent.CLIENT_LEFT_CLICK_AIR.register(::clientAttack) - LootEvent.MODIFY_LOOT_TABLE.register(LootEvent.ModifyLootTable { _, lootTableId, context, builtin -> - if (builtin && lootTableId == TREASURE_BASTION_CHEST_LOOT) { - context.addPool(LootPool.builder().with(ItemEntry.builder(crownOfKingOrangeItem.get()))) - } - }) + LootEvent.MODIFY_LOOT_TABLE.register(::modifyLootTables) } From 4b083fa619660a09320466188f7436a8f2820324 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 20 May 2024 01:51:23 +0200 Subject: [PATCH 046/128] Move attackBlock and clientAttack into Initializer.kt --- .../avm_staff/internal/Initializer.kt | 36 ++++++++++++- .../event_handler/StaffAttackHandler.kt | 53 ------------------- 2 files changed, 35 insertions(+), 54 deletions(-) delete mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt 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 e9abe9d10..e0563b390 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -18,17 +18,28 @@ package opekope2.avm_staff.internal +import dev.architectury.event.EventResult import dev.architectury.event.events.common.InteractionEvent import dev.architectury.event.events.common.LootEvent +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.ItemStack import net.minecraft.loot.LootManager import net.minecraft.loot.LootPool import net.minecraft.loot.entry.ItemEntry +import net.minecraft.util.Hand import net.minecraft.util.Identifier +import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Direction import opekope2.avm_staff.api.crownOfKingOrangeItem -import opekope2.avm_staff.internal.event_handler.* +import opekope2.avm_staff.api.staffsTag +import opekope2.avm_staff.internal.event_handler.addBlockToStaff +import opekope2.avm_staff.internal.event_handler.attack +import opekope2.avm_staff.internal.event_handler.removeBlockFromStaff import opekope2.avm_staff.internal.networking.c2s.play.AddItemToStaffC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.AttackC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.RemoveItemFromStaffC2SPacket +import opekope2.avm_staff.util.handlerOfItem +import opekope2.avm_staff.util.itemInStaff fun registerContent() { opekope2.avm_staff.api.registerContent() @@ -40,6 +51,29 @@ fun initializeNetworking() { AttackC2SPacket.registerHandler(::attack) } +private fun attackBlock(player: PlayerEntity, hand: Hand, target: BlockPos, direction: Direction): EventResult { + val staffStack = player.getStackInHand(hand) + if (!staffStack.isIn(staffsTag)) return EventResult.pass() + + val itemInStaff = staffStack.itemInStaff ?: return EventResult.pass() + val staffHandler = itemInStaff.handlerOfItem ?: return EventResult.pass() + + val result = staffHandler.attackBlock(staffStack, player.entityWorld, player, target, direction, hand) + return if (result.isFalse) EventResult.interruptTrue() // Force Fabric to send packet for Neo/Forge parity + else result +} + +private fun clientAttack(player: PlayerEntity, hand: Hand) { + val staffStack = player.getStackInHand(hand) + if (!staffStack.isIn(staffsTag)) return + + val itemInStaff: ItemStack = staffStack.itemInStaff ?: return + val staffHandler = itemInStaff.handlerOfItem ?: return + + staffHandler.attack(staffStack, player.entityWorld, player, hand) + AttackC2SPacket(hand).send() +} + private val TREASURE_BASTION_CHEST_LOOT = Identifier("chests/bastion_treasure") @Suppress("UNUSED_PARAMETER") diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt deleted file mode 100644 index 175766b0a..000000000 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/StaffAttackHandler.kt +++ /dev/null @@ -1,53 +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.event_handler - -import dev.architectury.event.EventResult -import net.minecraft.entity.player.PlayerEntity -import net.minecraft.item.ItemStack -import net.minecraft.util.Hand -import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.Direction -import opekope2.avm_staff.api.staffsTag -import opekope2.avm_staff.internal.networking.c2s.play.AttackC2SPacket -import opekope2.avm_staff.util.handlerOfItem -import opekope2.avm_staff.util.itemInStaff - -fun attackBlock(player: PlayerEntity, hand: Hand, target: BlockPos, direction: Direction): EventResult { - val staffStack = player.getStackInHand(hand) - if (!staffStack.isIn(staffsTag)) return EventResult.pass() - - val itemInStaff = staffStack.itemInStaff ?: return EventResult.pass() - val staffHandler = itemInStaff.handlerOfItem ?: return EventResult.pass() - - val result = staffHandler.attackBlock(staffStack, player.entityWorld, player, target, direction, hand) - return if (result.isFalse) EventResult.interruptTrue() // Force Fabric to send packet for Neo/Forge parity - else result -} - -fun clientAttack(player: PlayerEntity, hand: Hand) { - val staffStack = player.getStackInHand(hand) - if (!staffStack.isIn(staffsTag)) return - - val itemInStaff: ItemStack = staffStack.itemInStaff ?: return - val staffHandler = itemInStaff.handlerOfItem ?: return - - staffHandler.attack(staffStack, player.entityWorld, player, hand) - AttackC2SPacket(hand).send() -} From 594913fed5267ee8e2eb53a51ec52bf7a5514824 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 20 May 2024 15:18:06 +0200 Subject: [PATCH 047/128] Eliminate dead code --- .../internal/forge/StaffModClient.kt | 5 --- .../internal/neoforge/StaffModClient.kt | 5 --- .../api/render/IQuadBakerVertexConsumer.kt | 36 ------------------- 3 files changed, 46 deletions(-) delete mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/render/IQuadBakerVertexConsumer.kt diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt index cefc1b187..f6393fa93 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt @@ -24,7 +24,6 @@ import net.minecraftforge.api.distmarker.Dist import net.minecraftforge.api.distmarker.OnlyIn import net.minecraftforge.client.event.RegisterKeyMappingsEvent import net.minecraftforge.client.event.RegisterParticleProvidersEvent -import net.minecraftforge.event.BuildCreativeModeTabContentsEvent import net.minecraftforge.event.TickEvent import net.minecraftforge.eventbus.api.SubscribeEvent import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent @@ -53,10 +52,6 @@ object StaffModClient { } } - @SubscribeEvent - fun addItemsToItemGroups(event: BuildCreativeModeTabContentsEvent) { - } - @SubscribeEvent fun registerParticleProviders(event: RegisterParticleProvidersEvent) { event.registerSpriteSet(flamethrowerParticleType.get(), FlamethrowerParticle::Factory) 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 35f317a01..b111b2d52 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,7 +26,6 @@ import net.neoforged.bus.api.SubscribeEvent import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent import net.neoforged.neoforge.client.event.RegisterParticleProvidersEvent -import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent import net.neoforged.neoforge.event.TickEvent import opekope2.avm_staff.api.flamethrowerParticleType import opekope2.avm_staff.api.particle.FlamethrowerParticle @@ -53,10 +52,6 @@ object StaffModClient { } } - @SubscribeEvent - fun addItemsToItemGroups(event: BuildCreativeModeTabContentsEvent) { - } - @SubscribeEvent fun registerParticleProviders(event: RegisterParticleProvidersEvent) { event.registerSpriteSet(flamethrowerParticleType.get(), FlamethrowerParticle::Factory) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/render/IQuadBakerVertexConsumer.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/render/IQuadBakerVertexConsumer.kt deleted file mode 100644 index a154b4ede..000000000 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/render/IQuadBakerVertexConsumer.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.api.render - -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment -import net.minecraft.client.render.VertexConsumer -import net.minecraft.client.render.model.BakedQuad -import net.minecraft.client.texture.Sprite - -/** - * A vertex consumer, which creates [BakedQuad]s. - */ -@Environment(EnvType.CLIENT) -interface IQuadBakerVertexConsumer : VertexConsumer { - /** - * Gets or sets the sprite used to create [BakedQuad]s. - */ - var sprite: Sprite -} From bc08ae03490152ea1bcb30903f90651fbabb7bab Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 20 May 2024 15:18:21 +0200 Subject: [PATCH 048/128] Update suppressions --- StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt | 1 + .../internal/staff_item_handler/VanillaStaffItemHandlers.kt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) 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 863991dd2..cc8bec2fc 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -17,6 +17,7 @@ */ @file: JvmName("StaffMod") +@file: Suppress("unused") package opekope2.avm_staff.api diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt index 7e3995029..2e938f506 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt @@ -37,7 +37,6 @@ private fun Item.registerHandler(handler: StaffItemHandler) { StaffItemHandler.register(Registries.ITEM.getId(this), handler) } -@Suppress("unused") fun registerVanillaStaffItemHandlers() { Items.ANVIL.registerHandler(AnvilHandler(Items.CHIPPED_ANVIL::getDefaultStack)) Items.CHIPPED_ANVIL.registerHandler(AnvilHandler(Items.DAMAGED_ANVIL::getDefaultStack)) From edb815ed78f70475c9318fde41c772a5f819a79a Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 20 May 2024 21:22:21 +0200 Subject: [PATCH 049/128] Move utilities to utilities package --- .../avm_staff/internal/staff_item_handler/FurnaceHandler.kt | 1 - .../avm_staff/internal/staff_item_handler/TntHandler.kt | 1 - .../{api/item => util}/ActiveItemTempDataHolderUtil.kt | 3 ++- .../opekope2/avm_staff/{api/entity => util}/ImpactTntUtil.kt | 3 ++- 4 files changed, 4 insertions(+), 4 deletions(-) rename StaffMod/src/main/kotlin/opekope2/avm_staff/{api/item => util}/ActiveItemTempDataHolderUtil.kt (92%) rename StaffMod/src/main/kotlin/opekope2/avm_staff/{api/entity => util}/ImpactTntUtil.kt (93%) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt index fe6d06288..8fbe41b93 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt @@ -50,7 +50,6 @@ import net.minecraft.util.TypedActionResult import net.minecraft.util.math.Box import net.minecraft.world.World import opekope2.avm_staff.api.item.StaffItemHandler -import opekope2.avm_staff.api.item.activeItemTempData import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer import opekope2.avm_staff.util.* diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/TntHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/TntHandler.kt index 4492048c9..e448ab4d0 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/TntHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/TntHandler.kt @@ -28,7 +28,6 @@ import net.minecraft.util.ActionResult import net.minecraft.util.Hand import net.minecraft.world.World import net.minecraft.world.event.GameEvent -import opekope2.avm_staff.api.entity.explodesOnImpact import opekope2.avm_staff.api.item.StaffItemHandler import opekope2.avm_staff.util.* diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/ActiveItemTempDataHolderUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/ActiveItemTempDataHolderUtil.kt similarity index 92% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/ActiveItemTempDataHolderUtil.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/util/ActiveItemTempDataHolderUtil.kt index 79d7a4c2c..a9cebc9a5 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/ActiveItemTempDataHolderUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/ActiveItemTempDataHolderUtil.kt @@ -18,9 +18,10 @@ @file: JvmSynthetic -package opekope2.avm_staff.api.item +package opekope2.avm_staff.util import net.minecraft.entity.LivingEntity +import opekope2.avm_staff.api.item.IActiveItemTempDataHolder /** * Kotlin utility to get or set the temporary data associated with an entity. To be used by the item class being used on diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/ImpactTntUtil.kt similarity index 93% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntUtil.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/util/ImpactTntUtil.kt index a07c379cf..2d4e2eab3 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/ImpactTntUtil.kt @@ -18,9 +18,10 @@ @file: JvmSynthetic -package opekope2.avm_staff.api.entity +package opekope2.avm_staff.util import net.minecraft.entity.TntEntity +import opekope2.avm_staff.api.entity.IImpactTnt /** * Kotlin utility to get or set a TNT to explode when it collides with a block or entity. From e04b7483bbac84881cded57f8d40727a55c17a72 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 20 May 2024 21:43:04 +0200 Subject: [PATCH 050/128] Refactor StaffItemHandler Rename to StaffHandler Move to staff package from item package Merge IDisablesShield functionality --- .../mixin/fabric/LivingEntityMixin.java | 7 +++--- FabricMod/src/main/resources/fabric.mod.json | 4 +-- .../avm_staff/internal/forge/StaffMod.kt | 4 +-- .../internal/forge/StaffModClient.kt | 2 +- .../internal/forge/item/ForgeStaffItem.kt | 3 +-- .../avm_staff/internal/neoforge/StaffMod.kt | 4 +-- .../internal/neoforge/StaffModClient.kt | 2 +- .../neoforge/item/NeoForgeStaffItem.kt | 3 +-- .../avm_staff/api/item/IDisablesShield.kt | 24 ------------------ .../StaffHandler.kt} | 25 +++++++++++-------- .../AnvilHandler.kt | 9 ++++--- .../BellBlockHandler.kt | 6 ++--- .../BoneBlockHandler.kt | 6 ++--- .../CampfireHandler.kt | 6 ++--- .../FurnaceHandler.kt | 6 ++--- .../LightningRodHandler.kt | 6 ++--- .../MagmaBlockHandler.kt | 6 ++--- .../SnowBlockHandler.kt | 6 ++--- .../TntHandler.kt | 6 ++--- .../VanillaStaffHandlers.kt} | 10 ++++---- .../WitherSkeletonSkullHandler.kt | 6 ++--- .../WoolHandler.kt | 6 ++--- .../opekope2/avm_staff/util/StaffUtil.kt | 14 +++++------ 23 files changed, 75 insertions(+), 96 deletions(-) delete mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/IDisablesShield.kt rename StaffMod/src/main/kotlin/opekope2/avm_staff/api/{item/StaffItemHandler.kt => staff/StaffHandler.kt} (96%) rename StaffMod/src/main/kotlin/opekope2/avm_staff/internal/{staff_item_handler => staff_handler}/AnvilHandler.kt (94%) rename StaffMod/src/main/kotlin/opekope2/avm_staff/internal/{staff_item_handler => staff_handler}/BellBlockHandler.kt (96%) rename StaffMod/src/main/kotlin/opekope2/avm_staff/internal/{staff_item_handler => staff_handler}/BoneBlockHandler.kt (93%) rename StaffMod/src/main/kotlin/opekope2/avm_staff/internal/{staff_item_handler => staff_handler}/CampfireHandler.kt (98%) rename StaffMod/src/main/kotlin/opekope2/avm_staff/internal/{staff_item_handler => staff_handler}/FurnaceHandler.kt (98%) rename StaffMod/src/main/kotlin/opekope2/avm_staff/internal/{staff_item_handler => staff_handler}/LightningRodHandler.kt (95%) rename StaffMod/src/main/kotlin/opekope2/avm_staff/internal/{staff_item_handler => staff_handler}/MagmaBlockHandler.kt (95%) rename StaffMod/src/main/kotlin/opekope2/avm_staff/internal/{staff_item_handler => staff_handler}/SnowBlockHandler.kt (94%) rename StaffMod/src/main/kotlin/opekope2/avm_staff/internal/{staff_item_handler => staff_handler}/TntHandler.kt (93%) rename StaffMod/src/main/kotlin/opekope2/avm_staff/internal/{staff_item_handler/VanillaStaffItemHandlers.kt => staff_handler/VanillaStaffHandlers.kt} (95%) rename StaffMod/src/main/kotlin/opekope2/avm_staff/internal/{staff_item_handler => staff_handler}/WitherSkeletonSkullHandler.kt (97%) rename StaffMod/src/main/kotlin/opekope2/avm_staff/internal/{staff_item_handler => staff_handler}/WoolHandler.kt (95%) diff --git a/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/LivingEntityMixin.java b/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/LivingEntityMixin.java index f3df171a4..17b25bebf 100644 --- a/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/LivingEntityMixin.java +++ b/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/LivingEntityMixin.java @@ -21,8 +21,7 @@ import net.minecraft.entity.LivingEntity; import net.minecraft.item.ItemStack; import opekope2.avm_staff.api.StaffMod; -import opekope2.avm_staff.api.item.IDisablesShield; -import opekope2.avm_staff.api.item.StaffItemHandler; +import opekope2.avm_staff.api.staff.StaffHandler; import opekope2.avm_staff.util.StaffUtil; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -43,8 +42,8 @@ public void disableShield(CallbackInfoReturnable cir) { ItemStack itemInStaff = StaffUtil.getItemInStaff(mainHandStack); if (itemInStaff == null) return; - StaffItemHandler handlerOfItem = StaffUtil.getHandlerOfItem(itemInStaff); - if (handlerOfItem instanceof IDisablesShield) { + StaffHandler handlerOfItem = StaffUtil.getHandlerOfItemOrFallback(itemInStaff); + if (handlerOfItem.disablesShield()) { cir.setReturnValue(true); } } diff --git a/FabricMod/src/main/resources/fabric.mod.json b/FabricMod/src/main/resources/fabric.mod.json index 6cafec937..2595593dc 100644 --- a/FabricMod/src/main/resources/fabric.mod.json +++ b/FabricMod/src/main/resources/fabric.mod.json @@ -35,7 +35,7 @@ }, { "adapter": "kotlin", - "value": "opekope2.avm_staff.internal.staff_item_handler.VanillaStaffItemHandlersKt::registerVanillaStaffItemHandlers" + "value": "opekope2.avm_staff.internal.staff_handler.VanillaStaffHandlersKt::registerVanillaStaffHandlers" } ], "client": [ @@ -45,7 +45,7 @@ }, { "adapter": "kotlin", - "value": "opekope2.avm_staff.internal.staff_item_handler.VanillaStaffItemHandlersKt::registerVanillaStaffItemRenderers" + "value": "opekope2.avm_staff.internal.staff_handler.VanillaStaffHandlersKt::registerVanillaStaffItemRenderers" } ] }, diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt index bbfd1c9cb..171d6347d 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt @@ -23,7 +23,7 @@ import net.minecraftforge.api.distmarker.Dist import net.minecraftforge.fml.common.Mod import opekope2.avm_staff.internal.initializeNetworking import opekope2.avm_staff.internal.registerContent -import opekope2.avm_staff.internal.staff_item_handler.registerVanillaStaffItemHandlers +import opekope2.avm_staff.internal.staff_handler.registerVanillaStaffHandlers import opekope2.avm_staff.internal.subscribeToEvents import opekope2.avm_staff.util.MOD_ID import thedarkcolour.kotlinforforge.forge.MOD_BUS @@ -36,7 +36,7 @@ object StaffMod { registerContent() initializeNetworking() subscribeToEvents() - registerVanillaStaffItemHandlers() + registerVanillaStaffHandlers() runWhenOn(Dist.CLIENT, StaffModClient::initializeClient) } } diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt index f6393fa93..cf030cf52 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt @@ -33,7 +33,7 @@ import opekope2.avm_staff.api.soulFlamethrowerParticleType import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING import opekope2.avm_staff.internal.event_handler.handleKeyBindings import opekope2.avm_staff.internal.model.registerModelPredicateProviders -import opekope2.avm_staff.internal.staff_item_handler.registerVanillaStaffItemRenderers +import opekope2.avm_staff.internal.staff_handler.registerVanillaStaffItemRenderers import thedarkcolour.kotlinforforge.forge.FORGE_BUS import thedarkcolour.kotlinforforge.forge.MOD_BUS diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt index 1536d4f28..dd9cc33b2 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/ForgeStaffItem.kt @@ -35,7 +35,6 @@ import net.minecraft.item.ItemStack import net.minecraft.util.Hand import net.minecraftforge.client.extensions.common.IClientItemExtensions import net.minecraftforge.common.extensions.IForgeItem -import opekope2.avm_staff.api.item.IDisablesShield import opekope2.avm_staff.api.item.StaffItem import opekope2.avm_staff.api.item.renderer.StaffRenderer import opekope2.avm_staff.util.handlerOfItemOrFallback @@ -57,7 +56,7 @@ class ForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IForgeItem entity: LivingEntity?, attacker: LivingEntity? ): Boolean { - return stack.itemInStaff.handlerOfItemOrFallback is IDisablesShield || + return stack.itemInStaff.handlerOfItemOrFallback.disablesShield() || super.canDisableShield(stack, shield, entity, attacker) } 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 3bc2453d0..aed6e16d6 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 @@ -22,7 +22,7 @@ import net.neoforged.api.distmarker.Dist import net.neoforged.fml.common.Mod import opekope2.avm_staff.internal.initializeNetworking import opekope2.avm_staff.internal.registerContent -import opekope2.avm_staff.internal.staff_item_handler.registerVanillaStaffItemHandlers +import opekope2.avm_staff.internal.staff_handler.registerVanillaStaffHandlers import opekope2.avm_staff.internal.subscribeToEvents import opekope2.avm_staff.util.MOD_ID import thedarkcolour.kotlinforforge.neoforge.forge.runWhenOn @@ -33,7 +33,7 @@ object StaffMod { registerContent() initializeNetworking() subscribeToEvents() - registerVanillaStaffItemHandlers() + registerVanillaStaffHandlers() runWhenOn(Dist.CLIENT, StaffModClient::initializeClient) } } 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 b111b2d52..182e4cd33 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 @@ -33,7 +33,7 @@ import opekope2.avm_staff.api.soulFlamethrowerParticleType import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING import opekope2.avm_staff.internal.event_handler.handleKeyBindings import opekope2.avm_staff.internal.model.registerModelPredicateProviders -import opekope2.avm_staff.internal.staff_item_handler.registerVanillaStaffItemRenderers +import opekope2.avm_staff.internal.staff_handler.registerVanillaStaffItemRenderers import thedarkcolour.kotlinforforge.neoforge.forge.FORGE_BUS import thedarkcolour.kotlinforforge.neoforge.forge.MOD_BUS 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 79cd72860..2ff672d0a 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 @@ -35,7 +35,6 @@ import net.minecraft.item.ItemStack import net.minecraft.util.Hand import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions import net.neoforged.neoforge.common.extensions.IItemExtension -import opekope2.avm_staff.api.item.IDisablesShield import opekope2.avm_staff.api.item.StaffItem import opekope2.avm_staff.api.item.renderer.StaffRenderer import opekope2.avm_staff.util.handlerOfItemOrFallback @@ -57,7 +56,7 @@ class NeoForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IItemExt entity: LivingEntity, attacker: LivingEntity ): Boolean { - return stack.itemInStaff.handlerOfItemOrFallback is IDisablesShield || + return stack.itemInStaff.handlerOfItemOrFallback.disablesShield() || super.canDisableShield(stack, shield, entity, attacker) } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/IDisablesShield.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/IDisablesShield.kt deleted file mode 100644 index a1901f326..000000000 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/IDisablesShield.kt +++ /dev/null @@ -1,24 +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.item - -/** - * A [StaffItemHandler] implementing this interface disables the attacked entity's shield. - */ -interface IDisablesShield diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt similarity index 96% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt index afc3d0bb6..e1037fc13 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItemHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt @@ -16,7 +16,7 @@ * along with this mod. If not, see . */ -package opekope2.avm_staff.api.item +package opekope2.avm_staff.api.staff import com.google.common.collect.ImmutableMultimap import com.google.common.collect.Multimap @@ -45,10 +45,8 @@ import opekope2.avm_staff.util.attackSpeed /** * Provides functionality for a staff, when an item is inserted into it. - * - * @see IDisablesShield */ -abstract class StaffItemHandler { +abstract class StaffHandler { /** * The number of ticks the staff can be used for using the current item. */ @@ -293,6 +291,13 @@ abstract class StaffItemHandler { return EventResult.pass() } + /** + * Returns if attacking with the staff should disable the target's shield. + */ + open fun disablesShield(): Boolean { + return false + } + /** * Called on the client side by Fabric API, when the NBT of the held item gets updated. * @@ -341,9 +346,9 @@ abstract class StaffItemHandler { else ImmutableMultimap.of() } - object EmptyStaffHandler : StaffItemHandler() + object EmptyStaffHandler : StaffHandler() - object FallbackStaffHandler : StaffItemHandler() + object FallbackStaffHandler : StaffHandler() companion object { private val ATTRIBUTE_MODIFIERS = ImmutableMultimap.of( @@ -353,10 +358,10 @@ abstract class StaffItemHandler { attackSpeed(2.0) ) - private val staffItemsHandlers = mutableMapOf() + private val staffItemsHandlers = mutableMapOf() /** - * Registers a [StaffItemHandler] for the given [item ID][staffItem]. Call this from your common mod initializer. + * Registers a [StaffHandler] for the given [item ID][staffItem]. Call this from your common mod initializer. * * @param staffItem The item ID to register a handler for. This is the item, which can be * inserted into the staff @@ -365,7 +370,7 @@ abstract class StaffItemHandler { * @return `true`, if the registration was successful, `false`, if the item was already registered */ @JvmStatic - fun register(staffItem: Identifier, handler: StaffItemHandler): Boolean { + fun register(staffItem: Identifier, handler: StaffHandler): Boolean { if (staffItem in staffItemsHandlers) return false staffItemsHandlers[staffItem] = handler @@ -387,6 +392,6 @@ abstract class StaffItemHandler { * @param staffItem The item ID, which can be inserted into the staff */ @JvmStatic - operator fun get(staffItem: Identifier): StaffItemHandler? = staffItemsHandlers[staffItem] + operator fun get(staffItem: Identifier): StaffHandler? = staffItemsHandlers[staffItem] } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/AnvilHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/AnvilHandler.kt similarity index 94% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/AnvilHandler.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/AnvilHandler.kt index 8ac22c883..d8f54b9a7 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/AnvilHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/AnvilHandler.kt @@ -16,7 +16,7 @@ * along with this mod. If not, see . */ -package opekope2.avm_staff.internal.staff_item_handler +package opekope2.avm_staff.internal.staff_handler import com.google.common.collect.ImmutableMultimap import com.google.common.collect.Multimap @@ -32,14 +32,13 @@ import net.minecraft.item.ItemStack import net.minecraft.util.Hand import net.minecraft.world.World import net.minecraft.world.WorldEvents -import opekope2.avm_staff.api.item.IDisablesShield -import opekope2.avm_staff.api.item.StaffItemHandler +import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.equipTime import opekope2.avm_staff.util.itemInStaff import java.util.* -class AnvilHandler(private val damagedStackFactory: () -> ItemStack?) : StaffItemHandler(), IDisablesShield { +class AnvilHandler(private val damagedStackFactory: () -> ItemStack?) : StaffHandler() { override fun attackEntity( staffStack: ItemStack, world: World, @@ -66,6 +65,8 @@ class AnvilHandler(private val damagedStackFactory: () -> ItemStack?) : StaffIte return EventResult.pass() } + override fun disablesShield() = true + override fun getAttributeModifiers( staffStack: ItemStack, slot: EquipmentSlot diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BellBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/BellBlockHandler.kt similarity index 96% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BellBlockHandler.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/BellBlockHandler.kt index 1f22049a3..6183d2e33 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BellBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/BellBlockHandler.kt @@ -16,7 +16,7 @@ * along with this mod. If not, see . */ -package opekope2.avm_staff.internal.staff_item_handler +package opekope2.avm_staff.internal.staff_handler import com.google.common.collect.ImmutableMultimap import com.google.common.collect.Multimap @@ -41,13 +41,13 @@ 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.StaffItemHandler import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer +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 -class BellBlockHandler : StaffItemHandler() { +class BellBlockHandler : StaffHandler() { override fun use( staffStack: ItemStack, world: World, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BoneBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/BoneBlockHandler.kt similarity index 93% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BoneBlockHandler.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/BoneBlockHandler.kt index d0f8a6ea9..1be959e2d 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BoneBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/BoneBlockHandler.kt @@ -16,7 +16,7 @@ * along with this mod. If not, see . */ -package opekope2.avm_staff.internal.staff_item_handler +package opekope2.avm_staff.internal.staff_handler import net.minecraft.entity.LivingEntity import net.minecraft.item.BoneMealItem @@ -28,9 +28,9 @@ import net.minecraft.util.math.Direction import net.minecraft.world.World import net.minecraft.world.WorldEvents import net.minecraft.world.event.GameEvent -import opekope2.avm_staff.api.item.StaffItemHandler +import opekope2.avm_staff.api.staff.StaffHandler -class BoneBlockHandler : StaffItemHandler() { +class BoneBlockHandler : StaffHandler() { override fun useOnBlock( staffStack: ItemStack, world: World, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/CampfireHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/CampfireHandler.kt similarity index 98% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/CampfireHandler.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/CampfireHandler.kt index 9fce78fe9..eaba88e13 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/CampfireHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/CampfireHandler.kt @@ -16,7 +16,7 @@ * along with this mod. If not, see . */ -package opekope2.avm_staff.internal.staff_item_handler +package opekope2.avm_staff.internal.staff_handler import dev.architectury.event.events.common.TickEvent import dev.architectury.registry.registries.RegistrySupplier @@ -44,13 +44,13 @@ 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.item.StaffItemHandler +import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.* class CampfireHandler( private val particleEffectSupplier: RegistrySupplier, private val properties: Properties -) : StaffItemHandler() { +) : StaffHandler() { override val maxUseTime: Int get() = 72000 diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/FurnaceHandler.kt similarity index 98% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/FurnaceHandler.kt index 8fbe41b93..983872fc4 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/FurnaceHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/FurnaceHandler.kt @@ -16,7 +16,7 @@ * along with this mod. If not, see . */ -package opekope2.avm_staff.internal.staff_item_handler +package opekope2.avm_staff.internal.staff_handler import com.google.common.collect.ImmutableMultimap import com.google.common.collect.Multimap @@ -49,16 +49,16 @@ import net.minecraft.util.Hand import net.minecraft.util.TypedActionResult import net.minecraft.util.math.Box import net.minecraft.world.World -import opekope2.avm_staff.api.item.StaffItemHandler import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer +import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.* import kotlin.jvm.optionals.getOrNull class FurnaceHandler( private val recipeType: RecipeType, private val smeltSound: SoundEvent -) : StaffItemHandler() { +) : StaffHandler() { override val maxUseTime = 72000 override fun use( diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/LightningRodHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/LightningRodHandler.kt similarity index 95% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/LightningRodHandler.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/LightningRodHandler.kt index 590cf0b51..f34faf6ec 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/LightningRodHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/LightningRodHandler.kt @@ -16,7 +16,7 @@ * along with this mod. If not, see . */ -package opekope2.avm_staff.internal.staff_item_handler +package opekope2.avm_staff.internal.staff_handler import net.fabricmc.api.EnvType import net.fabricmc.api.Environment @@ -33,13 +33,13 @@ 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.item.StaffItemHandler import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer +import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.isItemCoolingDown import opekope2.avm_staff.util.push -class LightningRodHandler : StaffItemHandler() { +class LightningRodHandler : StaffHandler() { override fun useOnBlock( staffStack: ItemStack, world: World, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/MagmaBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/MagmaBlockHandler.kt similarity index 95% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/MagmaBlockHandler.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/MagmaBlockHandler.kt index 4cda3155a..dee30abcd 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/MagmaBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/MagmaBlockHandler.kt @@ -16,7 +16,7 @@ * along with this mod. If not, see . */ -package opekope2.avm_staff.internal.staff_item_handler +package opekope2.avm_staff.internal.staff_handler import com.google.common.collect.ImmutableMultimap import com.google.common.collect.Multimap @@ -34,10 +34,10 @@ 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.item.StaffItemHandler +import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.* -class MagmaBlockHandler : StaffItemHandler() { +class MagmaBlockHandler : StaffHandler() { override val maxUseTime = 72000 override fun use( diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/SnowBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/SnowBlockHandler.kt similarity index 94% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/SnowBlockHandler.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/SnowBlockHandler.kt index 4cf6ed547..1e14f439a 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/SnowBlockHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/SnowBlockHandler.kt @@ -16,7 +16,7 @@ * along with this mod. If not, see . */ -package opekope2.avm_staff.internal.staff_item_handler +package opekope2.avm_staff.internal.staff_handler import net.minecraft.entity.LivingEntity import net.minecraft.entity.player.PlayerEntity @@ -26,10 +26,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.StaffItemHandler +import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.* -class SnowBlockHandler : StaffItemHandler() { +class SnowBlockHandler : StaffHandler() { override val maxUseTime = 72000 override fun use( diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/TntHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/TntHandler.kt similarity index 93% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/TntHandler.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/TntHandler.kt index e448ab4d0..54e330bfa 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/TntHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/TntHandler.kt @@ -16,7 +16,7 @@ * along with this mod. If not, see . */ -package opekope2.avm_staff.internal.staff_item_handler +package opekope2.avm_staff.internal.staff_handler import net.minecraft.entity.LivingEntity import net.minecraft.entity.TntEntity @@ -28,10 +28,10 @@ import net.minecraft.util.ActionResult import net.minecraft.util.Hand import net.minecraft.world.World import net.minecraft.world.event.GameEvent -import opekope2.avm_staff.api.item.StaffItemHandler +import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.* -class TntHandler : StaffItemHandler() { +class TntHandler : StaffHandler() { override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand) { shootTnt(world, attacker) (attacker as? PlayerEntity)?.resetLastAttackedTicks() diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/VanillaStaffHandlers.kt similarity index 95% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/VanillaStaffHandlers.kt index 2e938f506..b819827d0 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/VanillaStaffItemHandlers.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/VanillaStaffHandlers.kt @@ -16,7 +16,7 @@ * along with this mod. If not, see . */ -package opekope2.avm_staff.internal.staff_item_handler +package opekope2.avm_staff.internal.staff_handler import net.fabricmc.api.EnvType import net.fabricmc.api.Environment @@ -28,16 +28,16 @@ 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.StaffItemHandler import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer import opekope2.avm_staff.api.soulFlamethrowerParticleType +import opekope2.avm_staff.api.staff.StaffHandler -private fun Item.registerHandler(handler: StaffItemHandler) { - StaffItemHandler.register(Registries.ITEM.getId(this), handler) +private fun Item.registerHandler(handler: StaffHandler) { + StaffHandler.register(Registries.ITEM.getId(this), handler) } -fun registerVanillaStaffItemHandlers() { +fun registerVanillaStaffHandlers() { Items.ANVIL.registerHandler(AnvilHandler(Items.CHIPPED_ANVIL::getDefaultStack)) Items.CHIPPED_ANVIL.registerHandler(AnvilHandler(Items.DAMAGED_ANVIL::getDefaultStack)) Items.DAMAGED_ANVIL.registerHandler(AnvilHandler { null }) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/WitherSkeletonSkullHandler.kt similarity index 97% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/WitherSkeletonSkullHandler.kt index 52f49e3ef..9f6866543 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WitherSkeletonSkullHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/WitherSkeletonSkullHandler.kt @@ -16,7 +16,7 @@ * along with this mod. If not, see . */ -package opekope2.avm_staff.internal.staff_item_handler +package opekope2.avm_staff.internal.staff_handler import dev.architectury.event.EventResult import net.fabricmc.api.EnvType @@ -40,11 +40,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.StaffItemHandler import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer +import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.* -class WitherSkeletonSkullHandler : StaffItemHandler() { +class WitherSkeletonSkullHandler : StaffHandler() { override val maxUseTime = 20 override fun use( diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WoolHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/WoolHandler.kt similarity index 95% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WoolHandler.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/WoolHandler.kt index 9b8f889ce..359d93d44 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/WoolHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_handler/WoolHandler.kt @@ -16,7 +16,7 @@ * along with this mod. If not, see . */ -package opekope2.avm_staff.internal.staff_item_handler +package opekope2.avm_staff.internal.staff_handler import com.google.common.collect.ImmutableMultimap import com.google.common.collect.Multimap @@ -40,12 +40,12 @@ 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.item.StaffItemHandler +import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.mixin.IMinecraftClientMixin import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.attackSpeed -class WoolHandler(woolBlock: Block, carpetBlock: Block) : StaffItemHandler() { +class WoolHandler(woolBlock: Block, carpetBlock: Block) : StaffHandler() { private val woolState = woolBlock.defaultState private val carpetState = carpetBlock.defaultState 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 85f39fc44..c7f8a0793 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt @@ -27,7 +27,7 @@ import net.minecraft.registry.Registries import net.minecraft.util.hit.HitResult import net.minecraft.util.math.Vec3d import net.minecraft.world.RaycastContext -import opekope2.avm_staff.api.item.StaffItemHandler +import opekope2.avm_staff.api.staff.StaffHandler /** * NBT key @@ -68,17 +68,17 @@ val ItemStack.hasHandlerOfItem: Boolean @JvmName("hasHandlerOfStaff") get() { val itemId = Registries.ITEM.getId(item) - return itemId in StaffItemHandler + return itemId in StaffHandler } /** * Returns the handler of the given item stack, if available. * This item stack is not the staff item stack, but the one can be inserted into the staff. */ -val ItemStack.handlerOfItem: StaffItemHandler? +val ItemStack.handlerOfItem: StaffHandler? get() { val itemId = Registries.ITEM.getId(item) - return StaffItemHandler[itemId] + return StaffHandler[itemId] } /** @@ -86,9 +86,9 @@ val ItemStack.handlerOfItem: StaffItemHandler? * item stack is `null`. * This item stack is not the staff item stack, but the one can be inserted into the staff. */ -val ItemStack?.handlerOfItemOrFallback: StaffItemHandler - get() = if (this == null) StaffItemHandler.EmptyStaffHandler - else handlerOfItem ?: StaffItemHandler.FallbackStaffHandler +val ItemStack?.handlerOfItemOrFallback: StaffHandler + get() = if (this == null) StaffHandler.EmptyStaffHandler + else handlerOfItem ?: StaffHandler.FallbackStaffHandler private const val STAFF_MODEL_LENGTH = 40.0 / 16.0 private const val STAFF_MODEL_ITEM_POSITION_CENTER = 33.5 / 16.0 From 534d81ea12f8ac8c90f65c52ab21a3e4852bf1b4 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 20 May 2024 21:44:04 +0200 Subject: [PATCH 051/128] Mention NeoForge where forgotten --- StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt | 4 ++-- .../main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt | 2 +- 2 files changed, 3 insertions(+), 3 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 cc8bec2fc..690a26c7f 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -123,7 +123,7 @@ val staffModItemGroup: RegistrySupplier = ITEM_GROUPS.register("avm_s /** * Gets the flamethrower's flame particle type. * - * Due to how Forge registries work, *always* use this getter instead of storing the result. + * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. * * @see ParticleManager.addParticle */ @@ -133,7 +133,7 @@ val flamethrowerParticleType: RegistrySupplier = /** * Gets the soul fire flamethrower's flame particle type. * - * Due to how Forge registries work, *always* use this getter instead of storing the result. + * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. * * @see ParticleManager.addParticle */ 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 e1037fc13..793792556 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 @@ -317,7 +317,7 @@ abstract class StaffHandler { } /** - * Called on the client side by Forge, when the NBT of the held item gets updated. + * Called on the client side by Neo/Forge, when the NBT of the held item gets updated. * * @param oldStaffStack The previous item stack * @param newStaffStack The updated item stack From eade1dddaacc873b68e082ec5e0e23523624238b Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 00:07:28 +0200 Subject: [PATCH 052/128] Use MOD_ID instead of hard-coding --- StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt | 4 ++-- .../avm_staff/internal/event_handler/ClientHandler.kt | 5 +++-- 2 files changed, 5 insertions(+), 4 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 690a26c7f..8f8ff3f66 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -112,8 +112,8 @@ val staffsTag: TagKey = TagKey.of(RegistryKeys.ITEM, Identifier(MOD_ID, "s /** * Gets Staff Mod's item group. */ -val staffModItemGroup: RegistrySupplier = ITEM_GROUPS.register("avm_staff_items") { - CreativeTabRegistry.create(Text.translatable("itemGroup.avm_staff_items")) { +val staffModItemGroup: RegistrySupplier = ITEM_GROUPS.register("${MOD_ID}_items") { + CreativeTabRegistry.create(Text.translatable("itemGroup.${MOD_ID}_items")) { royalStaffItem.get().defaultStack.apply { itemInStaff = Items.COMMAND_BLOCK.defaultStack } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/ClientHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/ClientHandler.kt index c4942107a..9ad305f73 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/ClientHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/ClientHandler.kt @@ -23,15 +23,16 @@ import net.minecraft.client.option.KeyBinding import net.minecraft.client.util.InputUtil import opekope2.avm_staff.internal.networking.c2s.play.AddItemToStaffC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.RemoveItemFromStaffC2SPacket +import opekope2.avm_staff.util.MOD_ID import opekope2.avm_staff.util.isItemInStaff import org.lwjgl.glfw.GLFW @JvmField val ADD_REMOVE_KEYBINDING = KeyBinding( - "key.avm_staff.add_remove_staff_block", + "key.$MOD_ID.add_remove_staff_block", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_R, - "key.categories.avm_staff" + "key.categories.$MOD_ID" ) fun handleKeyBindings(client: MinecraftClient) { From c2d96ed7628292fa1426f5722c01cc3bb336631d Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 01:52:03 +0200 Subject: [PATCH 053/128] Add staff infusion smithing template --- FabricMod/src/main/resources/fabric.mod.json | 4 ++ .../internal/forge/StaffModClient.kt | 2 + .../internal/neoforge/StaffModClient.kt | 2 + .../kotlin/opekope2/avm_staff/api/StaffMod.kt | 22 ++++++++ .../StaffInfusionSmithingRecipeTextures.kt | 53 ++++++++++++++++++ .../avm_staff/internal/Initializer.kt | 12 ++++ .../assets/avm_staff/lang/en_us.json | 4 ++ .../staff_infusion_smithing_template.json | 6 ++ .../textures/item/empty_slot_royal_staff.png | Bin 0 -> 115 bytes .../item/staff_infusion_smithing_template.png | Bin 0 -> 352 bytes .../main/resources/avm_staff.accesswidener | 15 +++-- 11 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffInfusionSmithingRecipeTextures.kt create mode 100644 StaffMod/src/main/resources/assets/avm_staff/models/item/staff_infusion_smithing_template.json create mode 100644 StaffMod/src/main/resources/assets/avm_staff/textures/item/empty_slot_royal_staff.png create mode 100644 StaffMod/src/main/resources/assets/avm_staff/textures/item/staff_infusion_smithing_template.png diff --git a/FabricMod/src/main/resources/fabric.mod.json b/FabricMod/src/main/resources/fabric.mod.json index 2595593dc..9ddcbac57 100644 --- a/FabricMod/src/main/resources/fabric.mod.json +++ b/FabricMod/src/main/resources/fabric.mod.json @@ -43,6 +43,10 @@ "adapter": "kotlin", "value": "opekope2.avm_staff.internal.fabric.StaffModClient" }, + { + "adapter": "kotlin", + "value": "opekope2.avm_staff.internal.InitializerKt::registerSmithingTableTextures" + }, { "adapter": "kotlin", "value": "opekope2.avm_staff.internal.staff_handler.VanillaStaffHandlersKt::registerVanillaStaffItemRenderers" diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt index cf030cf52..0c5978797 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt @@ -33,6 +33,7 @@ import opekope2.avm_staff.api.soulFlamethrowerParticleType import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING import opekope2.avm_staff.internal.event_handler.handleKeyBindings import opekope2.avm_staff.internal.model.registerModelPredicateProviders +import opekope2.avm_staff.internal.registerSmithingTableTextures import opekope2.avm_staff.internal.staff_handler.registerVanillaStaffItemRenderers import thedarkcolour.kotlinforforge.forge.FORGE_BUS import thedarkcolour.kotlinforforge.forge.MOD_BUS @@ -40,6 +41,7 @@ import thedarkcolour.kotlinforforge.forge.MOD_BUS @OnlyIn(Dist.CLIENT) object StaffModClient { fun initializeClient() { + registerSmithingTableTextures() registerVanillaStaffItemRenderers() MOD_BUS.register(this) FORGE_BUS.register(javaClass) 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 182e4cd33..1d52cd381 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 @@ -33,6 +33,7 @@ import opekope2.avm_staff.api.soulFlamethrowerParticleType import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING import opekope2.avm_staff.internal.event_handler.handleKeyBindings import opekope2.avm_staff.internal.model.registerModelPredicateProviders +import opekope2.avm_staff.internal.registerSmithingTableTextures import opekope2.avm_staff.internal.staff_handler.registerVanillaStaffItemRenderers import thedarkcolour.kotlinforforge.neoforge.forge.FORGE_BUS import thedarkcolour.kotlinforforge.neoforge.forge.MOD_BUS @@ -40,6 +41,7 @@ import thedarkcolour.kotlinforforge.neoforge.forge.MOD_BUS @OnlyIn(Dist.CLIENT) object StaffModClient { fun initializeClient() { + registerSmithingTableTextures() registerVanillaStaffItemRenderers() MOD_BUS.register(this) FORGE_BUS.addListener(::handleStaffKeybinding) 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 8f8ff3f66..278b25c5d 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -28,6 +28,7 @@ import net.minecraft.client.particle.ParticleManager import net.minecraft.item.Item import net.minecraft.item.ItemGroup import net.minecraft.item.Items +import net.minecraft.item.SmithingTemplateItem import net.minecraft.particle.DefaultParticleType import net.minecraft.registry.RegistryKeys import net.minecraft.registry.tag.TagKey @@ -37,6 +38,7 @@ import net.minecraft.util.Identifier import net.minecraft.util.Rarity import opekope2.avm_staff.api.item.CrownItem import opekope2.avm_staff.api.item.StaffItem +import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures import opekope2.avm_staff.internal.createCrownItem import opekope2.avm_staff.internal.createStaffItem import opekope2.avm_staff.internal.createStaffRendererItem @@ -104,6 +106,23 @@ val crownOfKingOrangeItem: RegistrySupplier = ITEMS.register("crown_o ) } +/** + * 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(SmithingTemplateItem.DESCRIPTION_FORMATTING), + SmithingTemplateItem.ARMOR_TRIM_INGREDIENTS_TEXT, + Text.translatable("item.$MOD_ID.staff_infusion_smithing_template.title") + .formatted(SmithingTemplateItem.TITLE_FORMATTING), + Text.translatable("item.$MOD_ID.staff_infusion_smithing_template.base_slot_description"), + SmithingTemplateItem.ARMOR_TRIM_ADDITIONS_SLOT_DESCRIPTION_TEXT, + StaffInfusionSmithingRecipeTextures.baseSlotTextures, + StaffInfusionSmithingRecipeTextures.additionsSlotTextures + ) +} + /** * Gets the [TagKey] containing all the staffs. */ @@ -148,4 +167,7 @@ internal fun registerContent() { ITEMS.register() ITEM_GROUPS.register() PARTICLE_TYPES.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/staff/StaffInfusionSmithingRecipeTextures.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffInfusionSmithingRecipeTextures.kt new file mode 100644 index 000000000..e0233501e --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffInfusionSmithingRecipeTextures.kt @@ -0,0 +1,53 @@ +/* + * 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.staff + +import net.minecraft.util.Identifier +import opekope2.avm_staff.api.staffInfusionSmithingTemplateItem + +/** + * Object holding textures to be displayed in a smithing table, when using a + * [staff infusion smithing template][staffInfusionSmithingTemplateItem]. + */ +object StaffInfusionSmithingRecipeTextures { + /** + * @suppress + */ + @JvmSynthetic + internal val baseSlotTextures = mutableListOf() + + /** + * @suppress + */ + @JvmSynthetic + internal val additionsSlotTextures = mutableListOf() + + /** + * 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. + */ + fun register(baseSlotTexture: Identifier, additionsSlotTexture: Identifier) { + baseSlotTextures += baseSlotTexture + additionsSlotTextures += additionsSlotTexture + } +} 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 e0563b390..de0a83d4b 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -21,8 +21,11 @@ package opekope2.avm_staff.internal import dev.architectury.event.EventResult import dev.architectury.event.events.common.InteractionEvent import dev.architectury.event.events.common.LootEvent +import net.fabricmc.api.EnvType +import net.fabricmc.api.Environment import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack +import net.minecraft.item.SmithingTemplateItem import net.minecraft.loot.LootManager import net.minecraft.loot.LootPool import net.minecraft.loot.entry.ItemEntry @@ -31,6 +34,7 @@ import net.minecraft.util.Identifier import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction import opekope2.avm_staff.api.crownOfKingOrangeItem +import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures import opekope2.avm_staff.api.staffsTag import opekope2.avm_staff.internal.event_handler.addBlockToStaff import opekope2.avm_staff.internal.event_handler.attack @@ -38,6 +42,7 @@ import opekope2.avm_staff.internal.event_handler.removeBlockFromStaff import opekope2.avm_staff.internal.networking.c2s.play.AddItemToStaffC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.AttackC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.RemoveItemFromStaffC2SPacket +import opekope2.avm_staff.util.MOD_ID import opekope2.avm_staff.util.handlerOfItem import opekope2.avm_staff.util.itemInStaff @@ -93,3 +98,10 @@ fun subscribeToEvents() { InteractionEvent.CLIENT_LEFT_CLICK_AIR.register(::clientAttack) LootEvent.MODIFY_LOOT_TABLE.register(::modifyLootTables) } + +@Environment(EnvType.CLIENT) +fun registerSmithingTableTextures() { + StaffInfusionSmithingRecipeTextures.register( + Identifier(MOD_ID, "item/empty_slot_royal_staff"), SmithingTemplateItem.EMPTY_SLOT_REDSTONE_DUST_TEXTURE + ) +} 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 17628aa1a..bd64e6cb9 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,10 @@ "item.avm_staff.faint_royal_staff": "Faint royal staff", "item.avm_staff.royal_staff": "Royal staff", "item.avm_staff.royal_staff.with_item": "Royal staff with %s", + "item.avm_staff.staff_infusion_smithing_template": "Smithing Template", + "item.avm_staff.staff_infusion_smithing_template.title": "Staff Infusion 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.crown_of_king_orange": "Crown of King Orange", "key.categories.avm_staff": "Staff Mod", "key.avm_staff.add_remove_staff_block": "Add/remove staff item", diff --git a/StaffMod/src/main/resources/assets/avm_staff/models/item/staff_infusion_smithing_template.json b/StaffMod/src/main/resources/assets/avm_staff/models/item/staff_infusion_smithing_template.json new file mode 100644 index 000000000..9847816b4 --- /dev/null +++ b/StaffMod/src/main/resources/assets/avm_staff/models/item/staff_infusion_smithing_template.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "avm_staff:item/staff_infusion_smithing_template" + } +} diff --git a/StaffMod/src/main/resources/assets/avm_staff/textures/item/empty_slot_royal_staff.png b/StaffMod/src/main/resources/assets/avm_staff/textures/item/empty_slot_royal_staff.png new file mode 100644 index 0000000000000000000000000000000000000000..479438eb4828186989da84338542149081ed256d GIT binary patch literal 115 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`R-P`7Ar`&K2@+QnOiaGiXJovn zugRLBv9)F51nv!;>*MxHt+(65wn*A*qqrNd1P|MW2a{E%^suutF#OTsm)FLTx7>SA8z@cf`-`2O~aIA#_vVZA`&bljt^3M^N15b+Lw*5Gv9gNS3f znj^hQu-+_CSB2sS4NS4bdb0o#M;xj#v%nGryNbYDV*j1*U*|!sQRX`lJ_}aZVF!un!Pf)*Ev<VXJ!N?Y#!l#N>3*zv3GXy_I{jJ)oEX0000 (Z)V -accessible method net/minecraft/block/entity/AbstractFurnaceBlockEntity dropExperience (Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/util/math/Vec3d;IF)V -accessible method net/minecraft/entity/Entity getRotationVector (FF)Lnet/minecraft/util/math/Vec3d; +accessible field net/minecraft/item/Item ATTACK_DAMAGE_MODIFIER_ID Ljava/util/UUID; +accessible field net/minecraft/item/Item ATTACK_SPEED_MODIFIER_ID Ljava/util/UUID; +accessible method net/minecraft/particle/DefaultParticleType (Z)V +accessible method net/minecraft/block/entity/AbstractFurnaceBlockEntity dropExperience (Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/util/math/Vec3d;IF)V +accessible method net/minecraft/entity/Entity getRotationVector (FF)Lnet/minecraft/util/math/Vec3d; +accessible field net/minecraft/item/SmithingTemplateItem TITLE_FORMATTING Lnet/minecraft/util/Formatting; +accessible field net/minecraft/item/SmithingTemplateItem DESCRIPTION_FORMATTING Lnet/minecraft/util/Formatting; +accessible field net/minecraft/item/SmithingTemplateItem ARMOR_TRIM_INGREDIENTS_TEXT Lnet/minecraft/text/Text; +accessible field net/minecraft/item/SmithingTemplateItem ARMOR_TRIM_ADDITIONS_SLOT_DESCRIPTION_TEXT Lnet/minecraft/text/Text; +accessible field net/minecraft/item/SmithingTemplateItem EMPTY_SLOT_REDSTONE_DUST_TEXTURE Lnet/minecraft/util/Identifier; From 5744c84adfdbd4deee3bf93ee3360230287cd732 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 01:56:34 +0200 Subject: [PATCH 054/128] Update StaffMod docs --- .../kotlin/opekope2/avm_staff/api/StaffMod.kt | 32 ++++++------------- 1 file changed, 9 insertions(+), 23 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 278b25c5d..969a4f210 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -50,18 +50,14 @@ private val ITEM_GROUPS = DeferredRegister.create(MOD_ID, RegistryKeys.ITEM_GROU private val PARTICLE_TYPES = DeferredRegister.create(MOD_ID, RegistryKeys.PARTICLE_TYPE) /** - * Gets `avm_staff:faint_staff_rod` item registered in Minecraft. - * - * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. + * Item registered as `avm_staff:faint_staff_rod`. */ val faintStaffRodItem: RegistrySupplier = ITEMS.register("faint_staff_rod") { Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21).`arch$tab`(staffModItemGroup)) } /** - * Gets `avm_staff:faint_royal_staff_head` item registered in Minecraft. - * - * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. + * Item registered as `avm_staff:faint_royal_staff_head`. */ val faintRoyalStaffHeadItem: RegistrySupplier = ITEMS.register("faint_royal_staff_head") { Item( @@ -71,9 +67,7 @@ val faintRoyalStaffHeadItem: RegistrySupplier = ITEMS.register("faint_roya } /** - * Gets `avm_staff:faint_royal_staff` item registered in Minecraft. - * - * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. + * Item registered as `avm_staff:faint_royal_staff`. */ val faintRoyalStaffItem: RegistrySupplier = ITEMS.register("faint_royal_staff") { createStaffRendererItem( @@ -83,9 +77,7 @@ val faintRoyalStaffItem: RegistrySupplier = ITEMS.register("faint_royal_st } /** - * Gets `avm_staff:royal_staff` item registered in Minecraft. - * - * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. + * Item registered as `avm_staff:royal_staff`. */ val royalStaffItem: RegistrySupplier = ITEMS.register("royal_staff") { createStaffItem( @@ -95,9 +87,7 @@ val royalStaffItem: RegistrySupplier = ITEMS.register("royal_staff") } /** - * Gets `avm_staff:crown_of_king_orange` item registered in Minecraft. - * - * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. + * Item registered as `avm_staff:crown_of_king_orange`. */ val crownOfKingOrangeItem: RegistrySupplier = ITEMS.register("crown_of_king_orange") { createCrownItem( @@ -124,12 +114,12 @@ val staffInfusionSmithingTemplateItem: RegistrySupplier = ITEMS.register(" } /** - * Gets the [TagKey] containing all the staffs. + * Tag registered as `avm_staff:staffs`. */ val staffsTag: TagKey = TagKey.of(RegistryKeys.ITEM, Identifier(MOD_ID, "staffs")) /** - * Gets Staff Mod's item group. + * 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")) { @@ -140,9 +130,7 @@ val staffModItemGroup: RegistrySupplier = ITEM_GROUPS.register("${MOD } /** - * Gets the flamethrower's flame particle type. - * - * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. + * Particle registered as `avm_staff:flame`. * * @see ParticleManager.addParticle */ @@ -150,9 +138,7 @@ val flamethrowerParticleType: RegistrySupplier = PARTICLE_TYPES.register("flame") { DefaultParticleType(false) } /** - * Gets the soul fire flamethrower's flame particle type. - * - * Due to how Neo/Forge registries work, *always* use this getter instead of storing the result. + * Particle registered as `avm_staff:soul_fire_flame`. * * @see ParticleManager.addParticle */ From 362cc69ab3aa21cf8ef259f5e62b924a770ca454 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 02:03:19 +0200 Subject: [PATCH 055/128] Use kotlin syntax instead of java functional interface in PacketRegistrar --- .../opekope2/avm_staff/internal/networking/PacketRegistrar.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/PacketRegistrar.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/PacketRegistrar.kt index 91dfb453b..797304214 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/PacketRegistrar.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/PacketRegistrar.kt @@ -21,12 +21,11 @@ package opekope2.avm_staff.internal.networking import dev.architectury.networking.NetworkChannel import dev.architectury.networking.NetworkManager import net.minecraft.network.PacketByteBuf -import java.util.function.Function abstract class PacketRegistrar( val channel: NetworkChannel, private val packetClass: Class, - private val packetConstructor: Function + private val packetConstructor: (PacketByteBuf) -> TPacket ) { fun registerHandler(handler: (TPacket, NetworkManager.PacketContext) -> Unit) { channel.register(packetClass, IPacket::write, packetConstructor) { packet, contextSupplier -> From ff588b51ac76f309ac6cbed3b2ce1a816ac3d3ca Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 03:04:29 +0200 Subject: [PATCH 056/128] Migrate key binding handling to Architectury API --- .../internal/fabric/StaffModClient.kt | 8 ------- FabricMod/src/main/resources/fabric.mod.json | 8 +++++++ .../internal/forge/StaffModClient.kt | 24 ++++--------------- .../internal/neoforge/StaffModClient.kt | 23 ++++-------------- .../avm_staff/internal/Initializer.kt | 16 ++++++++++--- ...{ClientHandler.kt => KeyBindingHandler.kt} | 13 ++++++---- .../assets/avm_staff/lang/en_us.json | 2 +- 7 files changed, 38 insertions(+), 56 deletions(-) rename StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/{ClientHandler.kt => KeyBindingHandler.kt} (83%) 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 3fd85ec9e..d03efd9de 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 @@ -21,25 +21,17 @@ package opekope2.avm_staff.internal.fabric import net.fabricmc.api.ClientModInitializer import net.fabricmc.api.EnvType import net.fabricmc.api.Environment -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents -import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry import net.minecraft.client.item.ModelPredicateProviderRegistry import opekope2.avm_staff.api.flamethrowerParticleType import opekope2.avm_staff.api.particle.FlamethrowerParticle import opekope2.avm_staff.api.soulFlamethrowerParticleType -import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING -import opekope2.avm_staff.internal.event_handler.handleKeyBindings import opekope2.avm_staff.internal.model.registerModelPredicateProviders @Suppress("unused") @Environment(EnvType.CLIENT) object StaffModClient : ClientModInitializer { override fun onInitializeClient() { - KeyBindingHelper.registerKeyBinding(ADD_REMOVE_KEYBINDING) - - ClientTickEvents.END_CLIENT_TICK.register(::handleKeyBindings) - ParticleFactoryRegistry.getInstance().register( flamethrowerParticleType.get(), FlamethrowerParticle::Factory diff --git a/FabricMod/src/main/resources/fabric.mod.json b/FabricMod/src/main/resources/fabric.mod.json index 9ddcbac57..3d6a8a2a4 100644 --- a/FabricMod/src/main/resources/fabric.mod.json +++ b/FabricMod/src/main/resources/fabric.mod.json @@ -43,10 +43,18 @@ "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.InitializerKt::subscribeToClientEvents" + }, { "adapter": "kotlin", "value": "opekope2.avm_staff.internal.staff_handler.VanillaStaffHandlersKt::registerVanillaStaffItemRenderers" diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt index 0c5978797..003305bc4 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt @@ -18,33 +18,30 @@ package opekope2.avm_staff.internal.forge -import net.minecraft.client.MinecraftClient import net.minecraft.client.item.ModelPredicateProviderRegistry import net.minecraftforge.api.distmarker.Dist import net.minecraftforge.api.distmarker.OnlyIn -import net.minecraftforge.client.event.RegisterKeyMappingsEvent import net.minecraftforge.client.event.RegisterParticleProvidersEvent -import net.minecraftforge.event.TickEvent import net.minecraftforge.eventbus.api.SubscribeEvent import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent import opekope2.avm_staff.api.flamethrowerParticleType import opekope2.avm_staff.api.particle.FlamethrowerParticle import opekope2.avm_staff.api.soulFlamethrowerParticleType -import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING -import opekope2.avm_staff.internal.event_handler.handleKeyBindings import opekope2.avm_staff.internal.model.registerModelPredicateProviders +import opekope2.avm_staff.internal.registerClientContent import opekope2.avm_staff.internal.registerSmithingTableTextures import opekope2.avm_staff.internal.staff_handler.registerVanillaStaffItemRenderers -import thedarkcolour.kotlinforforge.forge.FORGE_BUS +import opekope2.avm_staff.internal.subscribeToClientEvents import thedarkcolour.kotlinforforge.forge.MOD_BUS @OnlyIn(Dist.CLIENT) object StaffModClient { fun initializeClient() { + registerClientContent() registerSmithingTableTextures() + subscribeToClientEvents() registerVanillaStaffItemRenderers() MOD_BUS.register(this) - FORGE_BUS.register(javaClass) } @SubscribeEvent @@ -59,17 +56,4 @@ object StaffModClient { event.registerSpriteSet(flamethrowerParticleType.get(), FlamethrowerParticle::Factory) event.registerSpriteSet(soulFlamethrowerParticleType.get(), FlamethrowerParticle::Factory) } - - @SubscribeEvent - fun registerKeyBindings(event: RegisterKeyMappingsEvent) { - event.register(ADD_REMOVE_KEYBINDING) - } - - @JvmStatic - @SubscribeEvent - fun handleStaffKeybinding(event: TickEvent.ClientTickEvent) { - if (event.phase != TickEvent.Phase.END) return - - handleKeyBindings(MinecraftClient.getInstance()) - } } 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 1d52cd381..dca76b42b 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 @@ -18,33 +18,30 @@ package opekope2.avm_staff.internal.neoforge -import net.minecraft.client.MinecraftClient import net.minecraft.client.item.ModelPredicateProviderRegistry import net.neoforged.api.distmarker.Dist 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.RegisterKeyMappingsEvent import net.neoforged.neoforge.client.event.RegisterParticleProvidersEvent -import net.neoforged.neoforge.event.TickEvent import opekope2.avm_staff.api.flamethrowerParticleType import opekope2.avm_staff.api.particle.FlamethrowerParticle import opekope2.avm_staff.api.soulFlamethrowerParticleType -import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING -import opekope2.avm_staff.internal.event_handler.handleKeyBindings import opekope2.avm_staff.internal.model.registerModelPredicateProviders +import opekope2.avm_staff.internal.registerClientContent import opekope2.avm_staff.internal.registerSmithingTableTextures import opekope2.avm_staff.internal.staff_handler.registerVanillaStaffItemRenderers -import thedarkcolour.kotlinforforge.neoforge.forge.FORGE_BUS +import opekope2.avm_staff.internal.subscribeToClientEvents import thedarkcolour.kotlinforforge.neoforge.forge.MOD_BUS @OnlyIn(Dist.CLIENT) object StaffModClient { fun initializeClient() { + registerClientContent() registerSmithingTableTextures() + subscribeToClientEvents() registerVanillaStaffItemRenderers() MOD_BUS.register(this) - FORGE_BUS.addListener(::handleStaffKeybinding) } @SubscribeEvent @@ -59,16 +56,4 @@ object StaffModClient { event.registerSpriteSet(flamethrowerParticleType.get(), FlamethrowerParticle::Factory) event.registerSpriteSet(soulFlamethrowerParticleType.get(), FlamethrowerParticle::Factory) } - - @SubscribeEvent - fun registerKeyBindings(event: RegisterKeyMappingsEvent) { - event.register(ADD_REMOVE_KEYBINDING) - } - - @JvmStatic - fun handleStaffKeybinding(event: TickEvent.ClientTickEvent) { - if (event.phase != TickEvent.Phase.END) return - - handleKeyBindings(MinecraftClient.getInstance()) - } } 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 de0a83d4b..13ff6d6c5 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -19,8 +19,10 @@ package opekope2.avm_staff.internal import dev.architectury.event.EventResult +import dev.architectury.event.events.client.ClientTickEvent import dev.architectury.event.events.common.InteractionEvent import dev.architectury.event.events.common.LootEvent +import dev.architectury.registry.client.keymappings.KeyMappingRegistry import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.minecraft.entity.player.PlayerEntity @@ -36,9 +38,7 @@ import net.minecraft.util.math.Direction import opekope2.avm_staff.api.crownOfKingOrangeItem import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures import opekope2.avm_staff.api.staffsTag -import opekope2.avm_staff.internal.event_handler.addBlockToStaff -import opekope2.avm_staff.internal.event_handler.attack -import opekope2.avm_staff.internal.event_handler.removeBlockFromStaff +import opekope2.avm_staff.internal.event_handler.* import opekope2.avm_staff.internal.networking.c2s.play.AddItemToStaffC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.AttackC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.RemoveItemFromStaffC2SPacket @@ -99,9 +99,19 @@ fun subscribeToEvents() { LootEvent.MODIFY_LOOT_TABLE.register(::modifyLootTables) } +@Environment(EnvType.CLIENT) +fun registerClientContent() { + KeyMappingRegistry.register(addRemoveStaffItemKeyBinding) +} + @Environment(EnvType.CLIENT) fun registerSmithingTableTextures() { StaffInfusionSmithingRecipeTextures.register( Identifier(MOD_ID, "item/empty_slot_royal_staff"), SmithingTemplateItem.EMPTY_SLOT_REDSTONE_DUST_TEXTURE ) } + +@Environment(EnvType.CLIENT) +fun subscribeToClientEvents() { + ClientTickEvent.CLIENT_POST.register(::handleKeyBindings) +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/ClientHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/KeyBindingHandler.kt similarity index 83% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/ClientHandler.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/KeyBindingHandler.kt index 9ad305f73..415a9cd2c 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/ClientHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/KeyBindingHandler.kt @@ -16,8 +16,12 @@ * along with this mod. If not, see . */ +@file: Environment(EnvType.CLIENT) + package opekope2.avm_staff.internal.event_handler +import net.fabricmc.api.EnvType +import net.fabricmc.api.Environment import net.minecraft.client.MinecraftClient import net.minecraft.client.option.KeyBinding import net.minecraft.client.util.InputUtil @@ -27,17 +31,16 @@ import opekope2.avm_staff.util.MOD_ID import opekope2.avm_staff.util.isItemInStaff import org.lwjgl.glfw.GLFW -@JvmField -val ADD_REMOVE_KEYBINDING = KeyBinding( - "key.$MOD_ID.add_remove_staff_block", +val addRemoveStaffItemKeyBinding = KeyBinding( + "key.$MOD_ID.add_remove_staff_item", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_R, "key.categories.$MOD_ID" ) fun handleKeyBindings(client: MinecraftClient) { - if (!ADD_REMOVE_KEYBINDING.isPressed) return - ADD_REMOVE_KEYBINDING.isPressed = false + if (!addRemoveStaffItemKeyBinding.isPressed) return + addRemoveStaffItemKeyBinding.isPressed = false val player = client.player ?: return 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 bd64e6cb9..7025bb910 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 @@ -10,6 +10,6 @@ "item.avm_staff.staff_infusion_smithing_template.base_slot_description": "Add faint staff", "item.avm_staff.crown_of_king_orange": "Crown of King Orange", "key.categories.avm_staff": "Staff Mod", - "key.avm_staff.add_remove_staff_block": "Add/remove staff item", + "key.avm_staff.add_remove_staff_item": "Add/remove staff item", "itemGroup.avm_staff_items": "Staff Mod" } From 2845950c598114ed855e35eb74cf85485dfd50ab Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 03:13:02 +0200 Subject: [PATCH 057/128] Migrate particle registration to Architectury API --- .../avm_staff/internal/fabric/StaffModClient.kt | 13 ------------- .../avm_staff/internal/forge/StaffModClient.kt | 10 ---------- .../avm_staff/internal/neoforge/StaffModClient.kt | 10 ---------- .../opekope2/avm_staff/internal/Initializer.kt | 6 ++++++ 4 files changed, 6 insertions(+), 33 deletions(-) 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 d03efd9de..46b68c1e8 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 @@ -21,26 +21,13 @@ package opekope2.avm_staff.internal.fabric import net.fabricmc.api.ClientModInitializer import net.fabricmc.api.EnvType import net.fabricmc.api.Environment -import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry import net.minecraft.client.item.ModelPredicateProviderRegistry -import opekope2.avm_staff.api.flamethrowerParticleType -import opekope2.avm_staff.api.particle.FlamethrowerParticle -import opekope2.avm_staff.api.soulFlamethrowerParticleType import opekope2.avm_staff.internal.model.registerModelPredicateProviders @Suppress("unused") @Environment(EnvType.CLIENT) object StaffModClient : ClientModInitializer { override fun onInitializeClient() { - ParticleFactoryRegistry.getInstance().register( - flamethrowerParticleType.get(), - FlamethrowerParticle::Factory - ) - ParticleFactoryRegistry.getInstance().register( - soulFlamethrowerParticleType.get(), - FlamethrowerParticle::Factory - ) - registerModelPredicateProviders(ModelPredicateProviderRegistry::register) } } diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt index 003305bc4..4fecce391 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt @@ -21,12 +21,8 @@ package opekope2.avm_staff.internal.forge import net.minecraft.client.item.ModelPredicateProviderRegistry import net.minecraftforge.api.distmarker.Dist import net.minecraftforge.api.distmarker.OnlyIn -import net.minecraftforge.client.event.RegisterParticleProvidersEvent import net.minecraftforge.eventbus.api.SubscribeEvent import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent -import opekope2.avm_staff.api.flamethrowerParticleType -import opekope2.avm_staff.api.particle.FlamethrowerParticle -import opekope2.avm_staff.api.soulFlamethrowerParticleType import opekope2.avm_staff.internal.model.registerModelPredicateProviders import opekope2.avm_staff.internal.registerClientContent import opekope2.avm_staff.internal.registerSmithingTableTextures @@ -50,10 +46,4 @@ object StaffModClient { registerModelPredicateProviders(ModelPredicateProviderRegistry::registerGeneric) } } - - @SubscribeEvent - fun registerParticleProviders(event: RegisterParticleProvidersEvent) { - event.registerSpriteSet(flamethrowerParticleType.get(), FlamethrowerParticle::Factory) - event.registerSpriteSet(soulFlamethrowerParticleType.get(), FlamethrowerParticle::Factory) - } } 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 dca76b42b..c9a4cf9a0 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 @@ -23,10 +23,6 @@ import net.neoforged.api.distmarker.Dist 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.internal.model.registerModelPredicateProviders import opekope2.avm_staff.internal.registerClientContent import opekope2.avm_staff.internal.registerSmithingTableTextures @@ -50,10 +46,4 @@ object StaffModClient { registerModelPredicateProviders(ModelPredicateProviderRegistry::registerGeneric) } } - - @SubscribeEvent - fun registerParticleProviders(event: RegisterParticleProvidersEvent) { - event.registerSpriteSet(flamethrowerParticleType.get(), FlamethrowerParticle::Factory) - event.registerSpriteSet(soulFlamethrowerParticleType.get(), FlamethrowerParticle::Factory) - } } 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 13ff6d6c5..98ef286ca 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -23,6 +23,7 @@ import dev.architectury.event.events.client.ClientTickEvent import dev.architectury.event.events.common.InteractionEvent import dev.architectury.event.events.common.LootEvent import dev.architectury.registry.client.keymappings.KeyMappingRegistry +import dev.architectury.registry.client.particle.ParticleProviderRegistry import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.minecraft.entity.player.PlayerEntity @@ -36,6 +37,9 @@ import net.minecraft.util.Identifier import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction import opekope2.avm_staff.api.crownOfKingOrangeItem +import opekope2.avm_staff.api.flamethrowerParticleType +import opekope2.avm_staff.api.particle.FlamethrowerParticle +import opekope2.avm_staff.api.soulFlamethrowerParticleType import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures import opekope2.avm_staff.api.staffsTag import opekope2.avm_staff.internal.event_handler.* @@ -102,6 +106,8 @@ fun subscribeToEvents() { @Environment(EnvType.CLIENT) fun registerClientContent() { KeyMappingRegistry.register(addRemoveStaffItemKeyBinding) + ParticleProviderRegistry.register(flamethrowerParticleType, FlamethrowerParticle::Factory) + ParticleProviderRegistry.register(soulFlamethrowerParticleType, FlamethrowerParticle::Factory) } @Environment(EnvType.CLIENT) From 1489bfb5fdc5127548f5b9f2ef29e9bc70d385d0 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 12:43:09 +0200 Subject: [PATCH 058/128] Add royal staff ingredient --- .../kotlin/opekope2/avm_staff/api/StaffMod.kt | 7 +++++++ .../resources/assets/avm_staff/lang/en_us.json | 1 + .../models/item/royal_staff_ingredient.json | 6 ++++++ .../textures/item/royal_staff_ingredient.png | Bin 0 -> 317 bytes 4 files changed, 14 insertions(+) create mode 100644 StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff_ingredient.json create mode 100644 StaffMod/src/main/resources/assets/avm_staff/textures/item/royal_staff_ingredient.png 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 969a4f210..e91550325 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -86,6 +86,13 @@ val royalStaffItem: RegistrySupplier = ITEMS.register("royal_staff") ) } +/** + * Item registered as `avm_staff:royal_staff_ingredient`. + */ +val royalStaffIngredientItem: RegistrySupplier = ITEMS.register("royal_staff_ingredient") { + Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21).`arch$tab`(staffModItemGroup)) +} + /** * Item registered as `avm_staff:crown_of_king_orange`. */ 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 7025bb910..144ac0401 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 @@ "item.avm_staff.faint_royal_staff": "Faint royal staff", "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_infusion_smithing_template": "Smithing Template", "item.avm_staff.staff_infusion_smithing_template.title": "Staff Infusion Template", "item.avm_staff.staff_infusion_smithing_template.applies_to": "Faint staffs", diff --git a/StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff_ingredient.json b/StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff_ingredient.json new file mode 100644 index 000000000..e0e3a23a5 --- /dev/null +++ b/StaffMod/src/main/resources/assets/avm_staff/models/item/royal_staff_ingredient.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "avm_staff:item/royal_staff_ingredient" + } +} diff --git a/StaffMod/src/main/resources/assets/avm_staff/textures/item/royal_staff_ingredient.png b/StaffMod/src/main/resources/assets/avm_staff/textures/item/royal_staff_ingredient.png new file mode 100644 index 0000000000000000000000000000000000000000..51e961a9d7048e1ab8801be0fcee43c492ac6cc7 GIT binary patch literal 317 zcmV-D0mA-?P)%p3tO5UQZ0NF*W|X(i+o4zjV`nIg=3?ZQyP zRP$!{dr$iV|E5x%bg53d@m&1`Nq=)a=jw6>&@Ii{lezaxh%oS}>IQ)A+W|50rl6@3 z6P4@)3z(+?h03V+vDM_aQOp&9bm|dL>K!J4>Lv+@w{l>1H z>Z-p)Q{*i4EjyD9k^r7wo|#?vR+nvK_23o6WSr!}qRY1F4a_k|&-=vHeq%R`;j(SW zj_&|G7O$RKnzfg5eg)S=Krs?XK Date: Tue, 21 May 2024 12:45:07 +0200 Subject: [PATCH 059/128] Move staff silhouette to smithing_table folder Keep directory structure clean --- .../opekope2/avm_staff/internal/Initializer.kt | 3 ++- .../{ => smithing_table}/empty_slot_royal_staff.png | Bin 2 files changed, 2 insertions(+), 1 deletion(-) rename StaffMod/src/main/resources/assets/avm_staff/textures/item/{ => smithing_table}/empty_slot_royal_staff.png (100%) 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 98ef286ca..999f3c2a2 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -113,7 +113,8 @@ fun registerClientContent() { @Environment(EnvType.CLIENT) fun registerSmithingTableTextures() { StaffInfusionSmithingRecipeTextures.register( - Identifier(MOD_ID, "item/empty_slot_royal_staff"), SmithingTemplateItem.EMPTY_SLOT_REDSTONE_DUST_TEXTURE + Identifier(MOD_ID, "item/smithing_table/empty_slot_royal_staff"), + SmithingTemplateItem.EMPTY_SLOT_REDSTONE_DUST_TEXTURE ) } diff --git a/StaffMod/src/main/resources/assets/avm_staff/textures/item/empty_slot_royal_staff.png b/StaffMod/src/main/resources/assets/avm_staff/textures/item/smithing_table/empty_slot_royal_staff.png similarity index 100% rename from StaffMod/src/main/resources/assets/avm_staff/textures/item/empty_slot_royal_staff.png rename to StaffMod/src/main/resources/assets/avm_staff/textures/item/smithing_table/empty_slot_royal_staff.png From 7ae5721a43671d9aa409e9eea24d733df2675c86 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 12:51:01 +0200 Subject: [PATCH 060/128] Make items not dependent on update 1.21 data pack --- .../kotlin/opekope2/avm_staff/api/StaffMod.kt | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 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 e91550325..5c5d04a39 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -32,7 +32,6 @@ import net.minecraft.item.SmithingTemplateItem import net.minecraft.particle.DefaultParticleType import net.minecraft.registry.RegistryKeys import net.minecraft.registry.tag.TagKey -import net.minecraft.resource.featuretoggle.FeatureFlags import net.minecraft.text.Text import net.minecraft.util.Identifier import net.minecraft.util.Rarity @@ -53,7 +52,7 @@ private val PARTICLE_TYPES = DeferredRegister.create(MOD_ID, RegistryKeys.PARTIC * Item registered as `avm_staff:faint_staff_rod`. */ val faintStaffRodItem: RegistrySupplier = ITEMS.register("faint_staff_rod") { - Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21).`arch$tab`(staffModItemGroup)) + Item(Item.Settings().`arch$tab`(staffModItemGroup)) } /** @@ -61,8 +60,7 @@ val faintStaffRodItem: RegistrySupplier = ITEMS.register("faint_staff_rod" */ val faintRoyalStaffHeadItem: RegistrySupplier = ITEMS.register("faint_royal_staff_head") { Item( - Item.Settings().maxCount(16).rarity(Rarity.RARE).requires(FeatureFlags.UPDATE_1_21) - .`arch$tab`(staffModItemGroup) + Item.Settings().maxCount(16).rarity(Rarity.RARE).`arch$tab`(staffModItemGroup) ) } @@ -70,37 +68,28 @@ val faintRoyalStaffHeadItem: RegistrySupplier = ITEMS.register("faint_roya * Item registered as `avm_staff:faint_royal_staff`. */ val faintRoyalStaffItem: RegistrySupplier = ITEMS.register("faint_royal_staff") { - createStaffRendererItem( - Item.Settings().maxCount(1).rarity(Rarity.RARE).requires(FeatureFlags.UPDATE_1_21) - .`arch$tab`(staffModItemGroup) - ) + createStaffRendererItem(Item.Settings().maxCount(1).rarity(Rarity.RARE).`arch$tab`(staffModItemGroup)) } /** * Item registered as `avm_staff:royal_staff`. */ val royalStaffItem: RegistrySupplier = ITEMS.register("royal_staff") { - createStaffItem( - Item.Settings().maxCount(1).rarity(Rarity.EPIC).requires(FeatureFlags.UPDATE_1_21) - .`arch$tab`(staffModItemGroup) - ) + createStaffItem(Item.Settings().maxCount(1).rarity(Rarity.EPIC).`arch$tab`(staffModItemGroup)) } /** * Item registered as `avm_staff:royal_staff_ingredient`. */ val royalStaffIngredientItem: RegistrySupplier = ITEMS.register("royal_staff_ingredient") { - Item(Item.Settings().requires(FeatureFlags.UPDATE_1_21).`arch$tab`(staffModItemGroup)) + Item(Item.Settings().`arch$tab`(staffModItemGroup)) } /** * Item registered as `avm_staff:crown_of_king_orange`. */ val crownOfKingOrangeItem: RegistrySupplier = ITEMS.register("crown_of_king_orange") { - createCrownItem( - Item.Settings().maxCount(1).rarity(Rarity.UNCOMMON).requires(FeatureFlags.UPDATE_1_21) - .`arch$tab`(staffModItemGroup) - ) + createCrownItem(Item.Settings().maxCount(1).rarity(Rarity.UNCOMMON).`arch$tab`(staffModItemGroup)) } /** From d2349a5f6a55ceb873525c92f1f000d8ebadc912 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 12:59:07 +0200 Subject: [PATCH 061/128] Move interaction handlers to InteractionHandler.kt --- .../avm_staff/internal/Initializer.kt | 32 ----------- .../event_handler/InteractionHandler.kt | 56 +++++++++++++++++++ 2 files changed, 56 insertions(+), 32 deletions(-) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/InteractionHandler.kt 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 999f3c2a2..ad7bad6e3 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -18,7 +18,6 @@ package opekope2.avm_staff.internal -import dev.architectury.event.EventResult import dev.architectury.event.events.client.ClientTickEvent import dev.architectury.event.events.common.InteractionEvent import dev.architectury.event.events.common.LootEvent @@ -26,29 +25,21 @@ import dev.architectury.registry.client.keymappings.KeyMappingRegistry import dev.architectury.registry.client.particle.ParticleProviderRegistry import net.fabricmc.api.EnvType import net.fabricmc.api.Environment -import net.minecraft.entity.player.PlayerEntity -import net.minecraft.item.ItemStack import net.minecraft.item.SmithingTemplateItem import net.minecraft.loot.LootManager import net.minecraft.loot.LootPool import net.minecraft.loot.entry.ItemEntry -import net.minecraft.util.Hand import net.minecraft.util.Identifier -import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.Direction import opekope2.avm_staff.api.crownOfKingOrangeItem import opekope2.avm_staff.api.flamethrowerParticleType import opekope2.avm_staff.api.particle.FlamethrowerParticle import opekope2.avm_staff.api.soulFlamethrowerParticleType import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures -import opekope2.avm_staff.api.staffsTag import opekope2.avm_staff.internal.event_handler.* import opekope2.avm_staff.internal.networking.c2s.play.AddItemToStaffC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.AttackC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.RemoveItemFromStaffC2SPacket import opekope2.avm_staff.util.MOD_ID -import opekope2.avm_staff.util.handlerOfItem -import opekope2.avm_staff.util.itemInStaff fun registerContent() { opekope2.avm_staff.api.registerContent() @@ -60,29 +51,6 @@ fun initializeNetworking() { AttackC2SPacket.registerHandler(::attack) } -private fun attackBlock(player: PlayerEntity, hand: Hand, target: BlockPos, direction: Direction): EventResult { - val staffStack = player.getStackInHand(hand) - if (!staffStack.isIn(staffsTag)) return EventResult.pass() - - val itemInStaff = staffStack.itemInStaff ?: return EventResult.pass() - val staffHandler = itemInStaff.handlerOfItem ?: return EventResult.pass() - - val result = staffHandler.attackBlock(staffStack, player.entityWorld, player, target, direction, hand) - return if (result.isFalse) EventResult.interruptTrue() // Force Fabric to send packet for Neo/Forge parity - else result -} - -private fun clientAttack(player: PlayerEntity, hand: Hand) { - val staffStack = player.getStackInHand(hand) - if (!staffStack.isIn(staffsTag)) return - - val itemInStaff: ItemStack = staffStack.itemInStaff ?: return - val staffHandler = itemInStaff.handlerOfItem ?: return - - staffHandler.attack(staffStack, player.entityWorld, player, hand) - AttackC2SPacket(hand).send() -} - private val TREASURE_BASTION_CHEST_LOOT = Identifier("chests/bastion_treasure") @Suppress("UNUSED_PARAMETER") diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/InteractionHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/InteractionHandler.kt new file mode 100644 index 000000000..1c65a869b --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/InteractionHandler.kt @@ -0,0 +1,56 @@ +/* + * 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.EventResult +import net.fabricmc.api.EnvType +import net.fabricmc.api.Environment +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.ItemStack +import net.minecraft.util.Hand +import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Direction +import opekope2.avm_staff.api.staffsTag +import opekope2.avm_staff.internal.networking.c2s.play.AttackC2SPacket +import opekope2.avm_staff.util.handlerOfItem +import opekope2.avm_staff.util.itemInStaff + +fun attackBlock(player: PlayerEntity, hand: Hand, target: BlockPos, direction: Direction): EventResult { + val staffStack = player.getStackInHand(hand) + if (!staffStack.isIn(staffsTag)) return EventResult.pass() + + val itemInStaff = staffStack.itemInStaff ?: return EventResult.pass() + val staffHandler = itemInStaff.handlerOfItem ?: return EventResult.pass() + + val result = staffHandler.attackBlock(staffStack, player.entityWorld, player, target, direction, hand) + return if (result.isFalse) EventResult.interruptTrue() // Force Fabric to send packet for Neo/Forge parity + else result +} + +@Environment(EnvType.CLIENT) +fun clientAttack(player: PlayerEntity, hand: Hand) { + val staffStack = player.getStackInHand(hand) + if (!staffStack.isIn(staffsTag)) return + + val itemInStaff: ItemStack = staffStack.itemInStaff ?: return + val staffHandler = itemInStaff.handlerOfItem ?: return + + staffHandler.attack(staffStack, player.entityWorld, player, hand) + AttackC2SPacket(hand).send() +} From 30b87988d550f6fa3c0e7f8d0e76470eb263aafa Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 12:59:38 +0200 Subject: [PATCH 062/128] Register CLIENT_LEFT_CLICK_AIR on client side only --- .../src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ad7bad6e3..96ac3039d 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -67,7 +67,6 @@ fun modifyLootTables( fun subscribeToEvents() { InteractionEvent.LEFT_CLICK_BLOCK.register(::attackBlock) - InteractionEvent.CLIENT_LEFT_CLICK_AIR.register(::clientAttack) LootEvent.MODIFY_LOOT_TABLE.register(::modifyLootTables) } @@ -88,5 +87,6 @@ fun registerSmithingTableTextures() { @Environment(EnvType.CLIENT) fun subscribeToClientEvents() { + InteractionEvent.CLIENT_LEFT_CLICK_AIR.register(::clientAttack) ClientTickEvent.CLIENT_POST.register(::handleKeyBindings) } From c5714dbe94649ada256ee61e0dabe1840597bbc9 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 13:04:11 +0200 Subject: [PATCH 063/128] Update gradle --- gradle/wrapper/gradle-wrapper.jar | Bin 43462 -> 43453 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew.bat | 20 ++++++++++---------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd4917707c1f8861d8cb53dd15194d4248596..e6441136f3d4ba8a0da8d277868979cfbc8ad796 100644 GIT binary patch delta 34118 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 delta 34176 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 SGW6ptSs!X7{rG*o_g?|vpSEZK diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1af9e0930..b82aa23a4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew.bat b/gradlew.bat index 93e3f59f1..25da30dbd 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail From 6fef4d75c82bbf6380bdfc26c04ff2d15ad1c72d Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 13:04:43 +0200 Subject: [PATCH 064/128] 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 55c9fb9da..100df8200 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] java = "17" # Don't forget to update *.mixins.json kotlin = "1.8.22" -staff-mod = "0.14.1-beta" +staff-mod = "0.15.0" architectury-plugin = "3.4-SNAPSHOT" architectury-loom = "1.5-SNAPSHOT" yarn = "1.20.4+build.3" From d4427d529d429d11c786f338ae97796bf6b3f676 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 13:20:40 +0200 Subject: [PATCH 065/128] Temporarily remove Forge Will be re-added after my dependencies update --- .github/workflows/build.yml | 2 +- .github/workflows/publish-release.yml | 5 ++--- StaffMod/build.gradle.kts | 2 +- gradle/libs.versions.toml | 10 +++++----- settings.gradle.kts | 2 +- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bf5153953..cfe3c0a96 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -91,7 +91,7 @@ jobs: NeoForgeMod/build/libs/*.jar if-no-files-found: error - name: Upload Forge jars - if: inputs.build-project && inputs.upload-output + if: inputs.build-project && inputs.upload-output && false uses: actions/upload-artifact@v4.3.1 with: name: forge-jars diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 42abf334b..55758047a 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -33,6 +33,7 @@ jobs: name: neoforge-jars path: dist/neoforge - name: Download Forge jars + if: false uses: actions/download-artifact@v4.1.4 with: name: forge-jars @@ -95,6 +96,7 @@ jobs: game-version-filter: releases java: ${{ steps.load-java-version.outputs.value }} - name: Publish Forge mod to Modrinth and CurseForge + if: false uses: Kir-Antipov/mc-publish@v3.3.0 with: modrinth-id: ${{ vars.MODRINTH_ID }} @@ -123,8 +125,6 @@ jobs: dist/fabric/*-@(dev|sources|javadoc).jar dist/neoforge/!(*-@(dev|sources|javadoc)).jar dist/neoforge/*-@(dev|sources|javadoc).jar - dist/forge/!(*-@(dev|sources|javadoc)).jar - dist/forge/*-@(dev|sources|javadoc).jar changelog-file: CHANGELOG.g.md - name: Delete build output uses: geekyeggo/delete-artifact@v5.0.0 @@ -132,7 +132,6 @@ jobs: name: | fabric-jars neoforge-jars - forge-jars useGlob: false failOnError: false diff --git a/StaffMod/build.gradle.kts b/StaffMod/build.gradle.kts index 336efc459..0bea06795 100644 --- a/StaffMod/build.gradle.kts +++ b/StaffMod/build.gradle.kts @@ -26,7 +26,7 @@ plugins { } architectury { - common("fabric", "forge", "neoforge") + common("fabric", /*"forge",*/ "neoforge") } repositories {} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 100df8200..6df641486 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,7 +9,7 @@ shadow = "8.1.1" minecraft = "1.20.4" architectury-api = "11.0.11" fabric-loader = "0.15.3" -forge = "1.20.4-49.0.27" +#forge = "1.20.4-49.0.27" neoforge = "20.4.233" fabric-api = "0.91.3+1.20.4" fabric-language-kotlin = "1.10.18+kotlin.1.9.22" @@ -23,17 +23,17 @@ yarn = { group = "net.fabricmc", name = "yarn", version.ref = "yarn" } kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" } architectury = { group = "dev.architectury", name = "architectury", version.ref = "architectury-api" } architectury-fabric = { group = "dev.architectury", name = "architectury-fabric", version.ref = "architectury-api" } -architectury-forge = { group = "dev.architectury", name = "architectury-forge", version.ref = "architectury-api" } +#architectury-forge = { group = "dev.architectury", name = "architectury-forge", version.ref = "architectury-api" } architectury-neoforge = { group = "dev.architectury", name = "architectury-neoforge", version.ref = "architectury-api" } fabric-loader = { group = "net.fabricmc", name = "fabric-loader", version.ref = "fabric-loader" } fabric-api = { group = "net.fabricmc.fabric-api", name = "fabric-api", version.ref = "fabric-api" } fabric-language-kotlin = { group = "net.fabricmc", name = "fabric-language-kotlin", version.ref = "fabric-language-kotlin" } -forge = { group = "net.minecraftforge", name = "forge", version.ref = "forge" } +#forge = { group = "net.minecraftforge", name = "forge", version.ref = "forge" } neoforge = { group = "net.neoforged", name = "neoforge", version.ref = "neoforge" } -kotlinforforge = { group = "thedarkcolour", name = "kotlinforforge", version.ref = "kotlinforforge" } +#kotlinforforge = { group = "thedarkcolour", name = "kotlinforforge", version.ref = "kotlinforforge" } kotlinforforge-neoforge = { group = "thedarkcolour", name = "kotlinforforge-neoforge", version.ref = "kotlinforforge" } mixinextras-common = { group = "io.github.llamalad7", name = "mixinextras-common", version.ref = "mixin-extras" } -mixinextras-forge = { group = "io.github.llamalad7", name = "mixinextras-forge", version.ref = "mixin-extras" } +#mixinextras-forge = { group = "io.github.llamalad7", name = "mixinextras-forge", version.ref = "mixin-extras" } dokka-base = { group = "org.jetbrains.dokka", name = "dokka-base", version.ref = "dokka" } dokka-plugin-java-syntax = { group = "org.jetbrains.dokka", name = "kotlin-as-java-plugin", version.ref = "dokka" } diff --git a/settings.gradle.kts b/settings.gradle.kts index eedb8e76e..81a4dd8c3 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -36,5 +36,5 @@ include( "StaffMod", "FabricMod", "NeoForgeMod", - "ForgeMod" + //"ForgeMod" ) From e8aadd8ce4ba3dd9225918fc27dcaab9efa4b3bb Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 14:58:11 +0200 Subject: [PATCH 066/128] Update deps to Minecraft 1.20.6 --- .github/workflows/build.yml | 2 +- FabricMod/build.gradle.kts | 18 +++++++++++++ .../resources/avm_staff_fabric.mixins.json | 2 +- ForgeMod/build.gradle.kts | 18 +++++++++++++ NeoForgeMod/build.gradle.kts | 18 +++++++++++++ .../src/main/resources/avm_staff.mixins.json | 2 +- build.gradle.kts | 26 ++++++++++++++++++- gradle/libs.versions.toml | 25 +++++++++--------- 8 files changed, 95 insertions(+), 16 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cfe3c0a96..39f097c6d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -60,7 +60,7 @@ jobs: - name: JDK setup uses: actions/setup-java@v4.2.1 with: - java-version: 17 + java-version: 21 distribution: temurin - name: Build project if: inputs.build-project diff --git a/FabricMod/build.gradle.kts b/FabricMod/build.gradle.kts index 237fd40a4..208a2bcbf 100644 --- a/FabricMod/build.gradle.kts +++ b/FabricMod/build.gradle.kts @@ -1,3 +1,21 @@ +/* + * 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 . + */ + plugins { alias(libs.plugins.shadow) } diff --git a/FabricMod/src/main/resources/avm_staff_fabric.mixins.json b/FabricMod/src/main/resources/avm_staff_fabric.mixins.json index e7a5a8961..f1bdac7b3 100644 --- a/FabricMod/src/main/resources/avm_staff_fabric.mixins.json +++ b/FabricMod/src/main/resources/avm_staff_fabric.mixins.json @@ -1,7 +1,7 @@ { "required": true, "package": "opekope2.avm_staff.mixin.fabric", - "compatibilityLevel": "JAVA_17", + "compatibilityLevel": "JAVA_21", "minVersion": "0.8", "injectors": { "defaultRequire": 1 diff --git a/ForgeMod/build.gradle.kts b/ForgeMod/build.gradle.kts index 2adc8f2b4..c81fc5da0 100644 --- a/ForgeMod/build.gradle.kts +++ b/ForgeMod/build.gradle.kts @@ -1,3 +1,21 @@ +/* + * 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 . + */ + plugins { alias(libs.plugins.shadow) } diff --git a/NeoForgeMod/build.gradle.kts b/NeoForgeMod/build.gradle.kts index 0e498fea9..8a2f9a65f 100644 --- a/NeoForgeMod/build.gradle.kts +++ b/NeoForgeMod/build.gradle.kts @@ -1,3 +1,21 @@ +/* + * 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 . + */ + plugins { alias(libs.plugins.shadow) } diff --git a/StaffMod/src/main/resources/avm_staff.mixins.json b/StaffMod/src/main/resources/avm_staff.mixins.json index 3b6edd1f4..c430274ae 100644 --- a/StaffMod/src/main/resources/avm_staff.mixins.json +++ b/StaffMod/src/main/resources/avm_staff.mixins.json @@ -1,7 +1,7 @@ { "required": true, "package": "opekope2.avm_staff.mixin", - "compatibilityLevel": "JAVA_17", + "compatibilityLevel": "JAVA_21", "minVersion": "0.8", "injectors": { "defaultRequire": 1 diff --git a/build.gradle.kts b/build.gradle.kts index 091b6cfa5..cdbb62ca6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,21 @@ +/* + * 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 . + */ + plugins { java alias(libs.plugins.kotlin.jvm) @@ -24,9 +42,15 @@ buildscript { subprojects { apply(plugin = "dev.architectury.loom") + val loom = project.extensions.getByName("loom") + dependencies { "minecraft"(rootProject.libs.minecraft) - "mappings"(variantOf(rootProject.libs.yarn) { classifier("v2") }) + //"mappings"(variantOf(rootProject.libs.yarn) { classifier("v2") }) + "mappings"(loom.layered { // FIXME + mappings(variantOf(rootProject.libs.yarn) { classifier("v2") }) + mappings(rootProject.libs.yarn.patch.neoforge) + }) } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6df641486..bacab910a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,25 +1,26 @@ [versions] -java = "17" # Don't forget to update *.mixins.json -kotlin = "1.8.22" +java = "21" # Don't forget to update *.mixins.json +kotlin = "1.9.23" staff-mod = "0.15.0" architectury-plugin = "3.4-SNAPSHOT" -architectury-loom = "1.5-SNAPSHOT" -yarn = "1.20.4+build.3" +architectury-loom = "1.6-SNAPSHOT" +yarn = "1.20.6+build.2" shadow = "8.1.1" -minecraft = "1.20.4" -architectury-api = "11.0.11" -fabric-loader = "0.15.3" +minecraft = "1.20.6" +architectury-api = "12.1.2" +fabric-loader = "0.15.11" #forge = "1.20.4-49.0.27" -neoforge = "20.4.233" -fabric-api = "0.91.3+1.20.4" -fabric-language-kotlin = "1.10.18+kotlin.1.9.22" -kotlinforforge = "4.10.0" -mixin-extras = "0.3.5" +neoforge = "20.6.72-beta" +fabric-api = "0.99.0+1.20.6" +fabric-language-kotlin = "1.10.19+kotlin.1.9.23" +kotlinforforge = "5.1.0" +mixin-extras = "0.3.6" dokka = "1.9.20" [libraries] minecraft = { group = "com.mojang", name = "minecraft", version.ref = "minecraft" } yarn = { group = "net.fabricmc", name = "yarn", version.ref = "yarn" } +yarn-patch-neoforge = { group = "dev.architectury", name = "yarn-mappings-patch-neoforge", version.require = "1.20.5+build.3" } # FIXME kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" } architectury = { group = "dev.architectury", name = "architectury", version.ref = "architectury-api" } architectury-fabric = { group = "dev.architectury", name = "architectury-fabric", version.ref = "architectury-api" } From f10be4da1ad3f86ad5a29974939ff4015b6bb195 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 20:51:50 +0200 Subject: [PATCH 067/128] Migrate NBT to data components --- .../mixin/fabric/LivingEntityMixin.java | 5 +- .../avm_staff/internal/fabric/StaffMod.kt | 4 +- .../internal/fabric/item/FabricStaffItem.kt | 6 +- .../neoforge/item/NeoForgeStaffItem.kt | 9 ++- .../kotlin/opekope2/avm_staff/api/StaffMod.kt | 54 ++++++++++++-- .../opekope2/avm_staff/api/item/StaffItem.kt | 25 +++---- .../api/item/renderer/StaffRenderer.kt | 8 +-- .../avm_staff/api/staff/StaffItemComponent.kt | 65 +++++++++++++++++ .../event_handler/InteractionHandler.kt | 9 ++- .../internal/event_handler/NetworkHandler.kt | 21 +++--- .../internal/staff_handler/AnvilHandler.kt | 4 +- .../internal/staff_handler/CampfireHandler.kt | 11 +-- .../internal/staff_handler/FurnaceHandler.kt | 8 +-- .../opekope2/avm_staff/util/StaffUtil.kt | 71 ++++++++++--------- .../opekope2/avm_staff/util/UnitComponent.kt | 26 +++++++ 15 files changed, 229 insertions(+), 97 deletions(-) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffItemComponent.kt create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/util/UnitComponent.kt diff --git a/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/LivingEntityMixin.java b/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/LivingEntityMixin.java index 17b25bebf..3a460b2f5 100644 --- a/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/LivingEntityMixin.java +++ b/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/LivingEntityMixin.java @@ -19,6 +19,7 @@ package opekope2.avm_staff.mixin.fabric; import net.minecraft.entity.LivingEntity; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import opekope2.avm_staff.api.StaffMod; import opekope2.avm_staff.api.staff.StaffHandler; @@ -39,10 +40,10 @@ public void disableShield(CallbackInfoReturnable cir) { ItemStack mainHandStack = getMainHandStack(); if (!mainHandStack.isIn(StaffMod.getStaffsTag())) return; - ItemStack itemInStaff = StaffUtil.getItemInStaff(mainHandStack); + Item itemInStaff = StaffUtil.getItemInStaff(mainHandStack); if (itemInStaff == null) return; - StaffHandler handlerOfItem = StaffUtil.getHandlerOfItemOrFallback(itemInStaff); + StaffHandler handlerOfItem = StaffUtil.getStaffHandlerOrFallback(itemInStaff); if (handlerOfItem.disablesShield()) { cir.setReturnValue(true); } 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 b0dec02ca..5702891d1 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 @@ -27,8 +27,8 @@ import net.minecraft.util.Hand import net.minecraft.util.hit.EntityHitResult import net.minecraft.world.World import opekope2.avm_staff.api.staffsTag -import opekope2.avm_staff.util.handlerOfItem import opekope2.avm_staff.util.itemInStaff +import opekope2.avm_staff.util.staffHandler @Suppress("unused") object StaffMod : ModInitializer { @@ -48,7 +48,7 @@ object StaffMod : ModInitializer { if (!itemStack.isIn(staffsTag)) return ActionResult.PASS val itemInStaff = itemStack.itemInStaff ?: return ActionResult.PASS - val staffHandler = itemInStaff.handlerOfItem ?: return ActionResult.PASS + val staffHandler = itemInStaff.staffHandler ?: return ActionResult.PASS val result = staffHandler.attackEntity(itemStack, world, player, target, hand) return if (result.interruptsFurtherEvaluation()) ActionResult.SUCCESS 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 b227b96da..3aeec566d 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 @@ -32,8 +32,8 @@ import net.minecraft.item.ItemStack 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.handlerOfItemOrFallback import opekope2.avm_staff.util.itemInStaff +import opekope2.avm_staff.util.staffHandlerOrFallback class FabricStaffItem(settings: Item.Settings) : StaffItem(settings), FabricItem { init { @@ -48,8 +48,8 @@ class FabricStaffItem(settings: Item.Settings) : StaffItem(settings), FabricItem oldStack: ItemStack, newStack: ItemStack ): Boolean { - val oldHandler = oldStack.itemInStaff.handlerOfItemOrFallback - val newHandler = newStack.itemInStaff.handlerOfItemOrFallback + val oldHandler = oldStack.itemInStaff.staffHandlerOrFallback + val newHandler = newStack.itemInStaff.staffHandlerOrFallback return if (oldHandler !== newHandler) true else oldHandler.allowNbtUpdateAnimation(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 2ff672d0a..ac9574aa2 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 @@ -37,7 +37,6 @@ 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.handlerOfItemOrFallback import opekope2.avm_staff.util.itemInStaff import java.util.function.Consumer @@ -56,7 +55,7 @@ class NeoForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IItemExt entity: LivingEntity, attacker: LivingEntity ): Boolean { - return stack.itemInStaff.handlerOfItemOrFallback.disablesShield() || + return stack.itemInStaff.staffHandlerOrFallback.disablesShield() || super.canDisableShield(stack, shield, entity, attacker) } @@ -65,7 +64,7 @@ class NeoForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IItemExt } override fun onLeftClickEntity(stack: ItemStack, player: PlayerEntity, entity: Entity): Boolean { - return stack.itemInStaff.handlerOfItemOrFallback.attackEntity( + return stack.itemInStaff.staffHandlerOrFallback.attackEntity( stack, player.entityWorld, player, entity, Hand.MAIN_HAND ).interruptsFurtherEvaluation() } @@ -75,8 +74,8 @@ class NeoForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IItemExt newStack: ItemStack, slotChanged: Boolean ): Boolean { - val oldHandler = oldStack.itemInStaff.handlerOfItemOrFallback - val newHandler = newStack.itemInStaff.handlerOfItemOrFallback + 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/kotlin/opekope2/avm_staff/api/StaffMod.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt index 5c5d04a39..3ebd15d43 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -21,15 +21,18 @@ package opekope2.avm_staff.api +import com.mojang.serialization.Codec import dev.architectury.registry.CreativeTabRegistry import dev.architectury.registry.registries.DeferredRegister import dev.architectury.registry.registries.RegistrySupplier import net.minecraft.client.particle.ParticleManager +import net.minecraft.component.DataComponentType import net.minecraft.item.Item import net.minecraft.item.ItemGroup import net.minecraft.item.Items import net.minecraft.item.SmithingTemplateItem -import net.minecraft.particle.DefaultParticleType +import net.minecraft.network.codec.PacketCodec +import net.minecraft.particle.SimpleParticleType import net.minecraft.registry.RegistryKeys import net.minecraft.registry.tag.TagKey import net.minecraft.text.Text @@ -38,15 +41,18 @@ import net.minecraft.util.Rarity import opekope2.avm_staff.api.item.CrownItem import opekope2.avm_staff.api.item.StaffItem import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures +import opekope2.avm_staff.api.staff.StaffItemComponent import opekope2.avm_staff.internal.createCrownItem import opekope2.avm_staff.internal.createStaffItem import opekope2.avm_staff.internal.createStaffRendererItem import opekope2.avm_staff.util.MOD_ID -import opekope2.avm_staff.util.itemInStaff +import opekope2.avm_staff.util.UnitComponent +import opekope2.avm_staff.util.itemStackInStaff private val ITEMS = DeferredRegister.create(MOD_ID, RegistryKeys.ITEM) private val ITEM_GROUPS = DeferredRegister.create(MOD_ID, RegistryKeys.ITEM_GROUP) private val PARTICLE_TYPES = DeferredRegister.create(MOD_ID, RegistryKeys.PARTICLE_TYPE) +private val DATA_COMPONENT_TYPES = DeferredRegister.create(MOD_ID, RegistryKeys.DATA_COMPONENT_TYPE) /** * Item registered as `avm_staff:faint_staff_rod`. @@ -120,7 +126,7 @@ val staffsTag: TagKey = TagKey.of(RegistryKeys.ITEM, Identifier(MOD_ID, "s val staffModItemGroup: RegistrySupplier = ITEM_GROUPS.register("${MOD_ID}_items") { CreativeTabRegistry.create(Text.translatable("itemGroup.${MOD_ID}_items")) { royalStaffItem.get().defaultStack.apply { - itemInStaff = Items.COMMAND_BLOCK.defaultStack + itemStackInStaff = Items.COMMAND_BLOCK.defaultStack } } } @@ -130,16 +136,49 @@ val staffModItemGroup: RegistrySupplier = ITEM_GROUPS.register("${MOD * * @see ParticleManager.addParticle */ -val flamethrowerParticleType: RegistrySupplier = - PARTICLE_TYPES.register("flame") { DefaultParticleType(false) } +val flamethrowerParticleType: RegistrySupplier = + PARTICLE_TYPES.register("flame") { SimpleParticleType(false) } /** * Particle registered as `avm_staff:soul_fire_flame`. * * @see ParticleManager.addParticle */ -val soulFlamethrowerParticleType: RegistrySupplier = - PARTICLE_TYPES.register("soul_fire_flame") { DefaultParticleType(false) } +val soulFlamethrowerParticleType: RegistrySupplier = + PARTICLE_TYPES.register("soul_fire_flame") { 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") { + DataComponentType.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") { + DataComponentType.builder() + .codec(Codec.unit(UnitComponent)) + .packetCodec(PacketCodec.unit(UnitComponent)) + .build() + } + +/** + * Data component registered as `avm_staff:furnace_lit`. Stores if a furnace staff is lit. Only used for rendering. + */ +val furnaceLitComponentType: RegistrySupplier> = + DATA_COMPONENT_TYPES.register("furnace_lit") { + DataComponentType.builder() + .codec(Codec.unit(UnitComponent)) + .packetCodec(PacketCodec.unit(UnitComponent)) + .build() + } /** * @suppress @@ -149,6 +188,7 @@ internal fun registerContent() { ITEMS.register() ITEM_GROUPS.register() PARTICLE_TYPES.register() + DATA_COMPONENT_TYPES.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/item/StaffItem.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt index c8b916cc9..db1f8a9bf 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 @@ -30,10 +30,7 @@ import net.minecraft.util.ActionResult import net.minecraft.util.Hand import net.minecraft.util.TypedActionResult import net.minecraft.world.World -import opekope2.avm_staff.util.handlerOfItemOrFallback -import opekope2.avm_staff.util.isItemInStaff -import opekope2.avm_staff.util.itemInStaff -import java.util.stream.Stream +import opekope2.avm_staff.util.* /** * Staff item dispatching functionality to [StaffItemHandler] without loader specific functionality. @@ -43,33 +40,33 @@ import java.util.stream.Stream abstract class StaffItem(settings: Settings) : Item(settings) { override fun onItemEntityDestroyed(entity: ItemEntity) { val staffStack = entity.stack - val staffItem = staffStack.itemInStaff ?: return - ItemUsage.spawnItemContents(entity, Stream.of(staffItem)) + val staffItem = staffStack.mutableItemStackInStaff ?: return + ItemUsage.spawnItemContents(entity, listOf(staffItem)) } override fun getMaxUseTime(stack: ItemStack): Int { - return stack.itemInStaff.handlerOfItemOrFallback.maxUseTime + return stack.itemInStaff.staffHandlerOrFallback.maxUseTime } override fun use(world: World, user: PlayerEntity, hand: Hand): TypedActionResult { val staffStack = user.getStackInHand(hand) - return staffStack.itemInStaff.handlerOfItemOrFallback.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.handlerOfItemOrFallback.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.handlerOfItemOrFallback.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.handlerOfItemOrFallback.finishUsing(stack, world, user) + return stack.itemInStaff.staffHandlerOrFallback.finishUsing(stack, world, user) } override fun useOnBlock(context: ItemUsageContext): ActionResult { - return context.stack.itemInStaff.handlerOfItemOrFallback.useOnBlock( + return context.stack.itemInStaff.staffHandlerOrFallback.useOnBlock( context.stack, context.world, context.player ?: return ActionResult.PASS, @@ -80,11 +77,11 @@ abstract class StaffItem(settings: Settings) : Item(settings) { } override fun useOnEntity(stack: ItemStack, user: PlayerEntity, entity: LivingEntity, hand: Hand): ActionResult { - return stack.itemInStaff.handlerOfItemOrFallback.useOnEntity(stack, user.world, user, entity, hand) + return stack.itemInStaff.staffHandlerOrFallback.useOnEntity(stack, user.world, user, entity, hand) } override fun getName(stack: ItemStack): Text { - val staffItem = stack.itemInStaff ?: return super.getName(stack) + val staffItem = stack.itemStackInStaff ?: return super.getName(stack) val staffItemText = Text.translatable(staffItem.item.getTranslationKey(staffItem)) return Text.translatable(getTranslationKey(stack), staffItemText) } 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 67de4639d..9bf5915b4 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 @@ -31,7 +31,7 @@ import opekope2.avm_staff.internal.model.HEAD_SEED import opekope2.avm_staff.internal.model.ITEM_SEED import opekope2.avm_staff.internal.model.ROD_BOTTOM_SEED import opekope2.avm_staff.internal.model.ROD_TOP_SEED -import opekope2.avm_staff.util.itemInStaff +import opekope2.avm_staff.util.itemStackInStaff import opekope2.avm_staff.util.push /** @@ -89,7 +89,7 @@ object StaffRenderer { renderPart(staffStack, this, vertexConsumers, light, overlay, HEAD_SEED) // Item - staffStack.itemInStaff?.let { itemInStaff -> + staffStack.itemStackInStaff?.let { itemInStaff -> renderItem(mode, this, staffStack, itemInStaff, light, overlay, vertexConsumers) } } @@ -124,7 +124,7 @@ object StaffRenderer { renderPart(staffStack, this, vertexConsumers, light, overlay, HEAD_SEED) // Item - staffStack.itemInStaff?.let { itemInStaff -> + staffStack.itemStackInStaff?.let { itemInStaff -> renderItem(mode, this, staffStack, itemInStaff, light, overlay, vertexConsumers) } } @@ -148,7 +148,7 @@ object StaffRenderer { renderPart(staffStack, this, vertexConsumers, light, overlay, HEAD_SEED) // Item - staffStack.itemInStaff?.let { itemInStaff -> + staffStack.itemStackInStaff?.let { itemInStaff -> renderItem(mode, this, staffStack, itemInStaff, light, overlay, vertexConsumers) } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffItemComponent.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffItemComponent.kt new file mode 100644 index 000000000..f90ce8ead --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffItemComponent.kt @@ -0,0 +1,65 @@ +/* + * 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.staff + +import com.mojang.serialization.Codec +import com.mojang.serialization.codecs.RecordCodecBuilder +import net.minecraft.component.DataComponentType +import net.minecraft.item.ItemStack +import net.minecraft.network.RegistryByteBuf +import net.minecraft.network.codec.PacketCodec + +/** + * [ItemStack] wrapper to make them compatible with [DataComponentType]s. + * + * @param item The item stored in this component. Most be [copied][ItemStack.copy] before modifying it + */ +class StaffItemComponent(val item: ItemStack) { + override fun equals(other: Any?): Boolean { + return when { + this === other -> true + other is StaffItemComponent -> ItemStack.areEqual(item, other.item) + else -> false + } + } + + override fun hashCode(): Int { + return ItemStack.hashCode(item) + } + + companion object { + /** + * [Codec] for [StaffItemComponent]. + */ + @JvmField + val CODEC: Codec = RecordCodecBuilder.create { instance -> + instance.group( + ItemStack.CODEC.fieldOf("item").forGetter(StaffItemComponent::item) + ).apply(instance, ::StaffItemComponent) + } + + /** + * [PacketCodec] for [StaffItemComponent]. + */ + @JvmField + val PACKET_CODEC: PacketCodec = PacketCodec.tuple( + ItemStack.PACKET_CODEC, StaffItemComponent::item, ::StaffItemComponent + ) + } +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/InteractionHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/InteractionHandler.kt index 1c65a869b..9cd65e145 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/InteractionHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/InteractionHandler.kt @@ -22,21 +22,20 @@ import dev.architectury.event.EventResult import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.minecraft.entity.player.PlayerEntity -import net.minecraft.item.ItemStack import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction import opekope2.avm_staff.api.staffsTag import opekope2.avm_staff.internal.networking.c2s.play.AttackC2SPacket -import opekope2.avm_staff.util.handlerOfItem import opekope2.avm_staff.util.itemInStaff +import opekope2.avm_staff.util.staffHandler fun attackBlock(player: PlayerEntity, hand: Hand, target: BlockPos, direction: Direction): EventResult { val staffStack = player.getStackInHand(hand) if (!staffStack.isIn(staffsTag)) return EventResult.pass() val itemInStaff = staffStack.itemInStaff ?: return EventResult.pass() - val staffHandler = itemInStaff.handlerOfItem ?: return EventResult.pass() + val staffHandler = itemInStaff.staffHandler ?: return EventResult.pass() val result = staffHandler.attackBlock(staffStack, player.entityWorld, player, target, direction, hand) return if (result.isFalse) EventResult.interruptTrue() // Force Fabric to send packet for Neo/Forge parity @@ -48,8 +47,8 @@ fun clientAttack(player: PlayerEntity, hand: Hand) { val staffStack = player.getStackInHand(hand) if (!staffStack.isIn(staffsTag)) return - val itemInStaff: ItemStack = staffStack.itemInStaff ?: return - val staffHandler = itemInStaff.handlerOfItem ?: return + val itemInStaff = staffStack.itemInStaff ?: return + val staffHandler = itemInStaff.staffHandler ?: return staffHandler.attack(staffStack, player.entityWorld, player, hand) AttackC2SPacket(hand).send() diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt index 7b94c0686..d50c30634 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt @@ -26,20 +26,17 @@ import opekope2.avm_staff.api.staffsTag import opekope2.avm_staff.internal.networking.c2s.play.AddItemToStaffC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.AttackC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.RemoveItemFromStaffC2SPacket -import opekope2.avm_staff.util.handlerOfItem -import opekope2.avm_staff.util.hasHandlerOfItem -import opekope2.avm_staff.util.isItemInStaff -import opekope2.avm_staff.util.itemInStaff +import opekope2.avm_staff.util.* @Suppress("UNUSED_PARAMETER") fun addBlockToStaff(packet: AddItemToStaffC2SPacket, context: PacketContext) { val player = context.player - val (staffStack, itemStack) = findStaffAndItemStack(player) ?: return + val (staffStack, itemStackToAdd) = findStaffAndItemStack(player) ?: return - if (itemStack.isEmpty) return - if (!itemStack.hasHandlerOfItem) return + if (itemStackToAdd.isEmpty) return + if (!itemStackToAdd.item.hasStaffHandler) return if (staffStack.isItemInStaff) return - staffStack.itemInStaff = itemStack + staffStack.itemStackInStaff = itemStackToAdd.split(1) } @Suppress("UNUSED_PARAMETER") @@ -50,11 +47,11 @@ fun removeBlockFromStaff(packet: RemoveItemFromStaffC2SPacket, context: PacketCo val (staffStack, itemSlot) = findStaffStackAndItemSlot(player) ?: return val inventory = player.inventory val itemStack = inventory.getStack(itemSlot) - val staffItem = staffStack.itemInStaff ?: return + val staffItem = staffStack.mutableItemStackInStaff ?: return if (itemStack.canAccept(staffItem, inventory.maxCountPerStack)) { inventory.insertStack(itemSlot, staffItem) - staffStack.itemInStaff = null + staffStack.itemStackInStaff = null } } @@ -64,8 +61,8 @@ fun attack(packet: AttackC2SPacket, context: PacketContext) { if (!staffStack.isIn(staffsTag)) return - val itemInStaff: ItemStack = staffStack.itemInStaff ?: return - val staffHandler = itemInStaff.handlerOfItem ?: return + val itemInStaff = staffStack.itemInStaff ?: return + val staffHandler = itemInStaff.staffHandler ?: return staffHandler.attack(staffStack, player.entityWorld, player, packet.hand) } 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 d8f54b9a7..99da4479d 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 @@ -35,7 +35,7 @@ import net.minecraft.world.WorldEvents import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.equipTime -import opekope2.avm_staff.util.itemInStaff +import opekope2.avm_staff.util.itemStackInStaff import java.util.* class AnvilHandler(private val damagedStackFactory: () -> ItemStack?) : StaffHandler() { @@ -51,7 +51,7 @@ class AnvilHandler(private val damagedStackFactory: () -> ItemStack?) : StaffHan var broke = false if (attacker is PlayerEntity && !attacker.abilities.creativeMode && attacker.random.nextFloat() < 0.12F) { val damagedStack = damagedStackFactory() - staffStack.itemInStaff = damagedStack + staffStack.itemStackInStaff = damagedStack broke = damagedStack == null } 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 eaba88e13..664074cbd 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 @@ -44,6 +44,7 @@ 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.rocketModeComponentType import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.* @@ -60,7 +61,9 @@ class CampfireHandler( user: PlayerEntity, hand: Hand ): TypedActionResult { - staffStack.getOrCreateNbt().putBoolean(ROCKET_MODE_KEY, user.isSneaking && !user.isOnGround) + if (user.isSneaking && !user.isOnGround) { + staffStack[rocketModeComponentType.get()] = UnitComponent + } user.setCurrentHand(hand) return TypedActionResult.consume(staffStack) @@ -101,7 +104,7 @@ class CampfireHandler( } } - if (staffStack.nbt?.getBoolean(ROCKET_MODE_KEY) == true) { + if (rocketModeComponentType.get() in staffStack) { user.addVelocity(forward * -properties.rocketThrust) user.velocityModified = true if (forward.y < 0.0) { @@ -143,7 +146,7 @@ class CampfireHandler( } override fun onStoppedUsing(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - staffStack.getOrCreateNbt().remove(ROCKET_MODE_KEY) + staffStack.remove(rocketModeComponentType.get()) } override fun finishUsing(staffStack: ItemStack, world: World, user: LivingEntity): ItemStack { @@ -248,8 +251,6 @@ class CampfireHandler( private const val FLAMETHROWER_CONE_RAYS = 16 private const val FLAMETHROWER_CONE_RAYS_TOTAL = FLAMETHROWER_CONE_RAYS * FLAMETHROWER_CONE_RAYS - private const val ROCKET_MODE_KEY = "RocketMode" - private val flameParticleCount: Int @Environment(EnvType.CLIENT) get() = when (MinecraftClient.getInstance().options.graphicsMode.value!!) { 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 983872fc4..73bb8a932 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 @@ -49,6 +49,7 @@ import net.minecraft.util.Hand import net.minecraft.util.TypedActionResult import net.minecraft.util.math.Box import net.minecraft.world.World +import opekope2.avm_staff.api.furnaceLitComponentType import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer import opekope2.avm_staff.api.staff.StaffHandler @@ -69,7 +70,7 @@ class FurnaceHandler( ): TypedActionResult { if (world.isClient) { // Visual only - staffStack.orCreateNbt.putBoolean(LIT_KEY, true) + staffStack[furnaceLitComponentType.get()] = UnitComponent } else { user.activeItemTempData = BurnTimeTempData(0) } @@ -140,7 +141,7 @@ class FurnaceHandler( override fun onStoppedUsing(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { if (world.isClient) { // Visual only - staffStack.nbt?.remove(LIT_KEY) + staffStack.remove(furnaceLitComponentType.get()) } else { user.activeItemTempData = null } @@ -195,7 +196,7 @@ class FurnaceHandler( overlay: Int ) { val renderer = - if (staffStack.nbt?.getBoolean(LIT_KEY) == true) litRenderer + if (furnaceLitComponentType.get() in staffStack) litRenderer else unlitRenderer renderer.renderItemInStaff(staffStack, mode, matrices, vertexConsumers, light, overlay) @@ -218,7 +219,6 @@ class FurnaceHandler( } companion object { - private const val LIT_KEY = "Lit" private val SMELTING_VOLUME = Box(-0.5, -0.5, -0.5, 0.5, 0.5, 0.5).contract(0.25 / 2) private val ATTRIBUTE_MODIFIERS = ImmutableMultimap.of( EntityAttributes.GENERIC_ATTACK_DAMAGE, 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 c7f8a0793..b767e68af 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt @@ -21,74 +21,81 @@ package opekope2.avm_staff.util import net.minecraft.entity.Entity +import net.minecraft.item.Item import net.minecraft.item.ItemStack -import net.minecraft.nbt.NbtCompound import net.minecraft.registry.Registries import net.minecraft.util.hit.HitResult import net.minecraft.util.math.Vec3d import net.minecraft.world.RaycastContext import opekope2.avm_staff.api.staff.StaffHandler - -/** - * NBT key - */ -private const val ITEM_KEY = "Item" +import opekope2.avm_staff.api.staff.StaffItemComponent +import opekope2.avm_staff.api.staffItemComponentType /** * Checks if an item is added the given staff item stack. */ val ItemStack.isItemInStaff: Boolean @JvmName("isItemInStaff") - get() = nbt?.contains(ITEM_KEY) ?: false + get() = staffItemComponentType.get() in this /** - * Gets or sets the item added to the given staff item stack. + * Gets the item inserted into the given staff item stack. */ -var ItemStack.itemInStaff: ItemStack? - get() { - return if (!isItemInStaff) null - else ItemStack.fromNbt(nbt?.getCompound(ITEM_KEY) ?: return null) - } +val ItemStack.itemInStaff: Item? + get() = getOrDefault(staffItemComponentType.get(), null)?.item?.item + +/** + * Gets or sets the item stack inserted into the given staff item stack. + * The value returned MUST NOT be modified in any way, use [mutableItemStackInStaff] instead. + * The value passed in MUST NOT be stored elsewhere, pass in a copy of it instead. + * + * @see mutableItemStackInStaff + */ +var ItemStack.itemStackInStaff: ItemStack? + get() = getOrDefault(staffItemComponentType.get(), null)?.item set(value) { - if (value == null) { - removeSubNbt(ITEM_KEY) + if (value == null || value.isEmpty) { + remove(staffItemComponentType.get()) return } - val staffItemStack = value.split(1) - val nbt = getOrCreateNbt() - nbt.put(ITEM_KEY, NbtCompound().also(staffItemStack::writeNbt)) + this[staffItemComponentType.get()] = StaffItemComponent(value.copy()) } /** - * Returns if the given staff item stack has a registered handler. - * This item stack is not the staff item stack, but the one can be inserted into the staff. + * Gets a copy of the item stack inserted into the given staff item stack. The value returned can be freely modified. + * + * @see itemStackInStaff + */ +val ItemStack.mutableItemStackInStaff: ItemStack? + get() = itemStackInStaff?.copy() + +/** + * Returns if the given item has a registered handler when inserted into a staff. */ -val ItemStack.hasHandlerOfItem: Boolean - @JvmName("hasHandlerOfStaff") +val Item.hasStaffHandler: Boolean + @JvmName("hasStaffHandler") get() { - val itemId = Registries.ITEM.getId(item) + val itemId = Registries.ITEM.getId(this) return itemId in StaffHandler } /** - * Returns the handler of the given item stack, if available. - * This item stack is not the staff item stack, but the one can be inserted into the staff. + * Returns the registered staff handler of the given item if available. */ -val ItemStack.handlerOfItem: StaffHandler? +val Item.staffHandler: StaffHandler? get() { - val itemId = Registries.ITEM.getId(item) + val itemId = Registries.ITEM.getId(this) return StaffHandler[itemId] } /** - * Returns the handler of the given item stack, if available, a dummy one if not, and the empty staff handler if the - * item stack is `null`. - * This item stack is not the staff item stack, but the one can be inserted into the staff. + * Returns the registered staff handler of the given item stack if available, a dummy one if not, and the empty staff + * handler if the item is `null`. */ -val ItemStack?.handlerOfItemOrFallback: StaffHandler +val Item?.staffHandlerOrFallback: StaffHandler get() = if (this == null) StaffHandler.EmptyStaffHandler - else handlerOfItem ?: StaffHandler.FallbackStaffHandler + else staffHandler ?: StaffHandler.FallbackStaffHandler 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/kotlin/opekope2/avm_staff/util/UnitComponent.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/UnitComponent.kt new file mode 100644 index 000000000..df04d9ca3 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/UnitComponent.kt @@ -0,0 +1,26 @@ +/* + * 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.component.DataComponentType + +/** + * [Unit], but can be used as a [DataComponentType]. + */ +data object UnitComponent From e8f596931907f3e1e1da42ea8fa87e314d6a1b8b Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 21:23:14 +0200 Subject: [PATCH 068/128] Update attribute modifiers to 1.20.6 --- .../internal/fabric/item/FabricStaffItem.kt | 12 +-- .../neoforge/item/NeoForgeStaffItem.kt | 13 +-- .../avm_staff/api/staff/StaffHandler.kt | 26 ++---- .../internal/staff_handler/AnvilHandler.kt | 80 +++++++++++-------- .../staff_handler/BellBlockHandler.kt | 25 ++---- .../internal/staff_handler/FurnaceHandler.kt | 25 ++---- .../staff_handler/MagmaBlockHandler.kt | 25 ++---- .../internal/staff_handler/WoolHandler.kt | 25 ++---- .../opekope2/avm_staff/util/AttributeUtil.kt | 4 +- 9 files changed, 90 insertions(+), 145 deletions(-) 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 3aeec566d..f96a09bbf 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,14 +18,11 @@ package opekope2.avm_staff.internal.fabric.item -import com.google.common.collect.Multimap import net.fabricmc.api.EnvType import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry import net.fabricmc.fabric.api.item.v1.FabricItem import net.fabricmc.loader.api.FabricLoader -import net.minecraft.entity.EquipmentSlot -import net.minecraft.entity.attribute.EntityAttribute -import net.minecraft.entity.attribute.EntityAttributeModifier +import net.minecraft.component.type.AttributeModifiersComponent import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.Item import net.minecraft.item.ItemStack @@ -55,10 +52,7 @@ class FabricStaffItem(settings: Item.Settings) : StaffItem(settings), FabricItem else oldHandler.allowNbtUpdateAnimation(oldStack, newStack, player, hand) } - override fun getAttributeModifiers( - stack: ItemStack, - slot: EquipmentSlot - ): Multimap { - return stack.itemInStaff.handlerOfItemOrFallback.getAttributeModifiers(stack, slot) + override fun getAttributeModifiers(stack: ItemStack): AttributeModifiersComponent { + return stack.itemInStaff.staffHandlerOrFallback.getAttributeModifiers(stack) } } 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 ac9574aa2..baa56c908 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,17 +18,14 @@ package opekope2.avm_staff.internal.neoforge.item -import com.google.common.collect.Multimap 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 import net.minecraft.client.util.math.MatrixStack +import net.minecraft.component.type.AttributeModifiersComponent import net.minecraft.entity.Entity -import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.LivingEntity -import net.minecraft.entity.attribute.EntityAttribute -import net.minecraft.entity.attribute.EntityAttributeModifier import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.Item import net.minecraft.item.ItemStack @@ -38,14 +35,12 @@ 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.itemInStaff +import opekope2.avm_staff.util.staffHandlerOrFallback import java.util.function.Consumer class NeoForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IItemExtension { - override fun getAttributeModifiers( - slot: EquipmentSlot, - stack: ItemStack - ): Multimap { - return stack.itemInStaff.handlerOfItemOrFallback.getAttributeModifiers(stack, slot) + override fun getAttributeModifiers(stack: ItemStack): AttributeModifiersComponent { + return stack.itemInStaff.staffHandlerOrFallback.getAttributeModifiers(stack) } @Suppress("RemoveExplicitSuperQualifier") // Required because StaffItem apparently also has canDisableShield 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 793792556..d4c021786 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 @@ -18,15 +18,12 @@ package opekope2.avm_staff.api.staff -import com.google.common.collect.ImmutableMultimap -import com.google.common.collect.Multimap import dev.architectury.event.EventResult import net.minecraft.advancement.criterion.Criteria +import net.minecraft.component.type.AttributeModifierSlot +import net.minecraft.component.type.AttributeModifiersComponent import net.minecraft.entity.Entity -import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.LivingEntity -import net.minecraft.entity.attribute.EntityAttribute -import net.minecraft.entity.attribute.EntityAttributeModifier import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.Item @@ -336,14 +333,9 @@ abstract class StaffHandler { * Gets the attribute modifiers (damage, attack speed, etc.) of the staff when held. * * @param staffStack The staff item stack (not the item in the staff) - * @param slot The slot the staff is equipped in */ - open fun getAttributeModifiers( - staffStack: ItemStack, - slot: EquipmentSlot - ): Multimap { - return if (slot == EquipmentSlot.MAINHAND) ATTRIBUTE_MODIFIERS - else ImmutableMultimap.of() + open fun getAttributeModifiers(staffStack: ItemStack): AttributeModifiersComponent { + return ATTRIBUTE_MODIFIERS } object EmptyStaffHandler : StaffHandler() @@ -351,12 +343,10 @@ abstract class StaffHandler { object FallbackStaffHandler : StaffHandler() companion object { - private val ATTRIBUTE_MODIFIERS = ImmutableMultimap.of( - EntityAttributes.GENERIC_ATTACK_DAMAGE, - attackDamage(4.0), - EntityAttributes.GENERIC_ATTACK_SPEED, - attackSpeed(2.0) - ) + private val ATTRIBUTE_MODIFIERS = AttributeModifiersComponent.builder() + .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(4.0), AttributeModifierSlot.MAINHAND) + .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(2.0), AttributeModifierSlot.MAINHAND) + .build() private val staffItemsHandlers = mutableMapOf() 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 99da4479d..93112ace1 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 @@ -18,13 +18,11 @@ package opekope2.avm_staff.internal.staff_handler -import com.google.common.collect.ImmutableMultimap -import com.google.common.collect.Multimap import dev.architectury.event.EventResult +import net.minecraft.component.type.AttributeModifierSlot +import net.minecraft.component.type.AttributeModifiersComponent import net.minecraft.entity.Entity -import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.LivingEntity -import net.minecraft.entity.attribute.EntityAttribute import net.minecraft.entity.attribute.EntityAttributeModifier import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.entity.player.PlayerEntity @@ -67,40 +65,52 @@ class AnvilHandler(private val damagedStackFactory: () -> ItemStack?) : StaffHan override fun disablesShield() = true - override fun getAttributeModifiers( - staffStack: ItemStack, - slot: EquipmentSlot - ): Multimap { - return when (slot) { - EquipmentSlot.MAINHAND -> MAIN_HAND_ATTRIBUTE_MODIFIERS - EquipmentSlot.OFFHAND -> OFF_HAND_ATTRIBUTE_MODIFIERS - else -> super.getAttributeModifiers(staffStack, slot) - } - } + override fun getAttributeModifiers(staffStack: ItemStack): AttributeModifiersComponent = ATTRIBUTE_MODIFIERS private companion object { - private val MAIN_HAND_ATTRIBUTE_MODIFIERS = ImmutableMultimap.of( - EntityAttributes.GENERIC_ATTACK_DAMAGE, - attackDamage(40.0), - EntityAttributes.GENERIC_ATTACK_SPEED, - equipTime(4.0), - EntityAttributes.GENERIC_MOVEMENT_SPEED, - EntityAttributeModifier( - UUID.fromString("c0374b4f-d600-4b6a-9984-3ee35d37750d"), - "Weapon modifier", - -1.0, - EntityAttributeModifier.Operation.MULTIPLY_TOTAL + private val ATTRIBUTE_MODIFIERS = AttributeModifiersComponent.builder() + .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(40.0), AttributeModifierSlot.MAINHAND) + .add(EntityAttributes.GENERIC_ATTACK_SPEED, equipTime(4.0), AttributeModifierSlot.MAINHAND) + .add( + EntityAttributes.GENERIC_MOVEMENT_SPEED, + EntityAttributeModifier( + UUID.fromString("c0374b4f-d600-4b6a-9984-3ee35d37750d"), + "Weapon modifier", + -1.0, + EntityAttributeModifier.Operation.ADD_MULTIPLIED_TOTAL + ), + AttributeModifierSlot.MAINHAND ) - ) - - private val OFF_HAND_ATTRIBUTE_MODIFIERS = ImmutableMultimap.of( - EntityAttributes.GENERIC_MOVEMENT_SPEED, - EntityAttributeModifier( - UUID.fromString("c0374b4f-d600-4b6a-9984-3ee35d37750e"), - "Weapon modifier", - -1.0, - EntityAttributeModifier.Operation.MULTIPLY_TOTAL + .add( + EntityAttributes.GENERIC_MOVEMENT_SPEED, + EntityAttributeModifier( + UUID.fromString("c0374b4f-d600-4b6a-9984-3ee35d37750e"), + "Weapon modifier", + -1.0, + EntityAttributeModifier.Operation.ADD_MULTIPLIED_TOTAL + ), + AttributeModifierSlot.OFFHAND ) - ) + .add( + EntityAttributes.GENERIC_JUMP_STRENGTH, + EntityAttributeModifier( + UUID.fromString("cbaf4a1a-e200-427c-b423-37733a264173"), + "Weapon modifier", + -1.0, + EntityAttributeModifier.Operation.ADD_MULTIPLIED_TOTAL + ), + AttributeModifierSlot.MAINHAND + ) + .add( + EntityAttributes.GENERIC_JUMP_STRENGTH, + EntityAttributeModifier( + UUID.fromString("cbaf4a1a-e200-427c-b423-37733a264174"), + "Weapon modifier", + -1.0, + EntityAttributeModifier.Operation.ADD_MULTIPLIED_TOTAL + ), + AttributeModifierSlot.OFFHAND + ) + .build() } } 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 6183d2e33..9cc538315 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 @@ -18,8 +18,6 @@ package opekope2.avm_staff.internal.staff_handler -import com.google.common.collect.ImmutableMultimap -import com.google.common.collect.Multimap import dev.architectury.event.EventResult import net.fabricmc.api.EnvType import net.fabricmc.api.Environment @@ -28,11 +26,10 @@ 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.component.type.AttributeModifiersComponent import net.minecraft.entity.Entity -import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.LivingEntity -import net.minecraft.entity.attribute.EntityAttribute -import net.minecraft.entity.attribute.EntityAttributeModifier import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack @@ -78,13 +75,7 @@ class BellBlockHandler : StaffHandler() { return EventResult.pass() } - override fun getAttributeModifiers( - staffStack: ItemStack, - slot: EquipmentSlot - ): Multimap { - return if (slot == EquipmentSlot.MAINHAND) ATTRIBUTE_MODIFIERS - else super.getAttributeModifiers(staffStack, slot) - } + override fun getAttributeModifiers(staffStack: ItemStack): AttributeModifiersComponent = ATTRIBUTE_MODIFIERS @Environment(EnvType.CLIENT) class BellStaffItemRenderer : IStaffItemRenderer { @@ -118,11 +109,9 @@ class BellBlockHandler : StaffHandler() { } companion object { - private val ATTRIBUTE_MODIFIERS = ImmutableMultimap.of( - EntityAttributes.GENERIC_ATTACK_DAMAGE, - attackDamage(8.0), - EntityAttributes.GENERIC_ATTACK_SPEED, - attackSpeed(1.5) - ) + private val ATTRIBUTE_MODIFIERS = AttributeModifiersComponent.builder() + .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(8.0), AttributeModifierSlot.MAINHAND) + .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(1.5), AttributeModifierSlot.MAINHAND) + .build() } } 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 73bb8a932..2cb770b55 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 @@ -18,8 +18,6 @@ package opekope2.avm_staff.internal.staff_handler -import com.google.common.collect.ImmutableMultimap -import com.google.common.collect.Multimap import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.minecraft.block.AbstractFurnaceBlock @@ -30,11 +28,10 @@ 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 -import net.minecraft.entity.EquipmentSlot +import net.minecraft.component.type.AttributeModifierSlot +import net.minecraft.component.type.AttributeModifiersComponent import net.minecraft.entity.ItemEntity import net.minecraft.entity.LivingEntity -import net.minecraft.entity.attribute.EntityAttribute -import net.minecraft.entity.attribute.EntityAttributeModifier import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.entity.player.PlayerEntity import net.minecraft.inventory.SingleStackInventory @@ -169,13 +166,7 @@ class FurnaceHandler( return selectedSlotChanged } - override fun getAttributeModifiers( - staffStack: ItemStack, - slot: EquipmentSlot - ): Multimap { - return if (slot == EquipmentSlot.MAINHAND) ATTRIBUTE_MODIFIERS - else super.getAttributeModifiers(staffStack, slot) - } + override fun getAttributeModifiers(staffStack: ItemStack): AttributeModifiersComponent = ATTRIBUTE_MODIFIERS @Environment(EnvType.CLIENT) class FurnaceStaffItemRenderer(unlitState: BlockState, litState: BlockState) : IStaffItemRenderer { @@ -220,11 +211,9 @@ class FurnaceHandler( companion object { private val SMELTING_VOLUME = Box(-0.5, -0.5, -0.5, 0.5, 0.5, 0.5).contract(0.25 / 2) - private val ATTRIBUTE_MODIFIERS = ImmutableMultimap.of( - EntityAttributes.GENERIC_ATTACK_DAMAGE, - attackDamage(5.0), - EntityAttributes.GENERIC_ATTACK_SPEED, - attackSpeed(2.0) - ) + private val ATTRIBUTE_MODIFIERS = AttributeModifiersComponent.builder() + .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(5.0), AttributeModifierSlot.MAINHAND) + .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(2.0), AttributeModifierSlot.MAINHAND) + .build() } } 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 dee30abcd..25b677e35 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 @@ -18,14 +18,11 @@ package opekope2.avm_staff.internal.staff_handler -import com.google.common.collect.ImmutableMultimap -import com.google.common.collect.Multimap import dev.architectury.event.EventResult +import net.minecraft.component.type.AttributeModifierSlot +import net.minecraft.component.type.AttributeModifiersComponent import net.minecraft.entity.Entity -import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.LivingEntity -import net.minecraft.entity.attribute.EntityAttribute -import net.minecraft.entity.attribute.EntityAttributeModifier import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.entity.player.PlayerEntity import net.minecraft.entity.projectile.SmallFireballEntity @@ -90,20 +87,12 @@ class MagmaBlockHandler : StaffHandler() { }) } - override fun getAttributeModifiers( - staffStack: ItemStack, - slot: EquipmentSlot - ): Multimap { - return if (slot == EquipmentSlot.MAINHAND) ATTRIBUTE_MODIFIERS - else super.getAttributeModifiers(staffStack, slot) - } + override fun getAttributeModifiers(staffStack: ItemStack): AttributeModifiersComponent = ATTRIBUTE_MODIFIERS private companion object { - private val ATTRIBUTE_MODIFIERS = ImmutableMultimap.of( - EntityAttributes.GENERIC_ATTACK_DAMAGE, - attackDamage(5.0), - EntityAttributes.GENERIC_ATTACK_SPEED, - attackSpeed(2.0) - ) + private val ATTRIBUTE_MODIFIERS = AttributeModifiersComponent.builder() + .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(5.0), AttributeModifierSlot.MAINHAND) + .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(2.0), AttributeModifierSlot.MAINHAND) + .build() } } 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 359d93d44..58ef803d2 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 @@ -18,15 +18,12 @@ package opekope2.avm_staff.internal.staff_handler -import com.google.common.collect.ImmutableMultimap -import com.google.common.collect.Multimap import net.minecraft.block.Block import net.minecraft.client.MinecraftClient import net.minecraft.client.network.ClientPlayerEntity -import net.minecraft.entity.EquipmentSlot +import net.minecraft.component.type.AttributeModifierSlot +import net.minecraft.component.type.AttributeModifiersComponent import net.minecraft.entity.LivingEntity -import net.minecraft.entity.attribute.EntityAttribute -import net.minecraft.entity.attribute.EntityAttributeModifier import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemPlacementContext @@ -93,13 +90,7 @@ class WoolHandler(woolBlock: Block, carpetBlock: Block) : StaffHandler() { return ActionResult.SUCCESS } - override fun getAttributeModifiers( - staffStack: ItemStack, - slot: EquipmentSlot - ): Multimap { - return if (slot == EquipmentSlot.MAINHAND) ATTRIBUTE_MODIFIERS - else super.getAttributeModifiers(staffStack, slot) - } + override fun getAttributeModifiers(staffStack: ItemStack): AttributeModifiersComponent = ATTRIBUTE_MODIFIERS private class WoolPlacementContext( world: World, @@ -110,11 +101,9 @@ class WoolHandler(woolBlock: Block, carpetBlock: Block) : StaffHandler() { ) : ItemPlacementContext(world, playerEntity, hand, itemStack, blockHitResult) private companion object { - private val ATTRIBUTE_MODIFIERS = ImmutableMultimap.of( - EntityAttributes.GENERIC_ATTACK_DAMAGE, - attackDamage(2.0), - EntityAttributes.GENERIC_ATTACK_SPEED, - attackSpeed(2.0) - ) + private val ATTRIBUTE_MODIFIERS = AttributeModifiersComponent.builder() + .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(2.0), AttributeModifierSlot.MAINHAND) + .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(2.0), AttributeModifierSlot.MAINHAND) + .build() } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/AttributeUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/AttributeUtil.kt index 53aaea462..65437a2c0 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/AttributeUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/AttributeUtil.kt @@ -36,7 +36,7 @@ fun attackDamage(totalAttackDamage: Double): EntityAttributeModifier = EntityAtt Item.ATTACK_DAMAGE_MODIFIER_ID, "Weapon modifier", totalAttackDamage - PLAYER_BASE_ATTACK_DAMAGE, - EntityAttributeModifier.Operation.ADDITION + EntityAttributeModifier.Operation.ADD_VALUE ) /** @@ -49,7 +49,7 @@ fun attackSpeed(totalAttackSpeed: Double): EntityAttributeModifier = EntityAttri Item.ATTACK_SPEED_MODIFIER_ID, "Weapon modifier", totalAttackSpeed - PLAYER_BASE_ATTACK_SPEED, - EntityAttributeModifier.Operation.ADDITION + EntityAttributeModifier.Operation.ADD_VALUE ) /** From 58c5a36da6bd3fd7519a8585f71e76edbcefdc3d Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 21:37:24 +0200 Subject: [PATCH 069/128] Update networking to 1.20.6 --- .../avm_staff/internal/Initializer.kt | 4 +-- .../event_handler/InteractionHandler.kt | 2 +- .../event_handler/KeyBindingHandler.kt | 4 +-- .../internal/event_handler/NetworkHandler.kt | 4 +-- .../internal/networking/IC2SPacket.kt | 28 +++++++++++++++++++ .../avm_staff/internal/networking/IPacket.kt | 3 +- .../internal/networking/PacketRegistrar.kt | 22 +++++++-------- .../c2s/play/AddItemToStaffC2SPacket.kt | 20 ++++++------- .../networking/c2s/play/AttackC2SPacket.kt | 17 +++++------ .../c2s/play/RemoveItemFromStaffC2SPacket.kt | 20 ++++++------- 10 files changed, 73 insertions(+), 51 deletions(-) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/IC2SPacket.kt 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 96ac3039d..05c07eeff 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -46,8 +46,8 @@ fun registerContent() { } fun initializeNetworking() { - AddItemToStaffC2SPacket.registerHandler(::addBlockToStaff) - RemoveItemFromStaffC2SPacket.registerHandler(::removeBlockFromStaff) + AddItemToStaffC2SPacket.registerHandler(::addItemToStaff) + RemoveItemFromStaffC2SPacket.registerHandler(::removeItemFromStaff) AttackC2SPacket.registerHandler(::attack) } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/InteractionHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/InteractionHandler.kt index 9cd65e145..58de2a432 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/InteractionHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/InteractionHandler.kt @@ -51,5 +51,5 @@ fun clientAttack(player: PlayerEntity, hand: Hand) { val staffHandler = itemInStaff.staffHandler ?: return staffHandler.attack(staffStack, player.entityWorld, player, hand) - AttackC2SPacket(hand).send() + AttackC2SPacket(hand).sendToServer() } 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 415a9cd2c..8b58b7494 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 @@ -45,8 +45,8 @@ fun handleKeyBindings(client: MinecraftClient) { val player = client.player ?: return if (player.mainHandStack.isItemInStaff || player.offHandStack.isItemInStaff) { - RemoveItemFromStaffC2SPacket().send() + RemoveItemFromStaffC2SPacket().sendToServer() } else { - AddItemToStaffC2SPacket().send() + AddItemToStaffC2SPacket().sendToServer() } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt index d50c30634..f92851ef0 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt @@ -29,7 +29,7 @@ import opekope2.avm_staff.internal.networking.c2s.play.RemoveItemFromStaffC2SPac import opekope2.avm_staff.util.* @Suppress("UNUSED_PARAMETER") -fun addBlockToStaff(packet: AddItemToStaffC2SPacket, context: PacketContext) { +fun addItemToStaff(packet: AddItemToStaffC2SPacket, context: PacketContext) { val player = context.player val (staffStack, itemStackToAdd) = findStaffAndItemStack(player) ?: return @@ -40,7 +40,7 @@ fun addBlockToStaff(packet: AddItemToStaffC2SPacket, context: PacketContext) { } @Suppress("UNUSED_PARAMETER") -fun removeBlockFromStaff(packet: RemoveItemFromStaffC2SPacket, context: PacketContext) { +fun removeItemFromStaff(packet: RemoveItemFromStaffC2SPacket, context: PacketContext) { val player = context.player if (player.isUsingItem) return diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/IC2SPacket.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/IC2SPacket.kt new file mode 100644 index 000000000..5b485dd02 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/IC2SPacket.kt @@ -0,0 +1,28 @@ +/* + * 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.networking + +import dev.architectury.networking.NetworkManager +import net.fabricmc.api.EnvType +import net.fabricmc.api.Environment + +interface IC2SPacket : IPacket { + @Environment(EnvType.CLIENT) + fun sendToServer() = NetworkManager.sendToServer(this) +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/IPacket.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/IPacket.kt index 2a301d6de..49c2bf04e 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/IPacket.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/IPacket.kt @@ -19,7 +19,8 @@ package opekope2.avm_staff.internal.networking import net.minecraft.network.PacketByteBuf +import net.minecraft.network.packet.CustomPayload -interface IPacket { +interface IPacket : CustomPayload { fun write(buf: PacketByteBuf) } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/PacketRegistrar.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/PacketRegistrar.kt index 797304214..4bb72ec7d 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/PacketRegistrar.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/PacketRegistrar.kt @@ -18,21 +18,21 @@ package opekope2.avm_staff.internal.networking -import dev.architectury.networking.NetworkChannel import dev.architectury.networking.NetworkManager import net.minecraft.network.PacketByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.packet.CustomPayload +import net.minecraft.util.Identifier abstract class PacketRegistrar( - val channel: NetworkChannel, - private val packetClass: Class, - private val packetConstructor: (PacketByteBuf) -> TPacket + private val side: NetworkManager.Side, + id: Identifier, + packetConstructor: (PacketByteBuf) -> TPacket ) { - fun registerHandler(handler: (TPacket, NetworkManager.PacketContext) -> Unit) { - channel.register(packetClass, IPacket::write, packetConstructor) { packet, contextSupplier -> - val context = contextSupplier.get() - context.queue { - handler(packet, context) - } - } + protected val payloadId = CustomPayload.Id(id) + private val codec = PacketCodec.of(IPacket::write, packetConstructor) + + fun registerHandler(receiver: NetworkManager.NetworkReceiver) { + NetworkManager.registerReceiver(side, payloadId, codec, receiver) } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/AddItemToStaffC2SPacket.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/AddItemToStaffC2SPacket.kt index c02a75621..634b170dc 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/AddItemToStaffC2SPacket.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/AddItemToStaffC2SPacket.kt @@ -18,27 +18,25 @@ package opekope2.avm_staff.internal.networking.c2s.play -import dev.architectury.networking.NetworkChannel -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment +import dev.architectury.networking.NetworkManager import net.minecraft.network.PacketByteBuf import net.minecraft.util.Identifier -import opekope2.avm_staff.internal.networking.IPacket +import opekope2.avm_staff.internal.networking.IC2SPacket import opekope2.avm_staff.internal.networking.PacketRegistrar import opekope2.avm_staff.util.MOD_ID -class AddItemToStaffC2SPacket() : IPacket { - constructor(@Suppress("UNUSED_PARAMETER") buf: PacketByteBuf) : this() +class AddItemToStaffC2SPacket() : IC2SPacket { + @Suppress("UNUSED_PARAMETER") + constructor(buf: PacketByteBuf) : this() + + override fun getId() = payloadId override fun write(buf: PacketByteBuf) { } - @Environment(EnvType.CLIENT) - fun send() = channel.sendToServer(this) - companion object : PacketRegistrar( - NetworkChannel.create(Identifier(MOD_ID, "add_item_to_staff")), - AddItemToStaffC2SPacket::class.java, + NetworkManager.c2s(), + Identifier(MOD_ID, "add_item"), ::AddItemToStaffC2SPacket ) } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/AttackC2SPacket.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/AttackC2SPacket.kt index 728da0e00..9e84520e3 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/AttackC2SPacket.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/AttackC2SPacket.kt @@ -18,29 +18,26 @@ package opekope2.avm_staff.internal.networking.c2s.play -import dev.architectury.networking.NetworkChannel -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment +import dev.architectury.networking.NetworkManager import net.minecraft.network.PacketByteBuf import net.minecraft.util.Hand import net.minecraft.util.Identifier -import opekope2.avm_staff.internal.networking.IPacket +import opekope2.avm_staff.internal.networking.IC2SPacket import opekope2.avm_staff.internal.networking.PacketRegistrar import opekope2.avm_staff.util.MOD_ID -class AttackC2SPacket(val hand: Hand) : IPacket { +class AttackC2SPacket(val hand: Hand) : IC2SPacket { constructor(buf: PacketByteBuf) : this(buf.readEnumConstant(Hand::class.java)) + override fun getId() = payloadId + override fun write(buf: PacketByteBuf) { buf.writeEnumConstant(hand) } - @Environment(EnvType.CLIENT) - fun send() = channel.sendToServer(this) - companion object : PacketRegistrar( - NetworkChannel.create(Identifier(MOD_ID, "attack")), - AttackC2SPacket::class.java, + NetworkManager.c2s(), + Identifier(MOD_ID, "attack"), ::AttackC2SPacket ) } 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 3b226c403..7fc9276bf 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 @@ -18,27 +18,25 @@ package opekope2.avm_staff.internal.networking.c2s.play -import dev.architectury.networking.NetworkChannel -import net.fabricmc.api.EnvType -import net.fabricmc.api.Environment +import dev.architectury.networking.NetworkManager import net.minecraft.network.PacketByteBuf import net.minecraft.util.Identifier -import opekope2.avm_staff.internal.networking.IPacket +import opekope2.avm_staff.internal.networking.IC2SPacket import opekope2.avm_staff.internal.networking.PacketRegistrar import opekope2.avm_staff.util.MOD_ID -class RemoveItemFromStaffC2SPacket() : IPacket { - constructor(@Suppress("UNUSED_PARAMETER") buf: PacketByteBuf) : this() +class RemoveItemFromStaffC2SPacket() : IC2SPacket { + @Suppress("UNUSED_PARAMETER") + constructor(buf: PacketByteBuf) : this() + + override fun getId() = payloadId override fun write(buf: PacketByteBuf) { } - @Environment(EnvType.CLIENT) - fun send() = channel.sendToServer(this) - companion object : PacketRegistrar( - NetworkChannel.create(Identifier(MOD_ID, "remove_item_from_staff")), - RemoveItemFromStaffC2SPacket::class.java, + NetworkManager.c2s(), + Identifier(MOD_ID, "remove_item"), ::RemoveItemFromStaffC2SPacket ) } From 0d1ec4650d2409252eface271ca62129d1c74a55 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 21:39:39 +0200 Subject: [PATCH 070/128] Update loot table modifications to 1.20.6 --- .../kotlin/opekope2/avm_staff/internal/Initializer.kt | 9 ++++----- 1 file changed, 4 insertions(+), 5 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 05c07eeff..3eefd89d9 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -26,9 +26,10 @@ import dev.architectury.registry.client.particle.ParticleProviderRegistry import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.minecraft.item.SmithingTemplateItem -import net.minecraft.loot.LootManager import net.minecraft.loot.LootPool +import net.minecraft.loot.LootTable import net.minecraft.loot.entry.ItemEntry +import net.minecraft.registry.RegistryKey import net.minecraft.util.Identifier import opekope2.avm_staff.api.crownOfKingOrangeItem import opekope2.avm_staff.api.flamethrowerParticleType @@ -53,14 +54,12 @@ fun initializeNetworking() { private val TREASURE_BASTION_CHEST_LOOT = Identifier("chests/bastion_treasure") -@Suppress("UNUSED_PARAMETER") fun modifyLootTables( - lootManager: LootManager?, - lootTableId: Identifier, + lootTable: RegistryKey, context: LootEvent.LootTableModificationContext, builtin: Boolean ) { - if (builtin && lootTableId == TREASURE_BASTION_CHEST_LOOT) { + if (builtin && lootTable.value == TREASURE_BASTION_CHEST_LOOT) { context.addPool(LootPool.builder().with(ItemEntry.builder(crownOfKingOrangeItem.get()))) } } From 754ce31c09b3a1e82cf7dc128e62fcbe0c1fecfa Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 21:40:27 +0200 Subject: [PATCH 071/128] Update particles to 1.20.6 --- .../opekope2/avm_staff/api/particle/FlamethrowerParticle.kt | 6 +++--- .../avm_staff/internal/staff_handler/CampfireHandler.kt | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) 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 0525cf955..3955dfb61 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 @@ -22,7 +22,7 @@ import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.minecraft.client.particle.* import net.minecraft.client.world.ClientWorld -import net.minecraft.particle.DefaultParticleType +import net.minecraft.particle.SimpleParticleType import net.minecraft.util.math.BlockPos import opekope2.avm_staff.api.flamethrowerParticleType import opekope2.avm_staff.api.soulFlamethrowerParticleType @@ -111,9 +111,9 @@ class FlamethrowerParticle( * @see soulFlamethrowerParticleType * @see ParticleManager.addParticle */ - class Factory(private val spriteProvider: SpriteProvider) : ParticleFactory { + class Factory(private val spriteProvider: SpriteProvider) : ParticleFactory { override fun createParticle( - parameters: DefaultParticleType, + parameters: SimpleParticleType, world: ClientWorld, x: Double, y: Double, 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 664074cbd..1da424520 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,7 +30,7 @@ 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.DefaultParticleType +import net.minecraft.particle.SimpleParticleType import net.minecraft.server.MinecraftServer import net.minecraft.state.property.Properties.LIT import net.minecraft.util.Hand @@ -49,7 +49,7 @@ import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.* class CampfireHandler( - private val particleEffectSupplier: RegistrySupplier, + private val particleEffectSupplier: RegistrySupplier, private val properties: Properties ) : StaffHandler() { override val maxUseTime: Int From 0f46ba14cf44c1f401a2548a462141d2cede7763 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 21:53:34 +0200 Subject: [PATCH 072/128] Update most other things to 1.20.6 --- .../main/kotlin/opekope2/avm_staff/api/item/CrownItem.kt | 3 ++- .../avm_staff/internal/event_handler/NetworkHandler.kt | 2 +- .../avm_staff/internal/staff_handler/FurnaceHandler.kt | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/CrownItem.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/CrownItem.kt index d110d7df7..1286874e1 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/CrownItem.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/CrownItem.kt @@ -25,6 +25,7 @@ import net.minecraft.item.ArmorItem import net.minecraft.item.Equipment import net.minecraft.item.Item import net.minecraft.item.ItemStack +import net.minecraft.registry.entry.RegistryEntry import net.minecraft.sound.SoundEvent import net.minecraft.sound.SoundEvents import net.minecraft.util.Hand @@ -43,7 +44,7 @@ open class CrownItem(settings: Settings) : Item(settings), Equipment { return equipAndSwap(this, world, user, hand) } - override fun getEquipSound(): SoundEvent = SoundEvents.ITEM_ARMOR_EQUIP_GOLD + override fun getEquipSound(): RegistryEntry = SoundEvents.ITEM_ARMOR_EQUIP_GOLD override fun getSlotType(): EquipmentSlot = EquipmentSlot.HEAD } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt index f92851ef0..c0da0086f 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt @@ -68,7 +68,7 @@ fun attack(packet: AttackC2SPacket, context: PacketContext) { } private fun ItemStack.canAccept(other: ItemStack, maxCountPerStack: Int): Boolean { - val canCombine = isEmpty || ItemStack.canCombine(this, other) + val canCombine = isEmpty || ItemStack.areItemsAndComponentsEqual(this, other) val totalCount = count + other.count return canCombine && totalCount <= item.maxCount && totalCount <= maxCountPerStack 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 2cb770b55..14b70d232 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 @@ -200,13 +200,13 @@ class FurnaceHandler( private class ItemEntityInventory(private val itemEntity: ItemEntity) : SingleStackInventory { override fun getStack(): ItemStack = itemEntity.stack - override fun setStack(stack: ItemStack) {} + override fun setStack(stack: ItemStack?) {} override fun markDirty() {} - override fun decreaseStack(count: Int): ItemStack = ItemStack.EMPTY + override fun canPlayerUse(player: PlayerEntity?) = false - override fun asBlockEntity(): Nothing = throw UnsupportedOperationException() + override fun decreaseStack(count: Int): ItemStack = ItemStack.EMPTY } companion object { From b7e93b47621f49acbda352aeff74989a4a80a049 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 21:54:16 +0200 Subject: [PATCH 073/128] Update Fabric mod to 1.20.6 --- .../avm_staff/internal/fabric/item/FabricStaffItem.kt | 4 ++-- .../main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt | 2 +- .../avm_staff/internal/staff_handler/FurnaceHandler.kt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) 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 f96a09bbf..643ef3563 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 @@ -39,7 +39,7 @@ class FabricStaffItem(settings: Item.Settings) : StaffItem(settings), FabricItem } } - override fun allowNbtUpdateAnimation( + override fun allowComponentsUpdateAnimation( player: PlayerEntity, hand: Hand, oldStack: ItemStack, @@ -49,7 +49,7 @@ class FabricStaffItem(settings: Item.Settings) : StaffItem(settings), FabricItem val newHandler = newStack.itemInStaff.staffHandlerOrFallback return if (oldHandler !== newHandler) true - else oldHandler.allowNbtUpdateAnimation(oldStack, newStack, player, hand) + else oldHandler.allowComponentsUpdateAnimation(oldStack, newStack, player, hand) } override fun getAttributeModifiers(stack: ItemStack): AttributeModifiersComponent { 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 d4c021786..c640ba5be 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 @@ -304,7 +304,7 @@ abstract class StaffHandler { * @param hand The hand of [player], in which the [old staff][oldStaffStack] is * @return true to play the update/equip animation, false to skip it */ - open fun allowNbtUpdateAnimation( + open fun allowComponentsUpdateAnimation( oldStaffStack: ItemStack, newStaffStack: ItemStack, player: PlayerEntity, 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 14b70d232..d8e0c3f41 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 @@ -149,7 +149,7 @@ class FurnaceHandler( return staffStack } - override fun allowNbtUpdateAnimation( + override fun allowComponentsUpdateAnimation( oldStaffStack: ItemStack, newStaffStack: ItemStack, player: PlayerEntity, From 1ecf06b0f8a2e6aea58135e7511ddda0057003cb Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 21:55:07 +0200 Subject: [PATCH 074/128] Update NeoForge mod to 1.20.6 --- NeoForgeMod/build.gradle.kts | 2 +- .../main/resources/META-INF/{mods.toml => neoforge.mods.toml} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename NeoForgeMod/src/main/resources/META-INF/{mods.toml => neoforge.mods.toml} (100%) diff --git a/NeoForgeMod/build.gradle.kts b/NeoForgeMod/build.gradle.kts index 8a2f9a65f..11e430817 100644 --- a/NeoForgeMod/build.gradle.kts +++ b/NeoForgeMod/build.gradle.kts @@ -75,7 +75,7 @@ tasks { } processResources { - filesMatching("META-INF/mods.toml") { + filesMatching("META-INF/neoforge.mods.toml") { expand( mutableMapOf( "version" to version as String, diff --git a/NeoForgeMod/src/main/resources/META-INF/mods.toml b/NeoForgeMod/src/main/resources/META-INF/neoforge.mods.toml similarity index 100% rename from NeoForgeMod/src/main/resources/META-INF/mods.toml rename to NeoForgeMod/src/main/resources/META-INF/neoforge.mods.toml From 3b159bea9c8a720eb8e673aca30329616b11cf0a Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 21:56:52 +0200 Subject: [PATCH 075/128] Update StaffItem docs --- .../src/main/kotlin/opekope2/avm_staff/api/item/StaffItem.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 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 db1f8a9bf..75e689864 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 @@ -30,12 +30,13 @@ import net.minecraft.util.ActionResult 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.* /** - * Staff item dispatching functionality to [StaffItemHandler] without loader specific functionality. + * Staff item dispatching functionality to [StaffHandler] without loader specific functionality. * Implementing loader-specific interfaces is highly recommended when extending the class to pass loader-specific - * functionality to [StaffItemHandler]. + * functionality to [StaffHandler]. */ abstract class StaffItem(settings: Settings) : Item(settings) { override fun onItemEntityDestroyed(entity: ItemEntity) { From a86a1a9281c18720d6324300916873c2236a744f Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 22:46:20 +0200 Subject: [PATCH 076/128] Register particles in mods, because Architectury API refuses --- .../avm_staff/internal/fabric/StaffModClient.kt | 9 +++++++++ .../avm_staff/internal/neoforge/StaffModClient.kt | 10 ++++++++++ .../kotlin/opekope2/avm_staff/internal/Initializer.kt | 6 ------ .../internal/staff_handler/CampfireHandler.kt | 8 ++------ 4 files changed, 21 insertions(+), 12 deletions(-) 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 46b68c1e8..d290456fd 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 @@ -21,13 +21,22 @@ package opekope2.avm_staff.internal.fabric import net.fabricmc.api.ClientModInitializer import net.fabricmc.api.EnvType import net.fabricmc.api.Environment +import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry import net.minecraft.client.item.ModelPredicateProviderRegistry +import opekope2.avm_staff.api.flamethrowerParticleType +import opekope2.avm_staff.api.particle.FlamethrowerParticle +import opekope2.avm_staff.api.soulFlamethrowerParticleType import opekope2.avm_staff.internal.model.registerModelPredicateProviders @Suppress("unused") @Environment(EnvType.CLIENT) object StaffModClient : ClientModInitializer { override fun onInitializeClient() { + ParticleFactoryRegistry.getInstance().apply { + register(flamethrowerParticleType.get(), FlamethrowerParticle::Factory) + register(soulFlamethrowerParticleType.get(), FlamethrowerParticle::Factory) + } + 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 c9a4cf9a0..dca76b42b 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 @@ -23,6 +23,10 @@ import net.neoforged.api.distmarker.Dist 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.internal.model.registerModelPredicateProviders import opekope2.avm_staff.internal.registerClientContent import opekope2.avm_staff.internal.registerSmithingTableTextures @@ -46,4 +50,10 @@ object StaffModClient { registerModelPredicateProviders(ModelPredicateProviderRegistry::registerGeneric) } } + + @SubscribeEvent + fun registerParticleProviders(event: RegisterParticleProvidersEvent) { + event.registerSpriteSet(flamethrowerParticleType.get(), FlamethrowerParticle::Factory) + event.registerSpriteSet(soulFlamethrowerParticleType.get(), FlamethrowerParticle::Factory) + } } 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 3eefd89d9..ac107af96 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -22,7 +22,6 @@ import dev.architectury.event.events.client.ClientTickEvent import dev.architectury.event.events.common.InteractionEvent import dev.architectury.event.events.common.LootEvent import dev.architectury.registry.client.keymappings.KeyMappingRegistry -import dev.architectury.registry.client.particle.ParticleProviderRegistry import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.minecraft.item.SmithingTemplateItem @@ -32,9 +31,6 @@ import net.minecraft.loot.entry.ItemEntry import net.minecraft.registry.RegistryKey import net.minecraft.util.Identifier import opekope2.avm_staff.api.crownOfKingOrangeItem -import opekope2.avm_staff.api.flamethrowerParticleType -import opekope2.avm_staff.api.particle.FlamethrowerParticle -import opekope2.avm_staff.api.soulFlamethrowerParticleType import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures import opekope2.avm_staff.internal.event_handler.* import opekope2.avm_staff.internal.networking.c2s.play.AddItemToStaffC2SPacket @@ -72,8 +68,6 @@ fun subscribeToEvents() { @Environment(EnvType.CLIENT) fun registerClientContent() { KeyMappingRegistry.register(addRemoveStaffItemKeyBinding) - ParticleProviderRegistry.register(flamethrowerParticleType, FlamethrowerParticle::Factory) - ParticleProviderRegistry.register(soulFlamethrowerParticleType, FlamethrowerParticle::Factory) } @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 1da424520..c9fc88178 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 @@ -135,12 +135,8 @@ class CampfireHandler( particleManager.addParticle( particleEffectSupplier.get(), - origin.x, - origin.y, - origin.z, - particleSpeed.x, - particleSpeed.y, - particleSpeed.z + 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() } } From 07be4aebeef99c738343ed32dd50e172d61525ae Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 21 May 2024 22:46:56 +0200 Subject: [PATCH 077/128] Add translation for avm_staff:staffs tag --- 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 144ac0401..7857e8097 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 @@ -12,5 +12,6 @@ "item.avm_staff.crown_of_king_orange": "Crown of King Orange", "key.categories.avm_staff": "Staff Mod", "key.avm_staff.add_remove_staff_item": "Add/remove staff item", + "tag.item.avm_staff.staffs": "Staffs", "itemGroup.avm_staff_items": "Staff Mod" } From da5b3825c6021d40dea2c49cbadccb1bfa72c8ba Mon Sep 17 00:00:00 2001 From: opekope2 Date: Wed, 22 May 2024 01:37:27 +0200 Subject: [PATCH 078/128] Replace TntEntityMixin with new ImpactTntEntity class --- .../avm_staff/mixin/TntEntityMixin.java | 104 ------------------ .../kotlin/opekope2/avm_staff/api/StaffMod.kt | 18 +++ .../avm_staff/api/entity/ImpactTntEntity.kt | 72 ++++++++++++ .../avm_staff/internal/Initializer.kt | 4 + .../internal/staff_handler/TntHandler.kt | 16 +-- .../opekope2/avm_staff/util/ImpactTntUtil.kt | 39 ------- .../src/main/resources/avm_staff.mixins.json | 3 +- 7 files changed, 101 insertions(+), 155 deletions(-) delete mode 100644 StaffMod/src/main/java/opekope2/avm_staff/mixin/TntEntityMixin.java create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntEntity.kt delete mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/util/ImpactTntUtil.kt diff --git a/StaffMod/src/main/java/opekope2/avm_staff/mixin/TntEntityMixin.java b/StaffMod/src/main/java/opekope2/avm_staff/mixin/TntEntityMixin.java deleted file mode 100644 index 6a314900e..000000000 --- a/StaffMod/src/main/java/opekope2/avm_staff/mixin/TntEntityMixin.java +++ /dev/null @@ -1,104 +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.mixin; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.TntEntity; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtElement; -import net.minecraft.world.World; -import opekope2.avm_staff.api.entity.IImpactTnt; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.List; - -@Mixin(TntEntity.class) -public abstract class TntEntityMixin extends Entity implements IImpactTnt { - private TntEntityMixin(EntityType type, World world) { - super(type, world); - } - - @Shadow - protected abstract void explode(); - - @Inject(method = "initDataTracker", at = @At("TAIL")) - private void initDataTracker(CallbackInfo ci) { - dataTracker.startTracking(EXPLODES_ON_IMPACT, false); - } - - @Inject(method = "writeCustomDataToNbt", at = @At("TAIL")) - private void writeCustomDataToNbt(NbtCompound nbt, CallbackInfo ci) { - nbt.putBoolean(EXPLODES_ON_IMPACT_NBT_KEY, staffMod$explodesOnImpact()); - } - - @Inject(method = "readCustomDataFromNbt", at = @At("TAIL")) - private void readCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) { - if (nbt.contains(EXPLODES_ON_IMPACT_NBT_KEY, NbtElement.BYTE_TYPE)) { - staffMod$explodeOnImpact(nbt.getBoolean(EXPLODES_ON_IMPACT_NBT_KEY)); - } - } - - @Inject( - method = "tick", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/entity/TntEntity;move(Lnet/minecraft/entity/MovementType;Lnet/minecraft/util/math/Vec3d;)V", - shift = At.Shift.AFTER - ) - ) - private void explodeOnImpact(CallbackInfo ci) { - if (!staffMod$explodesOnImpact()) return; - - boolean explode = horizontalCollision || verticalCollision; - if (!explode) { - List collisions = getWorld().getOtherEntities(this, getBoundingBox(), entity -> true); - explode = !collisions.isEmpty(); - - for (Entity collider : collisions) { - if (collider instanceof TntEntity tnt && ((IImpactTnt) tnt).staffMod$explodesOnImpact()) { - // Force explode other TNT, because the current TNT gets discarded before the other TNT gets processed - tnt.setFuse(0); - } - } - } - - if (!explode) return; - - if (!getWorld().isClient) { - // Server sends EntitiesDestroyS2CPacket to client, because the position desync makes collision detection unreliable - discard(); - explode(); - } - } - - @Override - public boolean staffMod$explodesOnImpact() { - return dataTracker.get(EXPLODES_ON_IMPACT); - } - - @Override - public void staffMod$explodeOnImpact(boolean explode) { - dataTracker.set(EXPLODES_ON_IMPACT, explode); - } -} 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 3ebd15d43..98cabbf71 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -27,6 +27,8 @@ import dev.architectury.registry.registries.DeferredRegister import dev.architectury.registry.registries.RegistrySupplier import net.minecraft.client.particle.ParticleManager import net.minecraft.component.DataComponentType +import net.minecraft.entity.EntityType +import net.minecraft.entity.SpawnGroup import net.minecraft.item.Item import net.minecraft.item.ItemGroup import net.minecraft.item.Items @@ -38,6 +40,7 @@ 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.entity.ImpactTntEntity import opekope2.avm_staff.api.item.CrownItem import opekope2.avm_staff.api.item.StaffItem import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures @@ -51,6 +54,7 @@ import opekope2.avm_staff.util.itemStackInStaff 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) @@ -131,6 +135,19 @@ val staffModItemGroup: RegistrySupplier = ITEM_GROUPS.register("${MOD } } +/** + * 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(MOD_ID, "impact_tnt").toString()) +} + /** * Particle registered as `avm_staff:flame`. * @@ -187,6 +204,7 @@ val furnaceLitComponentType: RegistrySupplier> internal fun registerContent() { ITEMS.register() ITEM_GROUPS.register() + ENTITY_TYPES.register() PARTICLE_TYPES.register() DATA_COMPONENT_TYPES.register() 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 new file mode 100644 index 000000000..cc55575ab --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/entity/ImpactTntEntity.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.api.entity + +import net.minecraft.entity.* +import net.minecraft.util.math.Vec3d +import net.minecraft.world.World +import opekope2.avm_staff.api.impactTntEntityType + +class ImpactTntEntity(entityType: EntityType, world: World) : TntEntity(entityType, world), Ownable { + private var owner: LivingEntity? = null + + constructor(world: World, x: Double, y: Double, z: Double, velocity: Vec3d, igniter: LivingEntity?) : + this(impactTntEntityType.get(), world) { + setPosition(x, y, z) + this.velocity = velocity + fuse = 80 + prevX = x + prevY = y + prevZ = z + owner = igniter + } + + override fun move(movementType: MovementType?, movement: Vec3d?) { + super.move(movementType, movement) + explodeOnImpact() + } + + private fun explodeOnImpact() { + var explode = horizontalCollision || verticalCollision + if (!explode) { + val collisions = world.getOtherEntities(this, boundingBox) { true } + explode = collisions.isNotEmpty() + + for (collider in collisions) { + if (collider is ImpactTntEntity) { + // Force explode other TNT, because the current TNT gets discarded before the other TNT gets processed + collider.fuse = 0 + } + } + } + + if (explode && !world.isClient) { + fuse = 0 + } + } + + override fun copyFrom(original: Entity?) { + super.copyFrom(original) + if (original is ImpactTntEntity) { + owner = original.owner + } + } + + override fun getOwner() = owner +} 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 ac107af96..e546a33ac 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -22,8 +22,10 @@ import dev.architectury.event.events.client.ClientTickEvent import dev.architectury.event.events.common.InteractionEvent import dev.architectury.event.events.common.LootEvent import dev.architectury.registry.client.keymappings.KeyMappingRegistry +import dev.architectury.registry.client.level.entity.EntityRendererRegistry import net.fabricmc.api.EnvType import net.fabricmc.api.Environment +import net.minecraft.client.render.entity.TntEntityRenderer import net.minecraft.item.SmithingTemplateItem import net.minecraft.loot.LootPool import net.minecraft.loot.LootTable @@ -31,6 +33,7 @@ import net.minecraft.loot.entry.ItemEntry import net.minecraft.registry.RegistryKey import net.minecraft.util.Identifier import opekope2.avm_staff.api.crownOfKingOrangeItem +import opekope2.avm_staff.api.impactTntEntityType import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures import opekope2.avm_staff.internal.event_handler.* import opekope2.avm_staff.internal.networking.c2s.play.AddItemToStaffC2SPacket @@ -68,6 +71,7 @@ fun subscribeToEvents() { @Environment(EnvType.CLIENT) fun registerClientContent() { KeyMappingRegistry.register(addRemoveStaffItemKeyBinding) + EntityRendererRegistry.register(impactTntEntityType, ::TntEntityRenderer) } @Environment(EnvType.CLIENT) 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 54e330bfa..9aca477c8 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 @@ -19,7 +19,6 @@ package opekope2.avm_staff.internal.staff_handler import net.minecraft.entity.LivingEntity -import net.minecraft.entity.TntEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack import net.minecraft.sound.SoundCategory @@ -28,6 +27,7 @@ import net.minecraft.util.ActionResult 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.staff.StaffHandler import opekope2.avm_staff.util.* @@ -42,15 +42,11 @@ class TntHandler : StaffHandler() { if (attacker is PlayerEntity && attacker.isAttackCoolingDown) return ActionResult.FAIL - val (x, y, z) = attacker.approximateStaffTipPosition - world.spawnEntity( - TntEntity(world, x, y, z, attacker).apply { - velocity = attacker.rotationVector + attacker.velocity - explodesOnImpact = true - world.playSound(null, x, y, z, SoundEvents.ENTITY_TNT_PRIMED, SoundCategory.BLOCKS, 1.0f, 1.0f) - world.emitGameEvent(attacker, GameEvent.PRIME_FUSE, pos) - } - ) + val spawnPos = attacker.approximateStaffTipPosition + val (x, y, z) = spawnPos + world.spawnEntity(ImpactTntEntity(world, x, y, z, attacker.rotationVector + attacker.velocity, attacker)) + world.playSound(null, x, y, z, SoundEvents.ENTITY_TNT_PRIMED, SoundCategory.BLOCKS, 1.0f, 1.0f) + world.emitGameEvent(attacker, GameEvent.PRIME_FUSE, spawnPos) return ActionResult.SUCCESS } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/ImpactTntUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/ImpactTntUtil.kt deleted file mode 100644 index 2d4e2eab3..000000000 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/ImpactTntUtil.kt +++ /dev/null @@ -1,39 +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: JvmSynthetic - -package opekope2.avm_staff.util - -import net.minecraft.entity.TntEntity -import opekope2.avm_staff.api.entity.IImpactTnt - -/** - * Kotlin utility to get or set a TNT to explode when it collides with a block or entity. - * - * @see IImpactTnt - */ -inline var TntEntity.explodesOnImpact: Boolean - get() { - this as IImpactTnt - return `staffMod$explodesOnImpact`() - } - set(value) { - this as IImpactTnt - `staffMod$explodeOnImpact`(value) - } diff --git a/StaffMod/src/main/resources/avm_staff.mixins.json b/StaffMod/src/main/resources/avm_staff.mixins.json index c430274ae..8f9f0b4cd 100644 --- a/StaffMod/src/main/resources/avm_staff.mixins.json +++ b/StaffMod/src/main/resources/avm_staff.mixins.json @@ -12,7 +12,6 @@ "IParticleMixin" ], "mixins": [ - "LivingEntityMixin", - "TntEntityMixin" + "LivingEntityMixin" ] } From 44ea2dcb3ccd848f1b3c40a2ecd0aebdc48d0db3 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 23 May 2024 00:33:41 +0200 Subject: [PATCH 079/128] Add staff infusion smithing template to vault loot --- .../opekope2/avm_staff/internal/Initializer.kt | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 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 e546a33ac..da1552507 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -29,12 +29,14 @@ import net.minecraft.client.render.entity.TntEntityRenderer import net.minecraft.item.SmithingTemplateItem import net.minecraft.loot.LootPool import net.minecraft.loot.LootTable +import net.minecraft.loot.entry.EmptyEntry import net.minecraft.loot.entry.ItemEntry import net.minecraft.registry.RegistryKey import net.minecraft.util.Identifier import opekope2.avm_staff.api.crownOfKingOrangeItem import opekope2.avm_staff.api.impactTntEntityType import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures +import opekope2.avm_staff.api.staffInfusionSmithingTemplateItem import opekope2.avm_staff.internal.event_handler.* import opekope2.avm_staff.internal.networking.c2s.play.AddItemToStaffC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.AttackC2SPacket @@ -52,14 +54,26 @@ fun initializeNetworking() { } private val TREASURE_BASTION_CHEST_LOOT = Identifier("chests/bastion_treasure") +private val VAULT_UNIQUE_LOOT = Identifier("chests/trial_chambers/reward_unique") fun modifyLootTables( lootTable: RegistryKey, context: LootEvent.LootTableModificationContext, builtin: Boolean ) { - if (builtin && lootTable.value == TREASURE_BASTION_CHEST_LOOT) { - context.addPool(LootPool.builder().with(ItemEntry.builder(crownOfKingOrangeItem.get()))) + // FIXME builtin check after updating to 1.21 because Fabric detects experiments as data pack + when (lootTable.value) { + TREASURE_BASTION_CHEST_LOOT -> { + context.addPool(LootPool.builder().with(ItemEntry.builder(crownOfKingOrangeItem.get()))) + } + + VAULT_UNIQUE_LOOT -> { + context.addPool( + LootPool.builder() + .with(ItemEntry.builder(staffInfusionSmithingTemplateItem.get())) + .with(EmptyEntry.builder().weight(3)) + ) + } } } From 2b20792e1a1cff9e41b162956f2edb07a0057692 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 23 May 2024 01:20:50 +0200 Subject: [PATCH 080/128] Add crafting and smithing recipes --- .../avm_staff/recipes/faint_royal_staff.json | 19 +++++++++++++ .../recipes/faint_royal_staff_head.json | 19 +++++++++++++ .../avm_staff/recipes/faint_staff_rod.json | 22 +++++++++++++++ .../recipes/royal_staff_ingredient.json | 28 +++++++++++++++++++ .../recipes/royal_staff_smithing.json | 15 ++++++++++ .../staff_infusion_smithing_template.json | 23 +++++++++++++++ 6 files changed, 126 insertions(+) create mode 100644 StaffMod/src/main/resources/data/avm_staff/recipes/faint_royal_staff.json create mode 100644 StaffMod/src/main/resources/data/avm_staff/recipes/faint_royal_staff_head.json create mode 100644 StaffMod/src/main/resources/data/avm_staff/recipes/faint_staff_rod.json create mode 100644 StaffMod/src/main/resources/data/avm_staff/recipes/royal_staff_ingredient.json create mode 100644 StaffMod/src/main/resources/data/avm_staff/recipes/royal_staff_smithing.json create mode 100644 StaffMod/src/main/resources/data/avm_staff/recipes/staff_infusion_smithing_template.json diff --git a/StaffMod/src/main/resources/data/avm_staff/recipes/faint_royal_staff.json b/StaffMod/src/main/resources/data/avm_staff/recipes/faint_royal_staff.json new file mode 100644 index 000000000..116e169a6 --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/recipes/faint_royal_staff.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "H", + "R", + "R" + ], + "key": { + "H": { + "item": "avm_staff:faint_royal_staff_head" + }, + "R": { + "item": "avm_staff:faint_staff_rod" + } + }, + "result": { + "id": "avm_staff:faint_royal_staff" + } +} diff --git a/StaffMod/src/main/resources/data/avm_staff/recipes/faint_royal_staff_head.json b/StaffMod/src/main/resources/data/avm_staff/recipes/faint_royal_staff_head.json new file mode 100644 index 000000000..2d0a53f75 --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/recipes/faint_royal_staff_head.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "II", + "SI", + "II" + ], + "key": { + "I": { + "item": "avm_staff:royal_staff_ingredient" + }, + "S": { + "item": "minecraft:nether_star" + } + }, + "result": { + "id": "avm_staff:faint_royal_staff_head" + } +} diff --git a/StaffMod/src/main/resources/data/avm_staff/recipes/faint_staff_rod.json b/StaffMod/src/main/resources/data/avm_staff/recipes/faint_staff_rod.json new file mode 100644 index 000000000..88c595ab9 --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/recipes/faint_staff_rod.json @@ -0,0 +1,22 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "E", + "N", + "O" + ], + "key": { + "E": { + "item": "minecraft:end_rod" + }, + "N": { + "item": "minecraft:blaze_rod" + }, + "O": { + "item": "minecraft:breeze_rod" + } + }, + "result": { + "id": "avm_staff:faint_staff_rod" + } +} diff --git a/StaffMod/src/main/resources/data/avm_staff/recipes/royal_staff_ingredient.json b/StaffMod/src/main/resources/data/avm_staff/recipes/royal_staff_ingredient.json new file mode 100644 index 000000000..796c2da8d --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/recipes/royal_staff_ingredient.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "ISI", + "CKC", + "INI" + ], + "key": { + "I": { + "item": "minecraft:iron_ingot" + }, + "S": { + "item": "minecraft:echo_shard" + }, + "C": { + "item": "minecraft:copper_ingot" + }, + "K": { + "item": "avm_staff:crown_of_king_orange" + }, + "N": { + "item": "minecraft:netherite_ingot" + } + }, + "result": { + "id": "avm_staff:royal_staff_ingredient" + } +} diff --git a/StaffMod/src/main/resources/data/avm_staff/recipes/royal_staff_smithing.json b/StaffMod/src/main/resources/data/avm_staff/recipes/royal_staff_smithing.json new file mode 100644 index 000000000..0a373bec4 --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/recipes/royal_staff_smithing.json @@ -0,0 +1,15 @@ +{ + "type": "minecraft:smithing_transform", + "template": { + "item": "avm_staff:staff_infusion_smithing_template" + }, + "base": { + "item": "avm_staff:faint_royal_staff" + }, + "addition": { + "item": "minecraft:redstone" + }, + "result": { + "id": "avm_staff:royal_staff" + } +} diff --git a/StaffMod/src/main/resources/data/avm_staff/recipes/staff_infusion_smithing_template.json b/StaffMod/src/main/resources/data/avm_staff/recipes/staff_infusion_smithing_template.json new file mode 100644 index 000000000..aff3d0983 --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/recipes/staff_infusion_smithing_template.json @@ -0,0 +1,23 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "DTD", + "DMD", + "DDD" + ], + "key": { + "D": { + "item": "minecraft:diamond" + }, + "T": { + "item": "avm_staff:staff_infusion_smithing_template" + }, + "M": { + "item": "minecraft:lapis_block" + } + }, + "result": { + "id": "avm_staff:staff_infusion_smithing_template", + "count": 2 + } +} From 0ae386bf7c0550fd454028bbc0dd79087f398f8d Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 23 May 2024 02:50:44 +0200 Subject: [PATCH 081/128] Add advancements for showing recipes --- .../recipes/avm_staff/faint_royal_staff.json | 43 +++++++++++++++ .../avm_staff/faint_royal_staff_head.json | 43 +++++++++++++++ .../recipes/avm_staff/faint_staff_rod.json | 54 +++++++++++++++++++ .../avm_staff/royal_staff_ingredient.json | 32 +++++++++++ .../avm_staff/royal_staff_smithing.json | 32 +++++++++++ 5 files changed, 204 insertions(+) create mode 100644 StaffMod/src/main/resources/data/minecraft/advancements/recipes/avm_staff/faint_royal_staff.json create mode 100644 StaffMod/src/main/resources/data/minecraft/advancements/recipes/avm_staff/faint_royal_staff_head.json create mode 100644 StaffMod/src/main/resources/data/minecraft/advancements/recipes/avm_staff/faint_staff_rod.json create mode 100644 StaffMod/src/main/resources/data/minecraft/advancements/recipes/avm_staff/royal_staff_ingredient.json create mode 100644 StaffMod/src/main/resources/data/minecraft/advancements/recipes/avm_staff/royal_staff_smithing.json diff --git a/StaffMod/src/main/resources/data/minecraft/advancements/recipes/avm_staff/faint_royal_staff.json b/StaffMod/src/main/resources/data/minecraft/advancements/recipes/avm_staff/faint_royal_staff.json new file mode 100644 index 000000000..0f05a7fc5 --- /dev/null +++ b/StaffMod/src/main/resources/data/minecraft/advancements/recipes/avm_staff/faint_royal_staff.json @@ -0,0 +1,43 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_faint_royal_staff_head": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "items": "avm_staff:faint_royal_staff_head" + } + ] + } + }, + "has_faint_staff_rod": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "items": "avm_staff:faint_staff_rod" + } + ] + } + }, + "has_the_recipe": { + "trigger": "minecraft:recipe_unlocked", + "conditions": { + "recipe": "avm_staff:faint_royal_staff" + } + } + }, + "requirements": [ + [ + "has_faint_royal_staff_head", + "has_faint_staff_rod", + "has_the_recipe" + ] + ], + "rewards": { + "recipes": [ + "avm_staff:faint_royal_staff" + ] + } +} diff --git a/StaffMod/src/main/resources/data/minecraft/advancements/recipes/avm_staff/faint_royal_staff_head.json b/StaffMod/src/main/resources/data/minecraft/advancements/recipes/avm_staff/faint_royal_staff_head.json new file mode 100644 index 000000000..e5439a214 --- /dev/null +++ b/StaffMod/src/main/resources/data/minecraft/advancements/recipes/avm_staff/faint_royal_staff_head.json @@ -0,0 +1,43 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_royal_staff_ingredient": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "items": "avm_staff:royal_staff_ingredient" + } + ] + } + }, + "has_nether_star": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "items": "minecraft:nether_star" + } + ] + } + }, + "has_the_recipe": { + "trigger": "minecraft:recipe_unlocked", + "conditions": { + "recipe": "avm_staff:faint_royal_staff_head" + } + } + }, + "requirements": [ + [ + "has_royal_staff_ingredient", + "has_nether_star", + "has_the_recipe" + ] + ], + "rewards": { + "recipes": [ + "avm_staff:faint_royal_staff_head" + ] + } +} diff --git a/StaffMod/src/main/resources/data/minecraft/advancements/recipes/avm_staff/faint_staff_rod.json b/StaffMod/src/main/resources/data/minecraft/advancements/recipes/avm_staff/faint_staff_rod.json new file mode 100644 index 000000000..348e84c87 --- /dev/null +++ b/StaffMod/src/main/resources/data/minecraft/advancements/recipes/avm_staff/faint_staff_rod.json @@ -0,0 +1,54 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_end_rod": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "items": "minecraft:end_rod" + } + ] + } + }, + "has_blaze_rod": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "items": "minecraft:blaze_rod" + } + ] + } + }, + "has_breeze_rod": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "items": "minecraft:breeze_rod" + } + ] + } + }, + "has_the_recipe": { + "trigger": "minecraft:recipe_unlocked", + "conditions": { + "recipe": "avm_staff:faint_staff_rod" + } + } + }, + "requirements": [ + [ + "has_end_rod", + "has_blaze_rod", + "has_breeze_rod", + "has_the_recipe" + ] + ], + "rewards": { + "recipes": [ + "avm_staff:faint_staff_rod" + ] + } +} diff --git a/StaffMod/src/main/resources/data/minecraft/advancements/recipes/avm_staff/royal_staff_ingredient.json b/StaffMod/src/main/resources/data/minecraft/advancements/recipes/avm_staff/royal_staff_ingredient.json new file mode 100644 index 000000000..8ba9ad669 --- /dev/null +++ b/StaffMod/src/main/resources/data/minecraft/advancements/recipes/avm_staff/royal_staff_ingredient.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_crown_of_king_orange": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "items": "avm_staff:crown_of_king_orange" + } + ] + } + }, + "has_the_recipe": { + "trigger": "minecraft:recipe_unlocked", + "conditions": { + "recipe": "avm_staff:faint_royal_staff_head" + } + } + }, + "requirements": [ + [ + "has_crown_of_king_orange", + "has_the_recipe" + ] + ], + "rewards": { + "recipes": [ + "avm_staff:royal_staff_ingredient" + ] + } +} diff --git a/StaffMod/src/main/resources/data/minecraft/advancements/recipes/avm_staff/royal_staff_smithing.json b/StaffMod/src/main/resources/data/minecraft/advancements/recipes/avm_staff/royal_staff_smithing.json new file mode 100644 index 000000000..1d65c1375 --- /dev/null +++ b/StaffMod/src/main/resources/data/minecraft/advancements/recipes/avm_staff/royal_staff_smithing.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_faint_royal_staff": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "items": "avm_staff:faint_royal_staff" + } + ] + } + }, + "has_the_recipe": { + "trigger": "minecraft:recipe_unlocked", + "conditions": { + "recipe": "avm_staff:royal_staff" + } + } + }, + "requirements": [ + [ + "has_faint_royal_staff", + "has_the_recipe" + ] + ], + "rewards": { + "recipes": [ + "avm_staff:royal_staff_smithing" + ] + } +} From f64f23bfaba31a9d9f8027466b7afc245470dd0a Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 23 May 2024 16:45:39 +0200 Subject: [PATCH 082/128] Make impact TNT not explode when colliding with a spectator --- .../kotlin/opekope2/avm_staff/api/entity/ImpactTntEntity.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 cc55575ab..ebedb9104 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 @@ -19,6 +19,7 @@ package opekope2.avm_staff.api.entity 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 @@ -45,7 +46,7 @@ class ImpactTntEntity(entityType: EntityType, world: World) : T private fun explodeOnImpact() { var explode = horizontalCollision || verticalCollision if (!explode) { - val collisions = world.getOtherEntities(this, boundingBox) { true } + val collisions = world.getOtherEntities(this, boundingBox, EntityPredicates.EXCEPT_SPECTATOR) explode = collisions.isNotEmpty() for (collider in collisions) { From f3419d98a46956b3bd3ec9353dd6ded3206092dc Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 23 May 2024 18:52:02 +0200 Subject: [PATCH 083/128] Add StaffHandler.canSwingHand API --- .../mixin/fabric/LivingEntityMixin.java | 30 ++++++++++++++++++- .../neoforge/item/NeoForgeStaffItem.kt | 10 +++++++ .../avm_staff/api/staff/StaffHandler.kt | 14 +++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/LivingEntityMixin.java b/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/LivingEntityMixin.java index 3a460b2f5..94d9e017f 100644 --- a/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/LivingEntityMixin.java +++ b/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/LivingEntityMixin.java @@ -18,9 +18,13 @@ package opekope2.avm_staff.mixin.fabric; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.util.Hand; +import net.minecraft.world.World; import opekope2.avm_staff.api.StaffMod; import opekope2.avm_staff.api.staff.StaffHandler; import opekope2.avm_staff.util.StaffUtil; @@ -28,13 +32,21 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(LivingEntity.class) -public abstract class LivingEntityMixin { +public abstract class LivingEntityMixin extends Entity { + private LivingEntityMixin(EntityType type, World world) { + super(type, world); + } + @Shadow public abstract ItemStack getMainHandStack(); + @Shadow + public abstract ItemStack getStackInHand(Hand hand); + @Inject(method = "disablesShield", at = @At("HEAD"), cancellable = true) public void disableShield(CallbackInfoReturnable cir) { ItemStack mainHandStack = getMainHandStack(); @@ -48,4 +60,20 @@ public void disableShield(CallbackInfoReturnable cir) { cir.setReturnValue(true); } } + + @SuppressWarnings("UnreachableCode") // Calm down IDEA, this is not what it looks like. Literally + @Inject(method = "swingHand(Lnet/minecraft/util/Hand;Z)V", at = @At("HEAD"), cancellable = true) + public void swingHand(Hand hand, boolean fromServerPlayer, CallbackInfo ci) { + ItemStack stackInHand = getStackInHand(hand); + if (stackInHand.isEmpty()) return; + if (!stackInHand.isIn(StaffMod.getStaffsTag())) return; + + Item itemInStaff = StaffUtil.getItemInStaff(stackInHand); + if (itemInStaff == null) return; + + StaffHandler handlerOfItem = StaffUtil.getStaffHandlerOrFallback(itemInStaff); + if (!handlerOfItem.canSwingHand(stackInHand, getEntityWorld(), (LivingEntity) (Object) this, hand)) { + ci.cancel(); + } + } } 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 baa56c908..50938039a 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 @@ -58,6 +58,16 @@ class NeoForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IItemExt return false } + override fun onEntitySwing(stack: ItemStack, entity: LivingEntity): Boolean { + return !stack.itemInStaff.staffHandlerOrFallback.canSwingHand( + stack, + entity.entityWorld, + entity, + if (stack === entity.getStackInHand(Hand.MAIN_HAND)) Hand.MAIN_HAND + else Hand.OFF_HAND + ) + } + override fun onLeftClickEntity(stack: ItemStack, player: PlayerEntity, entity: Entity): Boolean { return stack.itemInStaff.staffHandlerOrFallback.attackEntity( stack, player.entityWorld, player, entity, Hand.MAIN_HAND 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 c640ba5be..2a5cf31b4 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 @@ -288,6 +288,20 @@ abstract class StaffHandler { return EventResult.pass() } + /** + * Called on both the client and the server by Staff Mod on Fabric and Neo/Forge API on Neo/Forge, when an entity + * holding a staff tries to swing its hand. + * + * @param staffStack The item stack used to perform the action + * @param world The world the [holder] is in + * @param holder The entity, which holds the staff + * @param hand The hand of the [holder], in which the [staff][staffStack] is + * @return `true` to allow hand swing, `false` to cancel it + */ + open fun canSwingHand(staffStack: ItemStack, world: World, holder: LivingEntity, hand: Hand): Boolean { + return true + } + /** * Returns if attacking with the staff should disable the target's shield. */ From 456b66c80f80f2b5d0892d01d95feb4c78d81d35 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 23 May 2024 18:58:56 +0200 Subject: [PATCH 084/128] Update StaffHandler attack and interact docs --- .../avm_staff/api/staff/StaffHandler.kt | 131 +++++++++--------- 1 file changed, 62 insertions(+), 69 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 2a5cf31b4..b9a36603a 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 @@ -56,16 +56,22 @@ abstract class StaffHandler { * If the staff can be used for multiple ticks, override [maxUseTime] to return a positive number, and call * [PlayerEntity.setCurrentHand] on [user] with [hand] as the argument. * - * On the logical client, the return values have the following meaning: + * @return + * On the logical client: * - * - SUCCESS: Swing hand, and reset equip progress - * - CONSUME, CONSUME_PARTIAL: Don't swing hand, and reset equip progress - * - PASS, FAIL: Don't swing hand, and don't reset equip progress + * - [ActionResult.SUCCESS]: + * swings hand, and resets equip progress + * - [ActionResult.CONSUME], [ActionResult.CONSUME_PARTIAL]: + * doesn't swing hand, and resets equip progress + * - [ActionResult.PASS], [ActionResult.FAIL]: + * doesn't swing hand, and doesn't reset equip progress * - * On the logical server, the return values have the following meaning (if used by player): + * On the logical server (if used by player): * - * - SUCCESS: Swing hand - * - CONSUME, CONSUME_PARTIAL, PASS, FAIL: Don't swing hand + * - [ActionResult.SUCCESS]: + * swings hand + * - [ActionResult.CONSUME], [ActionResult.CONSUME_PARTIAL], [ActionResult.PASS], [ActionResult.FAIL]: + * doesn't swing hand * * @param staffStack The item stack used to perform the action * @param world The world the [user] is in @@ -121,32 +127,30 @@ abstract class StaffHandler { * Called on both the client and the server by Minecraft, when an entity uses the staff on a block. * This method may not be called, if the block handles the use event (for example, a chest). * - * On the logical client, the return values have the following meaning: - * - * - SUCCESS: send a packet to the server, and swing hand - * - CONSUME, CONSUME_PARTIAL, FAIL: send a packet to the server, and don't swing hand - * - PASS: send a packet to the server, don't swing hand, then interact with the item by itself (see [use]) - * - * On the logical server, the return values have the following meaning (if used by player): - * - * - SUCCESS: - * Increment [*player used item* stat][Stats.USED], - * trigger [*item used on block* criterion][Criteria.ITEM_USED_ON_BLOCK], - * and swing hand - * - CONSUME: - * Increment [*player used item* stat][Stats.USED], - * trigger [*item used on block* criterion][Criteria.ITEM_USED_ON_BLOCK], - * and don't swing hand - * - CONSUME_PARTIAL: - * Don't increment [*player used item* stat][Stats.USED], - * trigger [*item used on block* criterion][Criteria.ITEM_USED_ON_BLOCK], - * and don't swing hand - * - PASS, FAIL: - * Don't increment [*player used item* stat][Stats.USED], - * don't trigger [*item used on block* criterion][Criteria.ITEM_USED_ON_BLOCK], - * and don't swing hand - * - * On the logical server, the return values are processed by the caller code (if not used by player). + * @return + * On the logical client: + * + * - [ActionResult.SUCCESS]: + * sends a packet to the server, and swings hand + * - [ActionResult.CONSUME], [ActionResult.CONSUME_PARTIAL], [ActionResult.FAIL]: + * sends a packet to the server, and doesn't swing hand + * - [ActionResult.PASS]: + * sends a packet to the server, doesn't swing hand, then interacts with the item using [use] + * + * On the logical server (if used by player): + * + * - [ActionResult.SUCCESS]: + * increments [*player used item* stat][Stats.USED], triggers + * [*item used on block* criterion][Criteria.ITEM_USED_ON_BLOCK], and swings hand + * - [ActionResult.CONSUME]: + * increments [*player used item* stat][Stats.USED], triggers + * [*item used on block* criterion][Criteria.ITEM_USED_ON_BLOCK], and doesn't swing hand + * - [ActionResult.CONSUME_PARTIAL]: + * doesn't increment [*player used item* stat][Stats.USED], triggers + * [*item used on block* criterion][Criteria.ITEM_USED_ON_BLOCK], and doesn't swing hand + * - [ActionResult.PASS], [ActionResult.FAIL]: + * doesn't increment [*player used item* stat][Stats.USED], doesn't trigger + * [*item used on block* criterion][Criteria.ITEM_USED_ON_BLOCK], and doesn't swing hand * * @param staffStack The item stack used to perform the action * @param world The world the [user] is in @@ -172,38 +176,29 @@ abstract class StaffHandler { * This method may not be called, if the entity handles the use event (for example, a horse). * This method will not be called, if the player is in spectator mode. * - * On the logical client, the return values have the following meaning: - * - * - SUCCESS: - * send a packet to the server, - * emit [*entity interact* game event][GameEvent.ENTITY_INTERACT], - * and swing hand - * - CONSUME, CONSUME_PARTIAL: - * send a packet to the server, - * emit [*entity interact* game event][GameEvent.ENTITY_INTERACT], - * and don't swing hand - * - PASS, FAIL: - * send a packet to the server, - * don't emit [*entity interact* game event][GameEvent.ENTITY_INTERACT], - * don't swing hand, - * then interact with the item by itself (see [use]) - * - * On the logical server, the return values have the following meaning (if used by player): - * - * - SUCCESS: - * Emit [*entity interact* game event][GameEvent.ENTITY_INTERACT], - * trigger [*player interacted with entity* criteria][Criteria.PLAYER_INTERACTED_WITH_ENTITY], - * and swing hand - * - CONSUME, CONSUME_PARTIAL: - * Emit [*entity interact* game event][GameEvent.ENTITY_INTERACT], - * trigger [*player interacted with entity* criteria][Criteria.PLAYER_INTERACTED_WITH_ENTITY], - * and don't swing hand - * - PASS, FAIL: - * Don't emit [*entity interact* game event][GameEvent.ENTITY_INTERACT], - * don't trigger [*player interacted with entity* criteria][Criteria.PLAYER_INTERACTED_WITH_ENTITY], - * and don't swing hand - * - * On the logical server, the return values are processed by the caller code (if not used by player). + * @return + * On the logical client: + * + * - [ActionResult.SUCCESS]: + * sends a packet to the server, emits [*entity interact* game event][GameEvent.ENTITY_INTERACT], and swings hand + * - [ActionResult.CONSUME], [ActionResult.CONSUME_PARTIAL]: + * sends a packet to the server, emits [*entity interact* game event][GameEvent.ENTITY_INTERACT], and doesn't + * swing hand + * - [ActionResult.PASS], [ActionResult.FAIL]: + * sends a packet to the server, doesn't emit [*entity interact* game event][GameEvent.ENTITY_INTERACT], doesn't + * swing hand, then interacts with the item using [use] + * + * On the logical server (if used by player): + * + * - [ActionResult.SUCCESS]: + * Emits [*entity interact* game event][GameEvent.ENTITY_INTERACT], triggers + * [*player interacted with entity* criteria][Criteria.PLAYER_INTERACTED_WITH_ENTITY], and swings hand + * - [ActionResult.CONSUME], [ActionResult.CONSUME_PARTIAL]: + * Emits [*entity interact* game event][GameEvent.ENTITY_INTERACT], triggers + * [*player interacted with entity* criteria][Criteria.PLAYER_INTERACTED_WITH_ENTITY], and doesn't swing hand + * - [ActionResult.PASS], [ActionResult.FAIL]: + * Doesn't emit [*entity interact* game event][GameEvent.ENTITY_INTERACT], doesn't trigger + * [*player interacted with entity* criteria][Criteria.PLAYER_INTERACTED_WITH_ENTITY], and doesn't swing hand * * @param staffStack The item stack used to perform the action * @param world The world the [user] is in @@ -236,8 +231,7 @@ abstract class StaffHandler { /** * Called on both the client and the server by Architectury API, when an entity attacks a block with a staff. * - * The return values have the following meaning: - * + * @return * - [EventResult.interruptTrue], [EventResult.interruptTrue]: * Cancels vanilla block breaking, and on the logical client, sends a packet to the server. * - [EventResult.interruptDefault], [EventResult.pass]: @@ -265,8 +259,7 @@ abstract class StaffHandler { * Called on both the client by Fabric/Neo/Forge API and the server by Fabric/Neo/Forge API, when an entity attacks * an entity with a staff. * - * The return values have the following meaning: - * + * @return * - [EventResult.interrupt], [EventResult.interruptTrue], [EventResult.interruptFalse], [EventResult.interruptDefault]: * Cancels vanilla entity attack, and on the logical client, sends a packet to the server. * - [EventResult.pass]: From f96ca64e39db5c7f594ef877426122a681f3d2cd Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 23 May 2024 19:01:21 +0200 Subject: [PATCH 085/128] Fix typo and missing backticks in docs --- .../main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt | 4 ++-- .../kotlin/opekope2/avm_staff/api/staff/StaffItemComponent.kt | 2 +- 2 files changed, 3 insertions(+), 3 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 b9a36603a..d2b4bbf1c 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 @@ -309,7 +309,7 @@ abstract class StaffHandler { * @param newStaffStack The updated item stack * @param player The holder of [oldStaffStack] * @param hand The hand of [player], in which the [old staff][oldStaffStack] is - * @return true to play the update/equip animation, false to skip it + * @return `true` to play the update/equip animation, `false` to skip it */ open fun allowComponentsUpdateAnimation( oldStaffStack: ItemStack, @@ -326,7 +326,7 @@ abstract class StaffHandler { * @param oldStaffStack The previous item stack * @param newStaffStack The updated item stack * @param selectedSlotChanged If the selected hotbar slot was changed - * @return true to play the update/equip animation, false to skip it + * @return `true` to play the update/equip animation, `false` to skip it */ open fun allowReequipAnimation( oldStaffStack: ItemStack, diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffItemComponent.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffItemComponent.kt index f90ce8ead..8beb159e1 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffItemComponent.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffItemComponent.kt @@ -28,7 +28,7 @@ import net.minecraft.network.codec.PacketCodec /** * [ItemStack] wrapper to make them compatible with [DataComponentType]s. * - * @param item The item stored in this component. Most be [copied][ItemStack.copy] before modifying it + * @param item The item stored in this component. Must be [copied][ItemStack.copy] before modifying it */ class StaffItemComponent(val item: ItemStack) { override fun equals(other: Any?): Boolean { From 852f279f56b5e4223f9b73337c621ee7556c5c22 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 23 May 2024 19:07:21 +0200 Subject: [PATCH 086/128] Merge Fallback and Empty staff handler to default Rename related utility method --- .../avm_staff/mixin/fabric/LivingEntityMixin.java | 4 ++-- .../internal/fabric/item/FabricStaffItem.kt | 8 ++++---- .../internal/neoforge/item/NeoForgeStaffItem.kt | 14 +++++++------- .../opekope2/avm_staff/api/item/StaffItem.kt | 14 +++++++------- .../opekope2/avm_staff/api/staff/StaffHandler.kt | 7 ++++--- .../kotlin/opekope2/avm_staff/util/StaffUtil.kt | 8 +++----- 6 files changed, 27 insertions(+), 28 deletions(-) diff --git a/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/LivingEntityMixin.java b/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/LivingEntityMixin.java index 94d9e017f..7ffb50757 100644 --- a/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/LivingEntityMixin.java +++ b/FabricMod/src/main/java/opekope2/avm_staff/mixin/fabric/LivingEntityMixin.java @@ -55,7 +55,7 @@ public void disableShield(CallbackInfoReturnable cir) { Item itemInStaff = StaffUtil.getItemInStaff(mainHandStack); if (itemInStaff == null) return; - StaffHandler handlerOfItem = StaffUtil.getStaffHandlerOrFallback(itemInStaff); + StaffHandler handlerOfItem = StaffUtil.getStaffHandlerOrDefault(itemInStaff); if (handlerOfItem.disablesShield()) { cir.setReturnValue(true); } @@ -71,7 +71,7 @@ public void swingHand(Hand hand, boolean fromServerPlayer, CallbackInfo ci) { Item itemInStaff = StaffUtil.getItemInStaff(stackInHand); if (itemInStaff == null) return; - StaffHandler handlerOfItem = StaffUtil.getStaffHandlerOrFallback(itemInStaff); + StaffHandler handlerOfItem = StaffUtil.getStaffHandlerOrDefault(itemInStaff); if (!handlerOfItem.canSwingHand(stackInHand, getEntityWorld(), (LivingEntity) (Object) this, hand)) { ci.cancel(); } 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 643ef3563..aa7547960 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.staffHandlerOrFallback +import opekope2.avm_staff.util.staffHandlerOrDefault class FabricStaffItem(settings: Item.Settings) : StaffItem(settings), FabricItem { init { @@ -45,14 +45,14 @@ class FabricStaffItem(settings: Item.Settings) : StaffItem(settings), FabricItem oldStack: ItemStack, newStack: ItemStack ): Boolean { - val oldHandler = oldStack.itemInStaff.staffHandlerOrFallback - val newHandler = newStack.itemInStaff.staffHandlerOrFallback + val oldHandler = oldStack.itemInStaff.staffHandlerOrDefault + val newHandler = newStack.itemInStaff.staffHandlerOrDefault return if (oldHandler !== newHandler) true else oldHandler.allowComponentsUpdateAnimation(oldStack, newStack, player, hand) } override fun getAttributeModifiers(stack: ItemStack): AttributeModifiersComponent { - return stack.itemInStaff.staffHandlerOrFallback.getAttributeModifiers(stack) + return stack.itemInStaff.staffHandlerOrDefault.getAttributeModifiers(stack) } } 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 50938039a..a81b1942b 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 @@ -35,12 +35,12 @@ 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.itemInStaff -import opekope2.avm_staff.util.staffHandlerOrFallback +import opekope2.avm_staff.util.staffHandlerOrDefault import java.util.function.Consumer class NeoForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IItemExtension { override fun getAttributeModifiers(stack: ItemStack): AttributeModifiersComponent { - return stack.itemInStaff.staffHandlerOrFallback.getAttributeModifiers(stack) + return stack.itemInStaff.staffHandlerOrDefault.getAttributeModifiers(stack) } @Suppress("RemoveExplicitSuperQualifier") // Required because StaffItem apparently also has canDisableShield @@ -50,7 +50,7 @@ class NeoForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IItemExt entity: LivingEntity, attacker: LivingEntity ): Boolean { - return stack.itemInStaff.staffHandlerOrFallback.disablesShield() || + return stack.itemInStaff.staffHandlerOrDefault.disablesShield() || super.canDisableShield(stack, shield, entity, attacker) } @@ -59,7 +59,7 @@ class NeoForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IItemExt } override fun onEntitySwing(stack: ItemStack, entity: LivingEntity): Boolean { - return !stack.itemInStaff.staffHandlerOrFallback.canSwingHand( + return !stack.itemInStaff.staffHandlerOrDefault.canSwingHand( stack, entity.entityWorld, entity, @@ -69,7 +69,7 @@ class NeoForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IItemExt } override fun onLeftClickEntity(stack: ItemStack, player: PlayerEntity, entity: Entity): Boolean { - return stack.itemInStaff.staffHandlerOrFallback.attackEntity( + return stack.itemInStaff.staffHandlerOrDefault.attackEntity( stack, player.entityWorld, player, entity, Hand.MAIN_HAND ).interruptsFurtherEvaluation() } @@ -79,8 +79,8 @@ class NeoForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IItemExt newStack: ItemStack, slotChanged: Boolean ): Boolean { - val oldHandler = oldStack.itemInStaff.staffHandlerOrFallback - val newHandler = newStack.itemInStaff.staffHandlerOrFallback + val oldHandler = oldStack.itemInStaff.staffHandlerOrDefault + val newHandler = newStack.itemInStaff.staffHandlerOrDefault return if (oldHandler !== newHandler) true else oldHandler.allowReequipAnimation(oldStack, newStack, slotChanged) 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 75e689864..ae0bf2811 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 @@ -46,28 +46,28 @@ abstract class StaffItem(settings: Settings) : Item(settings) { } override fun getMaxUseTime(stack: ItemStack): Int { - return stack.itemInStaff.staffHandlerOrFallback.maxUseTime + return stack.itemInStaff.staffHandlerOrDefault.maxUseTime } override fun use(world: World, user: PlayerEntity, hand: Hand): TypedActionResult { val staffStack = user.getStackInHand(hand) - return staffStack.itemInStaff.staffHandlerOrFallback.use(staffStack, world, user, hand) + return staffStack.itemInStaff.staffHandlerOrDefault.use(staffStack, world, user, hand) } override fun usageTick(world: World, user: LivingEntity, stack: ItemStack, remainingUseTicks: Int) { - stack.itemInStaff.staffHandlerOrFallback.usageTick(stack, world, user, remainingUseTicks) + stack.itemInStaff.staffHandlerOrDefault.usageTick(stack, world, user, remainingUseTicks) } override fun onStoppedUsing(stack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - stack.itemInStaff.staffHandlerOrFallback.onStoppedUsing(stack, world, user, remainingUseTicks) + stack.itemInStaff.staffHandlerOrDefault.onStoppedUsing(stack, world, user, remainingUseTicks) } override fun finishUsing(stack: ItemStack, world: World, user: LivingEntity): ItemStack { - return stack.itemInStaff.staffHandlerOrFallback.finishUsing(stack, world, user) + return stack.itemInStaff.staffHandlerOrDefault.finishUsing(stack, world, user) } override fun useOnBlock(context: ItemUsageContext): ActionResult { - return context.stack.itemInStaff.staffHandlerOrFallback.useOnBlock( + return context.stack.itemInStaff.staffHandlerOrDefault.useOnBlock( context.stack, context.world, context.player ?: return ActionResult.PASS, @@ -78,7 +78,7 @@ abstract class StaffItem(settings: Settings) : Item(settings) { } override fun useOnEntity(stack: ItemStack, user: PlayerEntity, entity: LivingEntity, hand: Hand): ActionResult { - return stack.itemInStaff.staffHandlerOrFallback.useOnEntity(stack, user.world, user, entity, hand) + return stack.itemInStaff.staffHandlerOrDefault.useOnEntity(stack, user.world, user, entity, hand) } override fun getName(stack: ItemStack): Text { 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 d2b4bbf1c..dee2be2b7 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 @@ -345,9 +345,10 @@ abstract class StaffHandler { return ATTRIBUTE_MODIFIERS } - object EmptyStaffHandler : StaffHandler() - - object FallbackStaffHandler : StaffHandler() + /** + * Handler of a staff with no item inserted into it. + */ + object Default : StaffHandler() companion object { private val ATTRIBUTE_MODIFIERS = AttributeModifiersComponent.builder() 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 b767e68af..18915290c 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt @@ -90,12 +90,10 @@ val Item.staffHandler: StaffHandler? } /** - * Returns the registered staff handler of the given item stack if available, a dummy one if not, and the empty staff - * handler if the item is `null`. + * Returns the registered staff handler of the given item if available, [StaffHandler.Default] otherwise. */ -val Item?.staffHandlerOrFallback: StaffHandler - get() = if (this == null) StaffHandler.EmptyStaffHandler - else staffHandler ?: StaffHandler.FallbackStaffHandler +val Item?.staffHandlerOrDefault: StaffHandler + get() = this?.staffHandler ?: StaffHandler.Default private const val STAFF_MODEL_LENGTH = 40.0 / 16.0 private const val STAFF_MODEL_ITEM_POSITION_CENTER = 33.5 / 16.0 From c43588d641d503263b3b0e1517af6f56540b04a2 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 23 May 2024 19:36:06 +0200 Subject: [PATCH 087/128] Organize access widener Remove redundant ones --- StaffMod/src/main/resources/avm_staff.accesswidener | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/StaffMod/src/main/resources/avm_staff.accesswidener b/StaffMod/src/main/resources/avm_staff.accesswidener index 0c7afe923..69cbc3891 100644 --- a/StaffMod/src/main/resources/avm_staff.accesswidener +++ b/StaffMod/src/main/resources/avm_staff.accesswidener @@ -1,12 +1,10 @@ accessWidener v2 named -accessible field net/minecraft/item/Item ATTACK_DAMAGE_MODIFIER_ID Ljava/util/UUID; -accessible field net/minecraft/item/Item ATTACK_SPEED_MODIFIER_ID Ljava/util/UUID; -accessible method net/minecraft/particle/DefaultParticleType (Z)V accessible method net/minecraft/block/entity/AbstractFurnaceBlockEntity dropExperience (Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/util/math/Vec3d;IF)V accessible method net/minecraft/entity/Entity getRotationVector (FF)Lnet/minecraft/util/math/Vec3d; -accessible field net/minecraft/item/SmithingTemplateItem TITLE_FORMATTING Lnet/minecraft/util/Formatting; -accessible field net/minecraft/item/SmithingTemplateItem DESCRIPTION_FORMATTING Lnet/minecraft/util/Formatting; -accessible field net/minecraft/item/SmithingTemplateItem ARMOR_TRIM_INGREDIENTS_TEXT Lnet/minecraft/text/Text; accessible field net/minecraft/item/SmithingTemplateItem ARMOR_TRIM_ADDITIONS_SLOT_DESCRIPTION_TEXT Lnet/minecraft/text/Text; +accessible field net/minecraft/item/SmithingTemplateItem ARMOR_TRIM_INGREDIENTS_TEXT Lnet/minecraft/text/Text; +accessible field net/minecraft/item/SmithingTemplateItem DESCRIPTION_FORMATTING Lnet/minecraft/util/Formatting; accessible field net/minecraft/item/SmithingTemplateItem EMPTY_SLOT_REDSTONE_DUST_TEXTURE Lnet/minecraft/util/Identifier; +accessible field net/minecraft/item/SmithingTemplateItem TITLE_FORMATTING Lnet/minecraft/util/Formatting; +accessible method net/minecraft/particle/SimpleParticleType (Z)V From 7bd16e67ec4ee1020915dc4207e12163c81a3c24 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 23 May 2024 20:43:46 +0200 Subject: [PATCH 088/128] Make Staff Mod loot tables data-driven --- .../avm_staff/internal/Initializer.kt | 30 ++++++++----------- .../chests/bastion_treasure.json | 13 ++++++++ .../chests/trial_chambers/reward_unique.json | 17 +++++++++++ 3 files changed, 43 insertions(+), 17 deletions(-) create mode 100644 StaffMod/src/main/resources/data/avm_staff/loot_tables/add_loot_pool/chests/bastion_treasure.json create mode 100644 StaffMod/src/main/resources/data/avm_staff/loot_tables/add_loot_pool/chests/trial_chambers/reward_unique.json 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 da1552507..c84d5b325 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -29,14 +29,12 @@ import net.minecraft.client.render.entity.TntEntityRenderer import net.minecraft.item.SmithingTemplateItem import net.minecraft.loot.LootPool import net.minecraft.loot.LootTable -import net.minecraft.loot.entry.EmptyEntry -import net.minecraft.loot.entry.ItemEntry +import net.minecraft.loot.entry.LootTableEntry import net.minecraft.registry.RegistryKey +import net.minecraft.registry.RegistryKeys import net.minecraft.util.Identifier -import opekope2.avm_staff.api.crownOfKingOrangeItem import opekope2.avm_staff.api.impactTntEntityType import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures -import opekope2.avm_staff.api.staffInfusionSmithingTemplateItem import opekope2.avm_staff.internal.event_handler.* import opekope2.avm_staff.internal.networking.c2s.play.AddItemToStaffC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.AttackC2SPacket @@ -53,8 +51,10 @@ fun initializeNetworking() { AttackC2SPacket.registerHandler(::attack) } -private val TREASURE_BASTION_CHEST_LOOT = Identifier("chests/bastion_treasure") -private val VAULT_UNIQUE_LOOT = Identifier("chests/trial_chambers/reward_unique") +private val MODIFIABLE_LOOT_TABLES = setOf( + Identifier("chests/bastion_treasure"), + Identifier("chests/trial_chambers/reward_unique") +) fun modifyLootTables( lootTable: RegistryKey, @@ -62,19 +62,15 @@ fun modifyLootTables( builtin: Boolean ) { // FIXME builtin check after updating to 1.21 because Fabric detects experiments as data pack - when (lootTable.value) { - TREASURE_BASTION_CHEST_LOOT -> { - context.addPool(LootPool.builder().with(ItemEntry.builder(crownOfKingOrangeItem.get()))) - } + if (lootTable.value !in MODIFIABLE_LOOT_TABLES) return - VAULT_UNIQUE_LOOT -> { - context.addPool( - LootPool.builder() - .with(ItemEntry.builder(staffInfusionSmithingTemplateItem.get())) - .with(EmptyEntry.builder().weight(3)) + context.addPool( + LootPool.builder().with( + LootTableEntry.builder( + RegistryKey.of(RegistryKeys.LOOT_TABLE, Identifier(MOD_ID, "add_loot_pool/${lootTable.value.path}")) ) - } - } + ) + ) } fun subscribeToEvents() { diff --git a/StaffMod/src/main/resources/data/avm_staff/loot_tables/add_loot_pool/chests/bastion_treasure.json b/StaffMod/src/main/resources/data/avm_staff/loot_tables/add_loot_pool/chests/bastion_treasure.json new file mode 100644 index 000000000..c26f719ff --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/loot_tables/add_loot_pool/chests/bastion_treasure.json @@ -0,0 +1,13 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "avm_staff:crown_of_king_orange" + } + ] + } + ] +} diff --git a/StaffMod/src/main/resources/data/avm_staff/loot_tables/add_loot_pool/chests/trial_chambers/reward_unique.json b/StaffMod/src/main/resources/data/avm_staff/loot_tables/add_loot_pool/chests/trial_chambers/reward_unique.json new file mode 100644 index 000000000..bed1e4d3a --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/loot_tables/add_loot_pool/chests/trial_chambers/reward_unique.json @@ -0,0 +1,17 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "avm_staff:staff_infusion_smithing_template" + }, + { + "type": "minecraft:empty", + "weight": 5 + } + ] + } + ] +} From 04083c74f36b29bb30e2de531b7de764859b6860 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 23 May 2024 21:37:16 +0200 Subject: [PATCH 089/128] Remove unnecessary .0 from float constants --- .../opekope2/avm_staff/internal/staff_handler/AnvilHandler.kt | 2 +- .../opekope2/avm_staff/internal/staff_handler/FurnaceHandler.kt | 2 +- .../opekope2/avm_staff/internal/staff_handler/TntHandler.kt | 2 +- .../opekope2/avm_staff/internal/staff_handler/WoolHandler.kt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) 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 93112ace1..f3619b406 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 @@ -47,7 +47,7 @@ class AnvilHandler(private val damagedStackFactory: () -> ItemStack?) : StaffHan if (world.isClient) return EventResult.pass() var broke = false - if (attacker is PlayerEntity && !attacker.abilities.creativeMode && attacker.random.nextFloat() < 0.12F) { + if (attacker is PlayerEntity && !attacker.abilities.creativeMode && attacker.random.nextFloat() < 0.12f) { val damagedStack = damagedStackFactory() staffStack.itemStackInStaff = damagedStack broke = damagedStack == null 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 d8e0c3f41..0ba637a4a 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 @@ -124,7 +124,7 @@ class FurnaceHandler( if (Math.random() >= 0.1) return val (x, y, z) = itemToSmelt.pos - world.playSound(x, y, z, smeltSound, SoundCategory.BLOCKS, 1.0f, 1.0f, false) + world.playSound(x, y, z, smeltSound, SoundCategory.BLOCKS, 1f, 1f, false) val rx = Math.random() * 0.25 - 0.25 / 2 val ry = Math.random() * 0.5 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 9aca477c8..af69b0b60 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 @@ -45,7 +45,7 @@ class TntHandler : StaffHandler() { val spawnPos = attacker.approximateStaffTipPosition val (x, y, z) = spawnPos world.spawnEntity(ImpactTntEntity(world, x, y, z, attacker.rotationVector + attacker.velocity, attacker)) - world.playSound(null, x, y, z, SoundEvents.ENTITY_TNT_PRIMED, SoundCategory.BLOCKS, 1.0f, 1.0f) + world.playSound(null, x, y, z, SoundEvents.ENTITY_TNT_PRIMED, SoundCategory.BLOCKS, 1f, 1f) world.emitGameEvent(attacker, GameEvent.PRIME_FUSE, spawnPos) return ActionResult.SUCCESS 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 58ef803d2..96da32785 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 @@ -82,7 +82,7 @@ class WoolHandler(woolBlock: Block, carpetBlock: Block) : StaffHandler() { woolPlaceContext.blockPos, woolSoundGroup.placeSound, SoundCategory.BLOCKS, - (woolSoundGroup.volume + 1.0f) / 2.0f, + (woolSoundGroup.volume + 1f) / 2f, woolSoundGroup.pitch * 0.8f ) world.emitGameEvent(GameEvent.BLOCK_PLACE, woolPlaceContext.blockPos, GameEvent.Emitter.of(user, placedState)) From f5aff122a836985fa7273ceb36107291046c4511 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 24 May 2024 02:17:59 +0200 Subject: [PATCH 090/128] Rework anvil staff mechanics Add AOE attack Can't swing hand if not falling --- .../internal/staff_handler/AnvilHandler.kt | 55 ++++++++++++++++--- 1 file changed, 47 insertions(+), 8 deletions(-) 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 f3619b406..aaa779df2 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 @@ -19,6 +19,7 @@ package opekope2.avm_staff.internal.staff_handler import dev.architectury.event.EventResult +import net.minecraft.block.AnvilBlock import net.minecraft.component.type.AttributeModifierSlot import net.minecraft.component.type.AttributeModifiersComponent import net.minecraft.entity.Entity @@ -27,7 +28,9 @@ import net.minecraft.entity.attribute.EntityAttributeModifier import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack +import net.minecraft.predicate.entity.EntityPredicates import net.minecraft.util.Hand +import net.minecraft.util.math.Box import net.minecraft.world.World import net.minecraft.world.WorldEvents import opekope2.avm_staff.api.staff.StaffHandler @@ -35,6 +38,8 @@ import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.equipTime import opekope2.avm_staff.util.itemStackInStaff import java.util.* +import kotlin.math.ceil +import kotlin.math.floor class AnvilHandler(private val damagedStackFactory: () -> ItemStack?) : StaffHandler() { override fun attackEntity( @@ -44,15 +49,16 @@ class AnvilHandler(private val damagedStackFactory: () -> ItemStack?) : StaffHan target: Entity, hand: Hand ): EventResult { - if (world.isClient) return EventResult.pass() + if (world.isClient) return EventResult.interruptDefault() - var broke = false - if (attacker is PlayerEntity && !attacker.abilities.creativeMode && attacker.random.nextFloat() < 0.12f) { - val damagedStack = damagedStackFactory() - staffStack.itemStackInStaff = damagedStack - broke = damagedStack == null - } + val fallDistance = ceil(attacker.fallDistance - 1f) + if (fallDistance <= 0) return EventResult.interruptDefault() + + aoeAttack(world, attacker, target, fallDistance) + world.syncWorldEvent(WorldEvents.SMASH_ATTACK, target.steppingPos, 750) + attacker.fallDistance = 0f + val broke = damageAnvil(staffStack, attacker, fallDistance) world.syncWorldEvent( if (broke) WorldEvents.ANVIL_DESTROYED else WorldEvents.ANVIL_LANDS, @@ -60,7 +66,40 @@ class AnvilHandler(private val damagedStackFactory: () -> ItemStack?) : StaffHan 0 ) - return EventResult.pass() + return EventResult.interruptDefault() + } + + private fun aoeAttack(world: World, attacker: LivingEntity, target: Entity, fallDistance: Float) { + val cappedFallDistance = floor(fallDistance * AnvilBlock.FALLING_BLOCK_ENTITY_DAMAGE_MULTIPLIER) + .coerceAtMost(AnvilBlock.FALLING_BLOCK_ENTITY_MAX_DAMAGE.toFloat()) + val cooldownProgress = + if (attacker is PlayerEntity) attacker.getAttackCooldownProgress(0f) + else 1f + val amount = cappedFallDistance * cooldownProgress + val radius = cappedFallDistance / 20f + val radius2 = radius * radius + val box = Box(target.pos, target.pos).expand(radius.toDouble()) + val predicate = EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR + .and(EntityPredicates.VALID_LIVING_ENTITY) + .and { it.squaredDistanceTo(target) <= radius2 } + + world.getOtherEntities(attacker, box, predicate).forEach { entity -> + entity.damage(world.damageSources.fallingAnvil(attacker), amount / (entity.distanceTo(target) + 1)) + } + } + + private fun damageAnvil(staffStack: ItemStack, attacker: LivingEntity, fallDistance: Float): Boolean { + if (attacker is PlayerEntity && !attacker.abilities.creativeMode && attacker.random.nextFloat() < 0.05f + fallDistance * 0.05f) { + val damagedStack = damagedStackFactory() + staffStack.itemStackInStaff = damagedStack + return damagedStack == null + } + + return false + } + + override fun canSwingHand(staffStack: ItemStack, world: World, holder: LivingEntity, hand: Hand): Boolean { + return ceil(holder.fallDistance - 1f) > 0f } override fun disablesShield() = true From 3de57821fd23f30443bc081bc1a9847e3a7a1731 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 26 May 2024 19:21:15 +0200 Subject: [PATCH 091/128] Make wool staff not able to place wool inside entity hitboxes --- .../staff_handler/VanillaStaffHandlers.kt | 37 +++++++++++-------- .../internal/staff_handler/WoolHandler.kt | 33 +++-------------- 2 files changed, 27 insertions(+), 43 deletions(-) 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 b819827d0..b7d5e9f32 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 @@ -22,6 +22,7 @@ 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 @@ -77,22 +78,26 @@ fun registerVanillaStaffHandlers() { WitherSkeletonSkullHandler() ) - Items.WHITE_WOOL.registerHandler(WoolHandler(WHITE_WOOL, WHITE_CARPET)) - Items.ORANGE_WOOL.registerHandler(WoolHandler(ORANGE_WOOL, ORANGE_CARPET)) - Items.MAGENTA_WOOL.registerHandler(WoolHandler(MAGENTA_WOOL, MAGENTA_CARPET)) - Items.LIGHT_BLUE_WOOL.registerHandler(WoolHandler(LIGHT_BLUE_WOOL, LIGHT_BLUE_CARPET)) - Items.YELLOW_WOOL.registerHandler(WoolHandler(YELLOW_WOOL, YELLOW_CARPET)) - Items.LIME_WOOL.registerHandler(WoolHandler(LIME_WOOL, LIME_CARPET)) - Items.PINK_WOOL.registerHandler(WoolHandler(PINK_WOOL, PINK_CARPET)) - Items.GRAY_WOOL.registerHandler(WoolHandler(GRAY_WOOL, GRAY_CARPET)) - Items.LIGHT_GRAY_WOOL.registerHandler(WoolHandler(LIGHT_GRAY_WOOL, LIGHT_GRAY_CARPET)) - Items.CYAN_WOOL.registerHandler(WoolHandler(CYAN_WOOL, CYAN_CARPET)) - Items.PURPLE_WOOL.registerHandler(WoolHandler(PURPLE_WOOL, PURPLE_CARPET)) - Items.BLUE_WOOL.registerHandler(WoolHandler(BLUE_WOOL, BLUE_CARPET)) - Items.BROWN_WOOL.registerHandler(WoolHandler(BROWN_WOOL, BROWN_CARPET)) - Items.GREEN_WOOL.registerHandler(WoolHandler(GREEN_WOOL, GREEN_CARPET)) - Items.RED_WOOL.registerHandler(WoolHandler(RED_WOOL, RED_CARPET)) - Items.BLACK_WOOL.registerHandler(WoolHandler(BLACK_WOOL, BLACK_CARPET)) + Items.WHITE_WOOL.registerHandler(WoolHandler(Items.WHITE_WOOL as BlockItem, Items.WHITE_CARPET as BlockItem)) + Items.ORANGE_WOOL.registerHandler(WoolHandler(Items.ORANGE_WOOL as BlockItem, Items.ORANGE_CARPET as BlockItem)) + Items.MAGENTA_WOOL.registerHandler(WoolHandler(Items.MAGENTA_WOOL as BlockItem, Items.MAGENTA_CARPET as BlockItem)) + Items.LIGHT_BLUE_WOOL.registerHandler( + WoolHandler(Items.LIGHT_BLUE_WOOL as BlockItem, Items.LIGHT_BLUE_CARPET as BlockItem) + ) + Items.YELLOW_WOOL.registerHandler(WoolHandler(Items.YELLOW_WOOL as BlockItem, Items.YELLOW_CARPET as BlockItem)) + Items.LIME_WOOL.registerHandler(WoolHandler(Items.LIME_WOOL as BlockItem, Items.LIME_CARPET as BlockItem)) + Items.PINK_WOOL.registerHandler(WoolHandler(Items.PINK_WOOL as BlockItem, Items.PINK_CARPET as BlockItem)) + Items.GRAY_WOOL.registerHandler(WoolHandler(Items.GRAY_WOOL as BlockItem, Items.GRAY_CARPET as BlockItem)) + Items.LIGHT_GRAY_WOOL.registerHandler( + WoolHandler(Items.LIGHT_GRAY_WOOL as BlockItem, Items.LIGHT_GRAY_CARPET as BlockItem) + ) + Items.CYAN_WOOL.registerHandler(WoolHandler(Items.CYAN_WOOL as BlockItem, Items.CYAN_CARPET as BlockItem)) + Items.PURPLE_WOOL.registerHandler(WoolHandler(Items.PURPLE_WOOL as BlockItem, Items.PURPLE_CARPET as BlockItem)) + Items.BLUE_WOOL.registerHandler(WoolHandler(Items.BLUE_WOOL as BlockItem, Items.BLUE_CARPET as BlockItem)) + Items.BROWN_WOOL.registerHandler(WoolHandler(Items.BROWN_WOOL as BlockItem, Items.BROWN_CARPET as BlockItem)) + Items.GREEN_WOOL.registerHandler(WoolHandler(Items.GREEN_WOOL as BlockItem, Items.GREEN_CARPET as BlockItem)) + Items.RED_WOOL.registerHandler(WoolHandler(Items.RED_WOOL as BlockItem, Items.RED_CARPET as BlockItem)) + Items.BLACK_WOOL.registerHandler(WoolHandler(Items.BLACK_WOOL as BlockItem, Items.BLACK_CARPET as BlockItem)) } @Environment(EnvType.CLIENT) 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 96da32785..b25cc8e8d 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 @@ -18,7 +18,6 @@ package opekope2.avm_staff.internal.staff_handler -import net.minecraft.block.Block import net.minecraft.client.MinecraftClient import net.minecraft.client.network.ClientPlayerEntity import net.minecraft.component.type.AttributeModifierSlot @@ -26,26 +25,23 @@ import net.minecraft.component.type.AttributeModifiersComponent import net.minecraft.entity.LivingEntity import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.BlockItem import net.minecraft.item.ItemPlacementContext import net.minecraft.item.ItemStack import net.minecraft.registry.tag.BlockTags -import net.minecraft.sound.SoundCategory import net.minecraft.util.ActionResult import net.minecraft.util.Hand import net.minecraft.util.hit.BlockHitResult 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.staff.StaffHandler import opekope2.avm_staff.mixin.IMinecraftClientMixin import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.attackSpeed +import opekope2.avm_staff.util.mutableItemStackInStaff -class WoolHandler(woolBlock: Block, carpetBlock: Block) : StaffHandler() { - private val woolState = woolBlock.defaultState - private val carpetState = carpetBlock.defaultState - +class WoolHandler(private val woolBlockItem: BlockItem, private val carpetBlockItem: BlockItem) : StaffHandler() { override fun useOnBlock( staffStack: ItemStack, world: World, @@ -62,32 +58,15 @@ class WoolHandler(woolBlock: Block, carpetBlock: Block) : StaffHandler() { val originalState = world.getBlockState(target) if (originalState.isIn(BlockTags.WOOL) || originalState.isIn(BlockTags.WOOL_CARPETS)) return ActionResult.FAIL + val itemToPlace = if (side == Direction.UP) carpetBlockItem else woolBlockItem val woolPlaceContext = WoolPlacementContext( world, user as? PlayerEntity, hand, - staffStack, + staffStack.mutableItemStackInStaff!!, BlockHitResult(target.toCenterPos(), side, target, false) ) - if (!woolPlaceContext.canPlace()) return ActionResult.FAIL - - val placedState = if (side == Direction.UP) carpetState else woolState - if (!world.isClient) { - world.setBlockState(woolPlaceContext.blockPos, placedState) - } - - val woolSoundGroup = placedState.soundGroup - world.playSound( - user, - woolPlaceContext.blockPos, - woolSoundGroup.placeSound, - SoundCategory.BLOCKS, - (woolSoundGroup.volume + 1f) / 2f, - woolSoundGroup.pitch * 0.8f - ) - world.emitGameEvent(GameEvent.BLOCK_PLACE, woolPlaceContext.blockPos, GameEvent.Emitter.of(user, placedState)) - - return ActionResult.SUCCESS + return itemToPlace.place(woolPlaceContext) } override fun getAttributeModifiers(staffStack: ItemStack): AttributeModifiersComponent = ATTRIBUTE_MODIFIERS From ca876083182320aa1b1ec04e92b5245264837845 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 26 May 2024 19:24:25 +0200 Subject: [PATCH 092/128] Swap Blocks and Items wildcard import in VanillaStaffHandlers.kt Because items are used more --- .../staff_handler/VanillaStaffHandlers.kt | 134 +++++++++--------- 1 file changed, 65 insertions(+), 69 deletions(-) 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 b7d5e9f32..d7ccb9d77 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 @@ -21,10 +21,10 @@ 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.block.Blocks import net.minecraft.item.BlockItem import net.minecraft.item.Item -import net.minecraft.item.Items +import net.minecraft.item.Items.* import net.minecraft.recipe.RecipeType import net.minecraft.registry.Registries import net.minecraft.sound.SoundEvents @@ -39,65 +39,61 @@ private fun Item.registerHandler(handler: StaffHandler) { } fun registerVanillaStaffHandlers() { - Items.ANVIL.registerHandler(AnvilHandler(Items.CHIPPED_ANVIL::getDefaultStack)) - Items.CHIPPED_ANVIL.registerHandler(AnvilHandler(Items.DAMAGED_ANVIL::getDefaultStack)) - Items.DAMAGED_ANVIL.registerHandler(AnvilHandler { null }) + ANVIL.registerHandler(AnvilHandler(CHIPPED_ANVIL::getDefaultStack)) + CHIPPED_ANVIL.registerHandler(AnvilHandler(DAMAGED_ANVIL::getDefaultStack)) + DAMAGED_ANVIL.registerHandler(AnvilHandler { null }) - Items.BELL.registerHandler(BellBlockHandler()) + BELL.registerHandler(BellBlockHandler()) - Items.BONE_BLOCK.registerHandler(BoneBlockHandler()) + BONE_BLOCK.registerHandler(BoneBlockHandler()) - Items.CAMPFIRE.registerHandler( + CAMPFIRE.registerHandler( CampfireHandler(flamethrowerParticleType, CampfireHandler.Properties(1 / 20.0, 5 / 20.0, 1, 0.1)) ) - Items.SOUL_CAMPFIRE.registerHandler( + SOUL_CAMPFIRE.registerHandler( CampfireHandler(soulFlamethrowerParticleType, CampfireHandler.Properties(2 / 20.0, 10 / 20.0, 2, 0.12)) ) // TODO command block - Items.FURNACE.registerHandler( + FURNACE.registerHandler( FurnaceHandler(RecipeType.SMELTING, SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE) ) - Items.BLAST_FURNACE.registerHandler( + BLAST_FURNACE.registerHandler( FurnaceHandler(RecipeType.BLASTING, SoundEvents.BLOCK_BLASTFURNACE_FIRE_CRACKLE) ) - Items.SMOKER.registerHandler( + SMOKER.registerHandler( FurnaceHandler(RecipeType.SMOKING, SoundEvents.BLOCK_SMOKER_SMOKE) ) - Items.LIGHTNING_ROD.registerHandler(LightningRodHandler()) + LIGHTNING_ROD.registerHandler(LightningRodHandler()) - Items.MAGMA_BLOCK.registerHandler(MagmaBlockHandler()) + MAGMA_BLOCK.registerHandler(MagmaBlockHandler()) - Items.SNOW_BLOCK.registerHandler(SnowBlockHandler()) + SNOW_BLOCK.registerHandler(SnowBlockHandler()) - Items.TNT.registerHandler(TntHandler()) + TNT.registerHandler(TntHandler()) - Items.WITHER_SKELETON_SKULL.registerHandler( + WITHER_SKELETON_SKULL.registerHandler( WitherSkeletonSkullHandler() ) - Items.WHITE_WOOL.registerHandler(WoolHandler(Items.WHITE_WOOL as BlockItem, Items.WHITE_CARPET as BlockItem)) - Items.ORANGE_WOOL.registerHandler(WoolHandler(Items.ORANGE_WOOL as BlockItem, Items.ORANGE_CARPET as BlockItem)) - Items.MAGENTA_WOOL.registerHandler(WoolHandler(Items.MAGENTA_WOOL as BlockItem, Items.MAGENTA_CARPET as BlockItem)) - Items.LIGHT_BLUE_WOOL.registerHandler( - WoolHandler(Items.LIGHT_BLUE_WOOL as BlockItem, Items.LIGHT_BLUE_CARPET as BlockItem) - ) - Items.YELLOW_WOOL.registerHandler(WoolHandler(Items.YELLOW_WOOL as BlockItem, Items.YELLOW_CARPET as BlockItem)) - Items.LIME_WOOL.registerHandler(WoolHandler(Items.LIME_WOOL as BlockItem, Items.LIME_CARPET as BlockItem)) - Items.PINK_WOOL.registerHandler(WoolHandler(Items.PINK_WOOL as BlockItem, Items.PINK_CARPET as BlockItem)) - Items.GRAY_WOOL.registerHandler(WoolHandler(Items.GRAY_WOOL as BlockItem, Items.GRAY_CARPET as BlockItem)) - Items.LIGHT_GRAY_WOOL.registerHandler( - WoolHandler(Items.LIGHT_GRAY_WOOL as BlockItem, Items.LIGHT_GRAY_CARPET as BlockItem) - ) - Items.CYAN_WOOL.registerHandler(WoolHandler(Items.CYAN_WOOL as BlockItem, Items.CYAN_CARPET as BlockItem)) - Items.PURPLE_WOOL.registerHandler(WoolHandler(Items.PURPLE_WOOL as BlockItem, Items.PURPLE_CARPET as BlockItem)) - Items.BLUE_WOOL.registerHandler(WoolHandler(Items.BLUE_WOOL as BlockItem, Items.BLUE_CARPET as BlockItem)) - Items.BROWN_WOOL.registerHandler(WoolHandler(Items.BROWN_WOOL as BlockItem, Items.BROWN_CARPET as BlockItem)) - Items.GREEN_WOOL.registerHandler(WoolHandler(Items.GREEN_WOOL as BlockItem, Items.GREEN_CARPET as BlockItem)) - Items.RED_WOOL.registerHandler(WoolHandler(Items.RED_WOOL as BlockItem, Items.RED_CARPET as BlockItem)) - Items.BLACK_WOOL.registerHandler(WoolHandler(Items.BLACK_WOOL as BlockItem, Items.BLACK_CARPET as BlockItem)) + 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)) } @Environment(EnvType.CLIENT) @@ -112,47 +108,47 @@ private fun Item.registerStaffItemRenderer(staffItem: Block) { @Environment(EnvType.CLIENT) fun registerVanillaStaffItemRenderers() { - Items.ANVIL.registerStaffItemRenderer(ANVIL) - Items.CHIPPED_ANVIL.registerStaffItemRenderer(CHIPPED_ANVIL) - Items.DAMAGED_ANVIL.registerStaffItemRenderer(DAMAGED_ANVIL) + ANVIL.registerStaffItemRenderer(Blocks.ANVIL) + CHIPPED_ANVIL.registerStaffItemRenderer(Blocks.CHIPPED_ANVIL) + DAMAGED_ANVIL.registerStaffItemRenderer(Blocks.DAMAGED_ANVIL) - Items.BELL.registerStaffItemRenderer(BellBlockHandler.BellStaffItemRenderer()) + BELL.registerStaffItemRenderer(BellBlockHandler.BellStaffItemRenderer()) - Items.BONE_BLOCK.registerStaffItemRenderer(BONE_BLOCK) + BONE_BLOCK.registerStaffItemRenderer(Blocks.BONE_BLOCK) - Items.CAMPFIRE.registerStaffItemRenderer(CAMPFIRE) - Items.SOUL_CAMPFIRE.registerStaffItemRenderer(SOUL_CAMPFIRE) + CAMPFIRE.registerStaffItemRenderer(Blocks.CAMPFIRE) + SOUL_CAMPFIRE.registerStaffItemRenderer(Blocks.SOUL_CAMPFIRE) - Items.COMMAND_BLOCK.registerStaffItemRenderer(COMMAND_BLOCK) + COMMAND_BLOCK.registerStaffItemRenderer(Blocks.COMMAND_BLOCK) - Items.FURNACE.registerStaffItemRenderer(FurnaceHandler.FurnaceStaffItemRenderer(FURNACE)) - Items.BLAST_FURNACE.registerStaffItemRenderer(FurnaceHandler.FurnaceStaffItemRenderer(BLAST_FURNACE)) - Items.SMOKER.registerStaffItemRenderer(FurnaceHandler.FurnaceStaffItemRenderer(SMOKER)) + FURNACE.registerStaffItemRenderer(FurnaceHandler.FurnaceStaffItemRenderer(Blocks.FURNACE)) + BLAST_FURNACE.registerStaffItemRenderer(FurnaceHandler.FurnaceStaffItemRenderer(Blocks.BLAST_FURNACE)) + SMOKER.registerStaffItemRenderer(FurnaceHandler.FurnaceStaffItemRenderer(Blocks.SMOKER)) - Items.LIGHTNING_ROD.registerStaffItemRenderer(LightningRodHandler.LightningRodStaffItemRenderer()) + LIGHTNING_ROD.registerStaffItemRenderer(LightningRodHandler.LightningRodStaffItemRenderer()) - Items.MAGMA_BLOCK.registerStaffItemRenderer(MAGMA_BLOCK) + MAGMA_BLOCK.registerStaffItemRenderer(Blocks.MAGMA_BLOCK) - Items.SNOW_BLOCK.registerStaffItemRenderer(SNOW_BLOCK) + SNOW_BLOCK.registerStaffItemRenderer(Blocks.SNOW_BLOCK) - Items.TNT.registerStaffItemRenderer(TNT) + TNT.registerStaffItemRenderer(Blocks.TNT) - Items.WITHER_SKELETON_SKULL.registerStaffItemRenderer(WitherSkeletonSkullHandler.WitherSkeletonSkullStaffItemRenderer()) + WITHER_SKELETON_SKULL.registerStaffItemRenderer(WitherSkeletonSkullHandler.WitherSkeletonSkullStaffItemRenderer()) - Items.WHITE_WOOL.registerStaffItemRenderer(WHITE_WOOL) - Items.ORANGE_WOOL.registerStaffItemRenderer(ORANGE_WOOL) - Items.MAGENTA_WOOL.registerStaffItemRenderer(MAGENTA_WOOL) - Items.LIGHT_BLUE_WOOL.registerStaffItemRenderer(LIGHT_BLUE_WOOL) - Items.YELLOW_WOOL.registerStaffItemRenderer(YELLOW_WOOL) - Items.LIME_WOOL.registerStaffItemRenderer(LIME_WOOL) - Items.PINK_WOOL.registerStaffItemRenderer(PINK_WOOL) - Items.GRAY_WOOL.registerStaffItemRenderer(GRAY_WOOL) - Items.LIGHT_GRAY_WOOL.registerStaffItemRenderer(LIGHT_GRAY_WOOL) - Items.CYAN_WOOL.registerStaffItemRenderer(CYAN_WOOL) - Items.PURPLE_WOOL.registerStaffItemRenderer(PURPLE_WOOL) - Items.BLUE_WOOL.registerStaffItemRenderer(BLUE_WOOL) - Items.BROWN_WOOL.registerStaffItemRenderer(BROWN_WOOL) - Items.GREEN_WOOL.registerStaffItemRenderer(GREEN_WOOL) - Items.RED_WOOL.registerStaffItemRenderer(RED_WOOL) - Items.BLACK_WOOL.registerStaffItemRenderer(BLACK_WOOL) + 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) } From 810763482e42352fdcdf020de57ce02308c822e5 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 26 May 2024 19:41:44 +0200 Subject: [PATCH 093/128] Make anvil staff not able to break blocks --- .../internal/staff_handler/AnvilHandler.kt | 13 +++++++++++++ 1 file changed, 13 insertions(+) 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 aaa779df2..696b6e50f 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 @@ -30,7 +30,9 @@ import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack import net.minecraft.predicate.entity.EntityPredicates import net.minecraft.util.Hand +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.minecraft.world.WorldEvents import opekope2.avm_staff.api.staff.StaffHandler @@ -42,6 +44,17 @@ import kotlin.math.ceil import kotlin.math.floor class AnvilHandler(private val damagedStackFactory: () -> ItemStack?) : StaffHandler() { + override fun attackBlock( + staffStack: ItemStack, + world: World, + attacker: LivingEntity, + target: BlockPos, + side: Direction, + hand: Hand + ): EventResult { + return EventResult.interruptFalse() + } + override fun attackEntity( staffStack: ItemStack, world: World, From cbcbae8a392d5684ae1a75a8bf71162aab48686c Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 26 May 2024 19:42:35 +0200 Subject: [PATCH 094/128] fixup! Rework anvil staff mechanics --- StaffMod/src/main/resources/avm_staff.accesswidener | 2 ++ 1 file changed, 2 insertions(+) diff --git a/StaffMod/src/main/resources/avm_staff.accesswidener b/StaffMod/src/main/resources/avm_staff.accesswidener index 69cbc3891..616ef51d5 100644 --- a/StaffMod/src/main/resources/avm_staff.accesswidener +++ b/StaffMod/src/main/resources/avm_staff.accesswidener @@ -1,5 +1,7 @@ accessWidener v2 named +accessible field net/minecraft/block/AnvilBlock FALLING_BLOCK_ENTITY_DAMAGE_MULTIPLIER F +accessible field net/minecraft/block/AnvilBlock FALLING_BLOCK_ENTITY_MAX_DAMAGE I accessible method net/minecraft/block/entity/AbstractFurnaceBlockEntity dropExperience (Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/util/math/Vec3d;IF)V accessible method net/minecraft/entity/Entity getRotationVector (FF)Lnet/minecraft/util/math/Vec3d; accessible field net/minecraft/item/SmithingTemplateItem ARMOR_TRIM_ADDITIONS_SLOT_DESCRIPTION_TEXT Lnet/minecraft/text/Text; From 14a9451c192a2d1688295ce09fda7ef6f9f73e3b Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 26 May 2024 19:44:44 +0200 Subject: [PATCH 095/128] Remove attackBlock Fabric parity because of its side effects --- .../main/kotlin/opekope2/avm_staff/api/staff/StaffHandler.kt | 4 ++-- .../avm_staff/internal/event_handler/InteractionHandler.kt | 4 +--- 2 files changed, 3 insertions(+), 5 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 dee2be2b7..49e2d8feb 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 @@ -232,8 +232,8 @@ abstract class StaffHandler { * Called on both the client and the server by Architectury API, when an entity attacks a block with a staff. * * @return - * - [EventResult.interruptTrue], [EventResult.interruptTrue]: - * Cancels vanilla block breaking, and on the logical client, sends a packet to the server. + * - [EventResult.interruptTrue], [EventResult.interruptFalse]: + * Cancels vanilla block breaking, and on a Neo/Forge logical client, sends a packet to the server. * - [EventResult.interruptDefault], [EventResult.pass]: * Lets Minecraft handle vanilla block breaking. * diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/InteractionHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/InteractionHandler.kt index 58de2a432..28122be8c 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/InteractionHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/InteractionHandler.kt @@ -37,9 +37,7 @@ fun attackBlock(player: PlayerEntity, hand: Hand, target: BlockPos, direction: D val itemInStaff = staffStack.itemInStaff ?: return EventResult.pass() val staffHandler = itemInStaff.staffHandler ?: return EventResult.pass() - val result = staffHandler.attackBlock(staffStack, player.entityWorld, player, target, direction, hand) - return if (result.isFalse) EventResult.interruptTrue() // Force Fabric to send packet for Neo/Forge parity - else result + return staffHandler.attackBlock(staffStack, player.entityWorld, player, target, direction, hand) } @Environment(EnvType.CLIENT) From e06e25f55067ca3909f429dfc4bf2a37429e7ccc Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sun, 26 May 2024 19:45:03 +0200 Subject: [PATCH 096/128] Extend reach of staff by 1 block --- .../opekope2/avm_staff/api/staff/StaffHandler.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) 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 49e2d8feb..fbe317622 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 @@ -24,6 +24,7 @@ import net.minecraft.component.type.AttributeModifierSlot import net.minecraft.component.type.AttributeModifiersComponent import net.minecraft.entity.Entity import net.minecraft.entity.LivingEntity +import net.minecraft.entity.attribute.EntityAttributeModifier import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.Item @@ -354,6 +355,16 @@ abstract class StaffHandler { private val ATTRIBUTE_MODIFIERS = AttributeModifiersComponent.builder() .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(4.0), AttributeModifierSlot.MAINHAND) .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(2.0), AttributeModifierSlot.MAINHAND) + .add( + EntityAttributes.PLAYER_ENTITY_INTERACTION_RANGE, + EntityAttributeModifier("Weapon modifier", 1.0, EntityAttributeModifier.Operation.ADD_VALUE), + AttributeModifierSlot.MAINHAND + ) + .add( + EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE, + EntityAttributeModifier("Weapon modifier", 1.0, EntityAttributeModifier.Operation.ADD_VALUE), + AttributeModifierSlot.MAINHAND + ) .build() private val staffItemsHandlers = mutableMapOf() From b4a485539c0c930b5f054cb614193803496e2cf7 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 30 May 2024 17:58:26 +0200 Subject: [PATCH 097/128] Move itemStackInStaff setter to mutableItemStackInStaff --- .../kotlin/opekope2/avm_staff/api/StaffMod.kt | 4 ++-- .../internal/event_handler/NetworkHandler.kt | 4 ++-- .../internal/staff_handler/AnvilHandler.kt | 4 ++-- .../opekope2/avm_staff/util/StaffUtil.kt | 22 +++++++++---------- 4 files changed, 17 insertions(+), 17 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 98cabbf71..39154beb7 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,7 @@ import opekope2.avm_staff.internal.createStaffItem import opekope2.avm_staff.internal.createStaffRendererItem import opekope2.avm_staff.util.MOD_ID import opekope2.avm_staff.util.UnitComponent -import opekope2.avm_staff.util.itemStackInStaff +import opekope2.avm_staff.util.mutableItemStackInStaff private val ITEMS = DeferredRegister.create(MOD_ID, RegistryKeys.ITEM) private val ITEM_GROUPS = DeferredRegister.create(MOD_ID, RegistryKeys.ITEM_GROUP) @@ -130,7 +130,7 @@ val staffsTag: TagKey = TagKey.of(RegistryKeys.ITEM, Identifier(MOD_ID, "s val staffModItemGroup: RegistrySupplier = ITEM_GROUPS.register("${MOD_ID}_items") { CreativeTabRegistry.create(Text.translatable("itemGroup.${MOD_ID}_items")) { royalStaffItem.get().defaultStack.apply { - itemStackInStaff = Items.COMMAND_BLOCK.defaultStack + mutableItemStackInStaff = Items.COMMAND_BLOCK.defaultStack } } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt index c0da0086f..2517074e0 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt @@ -36,7 +36,7 @@ fun addItemToStaff(packet: AddItemToStaffC2SPacket, context: PacketContext) { if (itemStackToAdd.isEmpty) return if (!itemStackToAdd.item.hasStaffHandler) return if (staffStack.isItemInStaff) return - staffStack.itemStackInStaff = itemStackToAdd.split(1) + staffStack.mutableItemStackInStaff = itemStackToAdd.split(1) } @Suppress("UNUSED_PARAMETER") @@ -51,7 +51,7 @@ fun removeItemFromStaff(packet: RemoveItemFromStaffC2SPacket, context: PacketCon if (itemStack.canAccept(staffItem, inventory.maxCountPerStack)) { inventory.insertStack(itemSlot, staffItem) - staffStack.itemStackInStaff = null + staffStack.mutableItemStackInStaff = null } } 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 696b6e50f..03e7a827a 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 @@ -38,7 +38,7 @@ import net.minecraft.world.WorldEvents import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.equipTime -import opekope2.avm_staff.util.itemStackInStaff +import opekope2.avm_staff.util.mutableItemStackInStaff import java.util.* import kotlin.math.ceil import kotlin.math.floor @@ -104,7 +104,7 @@ class AnvilHandler(private val damagedStackFactory: () -> ItemStack?) : StaffHan private fun damageAnvil(staffStack: ItemStack, attacker: LivingEntity, fallDistance: Float): Boolean { if (attacker is PlayerEntity && !attacker.abilities.creativeMode && attacker.random.nextFloat() < 0.05f + fallDistance * 0.05f) { val damagedStack = damagedStackFactory() - staffStack.itemStackInStaff = damagedStack + staffStack.mutableItemStackInStaff = damagedStack return damagedStack == null } 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 18915290c..b2359aa9c 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt @@ -45,14 +45,22 @@ val ItemStack.itemInStaff: Item? get() = getOrDefault(staffItemComponentType.get(), null)?.item?.item /** - * Gets or sets the item stack inserted into the given staff item stack. + * Gets the item stack inserted into the given staff item stack. * The value returned MUST NOT be modified in any way, use [mutableItemStackInStaff] instead. - * The value passed in MUST NOT be stored elsewhere, pass in a copy of it instead. * * @see mutableItemStackInStaff */ -var ItemStack.itemStackInStaff: ItemStack? +val ItemStack.itemStackInStaff: ItemStack? get() = getOrDefault(staffItemComponentType.get(), 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 + * be freely modified. + * + * @see itemStackInStaff + */ +var ItemStack.mutableItemStackInStaff: ItemStack? + get() = itemStackInStaff?.copy() set(value) { if (value == null || value.isEmpty) { remove(staffItemComponentType.get()) @@ -62,14 +70,6 @@ var ItemStack.itemStackInStaff: ItemStack? this[staffItemComponentType.get()] = StaffItemComponent(value.copy()) } -/** - * Gets a copy of the item stack inserted into the given staff item stack. The value returned can be freely modified. - * - * @see itemStackInStaff - */ -val ItemStack.mutableItemStackInStaff: ItemStack? - get() = itemStackInStaff?.copy() - /** * Returns if the given item has a registered handler when inserted into a staff. */ From 9feb9dc86f864bd00c62fc9b0dcc7ff2d170fbb3 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 30 May 2024 20:40:57 +0200 Subject: [PATCH 098/128] Split MathUtil to VectorUtil and MatrixUtil --- .../opekope2/avm_staff/util/MatrixUtil.kt | 35 +++++++++++++++++++ .../util/{MathUtil.kt => VectorUtil.kt} | 15 +------- 2 files changed, 36 insertions(+), 14 deletions(-) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/util/MatrixUtil.kt rename StaffMod/src/main/kotlin/opekope2/avm_staff/util/{MathUtil.kt => VectorUtil.kt} (80%) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/MatrixUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/MatrixUtil.kt new file mode 100644 index 000000000..b4d42f011 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/MatrixUtil.kt @@ -0,0 +1,35 @@ +/* + * 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("MatrixUtil") + +package opekope2.avm_staff.util + +import net.minecraft.client.util.math.MatrixStack + +/** + * [Pushes][MatrixStack.push] to the given matrix stack, invokes [action], then [pops][MatrixStack.pop] from the given + * matrix stack. + * + * @param action The action to invoke between [MatrixStack.push] and [MatrixStack.pop] + */ +inline fun MatrixStack.push(action: MatrixStack.() -> Unit) { + push() + action() + pop() +} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/MathUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/VectorUtil.kt similarity index 80% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/util/MathUtil.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/util/VectorUtil.kt index 3e77f6a8b..82133b793 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/MathUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/VectorUtil.kt @@ -16,12 +16,11 @@ * along with this mod. If not, see . */ -@file: JvmName("MathUtil") +@file: JvmSynthetic @file: Suppress("NOTHING_TO_INLINE") package opekope2.avm_staff.util -import net.minecraft.client.util.math.MatrixStack import net.minecraft.util.math.Vec3d import org.joml.Vector3f import org.joml.Vector3fc @@ -57,15 +56,3 @@ inline operator fun Vector3f.minusAssign(other: Vector3fc) { inline operator fun Vector3f.timesAssign(scalar: Float) { mul(scalar) } - -/** - * [Pushes][MatrixStack.push] to the given matrix stack, invokes [action], then [pops][MatrixStack.pop] from the given - * matrix stack. - * - * @param action The action to invoke between [MatrixStack.push] and [MatrixStack.pop] - */ -inline fun MatrixStack.push(action: MatrixStack.() -> Unit) { - push() - action() - pop() -} From 06a76c14302e3b361edfae060e009a954c186a48 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 30 May 2024 20:46:41 +0200 Subject: [PATCH 099/128] Remove unused DfuUtil --- .../kotlin/opekope2/avm_staff/util/DfuUtil.kt | 34 ------------------- 1 file changed, 34 deletions(-) delete mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/util/DfuUtil.kt diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/DfuUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/DfuUtil.kt deleted file mode 100644 index 7d8065cff..000000000 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/DfuUtil.kt +++ /dev/null @@ -1,34 +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("DfuUtil") -@file: Suppress("NOTHING_TO_INLINE") - -package opekope2.avm_staff.util - -import com.mojang.datafixers.util.Either -import com.mojang.datafixers.util.Pair -import java.util.* - -inline operator fun Pair.component1(): F = first - -inline operator fun Pair.component2(): S = second - -inline operator fun Either.component1(): Optional = left() - -inline operator fun Either.component2(): Optional = right() From 911848e58f7e3ff829356ddbcc990a6403f573e8 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 30 May 2024 23:09:20 +0200 Subject: [PATCH 100/128] Change staff item component handling Because FabricItem.getAttributeModifiers was nuked --- .../internal/fabric/item/FabricStaffItem.kt | 5 ---- .../neoforge/item/NeoForgeStaffItem.kt | 5 ---- .../kotlin/opekope2/avm_staff/api/StaffMod.kt | 6 ++++- .../opekope2/avm_staff/api/item/StaffItem.kt | 5 ++++ .../avm_staff/api/staff/StaffHandler.kt | 24 +++++++++---------- .../internal/staff_handler/AnvilHandler.kt | 5 ++-- .../staff_handler/BellBlockHandler.kt | 5 ++-- .../internal/staff_handler/FurnaceHandler.kt | 5 ++-- .../staff_handler/MagmaBlockHandler.kt | 5 ++-- .../internal/staff_handler/WoolHandler.kt | 5 ++-- .../opekope2/avm_staff/util/StaffUtil.kt | 10 +++++--- 11 files changed, 43 insertions(+), 37 deletions(-) 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 aa7547960..db0f4a948 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 @@ -22,7 +22,6 @@ import net.fabricmc.api.EnvType import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry import net.fabricmc.fabric.api.item.v1.FabricItem import net.fabricmc.loader.api.FabricLoader -import net.minecraft.component.type.AttributeModifiersComponent import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.Item import net.minecraft.item.ItemStack @@ -51,8 +50,4 @@ class FabricStaffItem(settings: Item.Settings) : StaffItem(settings), FabricItem return if (oldHandler !== newHandler) true else oldHandler.allowComponentsUpdateAnimation(oldStack, newStack, player, hand) } - - override fun getAttributeModifiers(stack: ItemStack): AttributeModifiersComponent { - return stack.itemInStaff.staffHandlerOrDefault.getAttributeModifiers(stack) - } } 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 a81b1942b..69c73202b 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 @@ -23,7 +23,6 @@ import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.render.item.BuiltinModelItemRenderer import net.minecraft.client.render.model.json.ModelTransformationMode import net.minecraft.client.util.math.MatrixStack -import net.minecraft.component.type.AttributeModifiersComponent import net.minecraft.entity.Entity import net.minecraft.entity.LivingEntity import net.minecraft.entity.player.PlayerEntity @@ -39,10 +38,6 @@ import opekope2.avm_staff.util.staffHandlerOrDefault import java.util.function.Consumer class NeoForgeStaffItem(settings: Item.Settings) : StaffItem(settings), IItemExtension { - override fun getAttributeModifiers(stack: ItemStack): AttributeModifiersComponent { - return stack.itemInStaff.staffHandlerOrDefault.getAttributeModifiers(stack) - } - @Suppress("RemoveExplicitSuperQualifier") // Required because StaffItem apparently also has canDisableShield override fun canDisableShield( stack: ItemStack, 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 39154beb7..8436e2ad8 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -43,6 +43,7 @@ import net.minecraft.util.Rarity 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.api.staff.StaffItemComponent import opekope2.avm_staff.internal.createCrownItem @@ -85,7 +86,10 @@ val faintRoyalStaffItem: RegistrySupplier = ITEMS.register("faint_royal_st * Item registered as `avm_staff:royal_staff`. */ val royalStaffItem: RegistrySupplier = ITEMS.register("royal_staff") { - createStaffItem(Item.Settings().maxCount(1).rarity(Rarity.EPIC).`arch$tab`(staffModItemGroup)) + createStaffItem( + Item.Settings().maxCount(1).rarity(Rarity.EPIC).attributeModifiers(StaffHandler.Default.ATTRIBUTE_MODIFIERS) + .`arch$tab`(staffModItemGroup) + ) } /** 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 ae0bf2811..fbbaf34e6 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 net.minecraft.component.DataComponentTypes import net.minecraft.entity.ItemEntity import net.minecraft.entity.LivingEntity import net.minecraft.entity.player.PlayerEntity @@ -45,6 +46,10 @@ abstract class StaffItem(settings: Settings) : Item(settings) { ItemUsage.spawnItemContents(entity, listOf(staffItem)) } + override fun postProcessComponents(stack: ItemStack) { + stack[DataComponentTypes.ATTRIBUTE_MODIFIERS] = stack.itemInStaff.staffHandlerOrDefault.attributeModifiers + } + override fun getMaxUseTime(stack: ItemStack): Int { return stack.itemInStaff.staffHandlerOrDefault.maxUseTime } 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 fbe317622..ea8db3c4d 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 @@ -51,6 +51,12 @@ abstract class StaffHandler { 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 by Minecraft when the player uses the staff. * @@ -337,22 +343,12 @@ abstract class StaffHandler { return oldStaffStack != newStaffStack } - /** - * Gets the attribute modifiers (damage, attack speed, etc.) of the staff when held. - * - * @param staffStack The staff item stack (not the item in the staff) - */ - open fun getAttributeModifiers(staffStack: ItemStack): AttributeModifiersComponent { - return ATTRIBUTE_MODIFIERS - } - /** * Handler of a staff with no item inserted into it. */ - object Default : StaffHandler() - - companion object { - private val ATTRIBUTE_MODIFIERS = AttributeModifiersComponent.builder() + object Default : StaffHandler() { + @JvmField + val ATTRIBUTE_MODIFIERS: AttributeModifiersComponent = AttributeModifiersComponent.builder() .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(4.0), AttributeModifierSlot.MAINHAND) .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(2.0), AttributeModifierSlot.MAINHAND) .add( @@ -366,7 +362,9 @@ abstract class StaffHandler { AttributeModifierSlot.MAINHAND ) .build() + } + companion object { private val staffItemsHandlers = mutableMapOf() /** 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 03e7a827a..0aa1f4487 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 @@ -44,6 +44,9 @@ import kotlin.math.ceil import kotlin.math.floor class AnvilHandler(private val damagedStackFactory: () -> ItemStack?) : StaffHandler() { + override val attributeModifiers: AttributeModifiersComponent + get() = ATTRIBUTE_MODIFIERS + override fun attackBlock( staffStack: ItemStack, world: World, @@ -117,8 +120,6 @@ class AnvilHandler(private val damagedStackFactory: () -> ItemStack?) : StaffHan override fun disablesShield() = true - override fun getAttributeModifiers(staffStack: ItemStack): AttributeModifiersComponent = ATTRIBUTE_MODIFIERS - private companion object { private val ATTRIBUTE_MODIFIERS = AttributeModifiersComponent.builder() .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(40.0), AttributeModifierSlot.MAINHAND) 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 9cc538315..be8a82e8a 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 @@ -45,6 +45,9 @@ import opekope2.avm_staff.util.attackSpeed import opekope2.avm_staff.util.push class BellBlockHandler : StaffHandler() { + override val attributeModifiers: AttributeModifiersComponent + get() = ATTRIBUTE_MODIFIERS + override fun use( staffStack: ItemStack, world: World, @@ -75,8 +78,6 @@ class BellBlockHandler : StaffHandler() { return EventResult.pass() } - override fun getAttributeModifiers(staffStack: ItemStack): AttributeModifiersComponent = ATTRIBUTE_MODIFIERS - @Environment(EnvType.CLIENT) class BellStaffItemRenderer : IStaffItemRenderer { private val bellModel = BellBlockEntityRenderer.getTexturedModelData().createModel().apply { 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 0ba637a4a..d1ee14f78 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,6 +59,9 @@ class FurnaceHandler( ) : StaffHandler() { override val maxUseTime = 72000 + override val attributeModifiers: AttributeModifiersComponent + get() = ATTRIBUTE_MODIFIERS + override fun use( staffStack: ItemStack, world: World, @@ -166,8 +169,6 @@ class FurnaceHandler( return selectedSlotChanged } - override fun getAttributeModifiers(staffStack: ItemStack): AttributeModifiersComponent = ATTRIBUTE_MODIFIERS - @Environment(EnvType.CLIENT) class FurnaceStaffItemRenderer(unlitState: BlockState, litState: BlockState) : IStaffItemRenderer { constructor(furnaceBlock: Block) : this( 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 25b677e35..c6e128af2 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 @@ -37,6 +37,9 @@ import opekope2.avm_staff.util.* class MagmaBlockHandler : StaffHandler() { override val maxUseTime = 72000 + override val attributeModifiers: AttributeModifiersComponent + get() = ATTRIBUTE_MODIFIERS + override fun use( staffStack: ItemStack, world: World, @@ -87,8 +90,6 @@ class MagmaBlockHandler : StaffHandler() { }) } - override fun getAttributeModifiers(staffStack: ItemStack): AttributeModifiersComponent = ATTRIBUTE_MODIFIERS - private companion object { private val ATTRIBUTE_MODIFIERS = AttributeModifiersComponent.builder() .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(5.0), AttributeModifierSlot.MAINHAND) 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 b25cc8e8d..7f8cf29f0 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 @@ -42,6 +42,9 @@ import opekope2.avm_staff.util.attackSpeed import opekope2.avm_staff.util.mutableItemStackInStaff class WoolHandler(private val woolBlockItem: BlockItem, private val carpetBlockItem: BlockItem) : StaffHandler() { + override val attributeModifiers: AttributeModifiersComponent + get() = ATTRIBUTE_MODIFIERS + override fun useOnBlock( staffStack: ItemStack, world: World, @@ -69,8 +72,6 @@ class WoolHandler(private val woolBlockItem: BlockItem, private val carpetBlockI return itemToPlace.place(woolPlaceContext) } - override fun getAttributeModifiers(staffStack: ItemStack): AttributeModifiersComponent = ATTRIBUTE_MODIFIERS - private class WoolPlacementContext( world: World, playerEntity: PlayerEntity?, 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 b2359aa9c..4be586af7 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt @@ -20,6 +20,7 @@ package opekope2.avm_staff.util +import net.minecraft.component.ComponentChanges import net.minecraft.entity.Entity import net.minecraft.item.Item import net.minecraft.item.ItemStack @@ -62,12 +63,15 @@ val ItemStack.itemStackInStaff: ItemStack? var ItemStack.mutableItemStackInStaff: ItemStack? get() = itemStackInStaff?.copy() set(value) { + val changes = ComponentChanges.builder() + if (value == null || value.isEmpty) { - remove(staffItemComponentType.get()) - return + changes.remove(staffItemComponentType.get()) + } else { + changes.add(staffItemComponentType.get(), StaffItemComponent(value.copy())) } - this[staffItemComponentType.get()] = StaffItemComponent(value.copy()) + applyChanges(changes.build()) } /** From fe437e857f22405ffef3cc039a5dbcb650cdc7f7 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 4 Jun 2024 20:13:13 +0200 Subject: [PATCH 101/128] Balance some items Others were already balanced --- .../internal/staff_handler/BoneBlockHandler.kt | 15 +++++++++++++++ .../internal/staff_handler/FurnaceHandler.kt | 4 ++-- .../internal/staff_handler/MagmaBlockHandler.kt | 4 ++-- 3 files changed, 19 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 1be959e2d..36b87b40d 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 @@ -18,7 +18,10 @@ package opekope2.avm_staff.internal.staff_handler +import net.minecraft.component.type.AttributeModifierSlot +import net.minecraft.component.type.AttributeModifiersComponent import net.minecraft.entity.LivingEntity +import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.item.BoneMealItem import net.minecraft.item.ItemStack import net.minecraft.util.ActionResult @@ -29,8 +32,13 @@ import net.minecraft.world.World import net.minecraft.world.WorldEvents import net.minecraft.world.event.GameEvent import opekope2.avm_staff.api.staff.StaffHandler +import opekope2.avm_staff.util.attackDamage +import opekope2.avm_staff.util.attackSpeed class BoneBlockHandler : StaffHandler() { + override val attributeModifiers: AttributeModifiersComponent + get() = ATTRIBUTE_MODIFIERS + override fun useOnBlock( staffStack: ItemStack, world: World, @@ -62,4 +70,11 @@ class BoneBlockHandler : StaffHandler() { return ActionResult.success(world.isClient) } + + companion object { + private val ATTRIBUTE_MODIFIERS = AttributeModifiersComponent.builder() + .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(5.0), AttributeModifierSlot.MAINHAND) + .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(2.0), AttributeModifierSlot.MAINHAND) + .build() + } } 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 d1ee14f78..0611af0b7 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 @@ -213,8 +213,8 @@ class FurnaceHandler( companion object { private val SMELTING_VOLUME = Box(-0.5, -0.5, -0.5, 0.5, 0.5, 0.5).contract(0.25 / 2) private val ATTRIBUTE_MODIFIERS = AttributeModifiersComponent.builder() - .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(5.0), AttributeModifierSlot.MAINHAND) - .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(2.0), AttributeModifierSlot.MAINHAND) + .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(10.0), AttributeModifierSlot.MAINHAND) + .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(1.25), AttributeModifierSlot.MAINHAND) .build() } } 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 c6e128af2..c8131b167 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 @@ -92,8 +92,8 @@ class MagmaBlockHandler : StaffHandler() { private companion object { private val ATTRIBUTE_MODIFIERS = AttributeModifiersComponent.builder() - .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(5.0), AttributeModifierSlot.MAINHAND) - .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(2.0), AttributeModifierSlot.MAINHAND) + .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(10.0), AttributeModifierSlot.MAINHAND) + .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(1.25), AttributeModifierSlot.MAINHAND) .build() } } From 8e1b6af1e58841a4f831b6ac2f518e19fd6ca11f Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 7 Jun 2024 01:56:40 +0200 Subject: [PATCH 102/128] Add avm_staff:staff_renderer_override component Used for Isometric Renders mod compatibility and renders in the docs --- .../mixin/BipedEntityModelMixin.java | 15 ++++- .../kotlin/opekope2/avm_staff/api/StaffMod.kt | 13 ++++ .../api/item/renderer/StaffRenderer.kt | 11 ++-- .../staff/StaffRendererOverrideComponent.kt | 61 +++++++++++++++++++ .../internal/model/ModelPredicates.kt | 2 + 5 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/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 6977c47bf..e2602e461 100644 --- a/StaffMod/src/main/java/opekope2/avm_staff/mixin/BipedEntityModelMixin.java +++ b/StaffMod/src/main/java/opekope2/avm_staff/mixin/BipedEntityModelMixin.java @@ -22,9 +22,11 @@ import net.minecraft.client.render.entity.model.BipedEntityModel; import net.minecraft.entity.LivingEntity; import opekope2.avm_staff.api.StaffMod; +import opekope2.avm_staff.api.staff.StaffRendererOverrideComponent; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -51,7 +53,7 @@ public abstract class BipedEntityModelMixin { @Inject(method = "positionLeftArm", at = @At("TAIL")) private void positionLeftArm(LivingEntity entity, CallbackInfo ci) { - if (leftArmPose == BipedEntityModel.ArmPose.ITEM && entity.getActiveItem().isIn(StaffMod.getStaffsTag())) { + if (staffMod$pointForward(leftArmPose, entity)) { leftArm.yaw = head.yaw; leftArm.pitch = head.pitch - 0.5f * (float) Math.PI; } @@ -59,9 +61,18 @@ private void positionLeftArm(LivingEntity entity, CallbackInfo ci) { @Inject(method = "positionRightArm", at = @At("TAIL")) private void positionRightArm(LivingEntity entity, CallbackInfo ci) { - if (rightArmPose == BipedEntityModel.ArmPose.ITEM && entity.getActiveItem().isIn(StaffMod.getStaffsTag())) { + if (staffMod$pointForward(rightArmPose, entity)) { rightArm.yaw = head.yaw; rightArm.pitch = head.pitch - 0.5f * (float) Math.PI; } } + + @Unique + private boolean staffMod$pointForward(BipedEntityModel.ArmPose armPose, LivingEntity entity) { + if (armPose != BipedEntityModel.ArmPose.ITEM) return false; + if (entity.getActiveItem().isIn(StaffMod.getStaffsTag())) return true; + + StaffRendererOverrideComponent rendererOverride = entity.getMainHandStack().get(StaffMod.getStaffRendererOverrideComponentType().get()); + return rendererOverride != null && rendererOverride.isActive(); + } } 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 8436e2ad8..92ac92450 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -46,6 +46,7 @@ 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.api.staff.StaffItemComponent +import opekope2.avm_staff.api.staff.StaffRendererOverrideComponent import opekope2.avm_staff.internal.createCrownItem import opekope2.avm_staff.internal.createStaffItem import opekope2.avm_staff.internal.createStaffRendererItem @@ -201,6 +202,18 @@ val furnaceLitComponentType: RegistrySupplier> .build() } +/** + * Data component registered as `avm_staff:staff_renderer_override`. Specifies how a staff is rendered. Intended for + * Isometric Renders mod compatibility. + */ +val staffRendererOverrideComponentType: RegistrySupplier> = + DATA_COMPONENT_TYPES.register("staff_renderer_override") { + DataComponentType.builder() + .codec(StaffRendererOverrideComponent.CODEC) + .packetCodec(StaffRendererOverrideComponent.PACKET_CODEC) + .build() + } + /** * @suppress */ 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 9bf5915b4..9de27cc5d 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,6 +27,7 @@ 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.staffRendererOverrideComponentType import opekope2.avm_staff.internal.model.HEAD_SEED import opekope2.avm_staff.internal.model.ITEM_SEED import opekope2.avm_staff.internal.model.ROD_BOTTOM_SEED @@ -57,17 +58,19 @@ object StaffRenderer { light: Int, overlay: Int ) { - when (mode) { + val renderMode = staffStack[staffRendererOverrideComponentType.get()]?.renderMode ?: mode + + when (renderMode) { ModelTransformationMode.GUI -> renderInventoryStaff( - mode, staffStack, matrices, vertexConsumers, light, overlay + renderMode, staffStack, matrices, vertexConsumers, light, overlay ) ModelTransformationMode.FIXED -> renderItemFrameStaff( - mode, staffStack, matrices, vertexConsumers, light, overlay + renderMode, staffStack, matrices, vertexConsumers, light, overlay ) else -> renderFullStaff( - mode, staffStack, matrices, vertexConsumers, light, overlay + renderMode, staffStack, matrices, vertexConsumers, light, overlay ) } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffRendererOverrideComponent.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffRendererOverrideComponent.kt new file mode 100644 index 000000000..5ffe52493 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/staff/StaffRendererOverrideComponent.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.api.staff + +import com.mojang.serialization.Codec +import com.mojang.serialization.codecs.RecordCodecBuilder +import net.minecraft.client.render.model.json.ModelTransformationMode +import net.minecraft.entity.LivingEntity +import net.minecraft.network.RegistryByteBuf +import net.minecraft.network.codec.PacketCodec +import opekope2.avm_staff.api.item.renderer.StaffRenderer + +/** + * 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] + */ +data class StaffRendererOverrideComponent(val renderMode: ModelTransformationMode, val isActive: Boolean) { + private constructor(buf: RegistryByteBuf) : this( + buf.readEnumConstant(ModelTransformationMode::class.java), + buf.readBoolean() + ) + + private fun encode(buf: RegistryByteBuf) { + buf.writeEnumConstant(renderMode) + buf.writeBoolean(isActive) + } + + companion object { + @JvmField + val CODEC: Codec = RecordCodecBuilder.create { instance -> + instance.group( + ModelTransformationMode.CODEC.fieldOf("renderMode") + .forGetter(StaffRendererOverrideComponent::renderMode), + Codec.BOOL.fieldOf("pointForward") + .forGetter(StaffRendererOverrideComponent::isActive) + ).apply(instance, ::StaffRendererOverrideComponent) + } + + @JvmField + val PACKET_CODEC: PacketCodec = + PacketCodec.of(StaffRendererOverrideComponent::encode, ::StaffRendererOverrideComponent) + } +} 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 cb8a500e7..a06c0e553 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 @@ -23,6 +23,7 @@ import net.fabricmc.api.Environment import net.minecraft.client.item.ClampedModelPredicateProvider import net.minecraft.item.ItemStack import net.minecraft.util.Identifier +import opekope2.avm_staff.api.staffRendererOverrideComponentType import opekope2.avm_staff.util.MOD_ID const val HEAD_SEED = -0b10011_10100_00001_00110_00110_00000 @@ -35,6 +36,7 @@ const val ROD_BOTTOM_SEED = -0b10011_10100_00001_00110_00110_00011 fun registerModelPredicateProviders(register: (Identifier, ClampedModelPredicateProvider) -> Unit) { register(Identifier(MOD_ID, "using_item")) { stack, _, entity, _ -> if (entity != null && entity.isUsingItem && ItemStack.areEqual(entity.activeItem, stack)) 1f + else if (stack[staffRendererOverrideComponentType.get()]?.isActive == true) 1f else 0f } register(Identifier(MOD_ID, "head")) { _, _, _, seed -> From 1bdcdc7fc7347ea3e3b86a9729c185a8d433ecc6 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 7 Jun 2024 22:15:05 +0200 Subject: [PATCH 103/128] Fix player attack cooldown not resetting after modifying a staff --- .../event_handler/KeyBindingHandler.kt | 11 ++- .../internal/event_handler/NetworkHandler.kt | 96 +++++++++++-------- 2 files changed, 65 insertions(+), 42 deletions(-) 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 8b58b7494..11da38749 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 @@ -28,7 +28,6 @@ import net.minecraft.client.util.InputUtil import opekope2.avm_staff.internal.networking.c2s.play.AddItemToStaffC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.RemoveItemFromStaffC2SPacket import opekope2.avm_staff.util.MOD_ID -import opekope2.avm_staff.util.isItemInStaff import org.lwjgl.glfw.GLFW val addRemoveStaffItemKeyBinding = KeyBinding( @@ -44,9 +43,13 @@ fun handleKeyBindings(client: MinecraftClient) { val player = client.player ?: return - if (player.mainHandStack.isItemInStaff || player.offHandStack.isItemInStaff) { - RemoveItemFromStaffC2SPacket().sendToServer() - } else { + player.canInsertIntoStaff().ifSuccess { AddItemToStaffC2SPacket().sendToServer() + player.resetLastAttackedTicks() + }.ifError { + player.canRemoveFromStaff().ifSuccess { + RemoveItemFromStaffC2SPacket().sendToServer() + player.resetLastAttackedTicks() + } } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt index 2517074e0..216b7f27a 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt @@ -18,6 +18,7 @@ package opekope2.avm_staff.internal.event_handler +import com.mojang.serialization.DataResult import dev.architectury.networking.NetworkManager.PacketContext import net.minecraft.entity.player.PlayerEntity import net.minecraft.entity.player.PlayerInventory @@ -30,28 +31,18 @@ import opekope2.avm_staff.util.* @Suppress("UNUSED_PARAMETER") fun addItemToStaff(packet: AddItemToStaffC2SPacket, context: PacketContext) { - val player = context.player - val (staffStack, itemStackToAdd) = findStaffAndItemStack(player) ?: return - - if (itemStackToAdd.isEmpty) return - if (!itemStackToAdd.item.hasStaffHandler) return - if (staffStack.isItemInStaff) return - staffStack.mutableItemStackInStaff = itemStackToAdd.split(1) + context.player.canInsertIntoStaff().ifSuccess { (staffStack, itemStackToAdd) -> + staffStack.mutableItemStackInStaff = itemStackToAdd.split(1) + context.player.resetLastAttackedTicks() + } } @Suppress("UNUSED_PARAMETER") fun removeItemFromStaff(packet: RemoveItemFromStaffC2SPacket, context: PacketContext) { - val player = context.player - if (player.isUsingItem) return - - val (staffStack, itemSlot) = findStaffStackAndItemSlot(player) ?: return - val inventory = player.inventory - val itemStack = inventory.getStack(itemSlot) - val staffItem = staffStack.mutableItemStackInStaff ?: return - - if (itemStack.canAccept(staffItem, inventory.maxCountPerStack)) { - inventory.insertStack(itemSlot, staffItem) + context.player.canRemoveFromStaff().ifSuccess { (staffStack, targetSlot) -> + context.player.inventory.insertStack(targetSlot, staffStack.mutableItemStackInStaff) staffStack.mutableItemStackInStaff = null + context.player.resetLastAttackedTicks() } } @@ -67,35 +58,64 @@ fun attack(packet: AttackC2SPacket, context: PacketContext) { staffHandler.attack(staffStack, player.entityWorld, player, packet.hand) } -private fun ItemStack.canAccept(other: ItemStack, maxCountPerStack: Int): Boolean { - val canCombine = isEmpty || ItemStack.areItemsAndComponentsEqual(this, other) - val totalCount = count + other.count +fun PlayerEntity.canInsertIntoStaff(): DataResult> { + val staffStack: ItemStack + val itemStackToAdd: ItemStack - return canCombine && totalCount <= item.maxCount && totalCount <= maxCountPerStack + when { + mainHandStack.isIn(staffsTag) && !offHandStack.isIn(staffsTag) -> { + staffStack = mainHandStack + itemStackToAdd = offHandStack + } + + offHandStack.isIn(staffsTag) && !mainHandStack.isIn(staffsTag) -> { + staffStack = offHandStack + itemStackToAdd = mainHandStack + } + + else -> return DataResult.error { "The player doesn't hold exactly 1 staff" } + } + + if (itemStackToAdd.isEmpty) return DataResult.error { "Can't insert empty ItemStack into staff" } + if (staffStack.isItemInStaff) return DataResult.error { "An item is already inserted into the staff" } + if (!itemStackToAdd.item.hasStaffHandler) return DataResult.error { "Can't insert item without a StaffHandler into the staff" } + + return DataResult.success(staffStack to itemStackToAdd) } -private fun findStaffStackAndItemSlot(player: PlayerEntity): Pair? { - val mainStack = player.mainHandStack - val offStack = player.offHandStack +fun PlayerEntity.canRemoveFromStaff(): DataResult> { + if (isUsingItem) return DataResult.error { "The player is using an item" } + + val staffStack: ItemStack + val targetSlot: Int - return when { - mainStack.isIn(staffsTag) && !offStack.isIn(staffsTag) -> - mainStack to PlayerInventory.OFF_HAND_SLOT + when { + mainHandStack.isIn(staffsTag) && !offHandStack.isIn(staffsTag) -> { + staffStack = mainHandStack + targetSlot = PlayerInventory.OFF_HAND_SLOT + } - offStack.isIn(staffsTag) && !mainStack.isIn(staffsTag) -> - offStack to player.inventory.selectedSlot + offHandStack.isIn(staffsTag) && !mainHandStack.isIn(staffsTag) -> { + staffStack = offHandStack + targetSlot = inventory.selectedSlot + } - else -> null + else -> return DataResult.error { "The player doesn't hold exactly 1 staff" } } -} -private fun findStaffAndItemStack(player: PlayerEntity): Pair? { - val mainStack = player.mainHandStack - val offStack = player.offHandStack + val targetStack = inventory.getStack(targetSlot) + val itemStackInStaff = staffStack.itemStackInStaff ?: return DataResult.error { "Staff is empty" } - return when { - mainStack.isIn(staffsTag) && !offStack.isIn(staffsTag) -> mainStack to offStack - offStack.isIn(staffsTag) && !mainStack.isIn(staffsTag) -> offStack to mainStack - else -> null + if (!targetStack.canAccept(itemStackInStaff, inventory.maxCountPerStack)) return DataResult.error { + "Target stack is incompatible with staff item" } + + return DataResult.success(staffStack to targetSlot) +} + +private fun ItemStack.canAccept(other: ItemStack, maxCountPerStack: Int): Boolean { + val canCombine = isEmpty || ItemStack.areItemsAndComponentsEqual(this, other) + val totalCount = count + other.count + + return canCombine && totalCount <= item.maxCount && totalCount <= maxCountPerStack } From 3a9232f289eed054a02a14b711d84b546de3cc02 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 7 Jun 2024 22:18:02 +0200 Subject: [PATCH 104/128] Fix sounds not playing on NeoForge in certain situations --- .../avm_staff/internal/staff_handler/MagmaBlockHandler.kt | 6 ++---- .../internal/staff_handler/WitherSkeletonSkullHandler.kt | 5 ++--- 2 files changed, 4 insertions(+), 7 deletions(-) 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 c8131b167..4ab516ddc 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 @@ -76,13 +76,11 @@ class MagmaBlockHandler : StaffHandler() { } private fun shootFireball(world: World, user: LivingEntity) { + if (world.isClient) return if (!user.canUseStaff) return - if (user is PlayerEntity && user.isAttackCoolingDown) return - world.syncWorldEvent(user as? PlayerEntity, WorldEvents.BLAZE_SHOOTS, user.blockPos, 0) - - if (world.isClient) return + world.syncWorldEvent(WorldEvents.BLAZE_SHOOTS, user.blockPos, 0) val (x, y, z) = user.rotationVector world.spawnEntity(SmallFireballEntity(world, user, x, y, z).apply { 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 9f6866543..ce4cfb788 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 @@ -71,12 +71,11 @@ class WitherSkeletonSkullHandler : StaffHandler() { } private fun shootSkull(world: World, user: LivingEntity, charged: Boolean) { + if (world.isClient) return if (!user.canUseStaff) return if (user is PlayerEntity && user.isAttackCoolingDown) return - world.syncWorldEvent(null, WorldEvents.WITHER_SHOOTS, user.blockPos, 0) - - if (world.isClient) return + world.syncWorldEvent(WorldEvents.WITHER_SHOOTS, user.blockPos, 0) val (x, y, z) = user.rotationVector world.spawnEntity(WitherSkullEntity(world, user, x, y, z).apply { From e164f81e4a6a164f8fd24f542ffc38326770d9b1 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 7 Jun 2024 22:19:15 +0200 Subject: [PATCH 105/128] Tweak bone block handler --- .../internal/staff_handler/BoneBlockHandler.kt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 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 36b87b40d..8e56615bc 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 @@ -24,6 +24,7 @@ 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.util.ActionResult import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos @@ -47,14 +48,14 @@ class BoneBlockHandler : StaffHandler() { side: Direction, hand: Hand ): ActionResult { - if (BoneMealItem.useOnFertilizable(staffStack.copy(), world, target)) { + if (BoneMealItem.useOnFertilizable(Items.BONE_MEAL.defaultStack, world, target)) { // TODO fertilize area when enchanted if (!world.isClient) { - user.emitGameEvent(GameEvent.ITEM_INTERACT_FINISH) // FIXME user originally PlayerEntity - world.syncWorldEvent(WorldEvents.BONE_MEAL_USED, target, 0) + user.emitGameEvent(GameEvent.ITEM_INTERACT_FINISH) + world.syncWorldEvent(WorldEvents.BONE_MEAL_USED, target, 15) } - return ActionResult.success(world.isClient) + return ActionResult.SUCCESS } val targetState = world.getBlockState(target) @@ -64,11 +65,11 @@ class BoneBlockHandler : StaffHandler() { if (!BoneMealItem.useOnGround(staffStack.copy(), world, neighborOnUsedSide, side)) return ActionResult.PASS if (!world.isClient) { - user.emitGameEvent(GameEvent.ITEM_INTERACT_FINISH) // FIXME user originally PlayerEntity - world.syncWorldEvent(WorldEvents.BONE_MEAL_USED, neighborOnUsedSide, 0) + user.emitGameEvent(GameEvent.ITEM_INTERACT_FINISH) + world.syncWorldEvent(WorldEvents.BONE_MEAL_USED, neighborOnUsedSide, 15) } - return ActionResult.success(world.isClient) + return ActionResult.SUCCESS } companion object { From 74dac330072901c05993e82a187c335efa762bc8 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 7 Jun 2024 22:45:53 +0200 Subject: [PATCH 106/128] Adjust wither skeleton skull handler --- .../staff_handler/WitherSkeletonSkullHandler.kt | 11 ++++------- 1 file changed, 4 insertions(+), 7 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 ce4cfb788..3f6331a24 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 @@ -91,13 +91,10 @@ class WitherSkeletonSkullHandler : StaffHandler() { target: Entity, hand: Hand ): EventResult { - if (!world.isClient) { - if (world.difficulty.id >= Difficulty.NORMAL.id) { - if (target is LivingEntity && !target.isInvulnerableTo(world.damageSources.wither())) { - val amplifier = if (world.difficulty == Difficulty.HARD) 1 else 0 - target.addStatusEffect(StatusEffectInstance(StatusEffects.WITHER, 5 * 20, amplifier)) - } - } + if (world.isClient) return EventResult.pass() + 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)) } return EventResult.pass() From b110c9b99828870e6814444a56260851addf4c8b Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 7 Jun 2024 22:46:18 +0200 Subject: [PATCH 107/128] Remove line break --- .../avm_staff/internal/staff_handler/SnowBlockHandler.kt | 1 - 1 file changed, 1 deletion(-) 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 1e14f439a..766b275c9 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 @@ -53,7 +53,6 @@ class SnowBlockHandler : StaffHandler() { private fun throwSnowball(world: World, user: LivingEntity) { if (!user.canUseStaff) return - if (user is PlayerEntity && user.isAttackCoolingDown) return world.playSound( From 655acea0dbc36b39e2cf1bd24a250ec562882670 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 7 Jun 2024 22:51:06 +0200 Subject: [PATCH 108/128] Rename AddItemToStaffC2SPacket to InsertItemIntoStaffC2SPacket --- .../main/kotlin/opekope2/avm_staff/internal/Initializer.kt | 4 ++-- .../avm_staff/internal/event_handler/KeyBindingHandler.kt | 4 ++-- .../avm_staff/internal/event_handler/NetworkHandler.kt | 4 ++-- ...mToStaffC2SPacket.kt => InsertItemIntoStaffC2SPacket.kt} | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) rename StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/{AddItemToStaffC2SPacket.kt => InsertItemIntoStaffC2SPacket.kt} (89%) 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 c84d5b325..c866ae35f 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -36,8 +36,8 @@ import net.minecraft.util.Identifier import opekope2.avm_staff.api.impactTntEntityType import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures import opekope2.avm_staff.internal.event_handler.* -import opekope2.avm_staff.internal.networking.c2s.play.AddItemToStaffC2SPacket 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.util.MOD_ID @@ -46,7 +46,7 @@ fun registerContent() { } fun initializeNetworking() { - AddItemToStaffC2SPacket.registerHandler(::addItemToStaff) + InsertItemIntoStaffC2SPacket.registerHandler(::addItemToStaff) RemoveItemFromStaffC2SPacket.registerHandler(::removeItemFromStaff) AttackC2SPacket.registerHandler(::attack) } 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 11da38749..6e3500ce4 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 @@ -25,7 +25,7 @@ import net.fabricmc.api.Environment import net.minecraft.client.MinecraftClient import net.minecraft.client.option.KeyBinding import net.minecraft.client.util.InputUtil -import opekope2.avm_staff.internal.networking.c2s.play.AddItemToStaffC2SPacket +import opekope2.avm_staff.internal.networking.c2s.play.InsertItemIntoStaffC2SPacket import opekope2.avm_staff.internal.networking.c2s.play.RemoveItemFromStaffC2SPacket import opekope2.avm_staff.util.MOD_ID import org.lwjgl.glfw.GLFW @@ -44,7 +44,7 @@ fun handleKeyBindings(client: MinecraftClient) { val player = client.player ?: return player.canInsertIntoStaff().ifSuccess { - AddItemToStaffC2SPacket().sendToServer() + InsertItemIntoStaffC2SPacket().sendToServer() player.resetLastAttackedTicks() }.ifError { player.canRemoveFromStaff().ifSuccess { diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt index 216b7f27a..bce860191 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt @@ -24,13 +24,13 @@ import net.minecraft.entity.player.PlayerEntity import net.minecraft.entity.player.PlayerInventory import net.minecraft.item.ItemStack import opekope2.avm_staff.api.staffsTag -import opekope2.avm_staff.internal.networking.c2s.play.AddItemToStaffC2SPacket 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.util.* @Suppress("UNUSED_PARAMETER") -fun addItemToStaff(packet: AddItemToStaffC2SPacket, context: PacketContext) { +fun addItemToStaff(packet: InsertItemIntoStaffC2SPacket, context: PacketContext) { context.player.canInsertIntoStaff().ifSuccess { (staffStack, itemStackToAdd) -> staffStack.mutableItemStackInStaff = itemStackToAdd.split(1) context.player.resetLastAttackedTicks() diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/AddItemToStaffC2SPacket.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/InsertItemIntoStaffC2SPacket.kt similarity index 89% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/AddItemToStaffC2SPacket.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/InsertItemIntoStaffC2SPacket.kt index 634b170dc..f14d33a8a 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/AddItemToStaffC2SPacket.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/networking/c2s/play/InsertItemIntoStaffC2SPacket.kt @@ -25,7 +25,7 @@ import opekope2.avm_staff.internal.networking.IC2SPacket import opekope2.avm_staff.internal.networking.PacketRegistrar import opekope2.avm_staff.util.MOD_ID -class AddItemToStaffC2SPacket() : IC2SPacket { +class InsertItemIntoStaffC2SPacket() : IC2SPacket { @Suppress("UNUSED_PARAMETER") constructor(buf: PacketByteBuf) : this() @@ -34,9 +34,9 @@ class AddItemToStaffC2SPacket() : IC2SPacket { override fun write(buf: PacketByteBuf) { } - companion object : PacketRegistrar( + companion object : PacketRegistrar( NetworkManager.c2s(), Identifier(MOD_ID, "add_item"), - ::AddItemToStaffC2SPacket + ::InsertItemIntoStaffC2SPacket ) } From 6eb65062662a9a06a3e8d297c3c6fa69384edfd3 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 8 Jun 2024 22:05:52 +0200 Subject: [PATCH 109/128] Add AccessTransformer to NeoForge JAR --- NeoForgeMod/build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/NeoForgeMod/build.gradle.kts b/NeoForgeMod/build.gradle.kts index 11e430817..450da616f 100644 --- a/NeoForgeMod/build.gradle.kts +++ b/NeoForgeMod/build.gradle.kts @@ -105,6 +105,7 @@ tasks { inputFile = shadowJar.get().archiveFile injectAccessWidener = true archiveClassifier = null + atAccessWideners.add(loom.accessWidenerPath.get().asFile.name) from(rootDir.resolve("COPYING")) from(rootDir.resolve("COPYING.LESSER")) From 1e0085ef59c05d5bddf7326b6f929737c3c35ad4 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 8 Jun 2024 22:16:39 +0200 Subject: [PATCH 110/128] Add ItemStaff in TagKey operator --- .../avm_staff/internal/fabric/StaffMod.kt | 3 +- .../event_handler/InteractionHandler.kt | 5 ++-- .../internal/event_handler/NetworkHandler.kt | 10 +++---- .../opekope2/avm_staff/util/ItemStackUtil.kt | 28 +++++++++++++++++++ 4 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/util/ItemStackUtil.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 5702891d1..a2ecda7fc 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 @@ -27,6 +27,7 @@ import net.minecraft.util.Hand import net.minecraft.util.hit.EntityHitResult import net.minecraft.world.World import opekope2.avm_staff.api.staffsTag +import opekope2.avm_staff.util.contains import opekope2.avm_staff.util.itemInStaff import opekope2.avm_staff.util.staffHandler @@ -45,7 +46,7 @@ object StaffMod : ModInitializer { hit: EntityHitResult? ): ActionResult { val itemStack = player.getStackInHand(hand) - if (!itemStack.isIn(staffsTag)) return ActionResult.PASS + if (itemStack !in staffsTag) return ActionResult.PASS val itemInStaff = itemStack.itemInStaff ?: return ActionResult.PASS val staffHandler = itemInStaff.staffHandler ?: return ActionResult.PASS diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/InteractionHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/InteractionHandler.kt index 28122be8c..2a3caae9d 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/InteractionHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/InteractionHandler.kt @@ -27,12 +27,13 @@ import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction import opekope2.avm_staff.api.staffsTag import opekope2.avm_staff.internal.networking.c2s.play.AttackC2SPacket +import opekope2.avm_staff.util.contains import opekope2.avm_staff.util.itemInStaff import opekope2.avm_staff.util.staffHandler fun attackBlock(player: PlayerEntity, hand: Hand, target: BlockPos, direction: Direction): EventResult { val staffStack = player.getStackInHand(hand) - if (!staffStack.isIn(staffsTag)) return EventResult.pass() + if (staffStack !in staffsTag) return EventResult.pass() val itemInStaff = staffStack.itemInStaff ?: return EventResult.pass() val staffHandler = itemInStaff.staffHandler ?: return EventResult.pass() @@ -43,7 +44,7 @@ fun attackBlock(player: PlayerEntity, hand: Hand, target: BlockPos, direction: D @Environment(EnvType.CLIENT) fun clientAttack(player: PlayerEntity, hand: Hand) { val staffStack = player.getStackInHand(hand) - if (!staffStack.isIn(staffsTag)) return + if (staffStack !in staffsTag) return val itemInStaff = staffStack.itemInStaff ?: return val staffHandler = itemInStaff.staffHandler ?: return diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt index bce860191..3cc50c128 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt @@ -50,7 +50,7 @@ fun attack(packet: AttackC2SPacket, context: PacketContext) { val player = context.player val staffStack = player.mainHandStack - if (!staffStack.isIn(staffsTag)) return + if (staffStack !in staffsTag) return val itemInStaff = staffStack.itemInStaff ?: return val staffHandler = itemInStaff.staffHandler ?: return @@ -63,12 +63,12 @@ fun PlayerEntity.canInsertIntoStaff(): DataResult> { val itemStackToAdd: ItemStack when { - mainHandStack.isIn(staffsTag) && !offHandStack.isIn(staffsTag) -> { + mainHandStack in staffsTag && offHandStack !in staffsTag -> { staffStack = mainHandStack itemStackToAdd = offHandStack } - offHandStack.isIn(staffsTag) && !mainHandStack.isIn(staffsTag) -> { + offHandStack in staffsTag && mainHandStack !in staffsTag -> { staffStack = offHandStack itemStackToAdd = mainHandStack } @@ -90,12 +90,12 @@ fun PlayerEntity.canRemoveFromStaff(): DataResult> { val targetSlot: Int when { - mainHandStack.isIn(staffsTag) && !offHandStack.isIn(staffsTag) -> { + mainHandStack in staffsTag && offHandStack !in staffsTag -> { staffStack = mainHandStack targetSlot = PlayerInventory.OFF_HAND_SLOT } - offHandStack.isIn(staffsTag) && !mainHandStack.isIn(staffsTag) -> { + offHandStack in staffsTag && mainHandStack !in staffsTag -> { staffStack = offHandStack targetSlot = inventory.selectedSlot } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/ItemStackUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/ItemStackUtil.kt new file mode 100644 index 000000000..45fee1bee --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/ItemStackUtil.kt @@ -0,0 +1,28 @@ +/* + * 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: JvmSynthetic +@file: Suppress("NOTHING_TO_INLINE") + +package opekope2.avm_staff.util + +import net.minecraft.item.Item +import net.minecraft.item.ItemStack +import net.minecraft.registry.tag.TagKey + +inline operator fun TagKey.contains(stack: ItemStack) = stack.isIn(this) From e2f0c51d3a6622829309e010a601f49384df6ffa Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 8 Jun 2024 22:19:41 +0200 Subject: [PATCH 111/128] Call StaffHandler.onStoppedUsing when item dropped or user dies --- .../avm_staff/internal/neoforge/StaffMod.kt | 14 +++++++ .../avm_staff/internal/Initializer.kt | 39 +++++++++++++++++++ 2 files changed, 53 insertions(+) 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 aed6e16d6..5b65bbc15 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,11 +20,14 @@ package opekope2.avm_staff.internal.neoforge import net.neoforged.api.distmarker.Dist import net.neoforged.fml.common.Mod +import net.neoforged.neoforge.event.entity.living.LivingDropsEvent import opekope2.avm_staff.internal.initializeNetworking 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 @Mod(MOD_ID) @@ -33,7 +36,18 @@ object StaffMod { registerContent() initializeNetworking() subscribeToEvents() + subscribeToNeoForgeEvents() registerVanillaStaffHandlers() runWhenOn(Dist.CLIENT, StaffModClient::initializeClient) } + + private fun subscribeToNeoForgeEvents() { + FORGE_BUS.addListener(::dropInventory) + } + + private fun dropInventory(event: LivingDropsEvent) { + for (item in event.drops) { + stopUsingStaffWhenDropped(event.entity, item) + } + } } 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 c866ae35f..17b9d599a 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -18,14 +18,22 @@ package opekope2.avm_staff.internal +import dev.architectury.event.EventResult import dev.architectury.event.events.client.ClientTickEvent +import dev.architectury.event.events.common.EntityEvent import dev.architectury.event.events.common.InteractionEvent import dev.architectury.event.events.common.LootEvent +import dev.architectury.event.events.common.PlayerEvent import dev.architectury.registry.client.keymappings.KeyMappingRegistry import dev.architectury.registry.client.level.entity.EntityRendererRegistry import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.minecraft.client.render.entity.TntEntityRenderer +import net.minecraft.entity.ItemEntity +import net.minecraft.entity.LivingEntity +import net.minecraft.entity.damage.DamageSource +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory import net.minecraft.item.SmithingTemplateItem import net.minecraft.loot.LootPool import net.minecraft.loot.LootTable @@ -35,11 +43,15 @@ import net.minecraft.registry.RegistryKeys import net.minecraft.util.Identifier import opekope2.avm_staff.api.impactTntEntityType import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures +import opekope2.avm_staff.api.staffsTag import opekope2.avm_staff.internal.event_handler.* 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.util.MOD_ID +import opekope2.avm_staff.util.contains +import opekope2.avm_staff.util.itemInStaff +import opekope2.avm_staff.util.staffHandlerOrDefault fun registerContent() { opekope2.avm_staff.api.registerContent() @@ -76,6 +88,33 @@ fun modifyLootTables( fun subscribeToEvents() { InteractionEvent.LEFT_CLICK_BLOCK.register(::attackBlock) LootEvent.MODIFY_LOOT_TABLE.register(::modifyLootTables) + EntityEvent.LIVING_DEATH.register(::stopUsingStaffOnPlayerDeath) + PlayerEvent.DROP_ITEM.register(::stopUsingStaffWhenDropped) +} + +@Suppress("UNUSED_PARAMETER") +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) in staffsTag) { + entity.stopUsingItem() + } + } + + return EventResult.pass() +} + +fun stopUsingStaffWhenDropped(entity: LivingEntity, item: ItemEntity): EventResult { + if (item.stack in staffsTag) { + item.stack.itemInStaff.staffHandlerOrDefault.onStoppedUsing( + item.stack, entity.entityWorld, entity, entity.itemUseTimeLeft + ) + } + return EventResult.pass() } @Environment(EnvType.CLIENT) From f21352e44384df3415cfb1ffa1bbf146d4bfc27b Mon Sep 17 00:00:00 2001 From: opekope2 Date: Sat, 8 Jun 2024 22:25:40 +0200 Subject: [PATCH 112/128] Fix furnace staff not turning on for other players --- .../internal/staff_handler/FurnaceHandler.kt | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) 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 0611af0b7..e9b8f7b73 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 @@ -68,10 +68,8 @@ class FurnaceHandler( user: PlayerEntity, hand: Hand ): TypedActionResult { - if (world.isClient) { - // Visual only - staffStack[furnaceLitComponentType.get()] = UnitComponent - } else { + staffStack[furnaceLitComponentType.get()] = UnitComponent + if (!world.isClient) { user.activeItemTempData = BurnTimeTempData(0) } @@ -139,10 +137,8 @@ class FurnaceHandler( } override fun onStoppedUsing(staffStack: ItemStack, world: World, user: LivingEntity, remainingUseTicks: Int) { - if (world.isClient) { - // Visual only - staffStack.remove(furnaceLitComponentType.get()) - } else { + staffStack.remove(furnaceLitComponentType.get()) + if (!world.isClient) { user.activeItemTempData = null } } From 87b6e367f2503d880dec01a65d298c38312d2910 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 10 Jun 2024 01:10:02 +0200 Subject: [PATCH 113/128] Prevent item insertion and removal from staffs on cooldown --- .../opekope2/avm_staff/internal/event_handler/NetworkHandler.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt index 3cc50c128..fd40115fd 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/event_handler/NetworkHandler.kt @@ -78,6 +78,7 @@ fun PlayerEntity.canInsertIntoStaff(): DataResult> { if (itemStackToAdd.isEmpty) return DataResult.error { "Can't insert empty ItemStack into staff" } if (staffStack.isItemInStaff) return DataResult.error { "An item is already inserted into the staff" } + if (isItemCoolingDown(staffStack.item)) return DataResult.error { "Staff is cooling down" } if (!itemStackToAdd.item.hasStaffHandler) return DataResult.error { "Can't insert item without a StaffHandler into the staff" } return DataResult.success(staffStack to itemStackToAdd) @@ -106,6 +107,7 @@ fun PlayerEntity.canRemoveFromStaff(): DataResult> { val targetStack = inventory.getStack(targetSlot) val itemStackInStaff = staffStack.itemStackInStaff ?: return DataResult.error { "Staff is empty" } + if (isItemCoolingDown(staffStack.item)) return DataResult.error { "Staff is cooling down" } if (!targetStack.canAccept(itemStackInStaff, inventory.maxCountPerStack)) return DataResult.error { "Target stack is incompatible with staff item" } From 72b867323f91a1aa4d23519af95f5f0a2923db97 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 10 Jun 2024 01:17:27 +0200 Subject: [PATCH 114/128] Replace temporary item textures with final ones --- .../textures/item/royal_staff_ingredient.png | Bin 317 -> 258 bytes .../item/staff_infusion_smithing_template.png | Bin 352 -> 462 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/StaffMod/src/main/resources/assets/avm_staff/textures/item/royal_staff_ingredient.png b/StaffMod/src/main/resources/assets/avm_staff/textures/item/royal_staff_ingredient.png index 51e961a9d7048e1ab8801be0fcee43c492ac6cc7..f78501cde702f2e3383598c8d78040122239745e 100644 GIT binary patch delta 241 zcmdnX)WkGFvYwfNfk8u;KNv_c76-XIF|0c$^AgB02=EDU1=5-FmIZn)%R&lnG)xE- z(X6)&>~@Zt>zlSer*U&!<(abfWHsyeE7m`rKKuWHLmLlGT?o`8P!i-9%b@~ui>~y#3bc^H)78&qol`;+01Mk@uK)l5 delta 301 zcmV+|0n+}00=)u|8Gi-<001BJ|6u?C0R%}zK~y-6)sj6%zEv@P{LI6X7_tf`vd=`Qk`_EPP*}2 z{RByWb3Nzkat6>X&DxW>_e+Q{@TuwsfbH7>G4ZCLsS*>F>VKqrxVy&`IaS>d20nmI zbJN4XM@KOLAD<;DNv8lzk)xxSU7Za;fpru^bk?i=#;%>}s=q{2gW9vTewY?*Kd&ubx_(wU=^!1=mDC zF%n2X=@r1hPx$h)G02R5*>Tlg}#zaTLHm!?Mh5tn{6& zrBE!J3v$6hDK{k!uA&^dl8bc_<%DwB!pUFYrqmudxQN=;j~xA&`I51XWsBBf+sW=^ z_rN>8_dcIq@Acr1p%f<6@NlLSlu8^roTm`}5@7&pe17EJ4S(KRLHbo98rn$OR<;i^ zIZ2)%2bz%t)Q4CYP{9BQvc@^0p$&6WM;l2v{VoB3GUH+1uxYRBWN5CR`;~VvV2yLC zrYy>T^p+LE^6thZ3@%m!kcobhewBGOmjFQR8e^v?1;Ek92}c_z>~&jEKL{Rwae>-3 z2B%S^A(^h+2Y;Z$?#>pUV~Bt#F~Mn+w}Vjt0>LH+eq6pqSsHXM@v9)EwxUeL5dp#D zRwI|bGXV5R_PpgXQCtAv)haMIb@W-2tCu*JzB7`xh4<~6RP$(Yfmf@b#^;CUSl+m4 zEyTxe2+Vlt36i#j9trcY{=n)*FH^Bm)FLTx7>VINh=J5QWWBC5|ia2H# zFJZkv;&j}jt_mzya}eZaCiHJaXPWG=$(R0yrj=gmHeQAJ}y%nM$8JavqDm;e9(07*qoM6N<$f?0ByKmY&$ From 068eaa7675f956e634179fe640e7ae74a2dda14a Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 10 Jun 2024 01:18:07 +0200 Subject: [PATCH 115/128] Add credits to mod meta --- FabricMod/src/main/resources/fabric.mod.json | 4 ++++ NeoForgeMod/src/main/resources/META-INF/neoforge.mods.toml | 1 + 2 files changed, 5 insertions(+) diff --git a/FabricMod/src/main/resources/fabric.mod.json b/FabricMod/src/main/resources/fabric.mod.json index 3d6a8a2a4..009c21396 100644 --- a/FabricMod/src/main/resources/fabric.mod.json +++ b/FabricMod/src/main/resources/fabric.mod.json @@ -7,6 +7,10 @@ "authors": [ "opekope2" ], + "contributors": [ + "Brother_Oliviär", + "Ink&Soul" + ], "contact": { "homepage": "https://opekope2.dev/StaffMod", "issues": "https://github.com/opekope2/StaffMod/issues", diff --git a/NeoForgeMod/src/main/resources/META-INF/neoforge.mods.toml b/NeoForgeMod/src/main/resources/META-INF/neoforge.mods.toml index 341408eb3..6fe2aea98 100644 --- a/NeoForgeMod/src/main/resources/META-INF/neoforge.mods.toml +++ b/NeoForgeMod/src/main/resources/META-INF/neoforge.mods.toml @@ -8,6 +8,7 @@ modId = "avm_staff" version = "$version" displayName = "Staff Mod (AvM Shorts)" authors = "opekope2" +credits = "Alan Becker, Brother_Oliviär, Ink&Soul" description = ''' Staff from Animation vs Minecraft Shorts ''' From ed9c9f17ede03ad8c132a8c0c49295f2418344e1 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 10 Jun 2024 01:20:13 +0200 Subject: [PATCH 116/128] Update mod name&description in mod meta --- FabricMod/src/main/resources/fabric.mod.json | 4 ++-- NeoForgeMod/src/main/resources/META-INF/neoforge.mods.toml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/FabricMod/src/main/resources/fabric.mod.json b/FabricMod/src/main/resources/fabric.mod.json index 009c21396..c37e3a037 100644 --- a/FabricMod/src/main/resources/fabric.mod.json +++ b/FabricMod/src/main/resources/fabric.mod.json @@ -2,8 +2,8 @@ "schemaVersion": 1, "id": "avm_staff", "version": "$version", - "name": "Staff Mod (AvM Shorts)", - "description": "Staff from Animation vs Minecraft Shorts", + "name": "Staff Mod (Animation vs Minecraft)", + "description": "AvM Staff Mod is a fan-made, mostly canonically accurate, and close to vanilla mod adding staffs from Animation vs Minecraft series to the latest version of Minecraft: Java Edition", "authors": [ "opekope2" ], diff --git a/NeoForgeMod/src/main/resources/META-INF/neoforge.mods.toml b/NeoForgeMod/src/main/resources/META-INF/neoforge.mods.toml index 6fe2aea98..58e21f9a4 100644 --- a/NeoForgeMod/src/main/resources/META-INF/neoforge.mods.toml +++ b/NeoForgeMod/src/main/resources/META-INF/neoforge.mods.toml @@ -6,11 +6,11 @@ license = "LGPL-3.0-or-later" [[mods]] modId = "avm_staff" version = "$version" -displayName = "Staff Mod (AvM Shorts)" +displayName = "Staff Mod (Animation vs Minecraft)" authors = "opekope2" credits = "Alan Becker, Brother_Oliviär, Ink&Soul" description = ''' -Staff from Animation vs Minecraft Shorts +AvM Staff Mod is a fan-made, mostly canonically accurate, and close to vanilla mod adding staffs from Animation vs Minecraft series to the latest version of Minecraft: Java Edition ''' logoFile = "assets/avm_staff/icon.png" features = { java_version = "[$java,)" } From 459e0fb1656d3d752adfb1044c94166ac9fb4ec3 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 10 Jun 2024 12:09:22 +0200 Subject: [PATCH 117/128] Update README --- README.md | 54 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 0cb680c90..fa2081a03 100644 --- a/README.md +++ b/README.md @@ -8,37 +8,43 @@ [![Wiki](https://img.shields.io/badge/Read_the-wiki-8ca1af?style=flat&logo=readthedocs)](https://opekope2.dev/StaffMod) [![Buy me a coffee](https://img.shields.io/badge/Buy_me_a_coffee-Ko--fi-f16061?style=flat&logo=ko-fi)](https://ko-fi.com/opekope2) -Adds staff from Animation vs Minecraft shorts. +Fan-made, mostly canonically accurate, and close to vanilla mod adding [staffs](https://animatorvsanimation.fandom.com/wiki/Staffs) from Animation vs Minecraft series -## Roadmap +## Credits -Functionality will be added gradually. -This will bring (hopefully) many smaller updates before a big update, so you can enjoy new (experimental) functionality, -even when I don't have much time for development. -Please note that the development cycle may be slow, because I'm working on a quite big update -for [OptiGUI](https://github.com/opekope2/optigui), my other mod, and I'm also in university. +* *[Alan Becker](https://www.youtube.com/@alanbecker)*, for animating Animation vs Minecraft series +* *Brother Oliviär*, for drawing *Royal Staff Ingredient* and *Staff Infusion Smithing Template* textures +* *[Ink&Soul](https://github.com/MBYL-InkAndSoul)*, for fixing a bug -### Phase 0 (done) +## Roadmap -* Add staff item -* Add basic functionality -* Alpha release +Functionality will be added gradually, bringing many smaller updates before the 1.0.0 release. +See [this GitHub discussion](https://github.com/opekope2/StaffMod/discussions/31) for upcoming features. -### Phase 1 (in development) +## [Staff Mod items](https://opekope2.dev/StaffMod/items.html) -* Add block functionalities inside staff item (a bunch of simple use blocks) -* Beta releases +Staff Mod adds the following items to the game: -### Phase 2 +* [Faint staff rod](https://opekope2.dev/StaffMod/items.html#faint-staff-rod) +* [Faint royal staff head](https://opekope2.dev/StaffMod/items.html#faint-royal-staff-head) +* [Faint royal staff](https://opekope2.dev/StaffMod/items.html#faint-royal-staff) +* [Royal staff](https://opekope2.dev/StaffMod/items.html#royal-staff) +* [Royal staff ingredient](https://opekope2.dev/StaffMod/items.html#royal-staff-ingredient) +* [Crown of King Orange](https://opekope2.dev/StaffMod/items.html#crown-of-king-orange) +* [Staff infusion smithing template](https://opekope2.dev/StaffMod/items.html#staff-infusion-smithing-template) -* Survival mode support and balancing (head over to GitHub to discuss/suggest functionality) -* Advanced block functionalities inside staff item -* Fix rendering, models, and textures -* Add server-side configuration support -* First stable release (big update) +## [Supported items in staffs](https://opekope2.dev/StaffMod/staff.html) -### Phase 3 +Staff Mod implements functionalities for the following items: -* Maybe add staff add/remove animations -* Add the rest of the blocks seen in AvM Shorts ep 33 -* Everything else +* [Anvil, chipped anvil, damaged anvil](https://opekope2.dev/StaffMod/staff.html#anvil-chipped-anvil-damaged-anvil) +* [Bell](https://opekope2.dev/StaffMod/staff.html#bell) +* [Bone block](https://opekope2.dev/StaffMod/staff.html#bone-block) +* [Campfire, soul campfire](https://opekope2.dev/StaffMod/staff.html#campfire-soul-campfire) +* [Furnace, blast furnace, smoker](https://opekope2.dev/StaffMod/staff.html#furnace-blast-furnace-smoker) +* [Lightning rod](https://opekope2.dev/StaffMod/staff.html#lightning-rod) +* [Magma block](https://opekope2.dev/StaffMod/staff.html#magma-block) +* [Snow block](https://opekope2.dev/StaffMod/staff.html#snow-block) +* [TNT](https://opekope2.dev/StaffMod/staff.html#tnt) +* [Wither Skeleton Skull](https://opekope2.dev/StaffMod/staff.html#wither-skeleton-skull) +* [Wool (any color)](https://opekope2.dev/StaffMod/staff.html#wool-any-color) From 840740d73a072cc14bdefff0f879418bcdf18089 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 10 Jun 2024 12:12:30 +0200 Subject: [PATCH 118/128] Include README in JARs --- FabricMod/build.gradle.kts | 2 ++ NeoForgeMod/build.gradle.kts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/FabricMod/build.gradle.kts b/FabricMod/build.gradle.kts index 208a2bcbf..34a0093ac 100644 --- a/FabricMod/build.gradle.kts +++ b/FabricMod/build.gradle.kts @@ -95,6 +95,7 @@ tasks { from(rootDir.resolve("COPYING")) from(rootDir.resolve("COPYING.LESSER")) + from(rootDir.resolve("README.md")) } remapJar { @@ -105,6 +106,7 @@ tasks { from(rootDir.resolve("COPYING")) from(rootDir.resolve("COPYING.LESSER")) + from(rootDir.resolve("README.md")) } sourcesJar { diff --git a/NeoForgeMod/build.gradle.kts b/NeoForgeMod/build.gradle.kts index 450da616f..1f17d6d97 100644 --- a/NeoForgeMod/build.gradle.kts +++ b/NeoForgeMod/build.gradle.kts @@ -98,6 +98,7 @@ tasks { from(rootDir.resolve("COPYING")) from(rootDir.resolve("COPYING.LESSER")) + from(rootDir.resolve("README.md")) } remapJar { @@ -109,6 +110,7 @@ tasks { from(rootDir.resolve("COPYING")) from(rootDir.resolve("COPYING.LESSER")) + from(rootDir.resolve("README.md")) } sourcesJar { From 8db8ad8caf293ca1b6537c2f8505f818a53dac7c Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 10 Jun 2024 18:23:06 +0200 Subject: [PATCH 119/128] Remove unused interface IImpactTnt How did I forget it? --- .../avm_staff/api/entity/IImpactTnt.java | 51 ------------------- 1 file changed, 51 deletions(-) delete mode 100644 StaffMod/src/main/java/opekope2/avm_staff/api/entity/IImpactTnt.java diff --git a/StaffMod/src/main/java/opekope2/avm_staff/api/entity/IImpactTnt.java b/StaffMod/src/main/java/opekope2/avm_staff/api/entity/IImpactTnt.java deleted file mode 100644 index 541598196..000000000 --- a/StaffMod/src/main/java/opekope2/avm_staff/api/entity/IImpactTnt.java +++ /dev/null @@ -1,51 +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.entity; - -import net.minecraft.entity.TntEntity; -import net.minecraft.entity.data.DataTracker; -import net.minecraft.entity.data.TrackedData; -import net.minecraft.entity.data.TrackedDataHandlerRegistry; - -/** - * A TNT, which can be configured to explode when collides (with blocks or other entities). - */ -public interface IImpactTnt { - /** - * Returns if the current TNT explodes, when it collides with a block or entity. - */ - boolean staffMod$explodesOnImpact(); - - /** - * Configures the current TNT to explode or not, when it collides with a block or entity. - * - * @param explode Whether to explode on collision - */ - void staffMod$explodeOnImpact(boolean explode); - - /** - * NBT Key for TNT's explodes on impact property. - */ - String EXPLODES_ON_IMPACT_NBT_KEY = "ExplodesOnImpact"; - - /** - * Data tracker for TNT's explodes on impact property. - */ - TrackedData EXPLODES_ON_IMPACT = DataTracker.registerData(TntEntity.class, TrackedDataHandlerRegistry.BOOLEAN); -} From 5fedbeb99c863f5df49c125629fef26d8d8b2d6a Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 10 Jun 2024 18:23:43 +0200 Subject: [PATCH 120/128] Update icon & add it to documentation --- StaffMod/build.gradle.kts | 1 + StaffMod/logo-icon.svg | 488 ++++++++++++++++++ .../main/resources/assets/avm_staff/icon.png | Bin 24715 -> 99253 bytes 3 files changed, 489 insertions(+) create mode 100644 StaffMod/logo-icon.svg diff --git a/StaffMod/build.gradle.kts b/StaffMod/build.gradle.kts index 0bea06795..5f1504d9e 100644 --- a/StaffMod/build.gradle.kts +++ b/StaffMod/build.gradle.kts @@ -58,6 +58,7 @@ tasks { pluginConfiguration { footerMessage = "© 2023-${Year.now().value} opekope2. AvM Staff Mod is not an official Minecraft product. Not associated with or endorsed by Mojang Studios." + customAssets = listOf(projectDir.resolve("logo-icon.svg")) separateInheritedMembers = true } diff --git a/StaffMod/logo-icon.svg b/StaffMod/logo-icon.svg new file mode 100644 index 000000000..703012369 --- /dev/null +++ b/StaffMod/logo-icon.svg @@ -0,0 +1,488 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/StaffMod/src/main/resources/assets/avm_staff/icon.png b/StaffMod/src/main/resources/assets/avm_staff/icon.png index 05d4286c544ddc34218b2467754f656300c1f1bf..9fe22898b4e82687c9c3a694ad8162190abc908a 100644 GIT binary patch literal 99253 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 WWM+Ksg!k#ZGHvqA_Y>ap-uizDD917Y literal 24715 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 E2jVo3#{d8T From f2a9cc4cae29175c6d9b2dd6ffbb38388d7603c2 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 10 Jun 2024 18:30:43 +0200 Subject: [PATCH 121/128] Annotate BlockStateStaffItemRenderer with @Environment(CLIENT) --- .../avm_staff/api/item/renderer/BlockStateStaffItemRenderer.kt | 3 +++ 1 file changed, 3 insertions(+) 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 8763c83c6..51d9dc1db 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 @@ -18,6 +18,8 @@ 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 @@ -31,6 +33,7 @@ import net.minecraft.item.ItemStack * * @param blockState The block state to render */ +@Environment(EnvType.CLIENT) class BlockStateStaffItemRenderer(blockState: BlockState) : IStaffItemRenderer { private val blockStateId = BlockModels.getModelId(blockState) private val blockItem = blockState.block.asItem().defaultStack From 993fa7921699bf1f61bbef5134575e2c72700ad7 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 10 Jun 2024 18:37:23 +0200 Subject: [PATCH 122/128] Annotate StaffInfusionSmithingRecipeTextures with @Environment(CLIENT) --- .../avm_staff/api/staff/StaffInfusionSmithingRecipeTextures.kt | 3 +++ 1 file changed, 3 insertions(+) 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..16fb987d0 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 @@ -18,6 +18,8 @@ package opekope2.avm_staff.api.staff +import net.fabricmc.api.EnvType +import net.fabricmc.api.Environment import net.minecraft.util.Identifier import opekope2.avm_staff.api.staffInfusionSmithingTemplateItem @@ -25,6 +27,7 @@ import opekope2.avm_staff.api.staffInfusionSmithingTemplateItem * Object holding textures to be displayed in a smithing table, when using a * [staff infusion smithing template][staffInfusionSmithingTemplateItem]. */ +@Environment(EnvType.CLIENT) object StaffInfusionSmithingRecipeTextures { /** * @suppress From e92d4895e715c77fa57e4383ccb5c3364b80d82e Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 10 Jun 2024 18:59:32 +0200 Subject: [PATCH 123/128] Migrate to Minecraft Unit from UnitComponent --- .../kotlin/opekope2/avm_staff/api/StaffMod.kt | 18 +++++++++--------- .../UnitComponent.kt => internal/Aliases.kt} | 9 ++------- .../internal/staff_handler/CampfireHandler.kt | 3 ++- .../internal/staff_handler/FurnaceHandler.kt | 3 ++- 4 files changed, 15 insertions(+), 18 deletions(-) rename StaffMod/src/main/kotlin/opekope2/avm_staff/{util/UnitComponent.kt => internal/Aliases.kt} (80%) 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 92ac92450..3ef3e0ee8 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/StaffMod.kt @@ -47,11 +47,11 @@ import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.api.staff.StaffInfusionSmithingRecipeTextures import opekope2.avm_staff.api.staff.StaffItemComponent import opekope2.avm_staff.api.staff.StaffRendererOverrideComponent +import opekope2.avm_staff.internal.MinecraftUnit import opekope2.avm_staff.internal.createCrownItem import opekope2.avm_staff.internal.createStaffItem import opekope2.avm_staff.internal.createStaffRendererItem import opekope2.avm_staff.util.MOD_ID -import opekope2.avm_staff.util.UnitComponent import opekope2.avm_staff.util.mutableItemStackInStaff private val ITEMS = DeferredRegister.create(MOD_ID, RegistryKeys.ITEM) @@ -183,22 +183,22 @@ val staffItemComponentType: RegistrySupplier> = +val rocketModeComponentType: RegistrySupplier> = DATA_COMPONENT_TYPES.register("rocket_mode") { - DataComponentType.builder() - .codec(Codec.unit(UnitComponent)) - .packetCodec(PacketCodec.unit(UnitComponent)) + DataComponentType.builder() + .codec(Codec.unit(MinecraftUnit.INSTANCE)) + .packetCodec(PacketCodec.unit(MinecraftUnit.INSTANCE)) .build() } /** * Data component registered as `avm_staff:furnace_lit`. Stores if a furnace staff is lit. Only used for rendering. */ -val furnaceLitComponentType: RegistrySupplier> = +val furnaceLitComponentType: RegistrySupplier> = DATA_COMPONENT_TYPES.register("furnace_lit") { - DataComponentType.builder() - .codec(Codec.unit(UnitComponent)) - .packetCodec(PacketCodec.unit(UnitComponent)) + DataComponentType.builder() + .codec(Codec.unit(MinecraftUnit.INSTANCE)) + .packetCodec(PacketCodec.unit(MinecraftUnit.INSTANCE)) .build() } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/UnitComponent.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Aliases.kt similarity index 80% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/util/UnitComponent.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Aliases.kt index df04d9ca3..c6afad535 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/UnitComponent.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Aliases.kt @@ -16,11 +16,6 @@ * along with this mod. If not, see . */ -package opekope2.avm_staff.util +package opekope2.avm_staff.internal -import net.minecraft.component.DataComponentType - -/** - * [Unit], but can be used as a [DataComponentType]. - */ -data object UnitComponent +internal typealias MinecraftUnit = net.minecraft.util.Unit 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 c9fc88178..50442902c 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 @@ -46,6 +46,7 @@ import net.minecraft.world.World import net.minecraft.world.event.GameEvent import opekope2.avm_staff.api.rocketModeComponentType import opekope2.avm_staff.api.staff.StaffHandler +import opekope2.avm_staff.internal.MinecraftUnit import opekope2.avm_staff.util.* class CampfireHandler( @@ -62,7 +63,7 @@ class CampfireHandler( hand: Hand ): TypedActionResult { if (user.isSneaking && !user.isOnGround) { - staffStack[rocketModeComponentType.get()] = UnitComponent + staffStack[rocketModeComponentType.get()] = MinecraftUnit.INSTANCE } 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 e9b8f7b73..3aa494a26 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 @@ -50,6 +50,7 @@ import opekope2.avm_staff.api.furnaceLitComponentType import opekope2.avm_staff.api.item.renderer.BlockStateStaffItemRenderer import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer import opekope2.avm_staff.api.staff.StaffHandler +import opekope2.avm_staff.internal.MinecraftUnit import opekope2.avm_staff.util.* import kotlin.jvm.optionals.getOrNull @@ -68,7 +69,7 @@ class FurnaceHandler( user: PlayerEntity, hand: Hand ): TypedActionResult { - staffStack[furnaceLitComponentType.get()] = UnitComponent + staffStack[furnaceLitComponentType.get()] = MinecraftUnit.INSTANCE if (!world.isClient) { user.activeItemTempData = BurnTimeTempData(0) } From b3254123fd5b03d9157e4af21cde5cbb6f7bc89d Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 10 Jun 2024 19:52:39 +0200 Subject: [PATCH 124/128] Rename "Weapon modifier" to "Staff modifier" Add interactionRange utility method --- .../opekope2/avm_staff/api/staff/StaffHandler.kt | 12 +++--------- .../opekope2/avm_staff/util/AttributeUtil.kt | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 11 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 ea8db3c4d..311ef1300 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 @@ -24,7 +24,6 @@ import net.minecraft.component.type.AttributeModifierSlot import net.minecraft.component.type.AttributeModifiersComponent import net.minecraft.entity.Entity import net.minecraft.entity.LivingEntity -import net.minecraft.entity.attribute.EntityAttributeModifier import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.Item @@ -40,6 +39,7 @@ import net.minecraft.world.World import net.minecraft.world.event.GameEvent import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.attackSpeed +import opekope2.avm_staff.util.interactionRange /** * Provides functionality for a staff, when an item is inserted into it. @@ -352,15 +352,9 @@ abstract class StaffHandler { .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(4.0), AttributeModifierSlot.MAINHAND) .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(2.0), AttributeModifierSlot.MAINHAND) .add( - EntityAttributes.PLAYER_ENTITY_INTERACTION_RANGE, - EntityAttributeModifier("Weapon modifier", 1.0, EntityAttributeModifier.Operation.ADD_VALUE), - AttributeModifierSlot.MAINHAND - ) - .add( - EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE, - EntityAttributeModifier("Weapon modifier", 1.0, EntityAttributeModifier.Operation.ADD_VALUE), - AttributeModifierSlot.MAINHAND + EntityAttributes.PLAYER_ENTITY_INTERACTION_RANGE, interactionRange(1.0), AttributeModifierSlot.MAINHAND ) + .add(EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE, interactionRange(1.0), AttributeModifierSlot.MAINHAND) .build() } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/AttributeUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/AttributeUtil.kt index 65437a2c0..33b7d8774 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/AttributeUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/AttributeUtil.kt @@ -34,7 +34,7 @@ private const val PLAYER_BASE_ATTACK_SPEED = 4.0 */ fun attackDamage(totalAttackDamage: Double): EntityAttributeModifier = EntityAttributeModifier( Item.ATTACK_DAMAGE_MODIFIER_ID, - "Weapon modifier", + "Staff modifier", totalAttackDamage - PLAYER_BASE_ATTACK_DAMAGE, EntityAttributeModifier.Operation.ADD_VALUE ) @@ -47,7 +47,7 @@ fun attackDamage(totalAttackDamage: Double): EntityAttributeModifier = EntityAtt */ fun attackSpeed(totalAttackSpeed: Double): EntityAttributeModifier = EntityAttributeModifier( Item.ATTACK_SPEED_MODIFIER_ID, - "Weapon modifier", + "Staff modifier", totalAttackSpeed - PLAYER_BASE_ATTACK_SPEED, EntityAttributeModifier.Operation.ADD_VALUE ) @@ -59,3 +59,14 @@ fun attackSpeed(totalAttackSpeed: Double): EntityAttributeModifier = EntityAttri * @param totalEquipTime The desired equip time in seconds */ fun equipTime(totalEquipTime: Double): EntityAttributeModifier = attackSpeed(1.0 / totalEquipTime) + +/** + * Creates an [EntityAttributeModifier], which increases the interaction range by [additionalRange]. + * + * @param additionalRange The number of blocks to add to the interaction range + */ +fun interactionRange(additionalRange: Double) = EntityAttributeModifier( + "Staff modifier", + additionalRange, + EntityAttributeModifier.Operation.ADD_VALUE +) From 87dd990729f2e2bc411748047e7412b994d9c5ef Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 10 Jun 2024 20:18:44 +0200 Subject: [PATCH 125/128] Simplify anvil staff modifier creation --- .../internal/staff_handler/AnvilHandler.kt | 49 +++---------------- 1 file changed, 8 insertions(+), 41 deletions(-) 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 0aa1f4487..c394f1d3c 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 @@ -39,7 +39,6 @@ import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.equipTime import opekope2.avm_staff.util.mutableItemStackInStaff -import java.util.* import kotlin.math.ceil import kotlin.math.floor @@ -124,46 +123,14 @@ class AnvilHandler(private val damagedStackFactory: () -> ItemStack?) : StaffHan private val ATTRIBUTE_MODIFIERS = AttributeModifiersComponent.builder() .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(40.0), AttributeModifierSlot.MAINHAND) .add(EntityAttributes.GENERIC_ATTACK_SPEED, equipTime(4.0), AttributeModifierSlot.MAINHAND) - .add( - EntityAttributes.GENERIC_MOVEMENT_SPEED, - EntityAttributeModifier( - UUID.fromString("c0374b4f-d600-4b6a-9984-3ee35d37750d"), - "Weapon modifier", - -1.0, - EntityAttributeModifier.Operation.ADD_MULTIPLIED_TOTAL - ), - AttributeModifierSlot.MAINHAND - ) - .add( - EntityAttributes.GENERIC_MOVEMENT_SPEED, - EntityAttributeModifier( - UUID.fromString("c0374b4f-d600-4b6a-9984-3ee35d37750e"), - "Weapon modifier", - -1.0, - EntityAttributeModifier.Operation.ADD_MULTIPLIED_TOTAL - ), - AttributeModifierSlot.OFFHAND - ) - .add( - EntityAttributes.GENERIC_JUMP_STRENGTH, - EntityAttributeModifier( - UUID.fromString("cbaf4a1a-e200-427c-b423-37733a264173"), - "Weapon modifier", - -1.0, - EntityAttributeModifier.Operation.ADD_MULTIPLIED_TOTAL - ), - AttributeModifierSlot.MAINHAND - ) - .add( - EntityAttributes.GENERIC_JUMP_STRENGTH, - EntityAttributeModifier( - UUID.fromString("cbaf4a1a-e200-427c-b423-37733a264174"), - "Weapon modifier", - -1.0, - EntityAttributeModifier.Operation.ADD_MULTIPLIED_TOTAL - ), - AttributeModifierSlot.OFFHAND - ) + .add(EntityAttributes.GENERIC_MOVEMENT_SPEED, anvilModifier(), AttributeModifierSlot.MAINHAND) + .add(EntityAttributes.GENERIC_MOVEMENT_SPEED, anvilModifier(), AttributeModifierSlot.OFFHAND) + .add(EntityAttributes.GENERIC_JUMP_STRENGTH, anvilModifier(), AttributeModifierSlot.MAINHAND) + .add(EntityAttributes.GENERIC_JUMP_STRENGTH, anvilModifier(), AttributeModifierSlot.OFFHAND) .build() + + private fun anvilModifier() = EntityAttributeModifier( + "Anvil modifier", -1.0, EntityAttributeModifier.Operation.ADD_MULTIPLIED_TOTAL + ) } } From 69f9de3f805fdb652caa1fcab574d04e2fe63c65 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 10 Jun 2024 20:19:54 +0200 Subject: [PATCH 126/128] Simplify default entity attribute modifier creation --- .../avm_staff/api/staff/StaffHandler.kt | 15 ++++------ .../opekope2/avm_staff/util/AttributeUtil.kt | 29 +++++++++++++++++++ 2 files changed, 34 insertions(+), 10 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 311ef1300..1402bf6ab 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,7 +20,6 @@ package opekope2.avm_staff.api.staff import dev.architectury.event.EventResult import net.minecraft.advancement.criterion.Criteria -import net.minecraft.component.type.AttributeModifierSlot import net.minecraft.component.type.AttributeModifiersComponent import net.minecraft.entity.Entity import net.minecraft.entity.LivingEntity @@ -37,9 +36,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.util.attackDamage -import opekope2.avm_staff.util.attackSpeed -import opekope2.avm_staff.util.interactionRange +import opekope2.avm_staff.util.addDefault /** * Provides functionality for a staff, when an item is inserted into it. @@ -349,12 +346,10 @@ abstract class StaffHandler { object Default : StaffHandler() { @JvmField val ATTRIBUTE_MODIFIERS: AttributeModifiersComponent = AttributeModifiersComponent.builder() - .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(4.0), AttributeModifierSlot.MAINHAND) - .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(2.0), AttributeModifierSlot.MAINHAND) - .add( - EntityAttributes.PLAYER_ENTITY_INTERACTION_RANGE, interactionRange(1.0), AttributeModifierSlot.MAINHAND - ) - .add(EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE, interactionRange(1.0), AttributeModifierSlot.MAINHAND) + .addDefault(EntityAttributes.GENERIC_ATTACK_DAMAGE) + .addDefault(EntityAttributes.GENERIC_ATTACK_SPEED) + .addDefault(EntityAttributes.PLAYER_ENTITY_INTERACTION_RANGE) + .addDefault(EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE) .build() } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/AttributeUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/AttributeUtil.kt index 33b7d8774..1437b4d44 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/AttributeUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/AttributeUtil.kt @@ -20,8 +20,13 @@ package opekope2.avm_staff.util +import net.minecraft.component.type.AttributeModifierSlot +import net.minecraft.component.type.AttributeModifiersComponent +import net.minecraft.entity.attribute.EntityAttribute import net.minecraft.entity.attribute.EntityAttributeModifier +import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.item.Item +import net.minecraft.registry.entry.RegistryEntry private const val PLAYER_BASE_ATTACK_DAMAGE = 1.0 private const val PLAYER_BASE_ATTACK_SPEED = 4.0 @@ -70,3 +75,27 @@ fun interactionRange(additionalRange: Double) = EntityAttributeModifier( additionalRange, EntityAttributeModifier.Operation.ADD_VALUE ) + +/** + * Adds the default staff modifier of the given entity attribute as [main hand][AttributeModifierSlot.MAINHAND] modifier. + * + * @param attribute The entity attribute to add the default value of + * @see EntityAttributes.GENERIC_ATTACK_DAMAGE + * @see EntityAttributes.GENERIC_ATTACK_SPEED + * @see EntityAttributes.PLAYER_ENTITY_INTERACTION_RANGE + * @see EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE + */ +fun AttributeModifiersComponent.Builder.addDefault(attribute: RegistryEntry): AttributeModifiersComponent.Builder { + add( + attribute, + when (attribute) { + EntityAttributes.GENERIC_ATTACK_DAMAGE -> attackDamage(4.0) + EntityAttributes.GENERIC_ATTACK_SPEED -> attackSpeed(2.0) + EntityAttributes.PLAYER_ENTITY_INTERACTION_RANGE -> interactionRange(1.0) + EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE -> interactionRange(1.0) + else -> throw IllegalArgumentException("Attribute has no default value") + }, + AttributeModifierSlot.MAINHAND + ) + return this +} From b4cbe6333f2c4ccac315f7473eeb26940c92d843 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 10 Jun 2024 20:21:10 +0200 Subject: [PATCH 127/128] Add +2 reach to lightning rod staff --- .../staff_handler/LightningRodHandler.kt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) 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 f34faf6ec..7e2ec8c5d 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 @@ -24,8 +24,11 @@ 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.component.type.AttributeModifiersComponent 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.item.ItemStack import net.minecraft.util.ActionResult @@ -36,10 +39,15 @@ 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.StaffHandler +import opekope2.avm_staff.util.addDefault +import opekope2.avm_staff.util.interactionRange import opekope2.avm_staff.util.isItemCoolingDown import opekope2.avm_staff.util.push class LightningRodHandler : StaffHandler() { + override val attributeModifiers: AttributeModifiersComponent + get() = ATTRIBUTE_MODIFIERS + override fun useOnBlock( staffStack: ItemStack, world: World, @@ -93,4 +101,15 @@ class LightningRodHandler : StaffHandler() { } } } + + private companion object { + val ATTRIBUTE_MODIFIERS: AttributeModifiersComponent = AttributeModifiersComponent.builder() + .addDefault(EntityAttributes.GENERIC_ATTACK_DAMAGE) + .addDefault(EntityAttributes.GENERIC_ATTACK_SPEED) + .add( + EntityAttributes.PLAYER_ENTITY_INTERACTION_RANGE, interactionRange(2.0), AttributeModifierSlot.MAINHAND + ) + .add(EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE, interactionRange(2.0), AttributeModifierSlot.MAINHAND) + .build() + } } From d8af4f0322111d1369df29a1a7c94da1c467fc67 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Mon, 10 Jun 2024 20:22:05 +0200 Subject: [PATCH 128/128] Add missing reach extending modifiers --- .../avm_staff/internal/staff_handler/BellBlockHandler.kt | 3 +++ .../avm_staff/internal/staff_handler/BoneBlockHandler.kt | 3 +++ .../avm_staff/internal/staff_handler/FurnaceHandler.kt | 2 ++ .../avm_staff/internal/staff_handler/MagmaBlockHandler.kt | 2 ++ .../opekope2/avm_staff/internal/staff_handler/WoolHandler.kt | 3 +++ 5 files changed, 13 insertions(+) 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 be8a82e8a..2b8bf6b0e 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 @@ -40,6 +40,7 @@ import net.minecraft.util.TypedActionResult import net.minecraft.world.World import opekope2.avm_staff.api.item.renderer.IStaffItemRenderer import opekope2.avm_staff.api.staff.StaffHandler +import opekope2.avm_staff.util.addDefault import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.attackSpeed import opekope2.avm_staff.util.push @@ -113,6 +114,8 @@ class BellBlockHandler : StaffHandler() { private val ATTRIBUTE_MODIFIERS = AttributeModifiersComponent.builder() .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(8.0), AttributeModifierSlot.MAINHAND) .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(1.5), AttributeModifierSlot.MAINHAND) + .addDefault(EntityAttributes.PLAYER_ENTITY_INTERACTION_RANGE) + .addDefault(EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE) .build() } } 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 8e56615bc..f575a8669 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 @@ -33,6 +33,7 @@ import net.minecraft.world.World import net.minecraft.world.WorldEvents import net.minecraft.world.event.GameEvent import opekope2.avm_staff.api.staff.StaffHandler +import opekope2.avm_staff.util.addDefault import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.attackSpeed @@ -76,6 +77,8 @@ class BoneBlockHandler : StaffHandler() { private val ATTRIBUTE_MODIFIERS = AttributeModifiersComponent.builder() .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(5.0), AttributeModifierSlot.MAINHAND) .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(2.0), AttributeModifierSlot.MAINHAND) + .addDefault(EntityAttributes.PLAYER_ENTITY_INTERACTION_RANGE) + .addDefault(EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE) .build() } } 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 3aa494a26..a542bbf60 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 @@ -212,6 +212,8 @@ class FurnaceHandler( private val ATTRIBUTE_MODIFIERS = AttributeModifiersComponent.builder() .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(10.0), AttributeModifierSlot.MAINHAND) .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(1.25), AttributeModifierSlot.MAINHAND) + .addDefault(EntityAttributes.PLAYER_ENTITY_INTERACTION_RANGE) + .addDefault(EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE) .build() } } 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 4ab516ddc..907f1fd5f 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 @@ -92,6 +92,8 @@ class MagmaBlockHandler : StaffHandler() { private val ATTRIBUTE_MODIFIERS = AttributeModifiersComponent.builder() .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(10.0), AttributeModifierSlot.MAINHAND) .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(1.25), AttributeModifierSlot.MAINHAND) + .addDefault(EntityAttributes.PLAYER_ENTITY_INTERACTION_RANGE) + .addDefault(EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE) .build() } } 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 7f8cf29f0..170c1f266 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,6 +37,7 @@ import net.minecraft.util.math.Direction import net.minecraft.world.World import opekope2.avm_staff.api.staff.StaffHandler import opekope2.avm_staff.mixin.IMinecraftClientMixin +import opekope2.avm_staff.util.addDefault import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.attackSpeed import opekope2.avm_staff.util.mutableItemStackInStaff @@ -84,6 +85,8 @@ class WoolHandler(private val woolBlockItem: BlockItem, private val carpetBlockI private val ATTRIBUTE_MODIFIERS = AttributeModifiersComponent.builder() .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(2.0), AttributeModifierSlot.MAINHAND) .add(EntityAttributes.GENERIC_ATTACK_SPEED, attackSpeed(2.0), AttributeModifierSlot.MAINHAND) + .addDefault(EntityAttributes.PLAYER_ENTITY_INTERACTION_RANGE) + .addDefault(EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE) .build() } }