2024/12/07
实装了贴贴拴绳箭的内容 整理了下代码结构 先推测试
This commit is contained in:
parent
e615fc6f09
commit
f10221a2c0
|
|
@ -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.
|
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
|
||||||
mod_license=MIT
|
mod_license=MIT
|
||||||
# The mod version. See https://semver.org/
|
# 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.
|
# 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.
|
# This should match the base package used for the mod sources.
|
||||||
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,13 @@ package com.r3944realms.leashedplayer;
|
||||||
|
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
import com.r3944realms.leashedplayer.content.commands.*;
|
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.effects.ModPotionRegister;
|
||||||
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
|
||||||
import com.r3944realms.leashedplayer.content.entities.LittlePlayer;
|
import com.r3944realms.leashedplayer.content.entities.LittlePlayer;
|
||||||
import com.r3944realms.leashedplayer.content.entities.ModEntityRegister;
|
import com.r3944realms.leashedplayer.content.entities.ModEntityRegister;
|
||||||
import com.r3944realms.leashedplayer.content.gamerules.GameruleRegistry;
|
import com.r3944realms.leashedplayer.content.gamerules.GameruleRegistry;
|
||||||
import com.r3944realms.leashedplayer.content.gamerules.Server.OpenTOPNeededModeWhenScreenIsNotNull;
|
import com.r3944realms.leashedplayer.content.gamerules.Server.OpenTOPNeededModeWhenScreenIsNotNull;
|
||||||
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
||||||
import com.r3944realms.leashedplayer.content.misc.LeadBreakItemBehavior;
|
import com.r3944realms.leashedplayer.content.misc.LeadBreakItemBehavior;
|
||||||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
|
||||||
import com.r3944realms.leashedplayer.network.client.BooleanGameRuleValueChangeData;
|
import com.r3944realms.leashedplayer.network.client.BooleanGameRuleValueChangeData;
|
||||||
import com.r3944realms.leashedplayer.utils.Logger;
|
import com.r3944realms.leashedplayer.utils.Logger;
|
||||||
import com.r3944realms.leashedplayer.utils.Util;
|
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.network.chat.Component;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.tags.ItemTags;
|
import net.minecraft.tags.ItemTags;
|
||||||
import net.minecraft.world.effect.MobEffectInstance;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.EquipmentSlot;
|
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.entity.animal.Fox;
|
||||||
import net.minecraft.world.item.CreativeModeTab;
|
import net.minecraft.world.item.CreativeModeTab;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
|
@ -102,23 +96,6 @@ public class CommonEventHandler {
|
||||||
if (level.isClientSide()) {
|
if (level.isClientSide()) {
|
||||||
return;
|
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 (entity instanceof Fox fox) {
|
||||||
if (fox.getMainHandItem().is(ItemTags.ANVIL)) {
|
if (fox.getMainHandItem().is(ItemTags.ANVIL)) {
|
||||||
fox.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY);
|
fox.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY);
|
||||||
|
|
@ -175,6 +152,6 @@ public class CommonEventHandler {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ public class LeashPlayerCommonConfig {
|
||||||
public static final ModConfigSpec SPEC;
|
public static final ModConfigSpec SPEC;
|
||||||
public static final ModConfigSpec.ConfigValue<String> LeashedPlayerModCommandPrefix;
|
public static final ModConfigSpec.ConfigValue<String> LeashedPlayerModCommandPrefix;
|
||||||
public static final ModConfigSpec.BooleanValue EnableLeashPlayerCommandPrefix;
|
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;
|
public static ModConfigSpec.DoubleValue TheMultipleThatLeashRopeArrowBreakLength, TheLeashBreakLengthTimesBase;
|
||||||
static {
|
static {
|
||||||
BUILDER.comment("Leash Player Config");
|
BUILDER.comment("Leash Player Config");
|
||||||
|
|
@ -20,8 +20,9 @@ public class LeashPlayerCommonConfig {
|
||||||
BUILDER.pop();
|
BUILDER.pop();
|
||||||
BUILDER.comment("Leash Player Arrow");
|
BUILDER.comment("Leash Player Arrow");
|
||||||
BUILDER.push("LeashRopeArrow");
|
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);
|
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.pop();
|
||||||
BUILDER.comment("Leash Player Misc");
|
BUILDER.comment("Leash Player Misc");
|
||||||
BUILDER.push("Misc");
|
BUILDER.push("Misc");
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.r3944realms.leashedplayer.content.effects;
|
package com.r3944realms.leashedplayer.content.effects;
|
||||||
|
|
||||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||||
|
import com.r3944realms.leashedplayer.content.effects.type.NoLeashEffect;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.world.effect.MobEffect;
|
import net.minecraft.world.effect.MobEffect;
|
||||||
import net.minecraft.world.effect.MobEffectCategory;
|
import net.minecraft.world.effect.MobEffectCategory;
|
||||||
|
|
@ -12,9 +13,9 @@ import java.util.function.Supplier;
|
||||||
|
|
||||||
public class ModEffectRegister {
|
public class ModEffectRegister {
|
||||||
public static DeferredRegister<MobEffect> MOB_EFFECT = DeferredRegister.create(Registries.MOB_EFFECT, LeashedPlayer.MOD_ID);
|
public static DeferredRegister<MobEffect> MOB_EFFECT = DeferredRegister.create(Registries.MOB_EFFECT, LeashedPlayer.MOD_ID);
|
||||||
public static DeferredHolder<MobEffect, ? extends MobEffect> NO_LEASH_EFFECT = register(
|
public static DeferredHolder<MobEffect, NoLeashEffect> NO_LEASH_EFFECT = register(
|
||||||
"no_leash",
|
"no_leash",
|
||||||
() -> new MobEffect(MobEffectCategory.NEUTRAL, 12063764)
|
() -> new NoLeashEffect(MobEffectCategory.NEUTRAL, 12063764)
|
||||||
);
|
);
|
||||||
public static <T extends MobEffect>DeferredHolder<MobEffect, T> register(String name, Supplier<T> effect) {
|
public static <T extends MobEffect>DeferredHolder<MobEffect, T> register(String name, Supplier<T> effect) {
|
||||||
return MOB_EFFECT.register(name, effect);
|
return MOB_EFFECT.register(name, effect);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -84,7 +84,7 @@ public class LeashRopeArrow extends AbstractArrow {
|
||||||
if(serverPlayer != null && !level().isClientSide) {
|
if(serverPlayer != null && !level().isClientSide) {
|
||||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity(serverPlayer, (ServerLevel) level());
|
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity(serverPlayer, (ServerLevel) level());
|
||||||
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
||||||
leashRopeArrow.setOwner(null);
|
leashRopeArrow.setOwner(null);//将先前的箭矢置空
|
||||||
}
|
}
|
||||||
((PlayerLeashable)serverPlayer).setLeashedTo(this, true);
|
((PlayerLeashable)serverPlayer).setLeashedTo(this, true);
|
||||||
}
|
}
|
||||||
|
|
@ -93,7 +93,7 @@ public class LeashRopeArrow extends AbstractArrow {
|
||||||
public LeashRopeArrow(EntityType<? extends AbstractArrow> entityType, LivingEntity pOwner, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon) {
|
public LeashRopeArrow(EntityType<? extends AbstractArrow> entityType, LivingEntity pOwner, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon) {
|
||||||
super(entityType, pOwner, pLevel, pPickupItemStack, pFiredFromWeapon);
|
super(entityType, pOwner, pLevel, pPickupItemStack, pFiredFromWeapon);
|
||||||
this.updateColor();
|
this.updateColor();
|
||||||
if(pOwner instanceof PlayerLeashable lPlayer && !level().isClientSide) {
|
if (pOwner instanceof PlayerLeashable lPlayer && !level().isClientSide) {
|
||||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) lPlayer, (ServerLevel) level());
|
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) lPlayer, (ServerLevel) level());
|
||||||
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
||||||
leashRopeArrow.setOwner(null);
|
leashRopeArrow.setOwner(null);
|
||||||
|
|
@ -225,7 +225,6 @@ public class LeashRopeArrow extends AbstractArrow {
|
||||||
pLiving.addEffect(effectInstance, entity);
|
pLiving.addEffect(effectInstance, entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//NOOP
|
|
||||||
}
|
}
|
||||||
protected ItemStack getOrginalItemStack() {
|
protected ItemStack getOrginalItemStack() {
|
||||||
return Items.ARROW.getDefaultInstance();
|
return Items.ARROW.getDefaultInstance();
|
||||||
|
|
@ -330,12 +329,12 @@ public class LeashRopeArrow extends AbstractArrow {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onHitEntity(@NotNull EntityHitResult pResult) {
|
protected void onHitEntity(@NotNull EntityHitResult pResult) {
|
||||||
if(!level().isClientSide()){
|
if (!level().isClientSide()) {
|
||||||
Entity entity = pResult.getEntity();
|
Entity entity = pResult.getEntity();
|
||||||
hitOnEntityHandler(entity);
|
hitOnEntityHandler(entity);
|
||||||
if(this.getOwner() instanceof LivingEntity livingEntity ) {
|
if (this.getOwner() instanceof LivingEntity livingEntity ) {
|
||||||
MobEffectInstance effect = livingEntity.getEffect(ModEffectRegister.NO_LEASH_EFFECT);
|
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);
|
livingEntity.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1);
|
||||||
this.setOwner(null);
|
this.setOwner(null);
|
||||||
}
|
}
|
||||||
|
|
@ -356,12 +355,11 @@ public class LeashRopeArrow extends AbstractArrow {
|
||||||
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
|
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
|
||||||
livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||||
pL.setLeashedTo(this, true);
|
pL.setLeashedTo(this, true);
|
||||||
return;
|
|
||||||
} else if (this.getOwner() instanceof PlayerLeashable pL) {
|
} else if (this.getOwner() instanceof PlayerLeashable pL) {
|
||||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
|
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
|
||||||
if(leashDataEntity != null) {
|
if(leashDataEntity != null) {
|
||||||
pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow));
|
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.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1);
|
||||||
leashRopeArrow.setOwner(null);
|
leashRopeArrow.setOwner(null);
|
||||||
}
|
}
|
||||||
|
|
@ -374,12 +372,12 @@ public class LeashRopeArrow extends AbstractArrow {
|
||||||
this.level().addFreshEntity(arrow);
|
this.level().addFreshEntity(arrow);
|
||||||
discard();
|
discard();
|
||||||
} else {
|
} else {
|
||||||
if(entity instanceof Leashable leashable) {
|
if (entity instanceof Leashable leashable) {
|
||||||
if (getOwner() == null) {
|
if (getOwner() == null) {
|
||||||
Entity leashDataEntity = leashable.getLeashHolder();
|
Entity leashDataEntity = leashable.getLeashHolder();
|
||||||
if (leashDataEntity != null) {
|
if (leashDataEntity != null) {
|
||||||
leashable.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow));
|
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.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1);
|
||||||
leashRopeArrow.setOwner(null);
|
leashRopeArrow.setOwner(null);
|
||||||
}
|
}
|
||||||
|
|
@ -390,8 +388,8 @@ public class LeashRopeArrow extends AbstractArrow {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(entity instanceof LivingEntity living) {
|
if (entity instanceof LivingEntity living) {
|
||||||
if(this.getOwner() != null && this.getOwner()instanceof Leashable leashable) {
|
if (this.getOwner() != null && this.getOwner()instanceof Leashable leashable) {
|
||||||
livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||||
leashable.setLeashedTo(living, true);
|
leashable.setLeashedTo(living, true);
|
||||||
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
|
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) {
|
else if (entity instanceof LeashFenceKnotEntity leashKnotFence) {
|
||||||
if (getOwner() instanceof PlayerLeashable pL) {
|
if (getOwner() instanceof PlayerLeashable pL) {
|
||||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
|
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
|
||||||
if(leashDataEntity != null) {
|
if (leashDataEntity != null) {
|
||||||
pL.dropLeash(true, true);
|
pL.dropLeash(true, true);
|
||||||
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
if (leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
||||||
leashRopeArrow.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1);
|
leashRopeArrow.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1);
|
||||||
leashRopeArrow.setOwner(null);
|
leashRopeArrow.setOwner(null);
|
||||||
}
|
}
|
||||||
|
|
@ -421,14 +419,13 @@ public class LeashRopeArrow extends AbstractArrow {
|
||||||
pL.setLeashedTo(leashKnotFence, true);
|
pL.setLeashedTo(leashKnotFence, true);
|
||||||
this.level().addFreshEntity(arrow);
|
this.level().addFreshEntity(arrow);
|
||||||
discard();
|
discard();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ItemEntity lead = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, Items.LEAD.getDefaultInstance());
|
ItemEntity lead = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, Items.LEAD.getDefaultInstance());
|
||||||
this.level().addFreshEntity(lead);
|
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}.
|
* Handles an entity event received from a {@link net.minecraft.network.protocol.game.ClientboundEntityEventPacket}.
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,151 @@
|
||||||
package com.r3944realms.leashedplayer.content.entities;
|
package com.r3944realms.leashedplayer.content.entities;
|
||||||
|
|
||||||
|
import com.r3944realms.leashedplayer.config.LeashPlayerCommonConfig;
|
||||||
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
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.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.EntityType;
|
import net.minecraft.world.entity.EntityType;
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
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.entity.projectile.AbstractArrow;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.Items;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.phys.EntityHitResult;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class NestleRopeArrow extends AbstractArrow {
|
public class NestleRopeArrow extends AbstractArrow {
|
||||||
public NestleRopeArrow(EntityType<? extends AbstractArrow> pEntityType, Level pLevel) {
|
private static final int maxLifeTime = LeashPlayerCommonConfig.TheNestleArrowMaxLifeTime.get();
|
||||||
|
protected NestleRopeArrow(EntityType<? extends AbstractArrow> pEntityType, Level pLevel) {
|
||||||
super(pEntityType, pLevel);
|
super(pEntityType, pLevel);
|
||||||
}
|
}
|
||||||
public NestleRopeArrow(EntityType<? extends AbstractArrow> entityType, double pX, double pY, double pZ, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon, @Nullable ServerPlayer serverPlayer) {
|
public NestleRopeArrow(EntityType<? extends AbstractArrow> 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);
|
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<? extends AbstractArrow> entityType, LivingEntity pOwner, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon) {
|
public NestleRopeArrow(EntityType<? extends AbstractArrow> entityType, LivingEntity pOwner, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon) {
|
||||||
super(entityType, pOwner, pLevel, pPickupItemStack, 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
|
@Override
|
||||||
protected @NotNull ItemStack getDefaultPickupItem() {
|
protected @NotNull ItemStack getDefaultPickupItem() {
|
||||||
return ModItemRegister.NESTLE_ROPE_ARROW.get().getDefaultInstance();
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
package com.r3944realms.leashedplayer.integration.jei.category;
|
package com.r3944realms.leashedplayer.integration.jei.category;
|
||||||
|
|
||||||
public class LeashedPlayerCategory {
|
public class LeashedPlayerCategory {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package com.r3944realms.leashedplayer.mixin.both;
|
||||||
|
|
||||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||||
import com.r3944realms.leashedplayer.content.commands.LeashCommand;
|
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.content.entities.LeashRopeArrow;
|
||||||
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
|
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
|
||||||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
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.EntityDataSerializers;
|
||||||
import net.minecraft.network.syncher.SynchedEntityData;
|
import net.minecraft.network.syncher.SynchedEntityData;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.effect.MobEffectInstance;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.EntityType;
|
import net.minecraft.world.entity.EntityType;
|
||||||
import net.minecraft.world.entity.Leashable;
|
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.decoration.LeashFenceKnotEntity;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.phys.Vec3;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
|
@ -30,10 +27,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
@Mixin(Player.class)
|
@Mixin(Player.class)
|
||||||
public abstract class MixinPlayer extends LivingEntity implements PlayerLeashable, ILivingEntityExtension {
|
public abstract class MixinPlayer extends LivingEntity implements PlayerLeashable, ILivingEntityExtension {
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
protected int Pl$LeashKeepTick;//保存状态,当超过断裂绳长时若LeashKeepTick大于0,则不断裂
|
protected int Pl$LeashKeepTick;//保存状态,当超过断裂绳长时若LeashKeepTick大于0,则不断裂
|
||||||
|
|
@ -106,87 +102,15 @@ public abstract class
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float leashLength = LeashCommand.MIN_VALUE;
|
PlayerLeashable.legacyElasticRangeLeashBehaviour(holderEntity, restrainedEntity);
|
||||||
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;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 降低坠落伤害
|
// 降低坠落伤害
|
||||||
restrainedEntity.checkSlowFallDistance();
|
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<Entity> pOpt) {
|
|
||||||
Consumer<Entity> 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
|
@Unique
|
||||||
protected void Pl$tickLeash() {
|
protected void Pl$tickLeash() {
|
||||||
if(this.Pl$LeashData == null) return;//没有Data直接退出
|
if(this.Pl$LeashData == null) return;//没有Data直接退出
|
||||||
|
|
@ -203,12 +127,6 @@ public abstract class
|
||||||
ILivingEntityExtension iEntityExtension = this;//获取设定值
|
ILivingEntityExtension iEntityExtension = this;//获取设定值
|
||||||
float leashLengthSelf = iEntityExtension.getLeashLength();
|
float leashLengthSelf = iEntityExtension.getLeashLength();
|
||||||
leashLength = leashLengthSelf > LeashCommand.MIN_VALUE ? leashLengthSelf : LeashCommand.MIN_VALUE;
|
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) {
|
if (entity != null) {
|
||||||
double breakDistanceTime = (entity instanceof LeashRopeArrow) ? LeashedPlayer.M1() * LeashedPlayer.M2() : LeashedPlayer.M1();
|
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)){
|
if(!isAlive() || !entity.isAlive() ||( distanceTo(entity) > Math.max(leashLength * breakDistanceTime, LeashCommand.MIN_VALUE * breakDistanceTime) && keepLeashTick == 0)){
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package com.r3944realms.leashedplayer.modInterface;
|
package com.r3944realms.leashedplayer.modInterface;
|
||||||
|
|
||||||
|
import com.r3944realms.leashedplayer.content.commands.LeashCommand;
|
||||||
import com.r3944realms.leashedplayer.content.criteriaTriggers.ModCriteriaTriggers;
|
import com.r3944realms.leashedplayer.content.criteriaTriggers.ModCriteriaTriggers;
|
||||||
|
import com.r3944realms.leashedplayer.utils.Util;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket;
|
import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
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.decoration.LeashFenceKnotEntity;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
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
|
@Nullable
|
||||||
static Entity getLeashDataEntity(@NotNull ServerPlayer serverPlayer , @NotNull ServerLevel serverLevel) {
|
static Entity getLeashDataEntity(@NotNull ServerPlayer serverPlayer , @NotNull ServerLevel serverLevel) {
|
||||||
LeashData leashDataFromEntityData = ((PlayerLeashable) serverPlayer).getLeashDataFromEntityData();
|
LeashData leashDataFromEntityData = ((PlayerLeashable) serverPlayer).getLeashDataFromEntityData();
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import static com.r3944realms.leashedplayer.utils.Logger.logger;
|
import static com.r3944realms.leashedplayer.utils.Logger.logger;
|
||||||
|
|
@ -98,4 +99,38 @@ public class Util {
|
||||||
}
|
}
|
||||||
else return null;
|
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<Entity> pOpt) {
|
||||||
|
Consumer<Entity> 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user