From 67eb8c755277285e7ae83e322a843506231c4bc0 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 9 Feb 2024 20:08:40 +0100 Subject: [PATCH 01/21] Rename IAdvancedStaffItemHandler to IDisablesShield Make it a marker interface to reduce noise Marker interface instead of an annotation to make things easy and fast --- .../opekope2/avm_staff/mixin/LivingEntityMixin.java | 6 +++--- ...dvancedStaffItemHandler.kt => IDisablesShield.kt} | 12 ++---------- .../opekope2/avm_staff/api/item/StaffItemHandler.kt | 2 +- .../internal/staff_item_handler/AnvilHandler.kt | 6 ++---- 4 files changed, 8 insertions(+), 18 deletions(-) rename StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/{IAdvancedStaffItemHandler.kt => IDisablesShield.kt} (65%) 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 441408038..ebed235ad 100644 --- a/StaffMod/src/main/java/opekope2/avm_staff/mixin/LivingEntityMixin.java +++ b/StaffMod/src/main/java/opekope2/avm_staff/mixin/LivingEntityMixin.java @@ -21,7 +21,7 @@ import net.minecraft.entity.LivingEntity; import net.minecraft.item.ItemStack; import opekope2.avm_staff.IStaffMod; -import opekope2.avm_staff.api.item.IAdvancedStaffItemHandler; +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; @@ -44,8 +44,8 @@ public void disableShield(CallbackInfoReturnable cir) { if (itemInStaff == null) return; StaffItemHandler handlerOfItem = StaffUtil.getHandlerOfItem(itemInStaff); - if (handlerOfItem instanceof IAdvancedStaffItemHandler advancedHandler) { - if (advancedHandler.disablesShield()) cir.setReturnValue(true); + if (handlerOfItem instanceof IDisablesShield) { + cir.setReturnValue(true); } } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/IAdvancedStaffItemHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/IDisablesShield.kt similarity index 65% rename from StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/IAdvancedStaffItemHandler.kt rename to StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/IDisablesShield.kt index 91e77c99e..a1901f326 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/IAdvancedStaffItemHandler.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/IDisablesShield.kt @@ -19,14 +19,6 @@ package opekope2.avm_staff.api.item /** - * Provides additional functionality for a staff, when an item is inserted into it. To make use of the extra - * functionalities, implement this interface alongside [StaffItemHandler]. - * - * @see StaffItemHandler + * A [StaffItemHandler] implementing this interface disables the attacked entity's shield. */ -interface IAdvancedStaffItemHandler { - /** - * Returns if the current item should disable the shield of the attacked entity. - */ - fun disablesShield(): Boolean = false -} +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/item/StaffItemHandler.kt index 727dd4681..3927664a8 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 @@ -57,7 +57,7 @@ import opekope2.avm_staff.util.transform /** * Provides functionality for a staff, when an item is inserted into it. * - * @see IAdvancedStaffItemHandler + * @see IDisablesShield */ abstract class StaffItemHandler { /** 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 19c2bc7ab..84dcb539b 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 @@ -33,14 +33,14 @@ import net.minecraft.util.ActionResult import net.minecraft.util.Hand import net.minecraft.world.World import net.minecraft.world.WorldEvents -import opekope2.avm_staff.api.item.IAdvancedStaffItemHandler +import opekope2.avm_staff.api.item.IDisablesShield import opekope2.avm_staff.api.item.StaffItemHandler import opekope2.avm_staff.api.item.model.ReloadableSingleBakedModelProvider import opekope2.avm_staff.util.* import java.util.* class AnvilHandler(anvilItem: BlockItem, private val damagedStackFactory: () -> ItemStack?) : StaffItemHandler(), - IAdvancedStaffItemHandler { + IDisablesShield { override val itemModelProvider = ReloadableSingleBakedModelProvider { anvilItem.block.defaultState.getTransformedModel(TRANSFORM_INTO_STAFF) } @@ -82,8 +82,6 @@ class AnvilHandler(anvilItem: BlockItem, private val damagedStackFactory: () -> } } - override fun disablesShield() = true - private companion object { private val MOVEMENT_SPEED_MODIFIER_ID: UUID = UUID.fromString("c0374b4f-d600-4b6a-9984-3ee35d37750d") From 14a6ee80f65ed90fee9544e9daade9bb1b71e778 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 13 Feb 2024 21:11:14 +0100 Subject: [PATCH 02/21] Add physical side check API to IStaffMod --- .../kotlin/opekope2/avm_staff/internal/fabric/StaffMod.kt | 5 +++++ .../kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt | 4 ++++ StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt | 5 +++++ 3 files changed, 14 insertions(+) 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 1a00be1b0..892937ab4 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,10 +18,12 @@ 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.loader.api.FabricLoader import net.minecraft.entity.Entity import net.minecraft.entity.player.PlayerEntity import net.minecraft.registry.Registries @@ -46,6 +48,9 @@ object StaffMod : ModInitializer, IStaffMod { FabricStaffItem(FabricItemSettings().maxCount(1)) ) + override val isPhysicalClient: Boolean + get() = FabricLoader.getInstance().environmentType == EnvType.CLIENT + override fun onInitialize() { AttackBlockCallback.EVENT.register(::attackBlock) AttackEntityCallback.EVENT.register(::handleEntityAttackEvent) 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 67f3be466..92ad430df 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 @@ -29,6 +29,7 @@ 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 @@ -48,6 +49,9 @@ object StaffMod : IStaffMod { override val staffItem: StaffItem get() = STAFF_ITEM.get() + override val isPhysicalClient: Boolean + get() = DIST.isClient + private fun initialize() { ITEMS.register(MOD_BUS) } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt index 159c80654..66d74d9ad 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt @@ -32,6 +32,11 @@ interface IStaffMod { */ val staffItem: StaffItem + /** + * Returns if Staff Mod is running on the physical client. + */ + val isPhysicalClient: Boolean + companion object Holder { /** * Gets the currently running loader-specific Staff Mod instance. From e7ab8c41163ce97e798a634cb90409027cdd1456 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 13 Feb 2024 21:22:42 +0100 Subject: [PATCH 03/21] Create staffs tag for future use --- .../kotlin/opekope2/avm_staff/internal/fabric/StaffMod.kt | 5 +++++ .../kotlin/opekope2/avm_staff/internal/forge/StaffMod.kt | 5 +++++ StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt | 7 +++++++ .../main/resources/data/avm_staff/tags/items/staffs.json | 6 ++++++ 4 files changed, 23 insertions(+) create mode 100644 StaffMod/src/main/resources/data/avm_staff/tags/items/staffs.json 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 892937ab4..f6a1d9f5e 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 @@ -26,8 +26,11 @@ import net.fabricmc.fabric.api.item.v1.FabricItemSettings import net.fabricmc.loader.api.FabricLoader import net.minecraft.entity.Entity import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.Item import net.minecraft.registry.Registries import net.minecraft.registry.Registry +import net.minecraft.registry.RegistryKeys +import net.minecraft.registry.tag.TagKey import net.minecraft.util.ActionResult import net.minecraft.util.Hand import net.minecraft.util.Identifier @@ -51,6 +54,8 @@ object StaffMod : ModInitializer, IStaffMod { override val isPhysicalClient: Boolean get() = FabricLoader.getInstance().environmentType == EnvType.CLIENT + override val staffsTag: TagKey = TagKey.of(RegistryKeys.ITEM, Identifier(MOD_ID, "staffs")) + override fun onInitialize() { AttackBlockCallback.EVENT.register(::attackBlock) AttackEntityCallback.EVENT.register(::handleEntityAttackEvent) 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 92ad430df..2198e6448 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 @@ -19,6 +19,9 @@ package opekope2.avm_staff.internal.forge import net.minecraft.item.Item +import net.minecraft.registry.tag.ItemTags +import net.minecraft.registry.tag.TagKey +import net.minecraft.util.Identifier import net.minecraftforge.api.distmarker.Dist import net.minecraftforge.fml.common.Mod import net.minecraftforge.registries.DeferredRegister @@ -52,6 +55,8 @@ object StaffMod : IStaffMod { override val isPhysicalClient: Boolean get() = DIST.isClient + override val staffsTag: TagKey = ItemTags.create(Identifier(MOD_ID, "staffs")) + private fun initialize() { ITEMS.register(MOD_BUS) } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt index 66d74d9ad..e7985fc96 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt @@ -18,6 +18,8 @@ package opekope2.avm_staff +import net.minecraft.item.Item +import net.minecraft.registry.tag.TagKey import opekope2.avm_staff.api.item.StaffItem import opekope2.avm_staff.internal.platform.getStaffMod @@ -37,6 +39,11 @@ interface IStaffMod { */ val isPhysicalClient: Boolean + /** + * Gets the [TagKey] containing all the staffs. + */ + val staffsTag: TagKey + companion object Holder { /** * Gets the currently running loader-specific Staff Mod instance. 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 new file mode 100644 index 000000000..8d8e67097 --- /dev/null +++ b/StaffMod/src/main/resources/data/avm_staff/tags/items/staffs.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "avm_staff:staff" + ] +} From 7f10902deafc727951feb25e21babdc2ac67e3f6 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 13 Feb 2024 21:25:50 +0100 Subject: [PATCH 04/21] Change StaffAttackHandler.kt JVM name to default It's internal, so no one else should be using it --- .../mixin/forge/ClientPlayerInteractionManagerMixin.java | 4 ++-- .../avm_staff/mixin/forge/ServerPlayerEntityMixin.java | 4 ++-- .../mixin/forge/ServerPlayerInteractionManagerMixin.java | 4 ++-- .../java/opekope2/avm_staff/mixin/MinecraftClientMixin.java | 6 +++--- .../avm_staff/internal/event_handler/StaffAttackHandler.kt | 2 -- 5 files changed, 9 insertions(+), 11 deletions(-) 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 index 3e10e5054..1ebb471b0 100644 --- a/ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ClientPlayerInteractionManagerMixin.java +++ b/ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ClientPlayerInteractionManagerMixin.java @@ -26,7 +26,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.GameMode; -import opekope2.avm_staff.internal.event_handler.StaffAttackHandler; +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; @@ -56,7 +56,7 @@ private void attackBlock(BlockPos pos, Direction direction, CallbackInfoReturnab assert client.player != null; assert client.world != null; - ActionResult result = StaffAttackHandler.attackBlock(client.player, client.world, Hand.MAIN_HAND, pos, direction); + 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. 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 index 566e59759..e2c32284c 100644 --- a/ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ServerPlayerEntityMixin.java +++ b/ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ServerPlayerEntityMixin.java @@ -20,7 +20,7 @@ import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; -import opekope2.avm_staff.internal.event_handler.StaffAttackHandler; +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; @@ -32,7 +32,7 @@ public class ServerPlayerEntityMixin { @Inject(method = "attack", at = @At("HEAD"), cancellable = true) public void onPlayerInteractEntity(Entity target, CallbackInfo info) { ServerPlayerEntity player = (ServerPlayerEntity) (Object) this; - ActionResult result = StaffAttackHandler.attackEntity(player, player.getEntityWorld(), Hand.MAIN_HAND, target); + ActionResult result = StaffAttackHandlerKt.attackEntity(player, player.getEntityWorld(), Hand.MAIN_HAND, target); if (result != ActionResult.PASS) { info.cancel(); 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 index 61bf75886..65c0e7ad2 100644 --- a/ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ServerPlayerInteractionManagerMixin.java +++ b/ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ServerPlayerInteractionManagerMixin.java @@ -28,7 +28,7 @@ import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; -import opekope2.avm_staff.internal.event_handler.StaffAttackHandler; +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; @@ -50,7 +50,7 @@ public abstract class ServerPlayerInteractionManagerMixin { 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 = StaffAttackHandler.attackBlock(player, world, Hand.MAIN_HAND, pos, direction); + ActionResult result = StaffAttackHandlerKt.attackBlock(player, world, Hand.MAIN_HAND, pos, direction); if (result == ActionResult.PASS) return; 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 0a219f2a8..fd7cc2bf9 100644 --- a/StaffMod/src/main/java/opekope2/avm_staff/mixin/MinecraftClientMixin.java +++ b/StaffMod/src/main/java/opekope2/avm_staff/mixin/MinecraftClientMixin.java @@ -29,7 +29,7 @@ import net.minecraft.util.Hand; import net.minecraft.util.hit.EntityHitResult; import net.minecraft.util.hit.HitResult; -import opekope2.avm_staff.internal.event_handler.StaffAttackHandler; +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; @@ -75,7 +75,7 @@ private void handleEntityAttack(CallbackInfoReturnable cir) { assert crosshairTarget != null; Entity target = ((EntityHitResult) crosshairTarget).getEntity(); - ActionResult result = StaffAttackHandler.attackEntity(player, world, Hand.MAIN_HAND, target); + ActionResult result = StaffAttackHandlerKt.attackEntity(player, world, Hand.MAIN_HAND, target); switch (result) { case SUCCESS -> { Objects.requireNonNull(getNetworkHandler()) @@ -107,7 +107,7 @@ private void handleAttack(CallbackInfoReturnable cir) { ItemStack stackInHand = player.getStackInHand(Hand.MAIN_HAND); - ActionResult result = StaffAttackHandler.attack(stackInHand, world, player, Hand.MAIN_HAND); + ActionResult result = StaffAttackHandlerKt.attack(stackInHand, world, player, Hand.MAIN_HAND); switch (result) { case SUCCESS -> { new StaffAttackC2SPacket().send(); 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 6c87bfa53..339969193 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 @@ -16,8 +16,6 @@ * along with this mod. If not, see . */ -@file: JvmName("StaffAttackHandler") - package opekope2.avm_staff.internal.event_handler import net.minecraft.entity.Entity From 8e40781d65b9fbd334741f50addbda7fde3381fc Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 13 Feb 2024 21:37:07 +0100 Subject: [PATCH 05/21] Add staff calculation helper properties --- .../opekope2/avm_staff/util/StaffUtil.kt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) 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 5dbbc52c3..a288e9cf5 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/StaffUtil.kt @@ -20,9 +20,11 @@ package opekope2.avm_staff.util +import net.minecraft.entity.Entity import net.minecraft.item.ItemStack import net.minecraft.nbt.NbtCompound import net.minecraft.registry.Registries +import net.minecraft.util.math.Vec3d import opekope2.avm_staff.api.item.StaffItemHandler /** @@ -85,3 +87,19 @@ val ItemStack.handlerOfItem: StaffItemHandler? val ItemStack?.handlerOfItemOrFallback: StaffItemHandler get() = if (this == null) StaffItemHandler.EmptyStaffHandler else handlerOfItem ?: StaffItemHandler.FallbackStaffHandler + +private const val STAFF_MODEL_LENGTH = 40.0 / 16.0 +private const val STAFF_MODEL_ITEM_POSITION_CENTER = 33.5 / 16.0 +private const val STAFF_MODEL_SCALE = 0.85 + +/** + * Gets the approximate position of the staff's tip, when held by an entity. + */ +val Entity.approximateStaffTipPosition: Vec3d + get() = eyePos + rotationVector * (STAFF_MODEL_LENGTH * STAFF_MODEL_SCALE) + +/** + * Gets the approximate position of the item in the staff, when held my an entity. + */ +val Entity.approximateStaffItemPosition: Vec3d + get() = eyePos + rotationVector * (STAFF_MODEL_ITEM_POSITION_CENTER * STAFF_MODEL_SCALE) From 45fcee78f90d73f7f59b2ac976c5b9dfd8f06f7e Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 13 Feb 2024 21:31:07 +0100 Subject: [PATCH 06/21] Adjust TNT staff behavior When shooting, the shooter's velocity is added The TNT now spawns at the staff's tip A shot TNT will explode, if it hits its shooter --- .../java/opekope2/avm_staff/mixin/TntEntityMixin.java | 11 ++--------- .../internal/staff_item_handler/TntHandler.kt | 8 ++++---- 2 files changed, 6 insertions(+), 13 deletions(-) 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 0ee9cf783..e369e74e0 100644 --- a/StaffMod/src/main/java/opekope2/avm_staff/mixin/TntEntityMixin.java +++ b/StaffMod/src/main/java/opekope2/avm_staff/mixin/TntEntityMixin.java @@ -20,13 +20,11 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; -import net.minecraft.entity.LivingEntity; 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.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -44,10 +42,6 @@ private TntEntityMixin(EntityType type, World world) { @Shadow protected abstract void explode(); - @Shadow - @Nullable - public abstract LivingEntity getOwner(); - @Inject(method = "initDataTracker", at = @At("TAIL")) private void initDataTracker(CallbackInfo ci) { dataTracker.startTracking(EXPLODES_ON_IMPACT, false); @@ -78,8 +72,7 @@ private void explodeOnImpact(CallbackInfo ci) { boolean explode = horizontalCollision || verticalCollision; if (!explode) { - Entity owner = getOwner(); - List collisions = getWorld().getOtherEntities(this, getBoundingBox(), entity -> entity != owner); + List collisions = getWorld().getOtherEntities(this, getBoundingBox(), entity -> true); explode = !collisions.isEmpty(); for (Entity collider : collisions) { @@ -93,7 +86,7 @@ private void explodeOnImpact(CallbackInfo ci) { if (!explode) return; if (!getWorld().isClient) { - // Server sends EntitiesDestroyS2CPacket to client, because TntEntity.getOwner() isn't available on the client. + // Server sends EntitiesDestroyS2CPacket to client, because the position desync makes collision detection unreliable discard(); explode(); } 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 a4e609a13..bb05e4fae 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 @@ -31,8 +31,7 @@ import net.minecraft.world.event.GameEvent import opekope2.avm_staff.api.entity.IImpactTnt import opekope2.avm_staff.api.item.StaffItemHandler import opekope2.avm_staff.api.item.model.ReloadableSingleBakedModelProvider -import opekope2.avm_staff.util.TRANSFORM_INTO_STAFF -import opekope2.avm_staff.util.getTransformedModel +import opekope2.avm_staff.util.* class TntHandler : StaffItemHandler() { override val itemModelProvider = ReloadableSingleBakedModelProvider { @@ -42,9 +41,10 @@ class TntHandler : StaffItemHandler() { override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand): ActionResult { if (world.isClient) return ActionResult.SUCCESS + val (x, y, z) = attacker.approximateStaffTipPosition world.spawnEntity( - TntEntity(world, attacker.x, attacker.eyeY, attacker.z, attacker).apply { - velocity = attacker.rotationVector.normalize() + TntEntity(world, x, y, z, attacker).apply { + velocity = attacker.rotationVector + attacker.velocity @Suppress("KotlinConstantConditions") // IImpactTnt is ducked into TntEntity (this as IImpactTnt).explodeOnImpact(true) world.playSound(null, x, y, z, SoundEvents.ENTITY_TNT_PRIMED, SoundCategory.BLOCKS, 1.0f, 1.0f) From 3876e97787179a6270e31914e5af432318736d82 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 13 Feb 2024 21:40:49 +0100 Subject: [PATCH 07/21] Adjust magma block staff The fireballs now spawn at the staff's tip, making it less obstructive --- .../avm_staff/internal/staff_item_handler/MagmaBlockHandler.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 e02e28758..e9bf93544 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 @@ -88,7 +88,7 @@ class MagmaBlockHandler : StaffItemHandler() { val (x, y, z) = user.rotationVector world.spawnEntity(SmallFireballEntity(world, user, x, y, z).apply { - setPosition(user.x, user.eyeY - 0.1, user.z) + setPosition(user.approximateStaffTipPosition) }) } From fb4f21d5fc8bd02b4c7af490811b776413a21eed Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 13 Feb 2024 21:42:29 +0100 Subject: [PATCH 08/21] Adjust snow block staff The snowballs now spawn at the staff's tip --- .../internal/staff_item_handler/SnowBlockHandler.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) 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 8a94c4087..65c6ab454 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 @@ -30,8 +30,7 @@ import net.minecraft.util.TypedActionResult import net.minecraft.world.World import opekope2.avm_staff.api.item.StaffItemHandler import opekope2.avm_staff.api.item.model.ReloadableSingleBakedModelProvider -import opekope2.avm_staff.util.TRANSFORM_INTO_STAFF -import opekope2.avm_staff.util.getTransformedModel +import opekope2.avm_staff.util.* class SnowBlockHandler : StaffItemHandler() { override val maxUseTime = 72000 @@ -70,7 +69,10 @@ class SnowBlockHandler : StaffItemHandler() { ) if (world.isClient) return - world.spawnEntity(SnowballEntity(world, user).apply { + + val (x, y, z) = user.approximateStaffTipPosition + world.spawnEntity(SnowballEntity(world, x, y, z).apply { + owner = user // TODO speed setVelocity(user, user.pitch, user.yaw, 0f, 4f, 1f) }) From 59e650d71a59e23244fe7b6efa31f39163bdbdd0 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 13 Feb 2024 22:08:12 +0100 Subject: [PATCH 09/21] Add using_item model predicate --- .../internal/fabric/StaffModClient.kt | 4 +++ .../internal/forge/StaffModClient.kt | 10 +++++++ .../avm_staff/internal/Initializer.kt | 28 +++++++++++++++++++ 3 files changed, 42 insertions(+) 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 4a30cc8f0..3517bc0d2 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 @@ -27,11 +27,13 @@ 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.itemgroup.v1.ItemGroupEvents import net.minecraft.client.render.model.BakedModel +import net.minecraft.client.item.ModelPredicateProviderRegistry import net.minecraft.item.ItemGroups import net.minecraft.item.Items import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING import opekope2.avm_staff.internal.fabric.item.model.StaffItemModel import opekope2.avm_staff.internal.event_handler.handleKeyBindings +import opekope2.avm_staff.internal.registerModelPredicateProviders import opekope2.avm_staff.util.MOD_ID @Suppress("unused") @@ -50,6 +52,8 @@ object StaffModClient : ClientModInitializer { KeyBindingHelper.registerKeyBinding(ADD_REMOVE_KEYBINDING) ClientTickEvents.END_CLIENT_TICK.register(::handleKeyBindings) + + registerModelPredicateProviders(ModelPredicateProviderRegistry::register) } private fun modelLoadingPlugin(pluginContext: ModelLoadingPlugin.Context) { 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 9fc806485..8406f5c06 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 @@ -19,6 +19,7 @@ package opekope2.avm_staff.internal.forge import net.minecraft.client.MinecraftClient +import net.minecraft.client.item.ModelPredicateProviderRegistry import net.minecraft.client.util.ModelIdentifier import net.minecraft.item.ItemGroup.StackVisibility.PARENT_AND_SEARCH_TABS import net.minecraft.item.ItemGroups @@ -32,10 +33,12 @@ import net.minecraftforge.common.MinecraftForge.EVENT_BUS 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.internal.event_handler.ADD_REMOVE_KEYBINDING import opekope2.avm_staff.internal.forge.item.model.StaffItemModel import opekope2.avm_staff.internal.event_handler.handleKeyBindings import opekope2.avm_staff.internal.platform.forge.getStaffMod +import opekope2.avm_staff.internal.registerModelPredicateProviders import opekope2.avm_staff.util.MOD_ID import thedarkcolour.kotlinforforge.forge.MOD_BUS @@ -46,6 +49,13 @@ object StaffModClient { EVENT_BUS.register(javaClass) } + @SubscribeEvent + fun initializeClient(event: FMLClientSetupEvent) { + event.enqueueWork { + registerModelPredicateProviders(ModelPredicateProviderRegistry::register) + } + } + @SubscribeEvent fun addItemsToItemGroups(event: BuildCreativeModeTabContentsEvent) { if (event.tabKey === ItemGroups.TOOLS) { 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..6f98a13d4 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/Initializer.kt @@ -18,15 +18,43 @@ 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 + ) +} From 96645edc75a93c6cec2170e82be7c83f1dfdbed8 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 13 Feb 2024 22:00:58 +0100 Subject: [PATCH 10/21] Change staff model Make it smaller Add forward facing model, while being used Make 1st person model less obstructive Make player hold 3rd person model towards the center --- .../assets/avm_staff/models/item/staff.json | 98 ++++++++++-------- .../avm_staff/models/item/staff_in_use.json | 26 +++++ .../assets/avm_staff/textures/item/staff.png | Bin 987 -> 970 bytes 3 files changed, 82 insertions(+), 42 deletions(-) create mode 100644 StaffMod/src/main/resources/assets/avm_staff/models/item/staff_in_use.json 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 index 86285911c..b5a1f4477 100644 --- a/StaffMod/src/main/resources/assets/avm_staff/models/item/staff.json +++ b/StaffMod/src/main/resources/assets/avm_staff/models/item/staff.json @@ -2,93 +2,107 @@ "credit": "Made with Blockbench", "texture_size": [32, 32], "textures": { - "0": "avm_staff:item/staff", - "particle": "avm_staff:item/staff" + "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": [8, 2.5, 9, 3.5], "texture": "#0"}, - "east": {"uv": [7, 2.5, 8, 3.5], "texture": "#0"}, - "south": {"uv": [6, 2.5, 7, 3.5], "texture": "#0"}, - "west": {"uv": [5, 2.5, 6, 3.5], "texture": "#0"}, - "up": {"uv": [6, 1.5, 7, 2.5], "texture": "#0"} + "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": [12.5, 30, 9], + "to": [9, 30, 12.5], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 29.5, 8]}, "faces": { - "north": {"uv": [8.75, 5, 6, 4.5], "texture": "#0"}, - "east": {"uv": [8.75, 6, 9.75, 6.5], "texture": "#0"}, - "south": {"uv": [6, 6, 8.75, 6.5], "texture": "#0"}, - "west": {"uv": [5, 6, 6, 6.5], "texture": "#0"}, - "up": {"uv": [6, 5, 8.75, 6], "texture": "#0"}, - "down": {"uv": [6, 6.5, 8.75, 7.5], "texture": "#0"} + "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": [11.5, 22, 7], - "to": [12.5, 29, 9], + "from": [7, 22, 11.5], + "to": [9, 29, 12.5], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 25.5, 8]}, "faces": { - "north": {"uv": [6.75, 8.5, 7.25, 12], "texture": "#0"}, - "east": {"uv": [8.75, 8.5, 9.75, 12], "texture": "#0"}, - "south": {"uv": [8.25, 8.5, 8.75, 12], "texture": "#0"}, - "west": {"uv": [7.25, 8.5, 8.25, 12], "texture": "#0"} + "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": [12.5, 22, 9], + "to": [9, 22, 12.5], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 21.5, 8]}, "faces": { - "north": {"uv": [8.75, 13.5, 6, 13], "texture": "#0"}, - "east": {"uv": [8.75, 14.5, 9.75, 15], "texture": "#0"}, - "south": {"uv": [6, 14.5, 8.75, 15], "texture": "#0"}, - "west": {"uv": [5, 14.5, 6, 15], "texture": "#0"}, - "up": {"uv": [6, 13.5, 8.75, 14.5], "texture": "#0"}, - "down": {"uv": [6, 15, 8.75, 16], "texture": "#0"} + "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": [3, 0.5, 4, 15], "texture": "#0"}, - "east": {"uv": [2, 0.5, 3, 15], "texture": "#0"}, - "south": {"uv": [1, 0.5, 2, 15], "texture": "#0"}, - "west": {"uv": [0, 0.5, 1, 15], "texture": "#0"}, - "down": {"uv": [1, 15, 2, 16], "texture": "#0"} + "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": { - "translation": [0, 8, 0] + "rotation": [0, 90, 0], + "translation": [0, 2, 0], + "scale": [0.85, 0.85, 0.85] }, "thirdperson_lefthand": { - "rotation": [180, 0, 180], - "translation": [0, 8, 0] + "rotation": [0, 90, 0], + "translation": [0, 2, 0], + "scale": [0.85, 0.85, 0.85] }, "firstperson_righthand": { - "translation": [0, -8, 0] + "rotation": [-25, 90, 0], + "translation": [1.13, -1.8, 3.46], + "scale": [0.68, 0.68, 0.68] }, "firstperson_lefthand": { - "rotation": [180, 0, 180], - "translation": [0, -8, 0] + "rotation": [0, 90, -25], + "translation": [1.13, -1.8, 3.46], + "scale": [0.68, 0.68, 0.68] }, "ground": { - "rotation": [0, 0, -45], - "translation": [-3.5, 6, 0], + "rotation": [90, 45, -90], + "translation": [-1.75, 6, 0], "scale": [0.5, 0.5, 0.5] }, "gui": { - "rotation": [0, 0, -45] + "rotation": [90, 45, -90] }, "fixed": { - "rotation": [180, 0, 135] + "rotation": [90, -45, 90] } } } \ No newline at end of file diff --git a/StaffMod/src/main/resources/assets/avm_staff/models/item/staff_in_use.json b/StaffMod/src/main/resources/assets/avm_staff/models/item/staff_in_use.json new file mode 100644 index 000000000..cddc2d71b --- /dev/null +++ b/StaffMod/src/main/resources/assets/avm_staff/models/item/staff_in_use.json @@ -0,0 +1,26 @@ +{ + "credit": "Made with Blockbench", + "parent": "avm_staff:item/staff", + "display": { + "thirdperson_righthand": { + "rotation": [-75, 90, 0], + "translation": [0, -2, -4], + "scale": [0.85, 0.85, 0.85] + }, + "thirdperson_lefthand": { + "rotation": [-75, 90, 0], + "translation": [0, -2, -4], + "scale": [0.85, 0.85, 0.85] + }, + "firstperson_righthand": { + "rotation": [-180, 70, 105], + "translation": [-2.37, 3.2, 3.46], + "scale": [0.68, 0.68, 0.68] + }, + "firstperson_lefthand": { + "rotation": [-180, 70, 105], + "translation": [-2.37, 3.2, 3.46], + "scale": [0.68, 0.68, 0.68] + } + } +} diff --git a/StaffMod/src/main/resources/assets/avm_staff/textures/item/staff.png b/StaffMod/src/main/resources/assets/avm_staff/textures/item/staff.png index 7fd317cdaf3782521f9ac24a2a8faa706315909b..ec47bd7b4df5acae1dafadf28be3076a52db591d 100644 GIT binary patch delta 949 zcmV;m14{hc2g(PKBYy*tNkl0A07#~Vsv0Ew{Xi2CG3Mss)&q#pxKQ6m;5}ecR*^|*-5KVw zF*lD&t%_f*Mh_0W2TaN;9^JhMJ()(ORt10_yqq0>XhJAc8NzGP-n8UUbD zt0I3;94W#g34cX}o=hXVFpW%E!|7R@!2pn5mq5FiK;1cb5_rnlP(C61Hkscrq>$4=360{Fq(6+4-f=F3j88v?Q%WehZS zvWXDrBjgkb01`^vxr7b_0jtSH^I7IWSHJ2`l3-rwkh;pzT*RxG=i^(~(wLG}#Pr*i z?|U+n1b+Y=9@Q-|FYP}q{G<+T`W?+(8v*%)qC_XNHGRpo7p!bHJx+1>G7As6_%PlZJtK$OEDCyar{ zPJg!W5WtI6(P7|3011WJnIu*=H#}bzB6JTAtq+6w z*LZtFY1=P@+Z?&u*V8j3*{$1T0K@d&&@T0S;Q9o6dVH>!oCDJ*D7M2cVt5!C^*+IW X>JW|tMFlfb00000NkvXXu0mjf!{o&F delta 966 zcmV;%13CQ42ipgbBYyw}VoOIv0RI300RJ8(lYRgI1CU8XK~#9!?OQu<(@+%tjG~g* z4rv-WZRJ$ZR*I0YC}JpcrH)8Qs4Oh3jGbA^Psq@LU%(VGbt5|>15&CWp-AN+QnhM` zLdmPDkj#)=_xi?mofIeW?LAA+*W)zxchBqk9s>Z(zTg_l4S!s7k+$z|n(J8u4~;u` z^KK6Sz~YxrALCQ`JBpR^0M6|fq)-#EnOrrErDXs>`R6wPz%aPbI0!WX5o2i?em#H) zjSGzfgx&*YWfhr}X00%bjiqH&>oxrDv<7hKJz!Q=@#yY7=*cvy^%?*S;PtEly>Wt% zUp^1whW8h2>3?fxCZz!Ys`VQ3hoz|^ERs-E=*cv)EAz-yG&Ik;HVgpSm3iPRkWhXg z9*x=XWs*s0SkD?gP$>h4Q&tA!(HH}4Z3)FBY`7gX!D-pUi5cLLa$_hX-A zj`;5ckeK&XR++|X5;?*mKvnEq(Adl7=JLf#`N9JjOn-=Q!@>h5L4cyn*bFrGvayoe zFGyzTy$Jxh*W0~#-Y)=o+coTG#BNX!APC^J5h8V8*V34iRm5(}j@Kn`zy@~S$WY1@Kyz^?5+WG0FI8~+6r??0GkuU zZcq>)2)JHJke0Vw+a{SYAjf4a-h1)Ny7qZKCw~bK;K>8x)OjPV(^$O~oeTk;&Y8_X zV=vnyc1_c3v0N!#ytJ8JVZTQ65 z9ykH*_PNbKV=vn<((If&>V7aE9`NVPQTKxbC!p2-YySr*>}4Cy1GgVr^2ESAj;9NQ=5UtUN(LRV4lm<*vl6B96(0mfr}R+M#WA-kK>agawnP8 zBzfR3Opu%Rb2d1Rvp`o5C|1h06{RsD!VQNy1cLT}X+Ikj9uTw#O#9iOblLp=Wth#} zZhz0uoFE+v80 oIfrIWP;7^N#PBFG?Q??v0F5q#!OOIBy#N3J07*qoM6N<$f+Wqxr~m)} From 1c8948acaac94560ee35a555868bb5b679781b83 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 13 Feb 2024 22:16:58 +0100 Subject: [PATCH 11/21] Hold staff where the player looks while in use --- .../mixin/BipedEntityModelMixin.java | 69 +++++++++++++++++++ .../src/main/resources/avm_staff.mixins.json | 1 + 2 files changed, 70 insertions(+) create mode 100644 StaffMod/src/main/java/opekope2/avm_staff/mixin/BipedEntityModelMixin.java diff --git a/StaffMod/src/main/java/opekope2/avm_staff/mixin/BipedEntityModelMixin.java b/StaffMod/src/main/java/opekope2/avm_staff/mixin/BipedEntityModelMixin.java new file mode 100644 index 000000000..ba0e666ee --- /dev/null +++ b/StaffMod/src/main/java/opekope2/avm_staff/mixin/BipedEntityModelMixin.java @@ -0,0 +1,69 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.mixin; + +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 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; + +@Mixin(BipedEntityModel.class) +public abstract class BipedEntityModelMixin { + @Shadow + public BipedEntityModel.ArmPose leftArmPose; + + @Shadow + @Final + public ModelPart leftArm; + + @Shadow + public BipedEntityModel.ArmPose rightArmPose; + + @Shadow + @Final + public ModelPart rightArm; + + @Unique + private float staffMod$degToRad(float degrees) { + return degrees * (float) Math.PI / 180f; + } + + @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); + } + } + + @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); + } + } +} diff --git a/StaffMod/src/main/resources/avm_staff.mixins.json b/StaffMod/src/main/resources/avm_staff.mixins.json index 984cee3c2..f5e5ba448 100644 --- a/StaffMod/src/main/resources/avm_staff.mixins.json +++ b/StaffMod/src/main/resources/avm_staff.mixins.json @@ -8,6 +8,7 @@ }, "client": [ "BakedModelManagerMixin", + "BipedEntityModelMixin", "IMinecraftClientMixin", "MinecraftClientMixin" ], From 3659046838b3b80337e7b86c705d1da93327a49f Mon Sep 17 00:00:00 2001 From: opekope2 Date: Tue, 13 Feb 2024 22:18:59 +0100 Subject: [PATCH 12/21] Add MixinExtras to Forge project --- ForgeMod/build.gradle.kts | 5 +++++ gradle.properties | 1 + 2 files changed, 6 insertions(+) diff --git a/ForgeMod/build.gradle.kts b/ForgeMod/build.gradle.kts index 8feeae420..7e5528834 100644 --- a/ForgeMod/build.gradle.kts +++ b/ForgeMod/build.gradle.kts @@ -31,6 +31,11 @@ dependencies { forge("net.minecraftforge", "forge", project.gradleProperty("forge_version")) modApi("dev.architectury", "architectury-forge", project.gradleProperty("architectury_api_version")) + compileOnly( + annotationProcessor("io.github.llamalad7", "mixinextras-common", project.gradleProperty("mixin_extras_version")) + ) + implementation(include("io.github.llamalad7", "mixinextras-forge", project.gradleProperty("mixin_extras_version"))) + common(project(":StaffMod", configuration = "namedElements")) { isTransitive = false } shadowCommon(project(":StaffMod", configuration = "transformProductionForge")) { isTransitive = false } diff --git a/gradle.properties b/gradle.properties index 3a46b73c4..e18b5bcb2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,6 +14,7 @@ architectury_api_version=11.0.11 fabric_loader_version=0.15.3 forge_version=1.20.4-49.0.27 fabric_api_version=0.91.3+1.20.4 +mixin_extras_version=0.3.5 # Don't forget to update *.mixins.json java_version=17 ########################################################################## From 0b06cd2b31e64f6f5b9e04fe8d1d6618dedf97a7 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 15 Feb 2024 21:54:42 +0100 Subject: [PATCH 13/21] Add baked model for staff item rendering --- .../api/item/model/IStaffItemBakedModel.kt | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/IStaffItemBakedModel.kt 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 new file mode 100644 index 000000000..7883468e4 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/IStaffItemBakedModel.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 . + */ + +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 +} From c7b10a577546ce5fdfdc2951e4ac2244d2b08f34 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 15 Feb 2024 22:04:34 +0100 Subject: [PATCH 14/21] Add unbaked model for staff item model loading --- .../api/item/model/IStaffItemUnbakedModel.kt | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/IStaffItemUnbakedModel.kt 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 new file mode 100644 index 000000000..4e765fc5a --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/IStaffItemUnbakedModel.kt @@ -0,0 +1,64 @@ +/* + * 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? +} From 500f374a97c0b80b6655fb2633799be3be2244bc Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 15 Feb 2024 22:06:50 +0100 Subject: [PATCH 15/21] Add default implementation of IStaffItemBakedModel --- .../api/item/model/StaffItemBakedModel.kt | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/StaffItemBakedModel.kt 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 new file mode 100644 index 000000000..8effd7b5d --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/StaffItemBakedModel.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.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 From 59985d00cef68b62316e5528004c3652a39fc04a Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 15 Feb 2024 22:10:30 +0100 Subject: [PATCH 16/21] Add default implementation of IStaffItemUnbakedModel --- .../api/item/model/UnbakedBlockStateModel.kt | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/UnbakedBlockStateModel.kt 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 new file mode 100644 index 000000000..ee8075a30 --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/UnbakedBlockStateModel.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.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)) + } +} From f2f4f8f9e52ad41352266a0205b3a42177a02233 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 15 Feb 2024 22:13:51 +0100 Subject: [PATCH 17/21] Add convenience supplier for UnbakedBlockStateModel --- .../model/UnbakedBlockStateModelSupplier.kt | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/UnbakedBlockStateModelSupplier.kt 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 new file mode 100644 index 000000000..54e80322c --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/UnbakedBlockStateModelSupplier.kt @@ -0,0 +1,34 @@ +/* + * AvM Staff Mod + * Copyright (c) 2024 opekope2 + * + * This mod is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This mod is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this mod. If not, see . + */ + +package opekope2.avm_staff.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) +} From be6177caecd9220a65fee911b37fd114ae711885 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 15 Feb 2024 22:16:40 +0100 Subject: [PATCH 18/21] Change model utilities Remove some buggy functions, which don't play nicely with the new model loading system Change BakedModel.transform() to get the missing sprite from the newly supplied textureGetter --- .../opekope2/avm_staff/util/ModelUtil.kt | 34 +++++++------------ 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/ModelUtil.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/ModelUtil.kt index 23bfb9db5..273ec783d 100644 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/util/ModelUtil.kt +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/util/ModelUtil.kt @@ -21,22 +21,24 @@ package opekope2.avm_staff.util import net.minecraft.block.BlockState -import net.minecraft.client.MinecraftClient 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. @@ -48,26 +50,6 @@ val TRANSFORM_INTO_STAFF = Transformation( Vector3f(7f / 16f) ) -/** - * Gets the missing sprite from the block atlas. - */ -val missingSprite: Sprite - get() { - val atlas = MinecraftClient.getInstance().getSpriteAtlas(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE) - return atlas.apply(MissingSprite.getMissingSpriteId()) - } - -private val BlockState.model - get() = MinecraftClient.getInstance().blockRenderManager.getModel(this) - -/** - * Creates a transformed model based on the model of the block state. - * - * @param transformation The transformation to apply to the model - */ -fun BlockState.getTransformedModel(transformation: Transformation): BakedModel = - model.transform(this, transformation) - private val cullFaces = arrayOf(*Direction.values(), null) /** @@ -75,11 +57,19 @@ private val cullFaces = arrayOf(*Direction.values(), null) * * @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): BakedModel { +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) { From 853550ec582c64dfc32fccc7cec495bc890e8d53 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 15 Feb 2024 22:55:48 +0100 Subject: [PATCH 19/21] Refactor staff model rendering (again) --- .../internal/fabric/StaffModClient.kt | 18 +++-- ...mModel.kt => BakedFabricStaffItemModel.kt} | 17 +++-- .../item/model/UnbakedFabricStaffItemModel.kt | 50 ++++++++++++++ .../forge/ModelLoaderBakerImplMixin.java | 58 +++++++++++++++++ .../internal/forge/StaffModClient.kt | 11 ---- ...emModel.kt => BakedForgeStaffItemModel.kt} | 22 +++++-- .../item/model/UnbakedForgeStaffItemModel.kt | 50 ++++++++++++++ .../resources/avm_staff_forge.mixins.json | 3 +- .../mixin/BakedModelManagerMixin.java | 35 ---------- .../avm_staff/api/item/StaffItemHandler.kt | 65 ++++++++----------- .../model/IReloadableBakedModelProvider.kt | 40 ------------ .../ReloadableSingleBakedModelProvider.kt | 37 ----------- .../item/model/UnbakedStaffItemModel.kt | 60 +++++++++++++++++ .../src/main/resources/avm_staff.mixins.json | 1 - 14 files changed, 284 insertions(+), 183 deletions(-) rename FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/model/{StaffItemModel.kt => BakedFabricStaffItemModel.kt} (72%) create mode 100644 FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/model/UnbakedFabricStaffItemModel.kt create mode 100644 ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ModelLoaderBakerImplMixin.java rename ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/model/{StaffItemModel.kt => BakedForgeStaffItemModel.kt} (65%) create mode 100644 ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/model/UnbakedForgeStaffItemModel.kt delete mode 100644 StaffMod/src/main/java/opekope2/avm_staff/mixin/BakedModelManagerMixin.java delete mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/IReloadableBakedModelProvider.kt delete mode 100644 StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/ReloadableSingleBakedModelProvider.kt create 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 3517bc0d2..77214fc07 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,13 +26,14 @@ 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.itemgroup.v1.ItemGroupEvents -import net.minecraft.client.render.model.BakedModel 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.internal.event_handler.ADD_REMOVE_KEYBINDING -import opekope2.avm_staff.internal.fabric.item.model.StaffItemModel 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 @@ -57,13 +58,16 @@ object StaffModClient : ClientModInitializer { } private fun modelLoadingPlugin(pluginContext: ModelLoadingPlugin.Context) { - pluginContext.modifyModelAfterBake().register(::modifyModelAfterBake) + pluginContext.modifyModelBeforeBake().register(::modifyModelBeforeBake) } - private fun modifyModelAfterBake(model: BakedModel?, context: ModelModifier.AfterBake.Context): BakedModel? { - val id = context.id() + private fun modifyModelBeforeBake(model: UnbakedModel, context: ModelModifier.BeforeBake.Context): UnbakedModel { + if (context.id().namespace != MOD_ID) return model - return if (model == null || id.namespace != MOD_ID || id.path != "staff") model - else StaffItemModel(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/StaffItemModel.kt b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/model/BakedFabricStaffItemModel.kt similarity index 72% rename from FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/model/StaffItemModel.kt rename to FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/model/BakedFabricStaffItemModel.kt index 05602b0e7..d8ba1c49c 100644 --- a/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/model/StaffItemModel.kt +++ b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/model/BakedFabricStaffItemModel.kt @@ -24,24 +24,29 @@ 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.util.handlerOfItemOrFallback +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 StaffItemModel(original: BakedModel) : BakedModel by original { +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 - val handler = itemStack.handlerOfItemOrFallback + val itemStack = stack.itemInStaff ?: return - val model = handler.itemModelProvider.getModel(stack) as FabricBakedModel - model.emitItemQuads(stack, randomSupplier, context) + 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 new file mode 100644 index 000000000..a230383f8 --- /dev/null +++ b/FabricMod/src/main/kotlin/opekope2/avm_staff/internal/fabric/item/model/UnbakedFabricStaffItemModel.kt @@ -0,0 +1,50 @@ +/* + * 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.json.JsonUnbakedModel +import net.minecraft.client.texture.MissingSprite +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(MissingSprite.getMissingSpriteId(), 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 new file mode 100644 index 000000000..b8aa98105 --- /dev/null +++ b/ForgeMod/src/main/java/opekope2/avm_staff/mixin/forge/ModelLoaderBakerImplMixin.java @@ -0,0 +1,58 @@ +/* + * 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/StaffModClient.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/StaffModClient.kt index 8406f5c06..97bc245af 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,14 +20,12 @@ package opekope2.avm_staff.internal.forge import net.minecraft.client.MinecraftClient import net.minecraft.client.item.ModelPredicateProviderRegistry -import net.minecraft.client.util.ModelIdentifier 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.ModelEvent import net.minecraftforge.client.event.RegisterKeyMappingsEvent import net.minecraftforge.common.MinecraftForge.EVENT_BUS import net.minecraftforge.event.BuildCreativeModeTabContentsEvent @@ -35,11 +33,9 @@ import net.minecraftforge.event.TickEvent import net.minecraftforge.eventbus.api.SubscribeEvent import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING -import opekope2.avm_staff.internal.forge.item.model.StaffItemModel import opekope2.avm_staff.internal.event_handler.handleKeyBindings import opekope2.avm_staff.internal.platform.forge.getStaffMod import opekope2.avm_staff.internal.registerModelPredicateProviders -import opekope2.avm_staff.util.MOD_ID import thedarkcolour.kotlinforforge.forge.MOD_BUS @OnlyIn(Dist.CLIENT) @@ -85,11 +81,4 @@ object StaffModClient { handleKeyBindings(MinecraftClient.getInstance()) } - - @SubscribeEvent - fun modifyModelAfterBake(event: ModelEvent.ModifyBakingResult) { - val id = ModelIdentifier(MOD_ID, "staff", "inventory") - - event.models[id] = StaffItemModel(event.models[id]!!) - } } diff --git a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/model/StaffItemModel.kt b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/model/BakedForgeStaffItemModel.kt similarity index 65% rename from ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/model/StaffItemModel.kt rename to ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/model/BakedForgeStaffItemModel.kt index 2eb7eddf9..fdb7cb8c5 100644 --- a/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/model/StaffItemModel.kt +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/model/BakedForgeStaffItemModel.kt @@ -22,12 +22,21 @@ 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 opekope2.avm_staff.util.handlerOfItemOrFallback +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 -class StaffItemModel(original: BakedModel) : BakedModelWrapper(original) { +@OnlyIn(Dist.CLIENT) +class BakedForgeStaffItemModel( + original: BakedModel, + private val itemModels: Map, + private val missingModel: BakedModel +) : BakedModelWrapper(original) { override fun applyTransform( cameraTransformType: ModelTransformationMode, poseStack: MatrixStack, @@ -38,13 +47,12 @@ class StaffItemModel(original: BakedModel) : BakedModelWrapper(origi return this } - override fun getRenderPasses(itemStack: ItemStack, fabulous: Boolean): MutableList { - if (!itemStack.isItemInStaff) return mutableListOf(this) + override fun getRenderPasses(stack: ItemStack, fabulous: Boolean): MutableList { + if (!stack.isItemInStaff) return mutableListOf(this) - val staffItemStack = itemStack.itemInStaff - val handler = staffItemStack.handlerOfItemOrFallback + val itemStack = stack.itemInStaff ?: return mutableListOf(this) - val model = handler.itemModelProvider.getModel(itemStack) + 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 new file mode 100644 index 000000000..92f92a423 --- /dev/null +++ b/ForgeMod/src/main/kotlin/opekope2/avm_staff/internal/forge/item/model/UnbakedForgeStaffItemModel.kt @@ -0,0 +1,50 @@ +/* + * 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.json.JsonUnbakedModel +import net.minecraft.client.texture.MissingSprite +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(MissingSprite.getMissingSpriteId(), 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 910fab075..59b98338a 100644 --- a/ForgeMod/src/main/resources/avm_staff_forge.mixins.json +++ b/ForgeMod/src/main/resources/avm_staff_forge.mixins.json @@ -7,7 +7,8 @@ "defaultRequire": 1 }, "client": [ - "ClientPlayerInteractionManagerMixin" + "ClientPlayerInteractionManagerMixin", + "ModelLoaderBakerImplMixin" ], "mixins": [ "ServerPlayerEntityMixin", diff --git a/StaffMod/src/main/java/opekope2/avm_staff/mixin/BakedModelManagerMixin.java b/StaffMod/src/main/java/opekope2/avm_staff/mixin/BakedModelManagerMixin.java deleted file mode 100644 index 633fc68d7..000000000 --- a/StaffMod/src/main/java/opekope2/avm_staff/mixin/BakedModelManagerMixin.java +++ /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.mixin; - -import net.minecraft.client.render.model.BakedModelManager; -import opekope2.avm_staff.api.item.StaffItemHandler; -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(BakedModelManager.class) -public abstract class BakedModelManagerMixin { - @Inject(method = "upload", at = @At("TAIL")) - @SuppressWarnings("deprecation") - void upload(CallbackInfo ci) { - StaffItemHandler.reloadModels(); // Shhh - this is internal use - } -} 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 3927664a8..14c3bdf2f 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 @@ -23,12 +23,6 @@ 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.client.MinecraftClient -import net.minecraft.client.render.model.BuiltinBakedModel -import net.minecraft.client.render.model.json.ModelOverrideList -import net.minecraft.client.render.model.json.ModelTransformation -import net.minecraft.client.texture.MissingSprite -import net.minecraft.client.texture.SpriteAtlasTexture import net.minecraft.entity.Entity import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.LivingEntity @@ -47,12 +41,11 @@ 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.IReloadableBakedModelProvider -import opekope2.avm_staff.api.item.model.ReloadableSingleBakedModelProvider -import opekope2.avm_staff.util.TRANSFORM_INTO_STAFF +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 -import opekope2.avm_staff.util.transform +import java.util.function.Supplier /** * Provides functionality for a staff, when an item is inserted into it. @@ -66,12 +59,6 @@ abstract class StaffItemHandler { open val maxUseTime: Int get() = 0 - /** - * The model provider of the item added to the staff. - */ - @get: Environment(EnvType.CLIENT) - abstract val itemModelProvider: IReloadableBakedModelProvider - /** * Called on both the client and the server by Minecraft when the player uses the staff. * @@ -417,19 +404,9 @@ abstract class StaffItemHandler { else ImmutableMultimap.of() } - object EmptyStaffHandler : StaffItemHandler() { - override val itemModelProvider = ReloadableSingleBakedModelProvider { - val atlas = MinecraftClient.getInstance().getSpriteAtlas(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE) - val sprite = atlas.apply(MissingSprite.getMissingSpriteId()) - BuiltinBakedModel(ModelTransformation.NONE, ModelOverrideList.EMPTY, sprite, false) - } - } + object EmptyStaffHandler : StaffItemHandler() - object FallbackStaffHandler : StaffItemHandler() { - override val itemModelProvider = ReloadableSingleBakedModelProvider { - MinecraftClient.getInstance().bakedModelManager.missingModel.transform(null, TRANSFORM_INTO_STAFF) - } - } + object FallbackStaffHandler : StaffItemHandler() companion object { private val ATTRIBUTE_MODIFIERS = ImmutableMultimap.of( @@ -441,19 +418,34 @@ abstract class StaffItemHandler { private val staffItemsHandlers = mutableMapOf() + 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]. * - * @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 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): Boolean { + fun register( + staffItem: Identifier, + handler: StaffItemHandler, + staffItemModelSupplierFactory: Supplier> + ): Boolean { if (staffItem in staffItemsHandlers) return false staffItemsHandlers[staffItem] = handler + if (IStaffMod.get().isPhysicalClient) { + staffItemModelProviders[staffItem] = staffItemModelSupplierFactory.get() + } return true } @@ -477,12 +469,9 @@ abstract class StaffItemHandler { /** * @suppress */ - @JvmStatic - @Deprecated("For internal use only") - fun reloadModels() { - for ((_, handler) in staffItemsHandlers) { - handler.itemModelProvider.reload() - } + @Environment(EnvType.CLIENT) + internal fun iterateStaffItemModelProviders(): Iterator>> { + return staffItemModelProviders.iterator() } } } diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/IReloadableBakedModelProvider.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/IReloadableBakedModelProvider.kt deleted file mode 100644 index 4a9e950bf..000000000 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/IReloadableBakedModelProvider.kt +++ /dev/null @@ -1,40 +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.minecraft.client.render.model.BakedModel -import net.minecraft.item.ItemStack - -/** - * [BakedModel] provider for a given staff item stack. - */ -interface IReloadableBakedModelProvider { - /** - * Gets the model of the item in the Staff. - * - * @param staffStack The staff item stack (not the item in the staff) - */ - fun getModel(staffStack: ItemStack): BakedModel - - /** - * Reloads the model(s) returned by [getModel]. - * Called after the game initially loads or reloads the resources. - */ - fun reload() -} diff --git a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/ReloadableSingleBakedModelProvider.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/ReloadableSingleBakedModelProvider.kt deleted file mode 100644 index 3c0309cd4..000000000 --- a/StaffMod/src/main/kotlin/opekope2/avm_staff/api/item/model/ReloadableSingleBakedModelProvider.kt +++ /dev/null @@ -1,37 +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.minecraft.client.render.model.BakedModel -import net.minecraft.item.ItemStack - -/** - * Implementation of [IReloadableBakedModelProvider], which reloads the model using the given factory. - * - * @param modelFactory The function, which creates the model - */ -class ReloadableSingleBakedModelProvider(private val modelFactory: () -> BakedModel) : IReloadableBakedModelProvider { - private lateinit var model: BakedModel - - override fun getModel(staffStack: ItemStack): BakedModel = model - - override fun reload() { - model = modelFactory() - } -} 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 new file mode 100644 index 000000000..6ba3a765b --- /dev/null +++ b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/item/model/UnbakedStaffItemModel.kt @@ -0,0 +1,60 @@ +/* + * 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) + } +} diff --git a/StaffMod/src/main/resources/avm_staff.mixins.json b/StaffMod/src/main/resources/avm_staff.mixins.json index f5e5ba448..36bdd670f 100644 --- a/StaffMod/src/main/resources/avm_staff.mixins.json +++ b/StaffMod/src/main/resources/avm_staff.mixins.json @@ -7,7 +7,6 @@ "defaultRequire": 1 }, "client": [ - "BakedModelManagerMixin", "BipedEntityModelMixin", "IMinecraftClientMixin", "MinecraftClientMixin" From 938cd8a0275b2fa09a6335569c259bd80567959b Mon Sep 17 00:00:00 2001 From: opekope2 Date: Thu, 15 Feb 2024 23:03:09 +0100 Subject: [PATCH 20/21] Migrate staff block handlers to the new model loading system --- .../staff_item_handler/AnvilHandler.kt | 13 +-- .../staff_item_handler/BellBlockHandler.kt | 52 +++++++----- .../staff_item_handler/BoneBlockHandler.kt | 8 -- .../staff_item_handler/FurnaceHandler.kt | 73 +++++++++++----- .../staff_item_handler/LightningRodHandler.kt | 69 ++++++++++++--- .../staff_item_handler/MagmaBlockHandler.kt | 6 -- .../staff_item_handler/SnowBlockHandler.kt | 11 +-- .../internal/staff_item_handler/TntHandler.kt | 6 -- .../VanillaStaffItemHandlers.kt | 84 +++++++++++-------- .../staff_item_handler/WoolHandler.kt | 15 +--- 10 files changed, 205 insertions(+), 132 deletions(-) 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 84dcb539b..99fe01d10 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 @@ -27,7 +27,6 @@ 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.BlockItem import net.minecraft.item.ItemStack import net.minecraft.util.ActionResult import net.minecraft.util.Hand @@ -35,16 +34,12 @@ 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.item.model.ReloadableSingleBakedModelProvider -import opekope2.avm_staff.util.* +import opekope2.avm_staff.util.attackDamage +import opekope2.avm_staff.util.equipTime +import opekope2.avm_staff.util.itemInStaff import java.util.* -class AnvilHandler(anvilItem: BlockItem, private val damagedStackFactory: () -> ItemStack?) : StaffItemHandler(), - IDisablesShield { - override val itemModelProvider = ReloadableSingleBakedModelProvider { - anvilItem.block.defaultState.getTransformedModel(TRANSFORM_INTO_STAFF) - } - +class AnvilHandler(private val damagedStackFactory: () -> ItemStack?) : StaffItemHandler(), IDisablesShield { override fun attackEntity( staffStack: ItemStack, world: World, 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 2a4be80f4..fba1168be 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 @@ -23,13 +23,12 @@ import com.google.common.collect.Multimap import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.minecraft.client.render.block.entity.BellBlockEntityRenderer -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.* 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.entity.Entity import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.LivingEntity @@ -42,19 +41,23 @@ 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.IReloadableBakedModelProvider +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.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 java.util.function.Supplier class BellBlockHandler : StaffItemHandler() { - override val itemModelProvider: IReloadableBakedModelProvider = ReloadableBellModelProvider() - override fun use( staffStack: ItemStack, world: World, @@ -94,18 +97,23 @@ class BellBlockHandler : StaffItemHandler() { } @Environment(EnvType.CLIENT) - private class ReloadableBellModelProvider : IReloadableBakedModelProvider { - private lateinit var model: BakedModel - - private val bellSprite: Sprite - get() = BellBlockEntityRenderer.BELL_BODY_TEXTURE.sprite + private class BellUnbakedModel : IStaffItemUnbakedModel { + override fun getModelDependencies() = setOf() - override fun getModel(staffStack: ItemStack): BakedModel = model + override fun setParents(modelLoader: Function?) { + } - override fun reload() { + 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, transformation) - model = BasicBakedModel( + val quads = bellModel.getBakedQuads(bellSprite, bellTransformation) + val baked = BasicBakedModel( quads, createEmptyFaceQuads(), true, @@ -115,13 +123,15 @@ class BellBlockHandler : StaffItemHandler() { ModelTransformation.NONE, ModelOverrideList.EMPTY ) + + return StaffItemBakedModel(baked.transform(null, transformation, textureGetter)) } private companion object { - private val transformation = Transformation( + private val bellTransformation = Transformation( Vector3f(), - Vector3f((9f - 7f) / 9f / 2f, (22f - 3f) / 16f, (9f - 7f) / 9f / 2f), - Vector3f(7f / 9f) + Vector3f(-3.5f / 9f, -4f / 9f, -3.5f / 9f), + Vector3f(16f / 9f) ) private fun createEmptyFaceQuads(): Map> = mapOf( @@ -135,12 +145,16 @@ class BellBlockHandler : StaffItemHandler() { } } - private companion object { + companion object { private val ATTRIBUTE_MODIFIERS = ImmutableMultimap.of( EntityAttributes.GENERIC_ATTACK_DAMAGE, attackDamage(8.0), 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/BoneBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/BoneBlockHandler.kt index 1e88cf225..d0f8a6ea9 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_item_handler/BoneBlockHandler.kt @@ -18,7 +18,6 @@ package opekope2.avm_staff.internal.staff_item_handler -import net.minecraft.block.Blocks import net.minecraft.entity.LivingEntity import net.minecraft.item.BoneMealItem import net.minecraft.item.ItemStack @@ -30,15 +29,8 @@ 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.item.model.ReloadableSingleBakedModelProvider -import opekope2.avm_staff.util.TRANSFORM_INTO_STAFF -import opekope2.avm_staff.util.getTransformedModel class BoneBlockHandler : StaffItemHandler() { - override val itemModelProvider = ReloadableSingleBakedModelProvider { - Blocks.BONE_BLOCK.defaultState.getTransformedModel(TRANSFORM_INTO_STAFF) - } - override fun useOnBlock( staffStack: ItemStack, world: World, 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 d5cf1fdae..50cdcf067 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 @@ -23,9 +23,17 @@ import com.google.common.collect.Multimap import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.minecraft.block.AbstractFurnaceBlock +import net.minecraft.block.Block import net.minecraft.block.BlockState import net.minecraft.client.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.entity.EquipmentSlot import net.minecraft.entity.ItemEntity import net.minecraft.entity.LivingEntity @@ -34,7 +42,6 @@ import net.minecraft.entity.attribute.EntityAttributeModifier import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.entity.player.PlayerEntity import net.minecraft.inventory.SingleStackInventory -import net.minecraft.item.BlockItem import net.minecraft.item.ItemStack import net.minecraft.particle.ParticleTypes import net.minecraft.recipe.AbstractCookingRecipe @@ -43,27 +50,25 @@ 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.IReloadableBakedModelProvider +import opekope2.avm_staff.api.item.model.IStaffItemBakedModel +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( - furnaceItem: BlockItem, private val recipeType: RecipeType, private val smeltSound: SoundEvent ) : StaffItemHandler() { override val maxUseTime = 72000 - override val itemModelProvider: IReloadableBakedModelProvider = ReloadableFurnaceModelProvider( - furnaceItem.block.defaultState.with(AbstractFurnaceBlock.LIT, true), - furnaceItem.block.defaultState - ) - override fun use( staffStack: ItemStack, world: World, @@ -117,7 +122,7 @@ class FurnaceHandler( user: LivingEntity, world: World ): ItemEntity? { - val smeltingPosition = user.eyePos + user.rotationVector.normalize() * 1.75 + val smeltingPosition = user.approximateStaffItemPosition val items = world.getEntitiesByClass(ItemEntity::class.java, SMELTING_VOLUME.offset(smeltingPosition)) { true } val closest = items.minByOrNull { (smeltingPosition - it.pos).lengthSquared() } return closest @@ -177,20 +182,41 @@ class FurnaceHandler( } @Environment(EnvType.CLIENT) - private class ReloadableFurnaceModelProvider(private val litState: BlockState, private val unlitState: BlockState) : - IReloadableBakedModelProvider { - private lateinit var litModel: BakedModel - private lateinit var unlitModel: BakedModel + private class FurnaceUnbakedModel(private val unlitState: BlockState, private val litState: BlockState) : + IStaffItemUnbakedModel { + 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 } - - override fun reload() { - litModel = litState.getTransformedModel(TRANSFORM_INTO_STAFF) - unlitModel = unlitState.getTransformedModel(TRANSFORM_INTO_STAFF) - } } private class ItemEntityInventory(private val itemEntity: ItemEntity) : SingleStackInventory { @@ -205,7 +231,7 @@ class FurnaceHandler( override fun asBlockEntity(): Nothing = throw UnsupportedOperationException() } - private companion object { + 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) @@ -215,5 +241,14 @@ 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 6d63f3466..4ff97ee6e 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 @@ -18,26 +18,36 @@ 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 +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.entity.EntityType import net.minecraft.entity.LivingEntity 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.ReloadableSingleBakedModelProvider -import opekope2.avm_staff.util.getTransformedModel +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.util.transform import org.joml.Vector3f +import java.util.function.Function +import java.util.function.Supplier class LightningRodHandler : StaffItemHandler() { - override val itemModelProvider = ReloadableSingleBakedModelProvider { - Blocks.LIGHTNING_ROD.defaultState.getTransformedModel(transformation) - } - override fun useOnBlock( staffStack: ItemStack, world: World, @@ -67,11 +77,46 @@ class LightningRodHandler : StaffItemHandler() { return ActionResult.SUCCESS } - private companion object { - private val transformation = Transformation( - Vector3f(), - Vector3f((16f - 7f) / 16f / 2f, 32f / 16f, (16f - 7f) / 16f / 2f), - Vector3f(7f / 16f) - ) + @Environment(EnvType.CLIENT) + private 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) + ) + } + } + + 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/MagmaBlockHandler.kt b/StaffMod/src/main/kotlin/opekope2/avm_staff/internal/staff_item_handler/MagmaBlockHandler.kt index e9bf93544..7a7e287c4 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,7 +20,6 @@ package opekope2.avm_staff.internal.staff_item_handler import com.google.common.collect.ImmutableMultimap import com.google.common.collect.Multimap -import net.minecraft.block.Blocks import net.minecraft.entity.Entity import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.LivingEntity @@ -36,16 +35,11 @@ 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.item.model.ReloadableSingleBakedModelProvider import opekope2.avm_staff.util.* class MagmaBlockHandler : StaffItemHandler() { override val maxUseTime = 72000 - override val itemModelProvider = ReloadableSingleBakedModelProvider { - Blocks.MAGMA_BLOCK.defaultState.getTransformedModel(TRANSFORM_INTO_STAFF) - } - override fun use( staffStack: ItemStack, world: World, 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 65c6ab454..a76c683e8 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 @@ -18,7 +18,6 @@ package opekope2.avm_staff.internal.staff_item_handler -import net.minecraft.block.Blocks import net.minecraft.entity.LivingEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.entity.projectile.thrown.SnowballEntity @@ -29,16 +28,14 @@ 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.model.ReloadableSingleBakedModelProvider -import opekope2.avm_staff.util.* +import opekope2.avm_staff.util.approximateStaffTipPosition +import opekope2.avm_staff.util.component1 +import opekope2.avm_staff.util.component2 +import opekope2.avm_staff.util.component3 class SnowBlockHandler : StaffItemHandler() { override val maxUseTime = 72000 - override val itemModelProvider = ReloadableSingleBakedModelProvider { - Blocks.SNOW_BLOCK.defaultState.getTransformedModel(TRANSFORM_INTO_STAFF) - } - override fun use( staffStack: ItemStack, world: World, 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 bb05e4fae..22d1d504f 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 @@ -18,7 +18,6 @@ package opekope2.avm_staff.internal.staff_item_handler -import net.minecraft.block.Blocks import net.minecraft.entity.LivingEntity import net.minecraft.entity.TntEntity import net.minecraft.item.ItemStack @@ -30,14 +29,9 @@ import net.minecraft.world.World import net.minecraft.world.event.GameEvent import opekope2.avm_staff.api.entity.IImpactTnt import opekope2.avm_staff.api.item.StaffItemHandler -import opekope2.avm_staff.api.item.model.ReloadableSingleBakedModelProvider import opekope2.avm_staff.util.* class TntHandler : StaffItemHandler() { - override val itemModelProvider = ReloadableSingleBakedModelProvider { - Blocks.TNT.defaultState.getTransformedModel(TRANSFORM_INTO_STAFF) - } - override fun attack(staffStack: ItemStack, world: World, attacker: LivingEntity, hand: Hand): ActionResult { if (world.isClient) return ActionResult.SUCCESS 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 f3face288..cca6fe2c7 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,60 +18,74 @@ package opekope2.avm_staff.internal.staff_item_handler -import net.minecraft.item.BlockItem +import net.minecraft.block.Block +import net.minecraft.block.Blocks.* 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 import opekope2.avm_staff.api.item.StaffItemHandler +import opekope2.avm_staff.api.item.model.IStaffItemUnbakedModel +import opekope2.avm_staff.api.item.model.UnbakedBlockStateModelSupplier +import java.util.function.Supplier -private fun Item.registerHandler(handler: StaffItemHandler) { - StaffItemHandler.register(Registries.ITEM.getId(this), handler) +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) } } @Suppress("unused") fun registerVanillaStaffItemHandlers() { - ANVIL.registerHandler(AnvilHandler(ANVIL as BlockItem, CHIPPED_ANVIL::getDefaultStack)) - CHIPPED_ANVIL.registerHandler(AnvilHandler(CHIPPED_ANVIL as BlockItem, DAMAGED_ANVIL::getDefaultStack)) - DAMAGED_ANVIL.registerHandler(AnvilHandler(DAMAGED_ANVIL as BlockItem) { null }) + 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) - BELL.registerHandler(BellBlockHandler()) + Items.BELL.registerHandler(BellBlockHandler(), BellBlockHandler.modelSupplierFactory) - BONE_BLOCK.registerHandler(BoneBlockHandler()) + Items.BONE_BLOCK.registerHandler(BoneBlockHandler(), BONE_BLOCK) - FURNACE.registerHandler( - FurnaceHandler(FURNACE as BlockItem, RecipeType.SMELTING, SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE) + Items.FURNACE.registerHandler( + FurnaceHandler(RecipeType.SMELTING, SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE), + FurnaceHandler.getModelSupplierFactory(FURNACE) ) - BLAST_FURNACE.registerHandler( - FurnaceHandler(BLAST_FURNACE as BlockItem, RecipeType.BLASTING, SoundEvents.BLOCK_BLASTFURNACE_FIRE_CRACKLE) + Items.BLAST_FURNACE.registerHandler( + FurnaceHandler(RecipeType.BLASTING, SoundEvents.BLOCK_BLASTFURNACE_FIRE_CRACKLE), + FurnaceHandler.getModelSupplierFactory(BLAST_FURNACE) ) - SMOKER.registerHandler( - FurnaceHandler(SMOKER as BlockItem, RecipeType.SMOKING, SoundEvents.BLOCK_SMOKER_SMOKE) + Items.SMOKER.registerHandler( + FurnaceHandler(RecipeType.SMOKING, SoundEvents.BLOCK_SMOKER_SMOKE), + FurnaceHandler.getModelSupplierFactory(SMOKER) ) - LIGHTNING_ROD.registerHandler(LightningRodHandler()) + Items.LIGHTNING_ROD.registerHandler(LightningRodHandler(), LightningRodHandler.modelSupplier) - MAGMA_BLOCK.registerHandler(MagmaBlockHandler()) + Items.MAGMA_BLOCK.registerHandler(MagmaBlockHandler(), MAGMA_BLOCK) - SNOW_BLOCK.registerHandler(SnowBlockHandler()) + Items.SNOW_BLOCK.registerHandler(SnowBlockHandler(), SNOW_BLOCK) - TNT.registerHandler(TntHandler()) + Items.TNT.registerHandler(TntHandler(), TNT) - 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)) + 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) } 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_item_handler/WoolHandler.kt index 24d6b6352..9b8f889ce 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_item_handler/WoolHandler.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 net.minecraft.block.Block import net.minecraft.client.MinecraftClient import net.minecraft.client.network.ClientPlayerEntity import net.minecraft.entity.EquipmentSlot @@ -28,7 +29,6 @@ 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.BlockItem import net.minecraft.item.ItemPlacementContext import net.minecraft.item.ItemStack import net.minecraft.registry.tag.BlockTags @@ -41,20 +41,13 @@ 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.item.model.ReloadableSingleBakedModelProvider import opekope2.avm_staff.mixin.IMinecraftClientMixin -import opekope2.avm_staff.util.TRANSFORM_INTO_STAFF import opekope2.avm_staff.util.attackDamage import opekope2.avm_staff.util.attackSpeed -import opekope2.avm_staff.util.getTransformedModel -class WoolHandler(woolItem: BlockItem, carpetItem: BlockItem) : StaffItemHandler() { - private val woolState = woolItem.block.defaultState - private val carpetState = carpetItem.block.defaultState - - override val itemModelProvider = ReloadableSingleBakedModelProvider { - woolItem.block.defaultState.getTransformedModel(TRANSFORM_INTO_STAFF) - } +class WoolHandler(woolBlock: Block, carpetBlock: Block) : StaffItemHandler() { + private val woolState = woolBlock.defaultState + private val carpetState = carpetBlock.defaultState override fun useOnBlock( staffStack: ItemStack, From 1ceed33b226ecbac157bdccbfae9d66b16cf8367 Mon Sep 17 00:00:00 2001 From: opekope2 Date: Fri, 16 Feb 2024 12:52:27 +0100 Subject: [PATCH 21/21] Bump version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index e18b5bcb2..61fdb2c12 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,7 +19,7 @@ mixin_extras_version=0.3.5 java_version=17 ########################################################################## # Mod Properties -mod_version=0.11.0-beta.2 +mod_version=0.12.0-beta maven_group=opekope2.avm_staff archives_name=staff-mod ##########################################################################