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.
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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 {
|
|||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ public class LeashPlayerCommonConfig {
|
|||
public static final ModConfigSpec SPEC;
|
||||
public static final ModConfigSpec.ConfigValue<String> 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");
|
||||
|
|
|
|||
|
|
@ -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<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",
|
||||
() -> new MobEffect(MobEffectCategory.NEUTRAL, 12063764)
|
||||
() -> new NoLeashEffect(MobEffectCategory.NEUTRAL, 12063764)
|
||||
);
|
||||
public static <T extends MobEffect>DeferredHolder<MobEffect, T> register(String name, Supplier<T> 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) {
|
||||
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<? extends AbstractArrow> 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}.
|
||||
|
|
|
|||
|
|
@ -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<? extends AbstractArrow> pEntityType, Level pLevel) {
|
||||
private static final int maxLifeTime = LeashPlayerCommonConfig.TheNestleArrowMaxLifeTime.get();
|
||||
protected NestleRopeArrow(EntityType<? extends AbstractArrow> pEntityType, Level 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) {
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
package com.r3944realms.leashedplayer.integration.jei.category;
|
||||
|
||||
public class LeashedPlayerCategory {
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<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
|
||||
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)){
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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<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