From f10221a2c0e5052aa74a21ebb35e8a4eed566f1a Mon Sep 17 00:00:00 2001 From: 3944Realms Date: Sat, 7 Dec 2024 13:33:39 +0800 Subject: [PATCH] =?UTF-8?q?2024/12/07=20=E5=AE=9E=E8=A3=85=E4=BA=86?= =?UTF-8?q?=E8=B4=B4=E8=B4=B4=E6=8B=B4=E7=BB=B3=E7=AE=AD=E7=9A=84=E5=86=85?= =?UTF-8?q?=E5=AE=B9=20=E6=95=B4=E7=90=86=E4=BA=86=E4=B8=8B=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=BB=93=E6=9E=84=20=E5=85=88=E6=8E=A8=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradle.properties | 2 +- .../leashedplayer/CommonEventHandler.java | 27 +--- .../config/LeashPlayerCommonConfig.java | 5 +- .../content/effects/ModEffectRegister.java | 5 +- .../content/effects/type/NoLeashEffect.java | 37 ++++++ .../content/entities/LeashRopeArrow.java | 29 ++-- .../content/entities/NestleRopeArrow.java | 124 +++++++++++++++++- .../jei/category/LeashedPlayerCategory.java | 1 + .../leashedplayer/mixin/both/MixinPlayer.java | 90 +------------ .../modInterface/PlayerLeashable.java | 69 ++++++++++ .../r3944realms/leashedplayer/utils/Util.java | 35 +++++ 11 files changed, 291 insertions(+), 133 deletions(-) create mode 100644 src/main/java/com/r3944realms/leashedplayer/content/effects/type/NoLeashEffect.java diff --git a/gradle.properties b/gradle.properties index 20812c5..93ac77b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -35,7 +35,7 @@ mod_name=Leashed Player # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=MIT # The mod version. See https://semver.org/ -mod_version=0.0.3.9.9.8 +mod_version=0.0.3.9.9.9 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. # See https://maven.apache.org/guides/mini/guide-naming-conventions.html diff --git a/src/main/java/com/r3944realms/leashedplayer/CommonEventHandler.java b/src/main/java/com/r3944realms/leashedplayer/CommonEventHandler.java index 6bc8779..3ded6f2 100644 --- a/src/main/java/com/r3944realms/leashedplayer/CommonEventHandler.java +++ b/src/main/java/com/r3944realms/leashedplayer/CommonEventHandler.java @@ -2,16 +2,13 @@ package com.r3944realms.leashedplayer; import com.mojang.brigadier.CommandDispatcher; import com.r3944realms.leashedplayer.content.commands.*; -import com.r3944realms.leashedplayer.content.effects.ModEffectRegister; import com.r3944realms.leashedplayer.content.effects.ModPotionRegister; -import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow; import com.r3944realms.leashedplayer.content.entities.LittlePlayer; import com.r3944realms.leashedplayer.content.entities.ModEntityRegister; import com.r3944realms.leashedplayer.content.gamerules.GameruleRegistry; import com.r3944realms.leashedplayer.content.gamerules.Server.OpenTOPNeededModeWhenScreenIsNotNull; import com.r3944realms.leashedplayer.content.items.ModItemRegister; import com.r3944realms.leashedplayer.content.misc.LeadBreakItemBehavior; -import com.r3944realms.leashedplayer.modInterface.PlayerLeashable; import com.r3944realms.leashedplayer.network.client.BooleanGameRuleValueChangeData; import com.r3944realms.leashedplayer.utils.Logger; import com.r3944realms.leashedplayer.utils.Util; @@ -22,11 +19,8 @@ import net.minecraft.core.component.DataComponents; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import net.minecraft.tags.ItemTags; -import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.Leashable; -import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.animal.Fox; import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.ItemStack; @@ -102,23 +96,6 @@ public class CommonEventHandler { if (level.isClientSide()) { return; } - if (entity instanceof LivingEntity living) { - MobEffectInstance effect = living.getEffect(ModEffectRegister.NO_LEASH_EFFECT); - if (effect != null && effect.getDuration() != 0) { - if (entity instanceof PlayerLeashable player) { - if (player.getLeashHolder() != null) { - if (player.getLeashHolder() instanceof LeashRopeArrow arrow) - arrow.setOwner(null); - player.dropLeash(true, !(player.getLeashHolder() instanceof LeashRopeArrow)); - } - } else if (entity instanceof Leashable leashable) { - if (leashable.getLeashHolder() != null) { - if (leashable.getLeashHolder() instanceof LeashRopeArrow arrow) - arrow.setOwner(null); - leashable.dropLeash(true, !(leashable.getLeashHolder() instanceof LeashRopeArrow)); - } - } - } if (entity instanceof Fox fox) { if (fox.getMainHandItem().is(ItemTags.ANVIL)) { fox.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY); @@ -175,6 +152,6 @@ public class CommonEventHandler { } - } - } + + diff --git a/src/main/java/com/r3944realms/leashedplayer/config/LeashPlayerCommonConfig.java b/src/main/java/com/r3944realms/leashedplayer/config/LeashPlayerCommonConfig.java index 0d9c0d6..b9d894a 100644 --- a/src/main/java/com/r3944realms/leashedplayer/config/LeashPlayerCommonConfig.java +++ b/src/main/java/com/r3944realms/leashedplayer/config/LeashPlayerCommonConfig.java @@ -7,7 +7,7 @@ public class LeashPlayerCommonConfig { public static final ModConfigSpec SPEC; public static final ModConfigSpec.ConfigValue LeashedPlayerModCommandPrefix; public static final ModConfigSpec.BooleanValue EnableLeashPlayerCommandPrefix; - public static ModConfigSpec.IntValue MinimumLeashLengthCanBeSet, MaximumLeashLengthCanBeSet, TheLeashArrowMaxLifeTime; + public static ModConfigSpec.IntValue MinimumLeashLengthCanBeSet, MaximumLeashLengthCanBeSet, TheLeashArrowMaxLifeTime, TheNestleArrowMaxLifeTime; public static ModConfigSpec.DoubleValue TheMultipleThatLeashRopeArrowBreakLength, TheLeashBreakLengthTimesBase; static { BUILDER.comment("Leash Player Config"); @@ -20,8 +20,9 @@ public class LeashPlayerCommonConfig { BUILDER.pop(); BUILDER.comment("Leash Player Arrow"); BUILDER.push("LeashRopeArrow"); - TheMultipleThatLeashRopeArrowBreakLength = BUILDER.comment("How many times is the length of the arrow rope based on BreakLength TimeBase", "[ Default : 5.0f, Invalid Range:[2.0f, 10.0f] ]").defineInRange("TheMultipleArrowBreak", 5.0f, 2.0f , 10.0f); + TheMultipleThatLeashRopeArrowBreakLength = BUILDER.comment("How many times is the length of the arrow rope based on BreakLength TimeBase", "[ Default : 5.0f, Invalid Range:[2.0f, 10.0f] ]").defineInRange("TheMultipleArrowBreak", 5.0f, 2.0f, 10.0f); TheLeashArrowMaxLifeTime = BUILDER.comment("If the LeashArrowEntity's life is bigger than this value ,it will be discarded", "[ Default : 2400, Invalid Range:[1200 , 10240]]").defineInRange("TheLeashArrowMaxLifeTime",2400, 1200, 10240); + TheNestleArrowMaxLifeTime = BUILDER.comment("If the NestleArrowEntity's life is bigger than this value ,it will be discarded\", \"[ Default : 2400, Invalid Range:[1200 , 10240]]").defineInRange("TheNestleArrowMaxLifeTime",2400, 1200, 10240); BUILDER.pop(); BUILDER.comment("Leash Player Misc"); BUILDER.push("Misc"); diff --git a/src/main/java/com/r3944realms/leashedplayer/content/effects/ModEffectRegister.java b/src/main/java/com/r3944realms/leashedplayer/content/effects/ModEffectRegister.java index c72ce79..b498e4a 100644 --- a/src/main/java/com/r3944realms/leashedplayer/content/effects/ModEffectRegister.java +++ b/src/main/java/com/r3944realms/leashedplayer/content/effects/ModEffectRegister.java @@ -1,6 +1,7 @@ package com.r3944realms.leashedplayer.content.effects; import com.r3944realms.leashedplayer.LeashedPlayer; +import com.r3944realms.leashedplayer.content.effects.type.NoLeashEffect; import net.minecraft.core.registries.Registries; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectCategory; @@ -12,9 +13,9 @@ import java.util.function.Supplier; public class ModEffectRegister { public static DeferredRegister MOB_EFFECT = DeferredRegister.create(Registries.MOB_EFFECT, LeashedPlayer.MOD_ID); - public static DeferredHolder NO_LEASH_EFFECT = register( + public static DeferredHolder NO_LEASH_EFFECT = register( "no_leash", - () -> new MobEffect(MobEffectCategory.NEUTRAL, 12063764) + () -> new NoLeashEffect(MobEffectCategory.NEUTRAL, 12063764) ); public static DeferredHolder register(String name, Supplier effect) { return MOB_EFFECT.register(name, effect); diff --git a/src/main/java/com/r3944realms/leashedplayer/content/effects/type/NoLeashEffect.java b/src/main/java/com/r3944realms/leashedplayer/content/effects/type/NoLeashEffect.java new file mode 100644 index 0000000..224aea3 --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/content/effects/type/NoLeashEffect.java @@ -0,0 +1,37 @@ +package com.r3944realms.leashedplayer.content.effects.type; + +import com.r3944realms.leashedplayer.content.effects.ModEffectRegister; +import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectCategory; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.entity.Leashable; +import net.minecraft.world.entity.LivingEntity; +import org.jetbrains.annotations.NotNull; + +public class NoLeashEffect extends MobEffect { + + public NoLeashEffect(MobEffectCategory pCategory, int pColor) { + super(pCategory, pColor); + } + + @Override + public boolean applyEffectTick(@NotNull LivingEntity pLivingEntity, int pAmplifier) { + MobEffectInstance effect = pLivingEntity.getEffect(ModEffectRegister.NO_LEASH_EFFECT); + if(effect != null && effect.getDuration() != 0) { + if (pLivingEntity instanceof Leashable leashable) { + if (leashable.getLeashHolder() instanceof LeashRopeArrow arrow) { + arrow.setOwner(null); + leashable.dropLeash(true, false); + } + leashable.dropLeash(true, true); + } + } + return true; + } + + @Override + public boolean shouldApplyEffectTickThisTick(int pDuration, int pAmplifier) { + return true; + } +} diff --git a/src/main/java/com/r3944realms/leashedplayer/content/entities/LeashRopeArrow.java b/src/main/java/com/r3944realms/leashedplayer/content/entities/LeashRopeArrow.java index 04a76cc..fa45f07 100644 --- a/src/main/java/com/r3944realms/leashedplayer/content/entities/LeashRopeArrow.java +++ b/src/main/java/com/r3944realms/leashedplayer/content/entities/LeashRopeArrow.java @@ -84,7 +84,7 @@ public class LeashRopeArrow extends AbstractArrow { if(serverPlayer != null && !level().isClientSide) { Entity leashDataEntity = PlayerLeashable.getLeashDataEntity(serverPlayer, (ServerLevel) level()); if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { - leashRopeArrow.setOwner(null); + leashRopeArrow.setOwner(null);//将先前的箭矢置空 } ((PlayerLeashable)serverPlayer).setLeashedTo(this, true); } @@ -93,7 +93,7 @@ public class LeashRopeArrow extends AbstractArrow { public LeashRopeArrow(EntityType entityType, LivingEntity pOwner, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon) { super(entityType, pOwner, pLevel, pPickupItemStack, pFiredFromWeapon); this.updateColor(); - if(pOwner instanceof PlayerLeashable lPlayer && !level().isClientSide) { + if (pOwner instanceof PlayerLeashable lPlayer && !level().isClientSide) { Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) lPlayer, (ServerLevel) level()); if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { leashRopeArrow.setOwner(null); @@ -225,7 +225,6 @@ public class LeashRopeArrow extends AbstractArrow { pLiving.addEffect(effectInstance, entity); } } - //NOOP } protected ItemStack getOrginalItemStack() { return Items.ARROW.getDefaultInstance(); @@ -330,12 +329,12 @@ public class LeashRopeArrow extends AbstractArrow { @Override protected void onHitEntity(@NotNull EntityHitResult pResult) { - if(!level().isClientSide()){ + if (!level().isClientSide()) { Entity entity = pResult.getEntity(); hitOnEntityHandler(entity); - if(this.getOwner() instanceof LivingEntity livingEntity ) { + if (this.getOwner() instanceof LivingEntity livingEntity ) { MobEffectInstance effect = livingEntity.getEffect(ModEffectRegister.NO_LEASH_EFFECT); - if(effect != null && effect.getDuration() != 0) { + if (effect != null && effect.getDuration() != 0) { livingEntity.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1); this.setOwner(null); } @@ -356,12 +355,11 @@ public class LeashRopeArrow extends AbstractArrow { pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID)); livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1); pL.setLeashedTo(this, true); - return; } else if (this.getOwner() instanceof PlayerLeashable pL) { Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level()); if(leashDataEntity != null) { pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow)); - if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { + if (leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { leashRopeArrow.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1); leashRopeArrow.setOwner(null); } @@ -374,12 +372,12 @@ public class LeashRopeArrow extends AbstractArrow { this.level().addFreshEntity(arrow); discard(); } else { - if(entity instanceof Leashable leashable) { + if (entity instanceof Leashable leashable) { if (getOwner() == null) { Entity leashDataEntity = leashable.getLeashHolder(); if (leashDataEntity != null) { leashable.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow)); - if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { + if (leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { leashRopeArrow.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1); leashRopeArrow.setOwner(null); } @@ -390,8 +388,8 @@ public class LeashRopeArrow extends AbstractArrow { return; } } - if(entity instanceof LivingEntity living) { - if(this.getOwner() != null && this.getOwner()instanceof Leashable leashable) { + if (entity instanceof LivingEntity living) { + if (this.getOwner() != null && this.getOwner()instanceof Leashable leashable) { livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1); leashable.setLeashedTo(living, true); ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack()); @@ -407,9 +405,9 @@ public class LeashRopeArrow extends AbstractArrow { else if (entity instanceof LeashFenceKnotEntity leashKnotFence) { if (getOwner() instanceof PlayerLeashable pL) { Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level()); - if(leashDataEntity != null) { + if (leashDataEntity != null) { pL.dropLeash(true, true); - if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { + if (leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { leashRopeArrow.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1); leashRopeArrow.setOwner(null); } @@ -421,14 +419,13 @@ public class LeashRopeArrow extends AbstractArrow { pL.setLeashedTo(leashKnotFence, true); this.level().addFreshEntity(arrow); discard(); - return; } } else { ItemEntity lead = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, Items.LEAD.getDefaultInstance()); this.level().addFreshEntity(lead); } } - if(!level().isClientSide()) super.onHitEntity(pResult); + else super.onHitEntity(pResult); } /** * Handles an entity event received from a {@link net.minecraft.network.protocol.game.ClientboundEntityEventPacket}. diff --git a/src/main/java/com/r3944realms/leashedplayer/content/entities/NestleRopeArrow.java b/src/main/java/com/r3944realms/leashedplayer/content/entities/NestleRopeArrow.java index 5631d68..3e38306 100644 --- a/src/main/java/com/r3944realms/leashedplayer/content/entities/NestleRopeArrow.java +++ b/src/main/java/com/r3944realms/leashedplayer/content/entities/NestleRopeArrow.java @@ -1,29 +1,151 @@ package com.r3944realms.leashedplayer.content.entities; +import com.r3944realms.leashedplayer.config.LeashPlayerCommonConfig; import com.r3944realms.leashedplayer.content.items.ModItemRegister; +import io.github.kunosayo.nestle.entity.NestleLeadNormalEntity; +import io.github.kunosayo.nestle.entity.NestleLeadPlayerEntity; +import io.github.kunosayo.nestle.entity.data.NestleLeadData; +import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.MobSpawnType; +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.item.ItemStack; +import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; +import net.minecraft.world.phys.EntityHitResult; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class NestleRopeArrow extends AbstractArrow { - public NestleRopeArrow(EntityType pEntityType, Level pLevel) { + private static final int maxLifeTime = LeashPlayerCommonConfig.TheNestleArrowMaxLifeTime.get(); + protected NestleRopeArrow(EntityType pEntityType, Level pLevel) { super(pEntityType, pLevel); } public NestleRopeArrow(EntityType entityType, double pX, double pY, double pZ, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon, @Nullable ServerPlayer serverPlayer) { super(entityType, pX, pY, pZ, pLevel, pPickupItemStack, pFiredFromWeapon); + if (serverPlayer != null && !level().isClientSide) { + if(serverPlayer.getVehicle() instanceof NestleRopeArrow nestleRopeArrow) { + nestleRopeArrow.removePassenger(serverPlayer);//重置先前的箭矢 + nestleRopeArrow.setOwner(null); + } + serverPlayer.startRiding(this); + this.setOwner(serverPlayer); + } } public NestleRopeArrow(EntityType entityType, LivingEntity pOwner, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon) { super(entityType, pOwner, pLevel, pPickupItemStack, pFiredFromWeapon); + if (!level().isClientSide) { + if(pOwner.getVehicle() instanceof NestleRopeArrow nestleRopeArrow) { + nestleRopeArrow.removePassenger(pOwner);//重置先前的箭矢 + nestleRopeArrow.setOwner(null); + } + pOwner.startRiding(this); + this.setOwner(pOwner); + } } @Override protected @NotNull ItemStack getDefaultPickupItem() { return ModItemRegister.NESTLE_ROPE_ARROW.get().getDefaultInstance(); } + protected ItemStack getOrginalItemStack() { + return Items.ARROW.getDefaultInstance(); + } + protected ItemStack getSelfItemStack() { + return ModItemRegister.NESTLE_ROPE_ARROW.get().getDefaultInstance(); + } + protected void hitOnEntityHandler(Entity pEntity) { + //NOOP + } + @Override + public void setOwner(@Nullable Entity pEntity) { + boolean isNull = pEntity == null; + this.ownerUUID = isNull ? null : pEntity.getUUID(); + this.cachedOwner = isNull ? null : pEntity; + this.pickup = this.pickup == Pickup.CREATIVE_ONLY ? this.pickup : Pickup.DISALLOWED; + } + + @Override + protected void tickDespawn() { + this.life++; + if (this.life >= maxLifeTime) { + ItemEntity nestle_arrow_item = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getSelfItemStack()); + this.level().addFreshEntity(nestle_arrow_item); + this.discard(); + } + } + + @Override + protected boolean tryPickup(@NotNull Player pPlayer) { + if (life <= 40) + return false; + else { + this.pickup = Pickup.ALLOWED; + } + return super.tryPickup(pPlayer); + } + + @Override + public void tick() { + super.tick(); + Entity owner = getOwner(); + if(owner != null && !owner.level().isClientSide) { + if (!inGround) { + if (owner.getVehicle() == null) owner.startRiding(this); + } + else { + owner.stopRiding(); + setOwner(null); + } + } + } + + @Override + protected void onHitEntity(@NotNull EntityHitResult pResult) { + if(!level().isClientSide) { + Entity entity = pResult.getEntity(); + hitOnEntityHandler(entity); + Entity owner = this.getOwner(); + if (owner == null && entity instanceof Player player) { + this.setOwner(player); + } + else if (owner != null && entity != owner ) { + if(entity instanceof LivingEntity livingEntity) { + ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack()); + if (livingEntity instanceof Player player) { + if (NestleLeadData.isNestle(player, livingEntity)) { + arrow.setItem(getSelfItemStack()); + } else { + NestleLeadData.nestleTwo((Player) owner, player); + NestleLeadPlayerEntity.inParamFrom = player.getUUID(); + NestleLeadPlayerEntity.inParamTarget = entity.getUUID(); + NestleLeadPlayerEntity.ENTITY_TYPE.spawn((ServerLevel)player.level(), player.getBlockPosBelowThatAffectsMyMovement(), MobSpawnType.EVENT); + } + } else { + Player player = (Player) owner; + if (NestleLeadData.isNestle(player, livingEntity)) { + arrow.setItem(getSelfItemStack()); + } else { + NestleLeadData.nestleTwo(player, livingEntity); + NestleLeadNormalEntity.inParamFrom = player; + NestleLeadNormalEntity.inParamTarget = livingEntity; + NestleLeadNormalEntity.ENTITY_TYPE.spawn((ServerLevel)player.level(), player.getBlockPosBelowThatAffectsMyMovement(), MobSpawnType.EVENT); + NestleLeadNormalEntity.inParamFrom = null; + NestleLeadNormalEntity.inParamTarget = null; + } + + } + this.level().addFreshEntity(arrow); + discard(); + } + } + } + else super.onHitEntity(pResult); + } } diff --git a/src/main/java/com/r3944realms/leashedplayer/integration/jei/category/LeashedPlayerCategory.java b/src/main/java/com/r3944realms/leashedplayer/integration/jei/category/LeashedPlayerCategory.java index d180318..eacbd75 100644 --- a/src/main/java/com/r3944realms/leashedplayer/integration/jei/category/LeashedPlayerCategory.java +++ b/src/main/java/com/r3944realms/leashedplayer/integration/jei/category/LeashedPlayerCategory.java @@ -1,4 +1,5 @@ package com.r3944realms.leashedplayer.integration.jei.category; public class LeashedPlayerCategory { + } diff --git a/src/main/java/com/r3944realms/leashedplayer/mixin/both/MixinPlayer.java b/src/main/java/com/r3944realms/leashedplayer/mixin/both/MixinPlayer.java index f3a758f..fa7e72b 100644 --- a/src/main/java/com/r3944realms/leashedplayer/mixin/both/MixinPlayer.java +++ b/src/main/java/com/r3944realms/leashedplayer/mixin/both/MixinPlayer.java @@ -2,7 +2,6 @@ package com.r3944realms.leashedplayer.mixin.both; import com.r3944realms.leashedplayer.LeashedPlayer; import com.r3944realms.leashedplayer.content.commands.LeashCommand; -import com.r3944realms.leashedplayer.content.effects.ModEffectRegister; import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow; import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension; import com.r3944realms.leashedplayer.modInterface.PlayerLeashable; @@ -12,7 +11,6 @@ import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Leashable; @@ -21,7 +19,6 @@ import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.decoration.LeashFenceKnotEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; -import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @@ -30,10 +27,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import javax.annotation.Nullable; import java.util.Objects; -import java.util.function.Consumer; @Mixin(Player.class) -public abstract class MixinPlayer extends LivingEntity implements PlayerLeashable, ILivingEntityExtension { +public abstract class MixinPlayer extends LivingEntity implements PlayerLeashable, ILivingEntityExtension { @Unique protected int Pl$LeashKeepTick;//保存状态,当超过断裂绳长时若LeashKeepTick大于0,则不断裂 @@ -106,87 +102,15 @@ public abstract class return; } - float leashLength = LeashCommand.MIN_VALUE; - if (restrainedEntity instanceof ILivingEntityExtension iEntity) { - // 获取绳长 - float leashLengthFormValue = iEntity.getLeashLength(); - leashLength = leashLengthFormValue > LeashCommand.MIN_VALUE ? leashLengthFormValue : LeashCommand.MIN_VALUE; - } - - // 两者距离 - float distance = holderEntity.distanceTo(restrainedEntity); - Entity applyMovementEntity = restrainedEntity.isPassenger() ? restrainedEntity.getVehicle() : restrainedEntity; - - // 仅当距离大于绳长时施加拉力 - if (applyMovementEntity != null && distance > leashLength) { - // 计算朝向持有者的拉力方向 - double dX = (holderEntity.getX() - applyMovementEntity.getX()) / (double) distance; - double dY = (holderEntity.getY() - applyMovementEntity.getY()) / (double) distance; - double dZ = (holderEntity.getZ() - applyMovementEntity.getZ()) / (double) distance; - - // 拉力大小,距离越远拉力越强,但施加一个最大限制 - double pullStrength = Math.min((distance - leashLength) * 0.1, 1.0); // 限制最大拉力 - applyMovementEntity.setDeltaMovement( - applyMovementEntity.getDeltaMovement().add( - dX * pullStrength, - dY * pullStrength, - dZ * pullStrength - ) - ); - - // 控制速度不要过快,避免偏激移动 - Whimsy$Brake(applyMovementEntity, entity -> { - Vec3 deltaMovement = entity.getDeltaMovement(); - entity.setDeltaMovement( - Math.min(Math.abs(deltaMovement.x), 1.0) * Math.signum(deltaMovement.x), - Math.min(Math.abs(deltaMovement.y), 1.0) * Math.signum(deltaMovement.y), - Math.min(Math.abs(deltaMovement.z), 1.0) * Math.signum(deltaMovement.z) - ); - entity.hurtMarked = true; - }); - } + PlayerLeashable.legacyElasticRangeLeashBehaviour(holderEntity, restrainedEntity); // 降低坠落伤害 restrainedEntity.checkSlowFallDistance(); } - /** - * 刹车( - * @param pEntity 刹车的实体 - * @param pMaxX X方向的最大动量 - * @param pMaxY Y方向的最大动量 - * @param pMaxZ Z方向的最大动量 - */ - @Unique - private static void Whimsy$Brake(Entity pEntity, double pMaxX, double pMaxY, double pMaxZ) { - Vec3 deltaMovement = pEntity.getDeltaMovement(); - double dX = Math.abs(deltaMovement.x) > pMaxX ? 0 : deltaMovement.x; - double dY = Math.abs(deltaMovement.y) > pMaxY ? 0 : deltaMovement.y; - double dZ = Math.abs(deltaMovement.z) > pMaxZ ? 0 : deltaMovement.z; - pEntity.setDeltaMovement(dX, dY,dZ); - pEntity.hurtMarked = true; - } - /** - * 刹车( - * @param pEntity 刹车的实体 - * @param pOpt 自定义规则 - */ - @Unique - private static void Whimsy$Brake(Entity pEntity, @Nullable Consumer pOpt) { - Consumer consumer = pOpt; - if(pOpt == null) { - consumer = entity -> { - Vec3 deltaMovement = entity.getDeltaMovement(); - double dX = Math.abs(deltaMovement.x) > 1 ? 0 : deltaMovement.x; - double dY = Math.abs(deltaMovement.y) > 1 ? 0 : deltaMovement.y; - double dZ = Math.abs(deltaMovement.z) > 1 ? 0 : deltaMovement.z; - entity.setDeltaMovement(dX, dY,dZ); - entity.hurtMarked = true; - }; - } - consumer.accept(pEntity); - } + + @Unique protected void Pl$tickLeash() { if(this.Pl$LeashData == null) return;//没有Data直接退出 @@ -203,12 +127,6 @@ public abstract class ILivingEntityExtension iEntityExtension = this;//获取设定值 float leashLengthSelf = iEntityExtension.getLeashLength(); leashLength = leashLengthSelf > LeashCommand.MIN_VALUE ? leashLengthSelf : LeashCommand.MIN_VALUE; - MobEffectInstance effect = this.getEffect(ModEffectRegister.NO_LEASH_EFFECT); - if(effect != null && effect.getDuration() != 0) { - if (entity instanceof LeashRopeArrow arrow) - arrow.setOwner(null); - this.dropLeash(true, !(entity instanceof LeashRopeArrow)); - } if (entity != null) { double breakDistanceTime = (entity instanceof LeashRopeArrow) ? LeashedPlayer.M1() * LeashedPlayer.M2() : LeashedPlayer.M1(); if(!isAlive() || !entity.isAlive() ||( distanceTo(entity) > Math.max(leashLength * breakDistanceTime, LeashCommand.MIN_VALUE * breakDistanceTime) && keepLeashTick == 0)){ diff --git a/src/main/java/com/r3944realms/leashedplayer/modInterface/PlayerLeashable.java b/src/main/java/com/r3944realms/leashedplayer/modInterface/PlayerLeashable.java index efdcad4..bba3d67 100644 --- a/src/main/java/com/r3944realms/leashedplayer/modInterface/PlayerLeashable.java +++ b/src/main/java/com/r3944realms/leashedplayer/modInterface/PlayerLeashable.java @@ -1,6 +1,8 @@ package com.r3944realms.leashedplayer.modInterface; +import com.r3944realms.leashedplayer.content.commands.LeashCommand; import com.r3944realms.leashedplayer.content.criteriaTriggers.ModCriteriaTriggers; +import com.r3944realms.leashedplayer.utils.Util; import net.minecraft.core.BlockPos; import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket; import net.minecraft.server.level.ServerLevel; @@ -10,6 +12,7 @@ import net.minecraft.world.entity.Leashable; import net.minecraft.world.entity.decoration.LeashFenceKnotEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; @@ -61,6 +64,72 @@ public interface PlayerLeashable extends Leashable { //这边覆写去掉了乘坐相关的逻辑,即乘坐状态下也可以正常被栓住,不影响其乘坐状态 } + static void legacyElasticRangeLeashBehaviour(Entity holderEntity, Entity restrainedEntity) { + float leashLength = LeashCommand.MIN_VALUE; + if (restrainedEntity instanceof ILivingEntityExtension iEntity) { + // 获取绳长 + float leashLengthFormValue = iEntity.getLeashLength(); + leashLength = leashLengthFormValue > LeashCommand.MIN_VALUE ? leashLengthFormValue : LeashCommand.MIN_VALUE; + } + + // 两者距离 + float distance = holderEntity.distanceTo(restrainedEntity); + Entity applyMovementEntity = restrainedEntity.isPassenger() ? restrainedEntity.getVehicle() : restrainedEntity; + // 仅当距离大于绳长时施加拉力 + if (applyMovementEntity != null && distance > leashLength) { + MethodA(holderEntity, applyMovementEntity, distance, leashLength); + // 控制速度不要过快,避免偏激移动 + Util.MovementBrake(applyMovementEntity, entity -> { + Vec3 deltaMovement = entity.getDeltaMovement(); + entity.setDeltaMovement( + Math.min(Math.abs(deltaMovement.x), 1.0) * Math.signum(deltaMovement.x), + Math.min(Math.abs(deltaMovement.y), 1.0) * Math.signum(deltaMovement.y), + Math.min(Math.abs(deltaMovement.z), 1.0) * Math.signum(deltaMovement.z) + ); + entity.hurtMarked = true; + }); + } + } + private static void MethodA(Entity holderEntity, Entity applyMovementEntity, float distance, float leashLength) { + // 计算朝向持有者的拉力方向 + double dX = (holderEntity.getX() - applyMovementEntity.getX()) / (double) distance; + double dY = (holderEntity.getY() - applyMovementEntity.getY()) / (double) distance; + double dZ = (holderEntity.getZ() - applyMovementEntity.getZ()) / (double) distance; + + // 拉力大小,距离越远拉力越强,但施加一个最大限制 + double pullStrength = Math.min((distance - leashLength) * 0.1, 1.0); // 限制最大拉力 + applyMovementEntity.setDeltaMovement( + applyMovementEntity.getDeltaMovement().add( + dX * pullStrength, + dY * pullStrength, + dZ * pullStrength + ) + ); + } + private static void MethodB(Entity holderEntity, Entity applyMovementEntity, float distance, float leashLength) { + // 计算朝向持有者的拉力方向 + double dX = (holderEntity.getX() - applyMovementEntity.getX()) / (double) distance; + double dZ = (holderEntity.getZ() - applyMovementEntity.getZ()) / (double) distance; + + // 稳定点的目标高度 + double targetY = holderEntity.getY() + 1.0; // 根据需要调整目标高度 + double currentY = applyMovementEntity.getY(); + double heightDifference = targetY - currentY; + + // 控制垂直方向的拉力 + double dY = heightDifference > 0.5 ? 0.1 : (heightDifference < -0.5 ? -0.1 : 0); + + // 拉力大小,距离越远拉力越强,但施加一个最大限制 + double pullStrength = Math.min((distance - leashLength) * 0.1, 1.0); // 限制最大拉力 + applyMovementEntity.setDeltaMovement( + applyMovementEntity.getDeltaMovement().add( + dX * pullStrength, + dY, + dZ * pullStrength + ) + ); + } + @Nullable static Entity getLeashDataEntity(@NotNull ServerPlayer serverPlayer , @NotNull ServerLevel serverLevel) { LeashData leashDataFromEntityData = ((PlayerLeashable) serverPlayer).getLeashDataFromEntityData(); diff --git a/src/main/java/com/r3944realms/leashedplayer/utils/Util.java b/src/main/java/com/r3944realms/leashedplayer/utils/Util.java index c23e070..7119d4d 100644 --- a/src/main/java/com/r3944realms/leashedplayer/utils/Util.java +++ b/src/main/java/com/r3944realms/leashedplayer/utils/Util.java @@ -16,6 +16,7 @@ import java.io.File; import java.util.ArrayList; import java.util.Comparator; import java.util.List; +import java.util.function.Consumer; import java.util.function.Function; import static com.r3944realms.leashedplayer.utils.Logger.logger; @@ -98,4 +99,38 @@ public class Util { } else return null; } + /** + * 刹车( + * @param pEntity 刹车的实体 + * @param pMaxX X方向的最大动量 + * @param pMaxY Y方向的最大动量 + * @param pMaxZ Z方向的最大动量 + */ + public static void MovementBrake(Entity pEntity, double pMaxX, double pMaxY, double pMaxZ) { + Vec3 deltaMovement = pEntity.getDeltaMovement(); + double dX = Math.abs(deltaMovement.x) > pMaxX ? 0 : deltaMovement.x; + double dY = Math.abs(deltaMovement.y) > pMaxY ? 0 : deltaMovement.y; + double dZ = Math.abs(deltaMovement.z) > pMaxZ ? 0 : deltaMovement.z; + pEntity.setDeltaMovement(dX, dY,dZ); + pEntity.hurtMarked = true; + } + /** + * 刹车( + * @param pEntity 刹车的实体 + * @param pOpt 自定义规则 + */ + public static void MovementBrake(Entity pEntity, @javax.annotation.Nullable Consumer pOpt) { + Consumer consumer = pOpt; + if(pOpt == null) { + consumer = entity -> { + Vec3 deltaMovement = entity.getDeltaMovement(); + double dX = Math.abs(deltaMovement.x) > 1 ? 0 : deltaMovement.x; + double dY = Math.abs(deltaMovement.y) > 1 ? 0 : deltaMovement.y; + double dZ = Math.abs(deltaMovement.z) > 1 ? 0 : deltaMovement.z; + entity.setDeltaMovement(dX, dY,dZ); + entity.hurtMarked = true; + }; + } + consumer.accept(pEntity); + } }