From 94418ba5e6da2fd4eddf8ce918f9df17e7214f21 Mon Sep 17 00:00:00 2001 From: cnlimiter Date: Mon, 20 May 2024 19:09:26 +0800 Subject: [PATCH] fix(1.20.1-forged): crossbow func fix --- .../entity/arrow/HeavenArrowEntity.java | 14 +- .../entity/arrow/HeavenSubArrowEntity.java | 8 +- .../common/item/tools/InfinityBowItem.java | 28 ++- .../item/tools/InfinityCrossBowItem.java | 202 ++++++++++++++++++ .../resources/META-INF/accesstransformer.cfg | 4 +- 5 files changed, 228 insertions(+), 28 deletions(-) create mode 100644 src/main/java/committee/nova/mods/avaritia/common/item/tools/InfinityCrossBowItem.java diff --git a/src/main/java/committee/nova/mods/avaritia/common/entity/arrow/HeavenArrowEntity.java b/src/main/java/committee/nova/mods/avaritia/common/entity/arrow/HeavenArrowEntity.java index c5f0a0c8..b1f8e0fb 100644 --- a/src/main/java/committee/nova/mods/avaritia/common/entity/arrow/HeavenArrowEntity.java +++ b/src/main/java/committee/nova/mods/avaritia/common/entity/arrow/HeavenArrowEntity.java @@ -28,8 +28,8 @@ public class HeavenArrowEntity extends Arrow { private LivingEntity shooter; - public HeavenArrowEntity(EntityType p_36858_, Level p_36859_) { - super(p_36858_, p_36859_); + public HeavenArrowEntity(EntityType entityType, Level level) { + super(entityType, level); } @@ -57,13 +57,13 @@ protected void onHitEntity(@NotNull EntityHitResult result) { } private void barrage(RandomSource randy, BlockPos pos) { - for (int i = 0; i < 30; i++) { + for (int i = 0; i < 30; i++) {//30支箭 double angle = randy.nextDouble() * 2 * Math.PI; double dist = randy.nextGaussian() * 0.5; double x = Math.sin(angle) * dist + pos.getX(); double z = Math.cos(angle) * dist + pos.getZ(); - double y = pos.getY() + 25.0; + double y = pos.getY() + 25.0;//高度25 double dangle = randy.nextDouble() * 2 * Math.PI; double ddist = randy.nextDouble() * 0.35; @@ -74,7 +74,7 @@ private void barrage(RandomSource randy, BlockPos pos) { if (shooter != null) subArrow.setOwner(shooter); subArrow.piercedAndKilledEntities = piercedAndKilledEntities; subArrow.push(dx, -(randy.nextDouble() * 1.85 + 0.15), dz); - subArrow.setCritArrow(true); + subArrow.setCritArrow(true);//子箭必定暴击 subArrow.pickup = pickup; level().addFreshEntity(subArrow); @@ -87,7 +87,7 @@ protected void onHitBlock(@NotNull BlockHitResult result) { var pos = result.getBlockPos(); var randy = level().random; barrage(randy, pos); - remove(RemovalReason.KILLED); + this.remove(RemovalReason.KILLED); } @Override @@ -100,7 +100,7 @@ public void addAdditionalSaveData(@NotNull CompoundTag compound) { @Override public void readAdditionalSaveData(@NotNull CompoundTag compound) { super.readAdditionalSaveData(compound); - this.setBaseDamage(compound.getDouble("damage")); + this.setBaseDamage(compound.contains("damage") ? compound.getDouble("damage") : Float.POSITIVE_INFINITY); } diff --git a/src/main/java/committee/nova/mods/avaritia/common/entity/arrow/HeavenSubArrowEntity.java b/src/main/java/committee/nova/mods/avaritia/common/entity/arrow/HeavenSubArrowEntity.java index 1c1ea46f..efffd02d 100644 --- a/src/main/java/committee/nova/mods/avaritia/common/entity/arrow/HeavenSubArrowEntity.java +++ b/src/main/java/committee/nova/mods/avaritia/common/entity/arrow/HeavenSubArrowEntity.java @@ -21,8 +21,8 @@ */ public class HeavenSubArrowEntity extends Arrow { - public HeavenSubArrowEntity(EntityType p_36858_, Level p_36859_) { - super(p_36858_, p_36859_); + public HeavenSubArrowEntity(EntityType entityType, Level level) { + super(entityType, level); } public static HeavenSubArrowEntity create(Level level, double x, double y, double z) { @@ -49,15 +49,13 @@ public void tick() { @Override public void readAdditionalSaveData(@NotNull CompoundTag compound) { super.readAdditionalSaveData(compound); - this.setBaseDamage(compound.getDouble("damage")); - + this.setBaseDamage(compound.contains("damage") ? compound.getDouble("damage") : ModConfig.subArrowDamage.get()); } @Override public void addAdditionalSaveData(@NotNull CompoundTag compound) { super.addAdditionalSaveData(compound); compound.putDouble("damage", ModConfig.subArrowDamage.get()); - } @Override diff --git a/src/main/java/committee/nova/mods/avaritia/common/item/tools/InfinityBowItem.java b/src/main/java/committee/nova/mods/avaritia/common/item/tools/InfinityBowItem.java index de5782a8..912112d7 100644 --- a/src/main/java/committee/nova/mods/avaritia/common/item/tools/InfinityBowItem.java +++ b/src/main/java/committee/nova/mods/avaritia/common/item/tools/InfinityBowItem.java @@ -70,17 +70,17 @@ public boolean onEntityItemUpdate(ItemStack stack, ItemEntity entity) { } @Override - public boolean isEnchantable(@NotNull ItemStack p_41456_) { + public boolean isEnchantable(@NotNull ItemStack pStack) { return true; } @Override public int getEnchantmentValue(ItemStack stack) { - return 0; - } + return 99; + }//附魔系数 @Override public int getUseDuration(@NotNull ItemStack stack) { return 1200; - } + }//使用时间 @Override public @NotNull UseAnim getUseAnimation(@NotNull ItemStack pStack) { return UseAnim.BOW; @@ -94,7 +94,6 @@ public Entity createEntity(Level level, Entity location, ItemStack stack) { @Override public @NotNull InteractionResultHolder use(@NotNull Level level, Player player, @NotNull InteractionHand hand) { - //无限箭矢 var itemstack = player.getItemInHand(hand); InteractionResultHolder ret = net.minecraftforge.event.ForgeEventFactory.onArrowNock(itemstack, level, player, hand, true); if (ret != null) return ret; @@ -120,14 +119,14 @@ public void releaseUsing(@NotNull ItemStack stack, @NotNull Level level, @NotNul float VELOCITY_MULTIPLIER = 1.2F; float DAMAGE_MULTIPLIER = 5000.0F; - float draw = getPowerForTime(drawTime); + float draw = getPowerForTime(drawTime);//蓄力时间 float powerForTime = draw * VELOCITY_MULTIPLIER; - ItemStack ammoStack = player.getProjectile(stack).isEmpty() ? new ItemStack(Items.ARROW) : player.getProjectile(stack); + ItemStack ammoStack = player.getProjectile(stack).isEmpty() ? new ItemStack(Items.ARROW) : player.getProjectile(stack);//无限箭矢 AbstractArrow arrowEntity; - if (stack.getOrCreateTag().getBoolean("tracer")) { + if (stack.getOrCreateTag().getBoolean("tracer")) {//追踪模式 if ((double)powerForTime >= 0.1D) { ArrowItem arrowitem = (ammoStack.getItem() instanceof ArrowItem arrowItem ? arrowItem : (ArrowItem) Items.ARROW); arrowEntity = this.customTraceArrow(arrowitem.createArrow(level, ammoStack, player)); @@ -138,8 +137,9 @@ public void releaseUsing(@NotNull ItemStack stack, @NotNull Level level, @NotNul } arrowEntity.shootFromRotation(player, player.getXRot(), player.getYRot(), 0.0F, powerForTime * 3.0F, 0.01F); + if (draw == 1.0F) { - arrowEntity.setCritArrow(true); + arrowEntity.setCritArrow(true);//蓄力满必暴击 } arrowEntity.setBaseDamage(arrowEntity.getBaseDamage() * (double)DAMAGE_MULTIPLIER); @@ -153,7 +153,7 @@ public void releaseUsing(@NotNull ItemStack stack, @NotNull Level level, @NotNul arrowEntity.setPos(player.getX() - 0.3, player.getEyeY() - 0.1, player.getZ()); arrowEntity.shootFromRotation(player, player.getXRot(), player.getYRot(), 0.0F, powerForTime * 3.0F, 0.01F); if (draw == 1.0F) { - arrowEntity.setCritArrow(true); + arrowEntity.setCritArrow(true);//蓄力满必暴击 } addEnchant(stack, level, player, arrowEntity, powerForTime); } @@ -166,7 +166,7 @@ public void releaseUsing(@NotNull ItemStack stack, @NotNull Level level, @NotNul } private void addEnchant(@NotNull ItemStack stack, @NotNull Level level, @NotNull LivingEntity player, AbstractArrow arrowEntity, float powerForTime) { - int j = EnchantmentHelper.getTagEnchantmentLevel(Enchantments.POWER_ARROWS, stack); + int j = EnchantmentHelper.getTagEnchantmentLevel(Enchantments.POWER_ARROWS, stack);//力量箭矢 if (j > 0) { arrowEntity.setBaseDamage(arrowEntity.getBaseDamage() + (double)j * 0.5D + 0.5D); } @@ -176,12 +176,10 @@ private void addEnchant(@NotNull ItemStack stack, @NotNull Level level, @NotNull arrowEntity.setKnockback(k); } - if (EnchantmentHelper.getTagEnchantmentLevel(Enchantments.FLAMING_ARROWS, stack) > 0) { + if (EnchantmentHelper.getTagEnchantmentLevel(Enchantments.FLAMING_ARROWS, stack) > 0) {//火焰箭矢 arrowEntity.setSecondsOnFire(100); } - stack.hurtAndBreak(1, player, (p_289501_) -> { - p_289501_.broadcastBreakEvent(player.getUsedItemHand()); - }); + stack.hurtAndBreak(1, player, (livingEntity) -> livingEntity.broadcastBreakEvent(player.getUsedItemHand())); arrowEntity.pickup = AbstractArrow.Pickup.CREATIVE_ONLY; level.addFreshEntity(arrowEntity); } diff --git a/src/main/java/committee/nova/mods/avaritia/common/item/tools/InfinityCrossBowItem.java b/src/main/java/committee/nova/mods/avaritia/common/item/tools/InfinityCrossBowItem.java new file mode 100644 index 00000000..092f8963 --- /dev/null +++ b/src/main/java/committee/nova/mods/avaritia/common/item/tools/InfinityCrossBowItem.java @@ -0,0 +1,202 @@ +package committee.nova.mods.avaritia.common.item.tools; + +import committee.nova.mods.avaritia.common.entity.ImmortalItemEntity; +import committee.nova.mods.avaritia.common.entity.arrow.HeavenArrowEntity; +import committee.nova.mods.avaritia.common.entity.arrow.TraceArrowEntity; +import committee.nova.mods.avaritia.init.registry.ModEntities; +import committee.nova.mods.avaritia.init.registry.ModItems; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.stats.Stats; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.damagesource.DamageTypes; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.HumanoidArm; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.AbstractArrow; +import net.minecraft.world.entity.projectile.Arrow; +import net.minecraft.world.entity.projectile.SpectralArrow; +import net.minecraft.world.item.*; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.level.Level; +import net.minecraftforge.event.ForgeEventFactory; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Description: + * Author: cnlimiter + * Date: 2022/4/2 20:07 + * Version: 1.0 + */ +public class InfinityCrossBowItem extends CrossbowItem { + public InfinityCrossBowItem() { + super(new Properties() + .stacksTo(1) + .rarity(ModItems.COSMIC_RARITY) + .fireResistant() + ); + } + + @Override + public boolean isDamageable(ItemStack stack) { + return false; + } + + @Override + public boolean canBeHurtBy(@NotNull DamageSource source) { + return source.is(DamageTypes.FELL_OUT_OF_WORLD); + } + + @Override + public boolean hasCustomEntity(ItemStack stack) { + return true; + } + + @Override + public boolean onEntityItemUpdate(ItemStack stack, ItemEntity entity) { + if (entity.getAge() >= 0) { + entity.setExtendedLifetime(); + } + return super.onEntityItemUpdate(stack, entity); + } + + @Override + public boolean isEnchantable(@NotNull ItemStack pStack) { + return true; + } + @Override + public int getEnchantmentValue(ItemStack stack) { + return 99; + } + @Override + public int getUseDuration(@NotNull ItemStack stack) { + return 1200; + } + @Override + public @NotNull UseAnim getUseAnimation(@NotNull ItemStack pStack) { + return UseAnim.BOW; + } + + @Nullable + @Override + public Entity createEntity(Level level, Entity location, ItemStack stack) { + return ImmortalItemEntity.create(ModEntities.IMMORTAL.get(), level, location.getX(), location.getY(), location.getZ(), stack); + } + + @Override + public @NotNull InteractionResultHolder use(@NotNull Level level, Player player, @NotNull InteractionHand hand) { + var itemstack = player.getItemInHand(hand); + InteractionResultHolder ret = ForgeEventFactory.onArrowNock(itemstack, level, player, hand, true); + if (ret != null) return ret; + player.startUsingItem(hand); + return InteractionResultHolder.success(itemstack); + } + + @Override + public void releaseUsing(@NotNull ItemStack stack, @NotNull Level level, @NotNull LivingEntity entity, int timeLeft) { + if (entity instanceof Player player) { + int drawTime = this.getUseDuration(stack) - timeLeft; + drawTime = ForgeEventFactory.onArrowLoose(stack, level, player, drawTime, true); + if (drawTime < 0) { + return; + } + float VELOCITY_MULTIPLIER = 1.2F; + float DAMAGE_MULTIPLIER = 5000.0F; + float draw = getPowerForTime(drawTime, stack);//蓄力时间 + float powerForTime = draw * VELOCITY_MULTIPLIER; + if (!level.isClientSide) { + ItemStack ammoStack = player.getProjectile(stack).isEmpty() ? new ItemStack(Items.ARROW) : player.getProjectile(stack);//无限箭矢 + + AbstractArrow arrowEntity; + if (stack.getOrCreateTag().getBoolean("tracer")) {//追踪模式 + if ((double)powerForTime >= 0.1D) { + ArrowItem arrowitem = (ammoStack.getItem() instanceof ArrowItem arrowItem ? arrowItem : (ArrowItem) Items.ARROW); + arrowEntity = this.customTraceArrow(arrowitem.createArrow(level, ammoStack, player)); + if (arrowEntity instanceof Arrow arrow2) { + arrow2.setEffectsFromItem(ammoStack); + } else if (arrowEntity instanceof TraceArrowEntity infinityArrow) { + infinityArrow.setEffectsFromItem(ammoStack); + } + + arrowEntity.shootFromRotation(player, player.getXRot(), player.getYRot(), 0.0F, powerForTime * 3.0F, 0.01F); + + if (draw == 1.0F) { + arrowEntity.setCritArrow(true);//蓄力满必暴击 + } + + arrowEntity.setBaseDamage(arrowEntity.getBaseDamage() * (double)DAMAGE_MULTIPLIER); + addEnchant(stack, level, player, arrowEntity, powerForTime); + + } + + } + else { + arrowEntity = HeavenArrowEntity.create(level, player); + arrowEntity.setPos(player.getX() - 0.3, player.getEyeY() - 0.1, player.getZ()); + arrowEntity.shootFromRotation(player, player.getXRot(), player.getYRot(), 0.0F, powerForTime * 3.0F, 0.01F); + if (draw == 1.0F) { + arrowEntity.setCritArrow(true);//蓄力满必暴击 + } + addEnchant(stack, level, player, arrowEntity, powerForTime); + } + } + level.playSound(null, entity.getX(), player.getY(), player.getZ(), SoundEvents.ARROW_SHOOT, SoundSource.PLAYERS, 1.0F, 1.0F / (level.random.nextFloat() * 0.4F + 1.2F) + powerForTime * 0.5F); + player.awardStat(Stats.ITEM_USED.get(this)); + } + } + + private void addEnchant(@NotNull ItemStack stack, @NotNull Level level, @NotNull LivingEntity player, AbstractArrow arrowEntity, float powerForTime) { + int j = EnchantmentHelper.getTagEnchantmentLevel(Enchantments.POWER_ARROWS, stack); + if (j > 0) { + arrowEntity.setBaseDamage(arrowEntity.getBaseDamage() + (double)j * 0.5D + 0.5D); + } + + int k = EnchantmentHelper.getTagEnchantmentLevel(Enchantments.PUNCH_ARROWS, stack); + if (k > 0) { + arrowEntity.setKnockback(k); + } + + if (EnchantmentHelper.getTagEnchantmentLevel(Enchantments.FLAMING_ARROWS, stack) > 0) { + arrowEntity.setSecondsOnFire(100); + } + stack.hurtAndBreak(1, player, (livingEntity) -> livingEntity.broadcastBreakEvent(player.getUsedItemHand())); + arrowEntity.pickup = AbstractArrow.Pickup.CREATIVE_ONLY; + level.addFreshEntity(arrowEntity); + } + + public @NotNull AbstractArrow customTraceArrow(AbstractArrow arrow) { + if (arrow.getType() != EntityType.ARROW && arrow.getType() != EntityType.SPECTRAL_ARROW) { + return arrow; + } else { + Entity owner = arrow.getOwner(); + if (!(owner instanceof LivingEntity)) { + return new TraceArrowEntity(ModEntities.TRACE_ARROW.get(), arrow.level()); + } else { + TraceArrowEntity newArrow = new TraceArrowEntity(arrow.level(), (LivingEntity)arrow.getOwner()); + if (arrow instanceof SpectralArrow spectralArrow) { + newArrow.setSpectral(spectralArrow.duration); + } + return newArrow; + } + } + } + + private static float getPowerForTime(int pUseTime, ItemStack pCrossbowStack) { + float f = (float)pUseTime / (float)getChargeDuration(pCrossbowStack); + if (f > 1.0F) { + f = 1.0F; + } + + return f; + } + +} diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index ddf1693b..df305060 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -38,4 +38,6 @@ public net.minecraft.world.entity.projectile.Projectile f_37246_ # leftOwner public net.minecraft.world.entity.projectile.AbstractArrow m_36798_()Z # shouldFall public net.minecraft.core.NonNullList f_122773_ # list -public net.minecraft.core.NonNullList (Ljava/util/List;Ljava/lang/Object;)V # init \ No newline at end of file +public net.minecraft.core.NonNullList (Ljava/util/List;Ljava/lang/Object;)V # init + +public net.minecraft.world.item.CrossbowItem getPowerForTime(ILnet/minecraft/world/item/ItemStack;)F # getPowerForTime \ No newline at end of file