From d5b6c6d39c39e7a05bd52c542794fa426571c46e Mon Sep 17 00:00:00 2001 From: QiuShui1012 <150409561+QiuShui1012@users.noreply.github.com> Date: Tue, 31 Mar 2026 17:25:16 +0800 Subject: [PATCH 1/6] =?UTF-8?q?feat(item):=20=E6=96=B0=E5=A2=9E=E5=B9=BB?= =?UTF-8?q?=E7=81=B5=E6=AD=A6=E5=99=A8=E5=8F=91=E5=B0=84=E5=99=A8=E5=8F=8A?= =?UTF-8?q?=E8=83=BD=E9=87=8F=E7=B3=BB=E7=BB=9F=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加幻灵武器发射器物品及渲染器,实现专属手持动画和装弹渲染 - 幻灵武器发射器消耗能量发射弹药,封装能量存储和能量条显示逻辑 - 增加能量组件ModComponents.STORED_ENERGY的注册及能量道具叠加支持 - 修改幻灵弹弓以兼容新的能量系统,更新弹药判断与发射弱化攻击逻辑 - 新增幻灵武器发射器的合成配方和解锁进度 - 增加物品工具提示支持显示剩余能量信息 - 服务器端玩家逻辑tick中添加幻灵武器发射器能量充能和逻辑更新 - 修改相关模型资源,实现能量耗尽时模型切换展示 - 优化数据生成工具,支持为带能量的物品批量生成测试样例与标签 - 调整各相关类的导入和调用关系,完善UI呈现和功能集成 --- .../assets/anvilcraft/lang/en_ud.json | 2 + .../assets/anvilcraft/lang/en_us.json | 2 + .../spectral_weapon_launcher.json | 21 +++ .../spectral_weapon_launcher.json | 16 ++ .../tags/item/enchantable/crossbow.json | 3 +- .../tags/item/enchantable/durability.json | 1 + .../api/tooltip/ItemTooltipManager.java | 13 +- .../anvilcraft/client/AnvilCraftClient.java | 7 + .../item/SpectralWeaponLauncherRenderer.java | 155 ++++++++++++++++++ .../WrappingItemCustomRenderedModels.java | 2 + .../data/lang/ToolPropertyLang.java | 1 + .../recipe/EnergyWeaponMakeRecipeLoader.java | 5 + .../entity/SpectralProjectileEntity.java | 10 +- .../event/PlayerTickEventHandler.java | 2 + .../dubhe/anvilcraft/init/item/ModItems.java | 13 ++ .../item/SpectralSlingshotItem.java | 51 +++--- .../item/SpectralWeaponLauncherItem.java | 94 +++++++++++ .../dubhe/anvilcraft/util/DataGenUtil.java | 11 ++ .../models/item/spectral_weapon_launcher.json | 8 + 19 files changed, 387 insertions(+), 30 deletions(-) create mode 100644 src/generated/resources/data/anvilcraft/advancement/recipes/energy_weapon_make/spectral_weapon_launcher.json create mode 100644 src/generated/resources/data/anvilcraft/recipe/energy_weapon_make/spectral_weapon_launcher.json create mode 100644 src/main/java/dev/dubhe/anvilcraft/client/renderer/item/SpectralWeaponLauncherRenderer.java create mode 100644 src/main/java/dev/dubhe/anvilcraft/item/SpectralWeaponLauncherItem.java diff --git a/src/generated/resources/assets/anvilcraft/lang/en_ud.json b/src/generated/resources/assets/anvilcraft/lang/en_ud.json index 83c24f643a..05ce35f83e 100644 --- a/src/generated/resources/assets/anvilcraft/lang/en_ud.json +++ b/src/generated/resources/assets/anvilcraft/lang/en_ud.json @@ -872,6 +872,7 @@ "item.anvilcraft.spectral_slingshot": "ʇoɥsᵷuᴉꞁS ꞁɐɹʇɔǝdS", "item.anvilcraft.spectral_slingshot.unload_return": "pǝpɐoꞁu∩ uǝɥʍ pǝuɹnʇǝᴚ", "item.anvilcraft.spectral_slingshot.unload_vanish": "pǝpɐoꞁu∩ uǝɥʍ sǝɥsᴉuɐɅ", + "item.anvilcraft.spectral_weapon_launcher": "ɹǝɥɔunɐꞀ uodɐǝM ꞁɐɹʇɔǝdS", "item.anvilcraft.sponge_gemmule": "ǝꞁnɯɯǝ⅁ ǝᵷuodS", "item.anvilcraft.stable_neutronium_ingot": "ʇoᵷuI ɯnᴉuoɹʇnǝN ǝꞁqɐʇS", "item.anvilcraft.structure_tool": "ꞁoo⟘ ǝɹnʇɔnɹʇS", @@ -1388,6 +1389,7 @@ "tooltip.anvilcraft.property.multiphase.suffix.3": "δ-", "tooltip.anvilcraft.property.providence": "sǝɯᴉʇ ǝꞁdᴉʇꞁnɯ sʇuǝɯʇuɐɥɔuǝ [%s pꞁoH] ɹǝᵷᵷᴉɹʇ oʇ ǝɔuɐɥɔ sɐɥ :ǝɔuǝpᴉʌoɹԀ", "tooltip.anvilcraft.property.providence.shifting": "sǝɯᴉʇ ǝꞁdᴉʇꞁnɯ sʇuǝɯʇuɐɥɔuǝ (%s) ɹǝᵷᵷᴉɹʇ oʇ ǝɔuɐɥɔ sɐɥ :ǝɔuǝpᴉʌoɹԀ", + "tooltip.anvilcraft.property.stored_energy": "%s :ʎᵷɹǝuƎ ᵷuᴉuᴉɐɯǝᴚ", "tooltip.anvilcraft.redstone.output_mode": "%s :ǝpoW ʇndʇnO ", "tooltip.anvilcraft.redstone.output_mode.compare": "ǝɹɐdɯoƆ", "tooltip.anvilcraft.redstone.output_mode.subtract": "ʇɔɐɹʇqnS", diff --git a/src/generated/resources/assets/anvilcraft/lang/en_us.json b/src/generated/resources/assets/anvilcraft/lang/en_us.json index 36ee3193f6..ccb8a4073f 100644 --- a/src/generated/resources/assets/anvilcraft/lang/en_us.json +++ b/src/generated/resources/assets/anvilcraft/lang/en_us.json @@ -872,6 +872,7 @@ "item.anvilcraft.spectral_slingshot": "Spectral Slingshot", "item.anvilcraft.spectral_slingshot.unload_return": "Returned when Unloaded", "item.anvilcraft.spectral_slingshot.unload_vanish": "Vanishes when Unloaded", + "item.anvilcraft.spectral_weapon_launcher": "Spectral Weapon Launcher", "item.anvilcraft.sponge_gemmule": "Sponge Gemmule", "item.anvilcraft.stable_neutronium_ingot": "Stable Neutronium Ingot", "item.anvilcraft.structure_tool": "Structure Tool", @@ -1388,6 +1389,7 @@ "tooltip.anvilcraft.property.multiphase.suffix.3": "-δ", "tooltip.anvilcraft.property.providence": "Providence: has chance to trigger [Hold %s] enchantments multiple times", "tooltip.anvilcraft.property.providence.shifting": "Providence: has chance to trigger (%s) enchantments multiple times", + "tooltip.anvilcraft.property.stored_energy": "Remaining Energy: %s", "tooltip.anvilcraft.redstone.output_mode": " Output Mode: %s", "tooltip.anvilcraft.redstone.output_mode.compare": "Compare", "tooltip.anvilcraft.redstone.output_mode.subtract": "Subtract", diff --git a/src/generated/resources/data/anvilcraft/advancement/recipes/energy_weapon_make/spectral_weapon_launcher.json b/src/generated/resources/data/anvilcraft/advancement/recipes/energy_weapon_make/spectral_weapon_launcher.json new file mode 100644 index 0000000000..31ccdd1bf7 --- /dev/null +++ b/src/generated/resources/data/anvilcraft/advancement/recipes/energy_weapon_make/spectral_weapon_launcher.json @@ -0,0 +1,21 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_the_recipe": { + "conditions": { + "recipe": "anvilcraft:energy_weapon_make/spectral_weapon_launcher" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe" + ] + ], + "rewards": { + "recipes": [ + "anvilcraft:energy_weapon_make/spectral_weapon_launcher" + ] + } +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/recipe/energy_weapon_make/spectral_weapon_launcher.json b/src/generated/resources/data/anvilcraft/recipe/energy_weapon_make/spectral_weapon_launcher.json new file mode 100644 index 0000000000..47769439d8 --- /dev/null +++ b/src/generated/resources/data/anvilcraft/recipe/energy_weapon_make/spectral_weapon_launcher.json @@ -0,0 +1,16 @@ +{ + "type": "anvilcraft:energy_weapon_make", + "ingredients": [ + { + "items": "anvilcraft:spectral_slingshot" + }, + { + "count": 8, + "items": "anvilcraft:spectral_anvil" + } + ], + "result": { + "count": 1, + "id": "anvilcraft:spectral_weapon_launcher" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/item/enchantable/crossbow.json b/src/generated/resources/data/minecraft/tags/item/enchantable/crossbow.json index 419e1ac7b3..9b17ea8897 100644 --- a/src/generated/resources/data/minecraft/tags/item/enchantable/crossbow.json +++ b/src/generated/resources/data/minecraft/tags/item/enchantable/crossbow.json @@ -1,5 +1,6 @@ { "values": [ - "anvilcraft:spectral_slingshot" + "anvilcraft:spectral_slingshot", + "anvilcraft:spectral_weapon_launcher" ] } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/item/enchantable/durability.json b/src/generated/resources/data/minecraft/tags/item/enchantable/durability.json index c310239274..9c0714ad87 100644 --- a/src/generated/resources/data/minecraft/tags/item/enchantable/durability.json +++ b/src/generated/resources/data/minecraft/tags/item/enchantable/durability.json @@ -16,6 +16,7 @@ "anvilcraft:transcendence_resonator", "anvilcraft:multitool", "anvilcraft:spectral_slingshot", + "anvilcraft:spectral_weapon_launcher", "anvilcraft:magnet" ] } \ No newline at end of file diff --git a/src/main/java/dev/dubhe/anvilcraft/api/tooltip/ItemTooltipManager.java b/src/main/java/dev/dubhe/anvilcraft/api/tooltip/ItemTooltipManager.java index acf60c4200..277c3c20f2 100644 --- a/src/main/java/dev/dubhe/anvilcraft/api/tooltip/ItemTooltipManager.java +++ b/src/main/java/dev/dubhe/anvilcraft/api/tooltip/ItemTooltipManager.java @@ -9,6 +9,7 @@ import dev.dubhe.anvilcraft.init.item.ModItemTags; import dev.dubhe.anvilcraft.init.item.ModItems; import dev.dubhe.anvilcraft.util.ListUtil; +import dev.dubhe.anvilcraft.util.UnitUtil; import dev.dubhe.anvilcraft.util.Util; import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; @@ -241,6 +242,14 @@ public class ItemTooltipManager { */ public static void addTooltip(ItemStack stack, List tooltip) { final Item item = stack.getItem(); + if (stack.has(ModComponents.STORED_ENERGY)) { + propertyTooltip( + "stored_energy", + tooltip, + ChatFormatting.GRAY, + UnitUtil.energyUnit(stack.getOrDefault(ModComponents.STORED_ENERGY, 0), Screen.hasShiftDown()) + ); + } if (stack.has(ModComponents.MULTIPHASE)) { if (AnvilCraftClient.CONFIG.showMultiphaseStoredId) { propertyTooltip( @@ -314,7 +323,7 @@ public static String getTranslationKey(Item item) { return "tooltip.%s.item.%s".formatted(key.getNamespace(), key.getPath()); } - private static void propertyTooltip(String propertyName, List tooltip, ChatFormatting color) { + private static void propertyTooltip(String propertyName, List tooltip, ChatFormatting color, Object... args) { int i = 0; for (int j = 0; j < tooltip.size(); j++) { if (tooltip.get(j).getContents() instanceof TranslatableContents t && t.getKey().contains("enchantment") @@ -330,7 +339,7 @@ private static void propertyTooltip(String propertyName, List tooltip } tooltip.add( 1 + i, - Component.translatable("tooltip.anvilcraft.property.%s".formatted(propertyName)).withStyle(color) + Component.translatable("tooltip.anvilcraft.property.%s".formatted(propertyName), args).withStyle(color) ); } diff --git a/src/main/java/dev/dubhe/anvilcraft/client/AnvilCraftClient.java b/src/main/java/dev/dubhe/anvilcraft/client/AnvilCraftClient.java index 61046cdd45..c8f0c0f71f 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/AnvilCraftClient.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/AnvilCraftClient.java @@ -14,8 +14,10 @@ import dev.dubhe.anvilcraft.config.AnvilCraftClientConfig; import dev.dubhe.anvilcraft.init.ModParticles; import dev.dubhe.anvilcraft.init.block.ModFluids; +import dev.dubhe.anvilcraft.init.item.ModComponents; import dev.dubhe.anvilcraft.init.item.ModItems; import net.minecraft.client.model.HumanoidModel; +import net.minecraft.client.renderer.item.ItemProperties; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ItemStack; @@ -56,6 +58,11 @@ public static void clientSetup(FMLClientSetupEvent event) { IntegrationHook.setModEventBus(modEventBus); IntegrationHook.setModContainer(modContainer); AnvilCraft.getINTEGRATION_MANAGER().loadAllClientIntegrations(); + + ItemProperties.registerGeneric( + AnvilCraft.of("stored_energy"), + (stack, level, entity, seed) -> stack.getOrDefault(ModComponents.STORED_ENERGY, 0) + ); } public static void registerClientExtensions(RegisterClientExtensionsEvent e) { diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/SpectralWeaponLauncherRenderer.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/SpectralWeaponLauncherRenderer.java new file mode 100644 index 0000000000..8b62cfcf7c --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/SpectralWeaponLauncherRenderer.java @@ -0,0 +1,155 @@ +package dev.dubhe.anvilcraft.client.renderer.item; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Axis; +import dev.dubhe.anvilcraft.init.item.ModItems; +import dev.dubhe.anvilcraft.item.SpectralWeaponLauncherItem; +import net.minecraft.client.Minecraft; +import net.minecraft.client.model.HumanoidModel; +import net.minecraft.client.model.geom.EntityModelSet; +import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher; +import net.minecraft.client.renderer.entity.ItemRenderer; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.component.DataComponents; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemDisplayContext; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.ChargedProjectiles; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.HalfTransparentBlock; +import net.minecraft.world.level.block.StainedGlassPaneBlock; +import org.jetbrains.annotations.Nullable; + +import java.util.Iterator; + +public class SpectralWeaponLauncherRenderer extends BlockEntityWithoutLevelRenderer { + private static SpectralWeaponLauncherRenderer instance; + + public static SpectralWeaponLauncherRenderer getInstance() { + if (instance == null) { + instance = new SpectralWeaponLauncherRenderer( + Minecraft.getInstance().getBlockEntityRenderDispatcher(), + Minecraft.getInstance().getEntityModels() + ); + } + return instance; + } + + public SpectralWeaponLauncherRenderer(BlockEntityRenderDispatcher blockEntityRenderDispatcher, EntityModelSet entityModelSet) { + super(blockEntityRenderDispatcher, entityModelSet); + } + + @Override + public void renderByItem( + ItemStack stack, + ItemDisplayContext displayContext, + PoseStack poseStack, + MultiBufferSource buffer, + int packedLight, + int packedOverlay + ) { + super.renderByItem(stack, displayContext, poseStack, buffer, packedLight, packedOverlay); + ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer(); + if (stack.is(ModItems.SPECTRAL_WEAPON_LAUNCHER)) { + BakedModel normalModel = itemRenderer.getItemModelShaper().getItemModel(stack); + renderItemAtCurrentPoseStack(itemRenderer, + stack, + displayContext, + poseStack, + buffer, + packedLight, + packedOverlay, + normalModel + ); + ChargedProjectiles cp = stack.get(DataComponents.CHARGED_PROJECTILES); + if (cp != null && !cp.isEmpty()) { + ItemStack ammo = cp.getItems().getFirst(); + poseStack.pushPose(); + poseStack.translate(0f, 5f, 0.50F); + poseStack.mulPose(Axis.YP.rotationDegrees(90)); + poseStack.mulPose(Axis.ZP.rotationDegrees(- 45)); + // poseStack.pushPose(); + BakedModel bakedModel = itemRenderer.getItemModelShaper().getItemModel(ammo); + renderItemAtCurrentPoseStack( + itemRenderer, + ammo, + displayContext, + poseStack, + buffer, + packedLight, + packedOverlay, + bakedModel + ); + // poseStack.popPose(); + poseStack.popPose(); + } + } + } + + public static void renderItemAtCurrentPoseStack( + ItemRenderer itemRenderer, + ItemStack itemStack, + ItemDisplayContext displayContext, + PoseStack poseStack, + MultiBufferSource bufferSource, + int combinedLight, + int combinedOverlay, + BakedModel model + ) { + boolean flag1; + label78: { + if (displayContext != ItemDisplayContext.GUI && !displayContext.firstPerson()) { + Item var12 = itemStack.getItem(); + if (var12 instanceof BlockItem blockitem) { + Block block = blockitem.getBlock(); + flag1 = !(block instanceof HalfTransparentBlock) && !(block instanceof StainedGlassPaneBlock); + break label78; + } + } + flag1 = true; + } + for (BakedModel model1 : model.getRenderPasses(itemStack, flag1)) { + VertexConsumer vertexconsumer; + for (Iterator var13 = model1.getRenderTypes(itemStack, flag1).iterator(); + var13.hasNext(); + itemRenderer.renderModelLists( + model1, + itemStack, + combinedLight, + combinedOverlay, + poseStack, + vertexconsumer + ) + ) { + RenderType rendertype = var13.next(); + vertexconsumer = ItemRenderer.getFoilBuffer(bufferSource, rendertype, true, itemStack.hasFoil()); + } + } + } + + public static class SpectralWeaponLauncherExtensions extends CustomRenderItemClientExtension { + protected SpectralWeaponLauncherExtensions(BlockEntityWithoutLevelRenderer renderer) { + super(renderer); + } + + public static SpectralWeaponLauncherExtensions of(BlockEntityWithoutLevelRenderer renderer) { + return new SpectralWeaponLauncherExtensions(renderer); + } + + @Nullable + @Override + public HumanoidModel.ArmPose getArmPose(LivingEntity entityLiving, InteractionHand hand, ItemStack itemStack) { + if (itemStack.is(ModItems.SPECTRAL_WEAPON_LAUNCHER) && SpectralWeaponLauncherItem.isCharged(itemStack)) { + return HumanoidModel.ArmPose.CROSSBOW_HOLD; + } + return super.getArmPose(entityLiving, hand, itemStack); + } + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/WrappingItemCustomRenderedModels.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/WrappingItemCustomRenderedModels.java index 57cdc8088a..c145142ad4 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/WrappingItemCustomRenderedModels.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/WrappingItemCustomRenderedModels.java @@ -19,6 +19,8 @@ public class WrappingItemCustomRenderedModels { public static void onModelBake(ModelEvent.ModifyBakingResult event) { Map modelRegistry = event.getModels(); swapModels(modelRegistry, ModelResourceLocation.inventory(AnvilCraft.of("spectral_slingshot"))); + swapModels(modelRegistry, ModelResourceLocation.inventory(AnvilCraft.of("spectral_weapon_launcher"))); + swapModels(modelRegistry, ModelResourceLocation.inventory(AnvilCraft.of("spectral_weapon_launcher_exhausted"))); } public static void swapModels(Map modelRegistry, ModelResourceLocation modelLocation) { diff --git a/src/main/java/dev/dubhe/anvilcraft/data/lang/ToolPropertyLang.java b/src/main/java/dev/dubhe/anvilcraft/data/lang/ToolPropertyLang.java index 429ee8699a..76c1e73e8a 100644 --- a/src/main/java/dev/dubhe/anvilcraft/data/lang/ToolPropertyLang.java +++ b/src/main/java/dev/dubhe/anvilcraft/data/lang/ToolPropertyLang.java @@ -21,5 +21,6 @@ public static void init(RegistrumLangProvider provider) { provider.add("tooltip.anvilcraft.property.eternal", "Eternal: unbreakable, immune fire, explode, cactus, even the time and the void"); provider.add("tooltip.anvilcraft.property.providence", "Providence: has chance to trigger [Hold %s] enchantments multiple times"); provider.add("tooltip.anvilcraft.property.providence.shifting", "Providence: has chance to trigger (%s) enchantments multiple times"); + provider.add("tooltip.anvilcraft.property.stored_energy", "Remaining Energy: %s"); } } diff --git a/src/main/java/dev/dubhe/anvilcraft/data/recipe/EnergyWeaponMakeRecipeLoader.java b/src/main/java/dev/dubhe/anvilcraft/data/recipe/EnergyWeaponMakeRecipeLoader.java index 074ce89d07..48eb6c0abb 100644 --- a/src/main/java/dev/dubhe/anvilcraft/data/recipe/EnergyWeaponMakeRecipeLoader.java +++ b/src/main/java/dev/dubhe/anvilcraft/data/recipe/EnergyWeaponMakeRecipeLoader.java @@ -7,6 +7,11 @@ public class EnergyWeaponMakeRecipeLoader { public static void init(RegistrumRecipeProvider provider) { + EnergyWeaponMakeRecipe.builder() + .requires(ModItems.SPECTRAL_SLINGSHOT, 1) + .requires(ModBlocks.SPECTRAL_ANVIL, 8) + .result(ModItems.SPECTRAL_WEAPON_LAUNCHER.asStack()) + .save(provider); EnergyWeaponMakeRecipe.builder() .requires(ModBlocks.ACCELERATION_RING, 4) .requires(ModBlocks.SLIDING_RAIL, 4) diff --git a/src/main/java/dev/dubhe/anvilcraft/entity/SpectralProjectileEntity.java b/src/main/java/dev/dubhe/anvilcraft/entity/SpectralProjectileEntity.java index d87639900a..5f058a68ae 100644 --- a/src/main/java/dev/dubhe/anvilcraft/entity/SpectralProjectileEntity.java +++ b/src/main/java/dev/dubhe/anvilcraft/entity/SpectralProjectileEntity.java @@ -46,7 +46,13 @@ public SpectralProjectileEntity(Level level, LivingEntity owner, ItemStack picku this.entityData.set(AS_ITEM_STACK, ItemStack.EMPTY); } - public static SpectralProjectileEntity of(Level level, LivingEntity owner, ItemStack asStack, @Nullable ItemStack firedFromWeapon) { + public static SpectralProjectileEntity of( + Level level, + LivingEntity owner, + ItemStack asStack, + @Nullable ItemStack firedFromWeapon, + double damageAmplification + ) { SpectralProjectileEntity sp = new SpectralProjectileEntity( level, owner, @@ -67,7 +73,7 @@ public static SpectralProjectileEntity of(Level level, LivingEntity owner, ItemS } } } - if (dmg > 0) sp.setBaseDamage(dmg * 0.5); + if (dmg > 0) sp.setBaseDamage(dmg * damageAmplification); } return sp; } diff --git a/src/main/java/dev/dubhe/anvilcraft/event/PlayerTickEventHandler.java b/src/main/java/dev/dubhe/anvilcraft/event/PlayerTickEventHandler.java index 80140c1159..ffef56c2ff 100644 --- a/src/main/java/dev/dubhe/anvilcraft/event/PlayerTickEventHandler.java +++ b/src/main/java/dev/dubhe/anvilcraft/event/PlayerTickEventHandler.java @@ -4,6 +4,7 @@ import dev.dubhe.anvilcraft.api.power.PowerGrid; import dev.dubhe.anvilcraft.item.CrabClawItem; import dev.dubhe.anvilcraft.item.IonoCraftBackpackItem; +import dev.dubhe.anvilcraft.item.SpectralWeaponLauncherItem; import dev.dubhe.anvilcraft.item.property.component.Eternal; import dev.dubhe.anvilcraft.item.property.component.Ferocious; import dev.dubhe.anvilcraft.item.property.component.Merciless; @@ -23,6 +24,7 @@ public static void onPlayerTick(PlayerTickEvent.Post event) { if (event.getEntity() instanceof ServerPlayer serverPlayer) { applyPowerGrid(serverPlayer); IonoCraftBackpackItem.playerTick(serverPlayer); + SpectralWeaponLauncherItem.playerTick(serverPlayer); Merciless.tick(serverPlayer); Ferocious.tick(serverPlayer); Eternal.tick(serverPlayer); diff --git a/src/main/java/dev/dubhe/anvilcraft/init/item/ModItems.java b/src/main/java/dev/dubhe/anvilcraft/init/item/ModItems.java index 12be34256b..47537f282e 100644 --- a/src/main/java/dev/dubhe/anvilcraft/init/item/ModItems.java +++ b/src/main/java/dev/dubhe/anvilcraft/init/item/ModItems.java @@ -68,6 +68,7 @@ import dev.dubhe.anvilcraft.item.RoyalSwordItem; import dev.dubhe.anvilcraft.item.SeedsPackItem; import dev.dubhe.anvilcraft.item.SpectralSlingshotItem; +import dev.dubhe.anvilcraft.item.SpectralWeaponLauncherItem; import dev.dubhe.anvilcraft.item.StructureToolItem; import dev.dubhe.anvilcraft.item.SuperCapacitorItem; import dev.dubhe.anvilcraft.item.TopazItem; @@ -783,9 +784,21 @@ public class ModItems { }) .register(); + public static final ItemEntry SPECTRAL_WEAPON_LAUNCHER = REGISTRUM + .item("spectral_weapon_launcher", SpectralWeaponLauncherItem::new) + .properties(properties -> properties.stacksTo(1)) + .tab(ModItemGroups.ANVILCRAFT_TOOL.getKey(), DataGenUtil::energy) + .tag( + ItemTags.DURABILITY_ENCHANTABLE, + ItemTags.CROSSBOW_ENCHANTABLE + ) + .model(DataGenUtil::noExtraModelOrState) + .register(); + public static final ItemEntry ANVIL_RAILGUN = REGISTRUM .item("anvil_railgun", AnvilRailgunItem::new) .properties(properties -> properties.stacksTo(1)) + .tab(ModItemGroups.ANVILCRAFT_TOOL.getKey(), DataGenUtil::energy) .model(DataGenUtil::noExtraModelOrState) .register(); diff --git a/src/main/java/dev/dubhe/anvilcraft/item/SpectralSlingshotItem.java b/src/main/java/dev/dubhe/anvilcraft/item/SpectralSlingshotItem.java index dc60421138..9b9d909ee5 100644 --- a/src/main/java/dev/dubhe/anvilcraft/item/SpectralSlingshotItem.java +++ b/src/main/java/dev/dubhe/anvilcraft/item/SpectralSlingshotItem.java @@ -4,15 +4,16 @@ import dev.dubhe.anvilcraft.client.renderer.item.SpectralSlingshotRenderer; import dev.dubhe.anvilcraft.entity.SpectralProjectileEntity; import dev.dubhe.anvilcraft.init.item.ModComponents; -import dev.dubhe.anvilcraft.init.item.ModItems; import net.minecraft.ChatFormatting; import net.minecraft.core.component.DataComponents; import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; +import net.minecraft.stats.Stats; import net.minecraft.util.Mth; import net.minecraft.util.RandomSource; import net.minecraft.util.Unit; @@ -89,10 +90,11 @@ public void initializeClient(Consumer consumer) { /** * 检查物品是否可以被装载(用于判断箭矢或具有攻击伤害的物品) * - * @param stack 要检查的物品堆堆 + * @param weapon 将要装载的武器物品堆 + * @param stack 要检查的物品堆 * @return 如果物品是箭矢或具有正攻击伤害属性则返回true,否则返回false */ - public static boolean checkLoadable(ItemStack stack) { + public boolean checkLoadable(ItemStack weapon, ItemStack stack) { // 装载箭矢的设定取消了:if (stack.is(ItemTags.ARROWS)) return true; ItemAttributeModifiers modifiers = stack.getAttributeModifiers(); double dmg = 0; @@ -103,20 +105,21 @@ public static boolean checkLoadable(ItemStack stack) { } } } - return (dmg > 0); + return dmg > 0; } /** * 获取幻灵弹弓的弹药,即从另一只手获取物品 * * @param player 玩家实体 - * @return 弹药的物品堆,注意,这个东西返回的是一个引用!不是copy的值 + * @return 弹药的物品堆 + * @apiNote 对此方法返回的物品堆的修改会影响原物品 */ private static ItemStack getSlingShotAmmo(Player player) { ItemStack stack = player.getMainHandItem(); ItemStack stack2 = player.getOffhandItem(); - if (stack.is(ModItems.SPECTRAL_SLINGSHOT.asItem()) && checkLoadable(stack2)) return stack2; - if (stack2.is(ModItems.SPECTRAL_SLINGSHOT.asItem()) && checkLoadable(stack)) return stack; + if (stack.getItem() instanceof SpectralSlingshotItem item && item.checkLoadable(stack, stack2)) return stack2; + if (stack2.getItem() instanceof SpectralSlingshotItem item && item.checkLoadable(stack2, stack)) return stack; return ItemStack.EMPTY; } @@ -136,7 +139,7 @@ public InteractionResultHolder use(Level level, Player player, Intera ChargedProjectiles chargedprojectiles = itemstack.get(DataComponents.CHARGED_PROJECTILES); if (chargedprojectiles != null && !chargedprojectiles.isEmpty()) { if (!player.isCrouching() && !player.getCooldowns().isOnCooldown(this)) { - this.performShooting(level, player, hand, itemstack, getShootingPower(chargedprojectiles), 1.0F, null); + this.performShooting(level, player, hand, itemstack, SpectralSlingshotItem.getShootingPower(), 1.0F, null); int quickCharge = itemstack.getEnchantmentLevel( player.level() .holderLookup(Registries.ENCHANTMENT) @@ -147,7 +150,7 @@ public InteractionResultHolder use(Level level, Player player, Intera } else { // 这个部分是卸载和替换弹药 ItemStack stack = chargedprojectiles.getItems().getFirst(); - if (canTakeOutAmmo(itemstack)) player.addItem(stack); // 如果能拿出来,那么拿出来 + if (SpectralSlingshotItem.canTakeOutAmmo(itemstack)) player.addItem(stack); // 如果能拿出来,那么拿出来 itemstack.set(DataComponents.CHARGED_PROJECTILES, ChargedProjectiles.EMPTY); // 装载走正常的使用流程 this.startSoundPlayed = false; @@ -166,10 +169,9 @@ public InteractionResultHolder use(Level level, Player player, Intera } } - @SuppressWarnings("unused") - private static float getShootingPower(ChargedProjectiles projectile) { + private static float getShootingPower() { // 原版的弩是projectile.contains(Items.FIREWORK_ROCKET) ? 1.6F : 3.15F;,这里直接固定用箭矢的速度 - return 1.6f; + return 3.15F; } @Override @@ -272,7 +274,7 @@ private static Vector3f getProjectileShotVector(LivingEntity shooter, Vec3 dista @Override protected Projectile createProjectile(Level level, LivingEntity shooter, ItemStack weapon, ItemStack ammo, boolean isCrit) { // 这里完全另外写了,毕竟固定射出来一个特殊射弹 - SpectralProjectileEntity projectile = SpectralProjectileEntity.of(level, shooter, ammo, weapon); + SpectralProjectileEntity projectile = SpectralProjectileEntity.of(level, shooter, ammo, weapon, this.getDamageAmplification()); projectile.setSoundEvent(SoundEvents.CROSSBOW_HIT); if (isCrit) { projectile.setCritArrow(true); @@ -280,6 +282,10 @@ protected Projectile createProjectile(Level level, LivingEntity shooter, ItemSta return projectile; } + protected double getDamageAmplification() { + return 0.5; + } + public void performShooting( Level level, LivingEntity shooter, @@ -301,7 +307,10 @@ public void performShooting( // 这里的替换是因为爆掉的时候要返还弹药 // 注意这里写的是isCrit = false,不会暴击 this.spectralShoot(serverlevel, shooter, hand, weapon, chargedprojectiles.getItems(), velocity, inaccuracy, false, target); - // 触发器和进度相关的删掉了——因为它并不是弩。 + if (shooter instanceof ServerPlayer serverplayer) { + // 触发器删掉了——因为它并不是弩。 + serverplayer.awardStat(Stats.ITEM_USED.get(weapon.getItem())); + } } } } @@ -440,16 +449,9 @@ protected static List spectralDraw(ItemStack weapon, ItemStack ammo, if (ammo.isEmpty()) { return List.of(); } else { - Level var5 = shooter.level(); - int var10000; - if (var5 instanceof ServerLevel serverlevel) { - // 这是原版的东西,是能让多重射击正常生效的东西 - var10000 = EnchantmentHelper.processProjectileCount(serverlevel, weapon, shooter, 1); - } else { - var10000 = 1; - } - - int i = var10000; + int i = shooter.level() instanceof ServerLevel serverlevel + ? EnchantmentHelper.processProjectileCount(serverlevel, weapon, shooter, 1) + : 1; List list = new ArrayList<>(i); ItemStack itemStack1 = ammo.copy(); @@ -548,6 +550,5 @@ protected void spectralShoot( } } } - } } diff --git a/src/main/java/dev/dubhe/anvilcraft/item/SpectralWeaponLauncherItem.java b/src/main/java/dev/dubhe/anvilcraft/item/SpectralWeaponLauncherItem.java new file mode 100644 index 0000000000..cf6a894652 --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/item/SpectralWeaponLauncherItem.java @@ -0,0 +1,94 @@ +package dev.dubhe.anvilcraft.item; + +import dev.dubhe.anvilcraft.client.renderer.item.SpectralWeaponLauncherRenderer; +import dev.dubhe.anvilcraft.init.item.ModComponents; +import dev.dubhe.anvilcraft.init.item.ModItems; +import dev.dubhe.anvilcraft.util.ColorUtil; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; +import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Consumer; + +public class SpectralWeaponLauncherItem extends SpectralSlingshotItem { + private static final int FULL_BAR_COLOR = 0xFF5454FF; + private static final int BAR_COLOR = 0x7087FFFF; + + public SpectralWeaponLauncherItem(Properties properties) { + super(properties.component(ModComponents.STORED_ENERGY, 0)); + } + + // 第一人称的手持动画、装填弹药的额外渲染等特殊代码在SpectralWeaponLauncherRenderer等类中 + @Override + @OnlyIn(Dist.CLIENT) + public void initializeClient(Consumer consumer) { + consumer.accept(SpectralWeaponLauncherRenderer.SpectralWeaponLauncherExtensions.of(SpectralWeaponLauncherRenderer.getInstance())); + } + + @Override + public boolean checkLoadable(ItemStack weapon, ItemStack stack) { + return weapon.getOrDefault(ModComponents.STORED_ENERGY, 0) >= 800 && super.checkLoadable(weapon, stack); + } + + @Override + public void performShooting( + Level level, + LivingEntity shooter, + InteractionHand hand, + ItemStack weapon, + float velocity, + float inaccuracy, + @Nullable LivingEntity target + ) { + super.performShooting(level, shooter, hand, weapon, velocity, inaccuracy, target); + if (shooter.hasInfiniteMaterials()) return; + weapon.set(ModComponents.STORED_ENERGY, weapon.getOrDefault(ModComponents.STORED_ENERGY, 0) - 800); + } + + public static void playerTick(ServerPlayer player) { + ItemStack launcher = player.getMainHandItem(); + if (launcher.isEmpty() || !launcher.is(ModItems.SPECTRAL_WEAPON_LAUNCHER)) launcher = player.getOffhandItem(); + if (launcher.isEmpty() || !launcher.is(ModItems.SPECTRAL_WEAPON_LAUNCHER)) return; + + int energy = launcher.getOrDefault(ModComponents.STORED_ENERGY, 0); + while (energy <= 240000) { // 240MJ + Inventory inventory = player.getInventory(); + int slot = inventory.findSlotMatchingItem(ModItems.SUPER_CAPACITOR.asStack()); + if (slot < 0) break; + + inventory.removeItem(slot, 1); + inventory.placeItemBackInInventory(ModItems.SUPER_CAPACITOR_EMPTY.asStack()); + energy += 80000; // 80MJ + } + launcher.set(ModComponents.STORED_ENERGY, energy); + } + + @Override + protected double getDamageAmplification() { + return 1.0; + } + + @Override + public boolean isBarVisible(ItemStack stack) { + return true; + } + + @Override + public int getBarWidth(ItemStack stack) { + int energy = stack.getOrDefault(ModComponents.STORED_ENERGY, 0); + return (int) (Math.clamp(energy / 320000F, 0F, 1F) * 13); + } + + @Override + public int getBarColor(ItemStack stack) { + int energy = stack.getOrDefault(ModComponents.STORED_ENERGY, 0); + return ColorUtil.lerpColor(energy / 320000F, BAR_COLOR, FULL_BAR_COLOR); + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/util/DataGenUtil.java b/src/main/java/dev/dubhe/anvilcraft/util/DataGenUtil.java index 44dfc3eb8f..8455a9e755 100644 --- a/src/main/java/dev/dubhe/anvilcraft/util/DataGenUtil.java +++ b/src/main/java/dev/dubhe/anvilcraft/util/DataGenUtil.java @@ -4,7 +4,9 @@ import dev.anvilcraft.lib.v2.registrum.providers.RegistrumBlockstateProvider; import dev.anvilcraft.lib.v2.registrum.providers.RegistrumProvider; import dev.anvilcraft.lib.v2.registrum.providers.loot.RegistrumBlockLootTables; +import dev.anvilcraft.lib.v2.registrum.util.CreativeModeTabModifier; import dev.dubhe.anvilcraft.block.plate.PowerLevelPressurePlateBlock; +import dev.dubhe.anvilcraft.init.item.ModComponents; import lombok.AccessLevel; import lombok.NoArgsConstructor; import net.minecraft.advancements.critereon.EnchantmentPredicate; @@ -17,6 +19,8 @@ import net.minecraft.core.component.DataComponents; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.enchantment.Enchantment; import net.minecraft.world.item.enchantment.Enchantments; import net.minecraft.world.level.ItemLike; @@ -99,6 +103,13 @@ public static void diodeBlock(RegistrumBlockstateProvider provider, ResourceLoca .addModels(new ConfiguredModel(diodeOn, 0, 270, false)); } + public static void energy(DataGenContext ctx, CreativeModeTabModifier modifier) { + ItemStack stack = ctx.get().getDefaultInstance(); + modifier.accept(stack.copy()); + stack.set(ModComponents.STORED_ENERGY, 320000); + modifier.accept(stack.copy()); + } + @SuppressWarnings("unused") public static void noExtraModelOrState(DataGenContext context, T provider) { } diff --git a/src/main/resources/assets/anvilcraft/models/item/spectral_weapon_launcher.json b/src/main/resources/assets/anvilcraft/models/item/spectral_weapon_launcher.json index 7c0bdc549a..beebd84a52 100644 --- a/src/main/resources/assets/anvilcraft/models/item/spectral_weapon_launcher.json +++ b/src/main/resources/assets/anvilcraft/models/item/spectral_weapon_launcher.json @@ -641,5 +641,13 @@ 41, 42, 43 + ], + "overrides": [ + { + "predicate": { + "anvilcraft:stored_energy": 800 + }, + "model": "anvilcraft:item/spectral_weapon_launcher_exhausted" + } ] } \ No newline at end of file From ae846d2e0405f0bcea1d91cb8edfc1bfc56cc432 Mon Sep 17 00:00:00 2001 From: QiuShui1012 <150409561+QiuShui1012@users.noreply.github.com> Date: Sat, 11 Apr 2026 02:29:57 +0800 Subject: [PATCH 2/6] feat(item): refactor spectral weapon launcher and gravity management --- .../anvilcraft/client/AnvilCraftClient.java | 7 --- .../item/SpectralWeaponLauncherRenderer.java | 21 +++++++-- .../WrappingItemCustomRenderedModels.java | 8 +++- .../event/PlayerTickEventHandler.java | 2 +- .../dubhe/anvilcraft/init/item/ModItems.java | 2 +- .../item/SpectralSlingshotItem.java | 6 +++ .../SpectralWeaponLauncherItem.java | 25 ++++++++-- .../anvilcraft/item/weapon/package-info.java | 7 +++ .../dubhe/anvilcraft/mixin/EntityMixin.java | 12 +---- .../anvilcraft/mixin/FallingBlockMixin.java | 3 +- .../anvilcraft/mixin/ModelBakeryMixin.java | 47 +++++++++++++++++++ .../dubhe/anvilcraft/util/DataGenUtil.java | 2 + .../dubhe/anvilcraft/util/GravityManager.java | 21 +-------- .../dubhe/anvilcraft/util/GravityType.java | 19 ++++++++ src/main/resources/anvilcraft.mixins.json | 1 + .../models/item/spectral_weapon_launcher.json | 2 +- 16 files changed, 132 insertions(+), 53 deletions(-) rename src/main/java/dev/dubhe/anvilcraft/item/{ => weapon}/SpectralWeaponLauncherItem.java (74%) create mode 100644 src/main/java/dev/dubhe/anvilcraft/item/weapon/package-info.java create mode 100644 src/main/java/dev/dubhe/anvilcraft/mixin/ModelBakeryMixin.java create mode 100644 src/main/java/dev/dubhe/anvilcraft/util/GravityType.java diff --git a/src/main/java/dev/dubhe/anvilcraft/client/AnvilCraftClient.java b/src/main/java/dev/dubhe/anvilcraft/client/AnvilCraftClient.java index c8f0c0f71f..61046cdd45 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/AnvilCraftClient.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/AnvilCraftClient.java @@ -14,10 +14,8 @@ import dev.dubhe.anvilcraft.config.AnvilCraftClientConfig; import dev.dubhe.anvilcraft.init.ModParticles; import dev.dubhe.anvilcraft.init.block.ModFluids; -import dev.dubhe.anvilcraft.init.item.ModComponents; import dev.dubhe.anvilcraft.init.item.ModItems; import net.minecraft.client.model.HumanoidModel; -import net.minecraft.client.renderer.item.ItemProperties; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ItemStack; @@ -58,11 +56,6 @@ public static void clientSetup(FMLClientSetupEvent event) { IntegrationHook.setModEventBus(modEventBus); IntegrationHook.setModContainer(modContainer); AnvilCraft.getINTEGRATION_MANAGER().loadAllClientIntegrations(); - - ItemProperties.registerGeneric( - AnvilCraft.of("stored_energy"), - (stack, level, entity, seed) -> stack.getOrDefault(ModComponents.STORED_ENERGY, 0) - ); } public static void registerClientExtensions(RegisterClientExtensionsEvent e) { diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/SpectralWeaponLauncherRenderer.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/SpectralWeaponLauncherRenderer.java index 8b62cfcf7c..196007b678 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/SpectralWeaponLauncherRenderer.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/SpectralWeaponLauncherRenderer.java @@ -4,7 +4,7 @@ import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.math.Axis; import dev.dubhe.anvilcraft.init.item.ModItems; -import dev.dubhe.anvilcraft.item.SpectralWeaponLauncherItem; +import dev.dubhe.anvilcraft.item.weapon.SpectralWeaponLauncherItem; import net.minecraft.client.Minecraft; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.model.geom.EntityModelSet; @@ -59,22 +59,33 @@ public void renderByItem( ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer(); if (stack.is(ModItems.SPECTRAL_WEAPON_LAUNCHER)) { BakedModel normalModel = itemRenderer.getItemModelShaper().getItemModel(stack); - renderItemAtCurrentPoseStack(itemRenderer, + renderItemAtCurrentPoseStack( + itemRenderer, stack, displayContext, poseStack, buffer, packedLight, packedOverlay, - normalModel + normalModel.getOverrides().resolve( + normalModel, + stack, + null, + null, + 42 + ) ); ChargedProjectiles cp = stack.get(DataComponents.CHARGED_PROJECTILES); if (cp != null && !cp.isEmpty()) { ItemStack ammo = cp.getItems().getFirst(); poseStack.pushPose(); - poseStack.translate(0f, 5f, 0.50F); + // poseStack.translate(38f / 256f, 5f / 64f, 7f / 8f); + // poseStack.mulPose(Axis.YP.rotationDegrees(90)); + // poseStack.mulPose(Axis.XN.rotationDegrees(45)); + // poseStack.mulPose(Axis.ZN.rotationDegrees(45)); + poseStack.translate(0f, 7f / 16f, 7f / 8f); poseStack.mulPose(Axis.YP.rotationDegrees(90)); - poseStack.mulPose(Axis.ZP.rotationDegrees(- 45)); + poseStack.mulPose(Axis.ZN.rotationDegrees(45)); // poseStack.pushPose(); BakedModel bakedModel = itemRenderer.getItemModelShaper().getItemModel(ammo); renderItemAtCurrentPoseStack( diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/WrappingItemCustomRenderedModels.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/WrappingItemCustomRenderedModels.java index c145142ad4..7a0db9f4e2 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/WrappingItemCustomRenderedModels.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/WrappingItemCustomRenderedModels.java @@ -4,6 +4,7 @@ import dev.dubhe.anvilcraft.AnvilCraft; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.ModelResourceLocation; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemDisplayContext; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; @@ -15,12 +16,15 @@ @EventBusSubscriber(modid = AnvilCraft.MOD_ID, value = Dist.CLIENT) public class WrappingItemCustomRenderedModels { + public static final ResourceLocation SPECTRAL_WEAPON_LAUNCHER = AnvilCraft.of("spectral_weapon_launcher"); + public static final ResourceLocation SPECTRAL_WEAPON_LAUNCHER_EXHAUSTED = AnvilCraft.of("spectral_weapon_launcher_exhausted"); + @SubscribeEvent public static void onModelBake(ModelEvent.ModifyBakingResult event) { Map modelRegistry = event.getModels(); swapModels(modelRegistry, ModelResourceLocation.inventory(AnvilCraft.of("spectral_slingshot"))); - swapModels(modelRegistry, ModelResourceLocation.inventory(AnvilCraft.of("spectral_weapon_launcher"))); - swapModels(modelRegistry, ModelResourceLocation.inventory(AnvilCraft.of("spectral_weapon_launcher_exhausted"))); + swapModels(modelRegistry, ModelResourceLocation.inventory(SPECTRAL_WEAPON_LAUNCHER)); + swapModels(modelRegistry, ModelResourceLocation.inventory(SPECTRAL_WEAPON_LAUNCHER_EXHAUSTED)); } public static void swapModels(Map modelRegistry, ModelResourceLocation modelLocation) { diff --git a/src/main/java/dev/dubhe/anvilcraft/event/PlayerTickEventHandler.java b/src/main/java/dev/dubhe/anvilcraft/event/PlayerTickEventHandler.java index ffef56c2ff..df8d23bbe8 100644 --- a/src/main/java/dev/dubhe/anvilcraft/event/PlayerTickEventHandler.java +++ b/src/main/java/dev/dubhe/anvilcraft/event/PlayerTickEventHandler.java @@ -4,11 +4,11 @@ import dev.dubhe.anvilcraft.api.power.PowerGrid; import dev.dubhe.anvilcraft.item.CrabClawItem; import dev.dubhe.anvilcraft.item.IonoCraftBackpackItem; -import dev.dubhe.anvilcraft.item.SpectralWeaponLauncherItem; import dev.dubhe.anvilcraft.item.property.component.Eternal; import dev.dubhe.anvilcraft.item.property.component.Ferocious; import dev.dubhe.anvilcraft.item.property.component.Merciless; import dev.dubhe.anvilcraft.item.property.component.MultiphaseRef; +import dev.dubhe.anvilcraft.item.weapon.SpectralWeaponLauncherItem; import dev.dubhe.anvilcraft.util.PlayerUtil; import net.minecraft.server.level.ServerPlayer; import net.neoforged.bus.api.SubscribeEvent; diff --git a/src/main/java/dev/dubhe/anvilcraft/init/item/ModItems.java b/src/main/java/dev/dubhe/anvilcraft/init/item/ModItems.java index 47537f282e..8e2e49f580 100644 --- a/src/main/java/dev/dubhe/anvilcraft/init/item/ModItems.java +++ b/src/main/java/dev/dubhe/anvilcraft/init/item/ModItems.java @@ -68,7 +68,6 @@ import dev.dubhe.anvilcraft.item.RoyalSwordItem; import dev.dubhe.anvilcraft.item.SeedsPackItem; import dev.dubhe.anvilcraft.item.SpectralSlingshotItem; -import dev.dubhe.anvilcraft.item.SpectralWeaponLauncherItem; import dev.dubhe.anvilcraft.item.StructureToolItem; import dev.dubhe.anvilcraft.item.SuperCapacitorItem; import dev.dubhe.anvilcraft.item.TopazItem; @@ -95,6 +94,7 @@ import dev.dubhe.anvilcraft.item.template.mto.FourToOneTemplateItem; import dev.dubhe.anvilcraft.item.template.mto.TwoToOneTemplateItem; import dev.dubhe.anvilcraft.item.weapon.AnvilRailgunItem; +import dev.dubhe.anvilcraft.item.weapon.SpectralWeaponLauncherItem; import dev.dubhe.anvilcraft.recipe.JewelCraftingRecipe; import dev.dubhe.anvilcraft.util.DataGenUtil; import dev.dubhe.anvilcraft.util.registrater.ModelProviderUtil; diff --git a/src/main/java/dev/dubhe/anvilcraft/item/SpectralSlingshotItem.java b/src/main/java/dev/dubhe/anvilcraft/item/SpectralSlingshotItem.java index 9b9d909ee5..66b48ad57d 100644 --- a/src/main/java/dev/dubhe/anvilcraft/item/SpectralSlingshotItem.java +++ b/src/main/java/dev/dubhe/anvilcraft/item/SpectralSlingshotItem.java @@ -96,6 +96,7 @@ public void initializeClient(Consumer consumer) { */ public boolean checkLoadable(ItemStack weapon, ItemStack stack) { // 装载箭矢的设定取消了:if (stack.is(ItemTags.ARROWS)) return true; + if (this.unableToUse(weapon)) return false; ItemAttributeModifiers modifiers = stack.getAttributeModifiers(); double dmg = 0; for (ItemAttributeModifiers.Entry entry : modifiers.modifiers()) { @@ -131,6 +132,10 @@ public static void setCanTakeOutAmmo(ItemStack stack, boolean can) { stack.set(ModComponents.CAN_TAKE_OUT_AMMO, can); } + public boolean unableToUse(ItemStack stack) { + return false; + } + // 以下的代码大量从原版(neoforge融合后的)的弩物品的代码复制过来的 @Override @@ -139,6 +144,7 @@ public InteractionResultHolder use(Level level, Player player, Intera ChargedProjectiles chargedprojectiles = itemstack.get(DataComponents.CHARGED_PROJECTILES); if (chargedprojectiles != null && !chargedprojectiles.isEmpty()) { if (!player.isCrouching() && !player.getCooldowns().isOnCooldown(this)) { + if (this.unableToUse(itemstack)) return InteractionResultHolder.fail(itemstack); this.performShooting(level, player, hand, itemstack, SpectralSlingshotItem.getShootingPower(), 1.0F, null); int quickCharge = itemstack.getEnchantmentLevel( player.level() diff --git a/src/main/java/dev/dubhe/anvilcraft/item/SpectralWeaponLauncherItem.java b/src/main/java/dev/dubhe/anvilcraft/item/weapon/SpectralWeaponLauncherItem.java similarity index 74% rename from src/main/java/dev/dubhe/anvilcraft/item/SpectralWeaponLauncherItem.java rename to src/main/java/dev/dubhe/anvilcraft/item/weapon/SpectralWeaponLauncherItem.java index cf6a894652..4848e5eaf6 100644 --- a/src/main/java/dev/dubhe/anvilcraft/item/SpectralWeaponLauncherItem.java +++ b/src/main/java/dev/dubhe/anvilcraft/item/weapon/SpectralWeaponLauncherItem.java @@ -1,14 +1,17 @@ -package dev.dubhe.anvilcraft.item; +package dev.dubhe.anvilcraft.item.weapon; import dev.dubhe.anvilcraft.client.renderer.item.SpectralWeaponLauncherRenderer; import dev.dubhe.anvilcraft.init.item.ModComponents; import dev.dubhe.anvilcraft.init.item.ModItems; +import dev.dubhe.anvilcraft.item.SpectralSlingshotItem; import dev.dubhe.anvilcraft.util.ColorUtil; +import net.minecraft.core.component.DataComponents; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.CustomModelData; import net.minecraft.world.level.Level; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; @@ -18,11 +21,17 @@ import java.util.function.Consumer; public class SpectralWeaponLauncherItem extends SpectralSlingshotItem { + public static final int SHOOT_CONSUME = 800; + public static final int EXHAUSTED_MODEL = 1; private static final int FULL_BAR_COLOR = 0xFF5454FF; private static final int BAR_COLOR = 0x7087FFFF; public SpectralWeaponLauncherItem(Properties properties) { - super(properties.component(ModComponents.STORED_ENERGY, 0)); + super( + properties + .component(ModComponents.STORED_ENERGY, 0) + .component(DataComponents.CUSTOM_MODEL_DATA, new CustomModelData(SpectralWeaponLauncherItem.EXHAUSTED_MODEL)) + ); } // 第一人称的手持动画、装填弹药的额外渲染等特殊代码在SpectralWeaponLauncherRenderer等类中 @@ -33,8 +42,8 @@ public void initializeClient(Consumer consumer) { } @Override - public boolean checkLoadable(ItemStack weapon, ItemStack stack) { - return weapon.getOrDefault(ModComponents.STORED_ENERGY, 0) >= 800 && super.checkLoadable(weapon, stack); + public boolean unableToUse(ItemStack stack) { + return stack.getOrDefault(ModComponents.STORED_ENERGY, 0) < SpectralWeaponLauncherItem.SHOOT_CONSUME; } @Override @@ -49,7 +58,13 @@ public void performShooting( ) { super.performShooting(level, shooter, hand, weapon, velocity, inaccuracy, target); if (shooter.hasInfiniteMaterials()) return; - weapon.set(ModComponents.STORED_ENERGY, weapon.getOrDefault(ModComponents.STORED_ENERGY, 0) - 800); + int newEnergy = weapon.getOrDefault(ModComponents.STORED_ENERGY, 0) - SpectralWeaponLauncherItem.SHOOT_CONSUME; + weapon.set(ModComponents.STORED_ENERGY, newEnergy); + if (newEnergy < 800) { + weapon.set(DataComponents.CUSTOM_MODEL_DATA, new CustomModelData(SpectralWeaponLauncherItem.EXHAUSTED_MODEL)); + } else { + weapon.set(DataComponents.CUSTOM_MODEL_DATA, CustomModelData.DEFAULT); + } } public static void playerTick(ServerPlayer player) { diff --git a/src/main/java/dev/dubhe/anvilcraft/item/weapon/package-info.java b/src/main/java/dev/dubhe/anvilcraft/item/weapon/package-info.java new file mode 100644 index 0000000000..26b3ee4c46 --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/item/weapon/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package dev.dubhe.anvilcraft.item.weapon; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/EntityMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/EntityMixin.java index e13c2dca31..3a0933ebc1 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/EntityMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/EntityMixin.java @@ -278,17 +278,7 @@ private void handlePortal(CallbackInfo ci) { Level level = entity.level(); // 获取基础重力 - double baseGravity = cir.getReturnValue(); - - // 应用物质特殊属性 - GravityManager.GravityType type = GravityManager.getGravityType(entity); - switch (type) { - case ANTI_GRAVITY -> baseGravity *= -1; - case MICRO_ANTI_GRAVITY -> baseGravity *= -0.005; - case LOW_GRAVITY -> baseGravity *= 0.5; - default -> { - } - } + double baseGravity = cir.getReturnValue() * GravityManager.getGravityType(entity).getScalar(); // 维度重力 = 基础重力 * 维度系数 double dimensionGravity = baseGravity * GravityManager.getDimensionGravity(level); diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/FallingBlockMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/FallingBlockMixin.java index 9996feb9f0..106629e55d 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/FallingBlockMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/FallingBlockMixin.java @@ -3,6 +3,7 @@ import dev.dubhe.anvilcraft.entity.LevitatingBlockEntity; import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.util.GravityManager; +import dev.dubhe.anvilcraft.util.GravityType; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.server.level.ServerLevel; @@ -37,7 +38,7 @@ public static boolean isFree(BlockState state) { ) private void anvilcraft$fall(BlockState state, ServerLevel level, BlockPos pos, RandomSource random, CallbackInfo ci) { // 1. 计算净重力 - GravityManager.GravityType gravityType = GravityManager.getFallingBlockGravityType(state.getBlock()); + GravityType gravityType = GravityManager.getFallingBlockGravityType(state.getBlock()); Vec3 netGravity = GravityManager.getNetGravityVectorForFallingBlock(level, Vec3.atCenterOf(pos), gravityType); double gravitySq = netGravity.lengthSqr(); diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/ModelBakeryMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/ModelBakeryMixin.java new file mode 100644 index 0000000000..181f0a2b57 --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/ModelBakeryMixin.java @@ -0,0 +1,47 @@ +package dev.dubhe.anvilcraft.mixin; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import dev.dubhe.anvilcraft.client.renderer.item.WrappingItemCustomRenderedModels; +import net.minecraft.client.renderer.block.model.ItemOverrides; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.Material; +import net.minecraft.client.resources.model.ModelBaker; +import net.minecraft.client.resources.model.ModelState; +import net.minecraft.resources.ResourceLocation; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import java.util.function.Function; + +@Mixin(ItemOverrides.class) +abstract class ModelBakeryMixin { + @WrapOperation( + method = "bakeModel", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/resources/model/ModelBaker;bake(" + + "Lnet/minecraft/resources/ResourceLocation;" + + "Lnet/minecraft/client/resources/model/ModelState;" + + "Ljava/util/function/Function;)" + + "Lnet/minecraft/client/resources/model/BakedModel;" + ) + ) + private BakedModel wrapSpecific( + ModelBaker instance, + ResourceLocation location, + ModelState transform, + Function sprites, + Operation original + ) { + if ( + location.equals(WrappingItemCustomRenderedModels.SPECTRAL_WEAPON_LAUNCHER.withPrefix("item/")) + || location.equals(WrappingItemCustomRenderedModels.SPECTRAL_WEAPON_LAUNCHER_EXHAUSTED.withPrefix("item/")) + ) { + return new WrappingItemCustomRenderedModels.CustomRenderedModelWrapper(original.call(instance, location, transform, sprites)); + } else { + return original.call(instance, location, transform, sprites); + } + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/util/DataGenUtil.java b/src/main/java/dev/dubhe/anvilcraft/util/DataGenUtil.java index 8455a9e755..79f3973dc1 100644 --- a/src/main/java/dev/dubhe/anvilcraft/util/DataGenUtil.java +++ b/src/main/java/dev/dubhe/anvilcraft/util/DataGenUtil.java @@ -21,6 +21,7 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.CustomModelData; import net.minecraft.world.item.enchantment.Enchantment; import net.minecraft.world.item.enchantment.Enchantments; import net.minecraft.world.level.ItemLike; @@ -107,6 +108,7 @@ public static void energy(DataGenContext ctx, Creative ItemStack stack = ctx.get().getDefaultInstance(); modifier.accept(stack.copy()); stack.set(ModComponents.STORED_ENERGY, 320000); + stack.set(DataComponents.CUSTOM_MODEL_DATA, CustomModelData.DEFAULT); modifier.accept(stack.copy()); } diff --git a/src/main/java/dev/dubhe/anvilcraft/util/GravityManager.java b/src/main/java/dev/dubhe/anvilcraft/util/GravityManager.java index a3ce4c616d..d10649625e 100644 --- a/src/main/java/dev/dubhe/anvilcraft/util/GravityManager.java +++ b/src/main/java/dev/dubhe/anvilcraft/util/GravityManager.java @@ -67,15 +67,6 @@ public static void onLevelUnload(LevelEvent.Unload event) { } } - // 特殊物质定义不同引力类型 - public enum GravityType { - NORMAL, // 正常重力 1 - ANTI_GRAVITY, // 反转重力 -1 - MICRO_ANTI_GRAVITY, // 略有失重感 -0.005 - LOW_GRAVITY // 低重力 0.5 - - } - public static GravityType getGravityType(Entity entity) { if (entity instanceof ItemEntity itemEntity) { var item = itemEntity.getItem(); @@ -124,16 +115,8 @@ public static Vec3 getGravityVector(Entity entity) { return Vec3.ZERO; } - // 获取实体引力类型 - GravityType type = getGravityType(entity); - - // 根据类型修正向量方向/大小 - return switch (type) { - case ANTI_GRAVITY -> gravityVector.reverse(); - case MICRO_ANTI_GRAVITY -> gravityVector.scale(-0.005); - case LOW_GRAVITY -> gravityVector.scale(0.5); - default -> gravityVector; - }; + // 根据实体引力类型修正向量方向/大小 + return gravityVector.scale(GravityManager.getGravityType(entity).getScalar()); } // 得到含维度的总体重力向量(仅用于下落方块方块) diff --git a/src/main/java/dev/dubhe/anvilcraft/util/GravityType.java b/src/main/java/dev/dubhe/anvilcraft/util/GravityType.java new file mode 100644 index 0000000000..ea972701c9 --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/util/GravityType.java @@ -0,0 +1,19 @@ +package dev.dubhe.anvilcraft.util; + +import lombok.Getter; + +// 特殊物质定义不同引力类型 +public enum GravityType { + NORMAL(1), // 正常重力 + ANTI_GRAVITY(-1), // 反转重力 + MICRO_ANTI_GRAVITY(-0.005), // 略有失重感 + LOW_GRAVITY(0.5), // 低重力 + ; + + @Getter + private final double scalar; + + GravityType(double scalar) { + this.scalar = scalar; + } +} diff --git a/src/main/resources/anvilcraft.mixins.json b/src/main/resources/anvilcraft.mixins.json index 91d3f37970..28cdc0eade 100644 --- a/src/main/resources/anvilcraft.mixins.json +++ b/src/main/resources/anvilcraft.mixins.json @@ -38,6 +38,7 @@ "LevelChunkMixin", "LightningBoltMixin", "LivingEntityMixin", + "ModelBakeryMixin", "NearestAttackableTargetGoalMixin", "PhantomGoalMixin", "PigMixin", diff --git a/src/main/resources/assets/anvilcraft/models/item/spectral_weapon_launcher.json b/src/main/resources/assets/anvilcraft/models/item/spectral_weapon_launcher.json index beebd84a52..15021b2173 100644 --- a/src/main/resources/assets/anvilcraft/models/item/spectral_weapon_launcher.json +++ b/src/main/resources/assets/anvilcraft/models/item/spectral_weapon_launcher.json @@ -645,7 +645,7 @@ "overrides": [ { "predicate": { - "anvilcraft:stored_energy": 800 + "custom_model_data": 1 }, "model": "anvilcraft:item/spectral_weapon_launcher_exhausted" } From 957d6a9b1328ca2d5ea3e55ba27eae219edd2777 Mon Sep 17 00:00:00 2001 From: QiuShui1012 <150409561+QiuShui1012@users.noreply.github.com> Date: Sun, 12 Apr 2026 07:37:33 +0800 Subject: [PATCH 3/6] refactor(renderer): update baked model resolution for slingshot and weapon launcher --- .../client/renderer/item/SpectralSlingshotRenderer.java | 8 +++++++- .../renderer/item/SpectralWeaponLauncherRenderer.java | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/SpectralSlingshotRenderer.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/SpectralSlingshotRenderer.java index ae4ee8c090..1c94768c73 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/SpectralSlingshotRenderer.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/SpectralSlingshotRenderer.java @@ -85,7 +85,13 @@ public void renderByItem( buffer, packedLight, packedOverlay, - bakedModel + bakedModel.getOverrides().resolve( + bakedModel, + ammo, + null, + null, + 42 + ) ); // poseStack.popPose(); poseStack.popPose(); diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/SpectralWeaponLauncherRenderer.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/SpectralWeaponLauncherRenderer.java index 196007b678..19ea66d682 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/SpectralWeaponLauncherRenderer.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/item/SpectralWeaponLauncherRenderer.java @@ -96,7 +96,13 @@ public void renderByItem( buffer, packedLight, packedOverlay, - bakedModel + bakedModel.getOverrides().resolve( + bakedModel, + ammo, + null, + null, + 42 + ) ); // poseStack.popPose(); poseStack.popPose(); From 357208832c9d4f1e9b0d891893f58324d670fa2d Mon Sep 17 00:00:00 2001 From: QiuShui1012 <150409561+QiuShui1012@users.noreply.github.com> Date: Mon, 13 Apr 2026 06:09:00 +0800 Subject: [PATCH 4/6] refactor(item): rename ModelBakeryMixin to ItemOverridesMixin and update energy consumption logic in SpectralWeaponLauncherItem --- .../item/weapon/SpectralWeaponLauncherItem.java | 9 ++++++--- .../{ModelBakeryMixin.java => ItemOverridesMixin.java} | 2 +- src/main/resources/anvilcraft.mixins.json | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) rename src/main/java/dev/dubhe/anvilcraft/mixin/{ModelBakeryMixin.java => ItemOverridesMixin.java} (98%) diff --git a/src/main/java/dev/dubhe/anvilcraft/item/weapon/SpectralWeaponLauncherItem.java b/src/main/java/dev/dubhe/anvilcraft/item/weapon/SpectralWeaponLauncherItem.java index 4848e5eaf6..3ae11937cc 100644 --- a/src/main/java/dev/dubhe/anvilcraft/item/weapon/SpectralWeaponLauncherItem.java +++ b/src/main/java/dev/dubhe/anvilcraft/item/weapon/SpectralWeaponLauncherItem.java @@ -60,7 +60,7 @@ public void performShooting( if (shooter.hasInfiniteMaterials()) return; int newEnergy = weapon.getOrDefault(ModComponents.STORED_ENERGY, 0) - SpectralWeaponLauncherItem.SHOOT_CONSUME; weapon.set(ModComponents.STORED_ENERGY, newEnergy); - if (newEnergy < 800) { + if (newEnergy < SpectralWeaponLauncherItem.SHOOT_CONSUME) { weapon.set(DataComponents.CUSTOM_MODEL_DATA, new CustomModelData(SpectralWeaponLauncherItem.EXHAUSTED_MODEL)); } else { weapon.set(DataComponents.CUSTOM_MODEL_DATA, CustomModelData.DEFAULT); @@ -78,11 +78,14 @@ public static void playerTick(ServerPlayer player) { int slot = inventory.findSlotMatchingItem(ModItems.SUPER_CAPACITOR.asStack()); if (slot < 0) break; - inventory.removeItem(slot, 1); - inventory.placeItemBackInInventory(ModItems.SUPER_CAPACITOR_EMPTY.asStack()); + if (!player.hasInfiniteMaterials()) { + inventory.removeItem(slot, 1); + inventory.placeItemBackInInventory(ModItems.SUPER_CAPACITOR_EMPTY.asStack()); + } energy += 80000; // 80MJ } launcher.set(ModComponents.STORED_ENERGY, energy); + launcher.set(DataComponents.CUSTOM_MODEL_DATA, new CustomModelData(SpectralWeaponLauncherItem.EXHAUSTED_MODEL)); } @Override diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/ModelBakeryMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/ItemOverridesMixin.java similarity index 98% rename from src/main/java/dev/dubhe/anvilcraft/mixin/ModelBakeryMixin.java rename to src/main/java/dev/dubhe/anvilcraft/mixin/ItemOverridesMixin.java index 181f0a2b57..65979d53ac 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/ModelBakeryMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/ItemOverridesMixin.java @@ -16,7 +16,7 @@ import java.util.function.Function; @Mixin(ItemOverrides.class) -abstract class ModelBakeryMixin { +abstract class ItemOverridesMixin { @WrapOperation( method = "bakeModel", at = @At( diff --git a/src/main/resources/anvilcraft.mixins.json b/src/main/resources/anvilcraft.mixins.json index 28cdc0eade..a1694de655 100644 --- a/src/main/resources/anvilcraft.mixins.json +++ b/src/main/resources/anvilcraft.mixins.json @@ -38,7 +38,6 @@ "LevelChunkMixin", "LightningBoltMixin", "LivingEntityMixin", - "ModelBakeryMixin", "NearestAttackableTargetGoalMixin", "PhantomGoalMixin", "PigMixin", @@ -82,6 +81,7 @@ "GuiGraphicsMixin", "ItemFrameRendererMixin", "ItemInHandRendererMixin", + "ItemOverridesMixin", "LevelRendererMixin", "MinecraftClientMixin", "MouseHandlerMixin", From d457c602ac1691d949c20c89c34c6484e969c377 Mon Sep 17 00:00:00 2001 From: QiuShui1012 <150409561+QiuShui1012@users.noreply.github.com> Date: Mon, 13 Apr 2026 06:19:30 +0800 Subject: [PATCH 5/6] refactor(item): update CustomModelData handling in SpectralWeaponLauncherItem --- .../anvilcraft/item/weapon/SpectralWeaponLauncherItem.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/dev/dubhe/anvilcraft/item/weapon/SpectralWeaponLauncherItem.java b/src/main/java/dev/dubhe/anvilcraft/item/weapon/SpectralWeaponLauncherItem.java index 3ae11937cc..179b493e3a 100644 --- a/src/main/java/dev/dubhe/anvilcraft/item/weapon/SpectralWeaponLauncherItem.java +++ b/src/main/java/dev/dubhe/anvilcraft/item/weapon/SpectralWeaponLauncherItem.java @@ -85,7 +85,7 @@ public static void playerTick(ServerPlayer player) { energy += 80000; // 80MJ } launcher.set(ModComponents.STORED_ENERGY, energy); - launcher.set(DataComponents.CUSTOM_MODEL_DATA, new CustomModelData(SpectralWeaponLauncherItem.EXHAUSTED_MODEL)); + launcher.set(DataComponents.CUSTOM_MODEL_DATA, CustomModelData.DEFAULT); } @Override From 0eae384df8d4026cba16c52ac0161c31327e8e38 Mon Sep 17 00:00:00 2001 From: QiuShui1012 <150409561+QiuShui1012@users.noreply.github.com> Date: Mon, 13 Apr 2026 06:21:23 +0800 Subject: [PATCH 6/6] fix(item): prevent redundant energy setting in SpectralWeaponLauncherItem --- .../dubhe/anvilcraft/item/weapon/SpectralWeaponLauncherItem.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/dev/dubhe/anvilcraft/item/weapon/SpectralWeaponLauncherItem.java b/src/main/java/dev/dubhe/anvilcraft/item/weapon/SpectralWeaponLauncherItem.java index 179b493e3a..f3b1e66a60 100644 --- a/src/main/java/dev/dubhe/anvilcraft/item/weapon/SpectralWeaponLauncherItem.java +++ b/src/main/java/dev/dubhe/anvilcraft/item/weapon/SpectralWeaponLauncherItem.java @@ -84,6 +84,7 @@ public static void playerTick(ServerPlayer player) { } energy += 80000; // 80MJ } + if (energy == launcher.getOrDefault(ModComponents.STORED_ENERGY, 0)) return; launcher.set(ModComponents.STORED_ENERGY, energy); launcher.set(DataComponents.CUSTOM_MODEL_DATA, CustomModelData.DEFAULT); }