LeashedPlayer/src/main/java/com/r3944realms/leashedplayer/content/entities/LeashRopeArrow.java
3944Realms 0cce76511f 2024-10-28
修复了有关箭不能正常显示的BUG
将默认值调高减少拴绳断裂的可能性
2024/10/28
Fix some BUG
2024-10-28 22:47:18 +08:00

302 lines
17 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.r3944realms.leashedplayer.content.entities;
import com.r3944realms.leashedplayer.config.LeashPlayerCommonConfig;
import com.r3944realms.leashedplayer.content.effects.ModEffectRegister;
import com.r3944realms.leashedplayer.content.gamerules.GameruleRegistry;
import com.r3944realms.leashedplayer.content.gamerules.Server.KeepLeashNotDropTime;
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Leashable;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.decoration.LeashFenceKnotEntity;
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.BlockHitResult;
import net.minecraft.world.phys.EntityHitResult;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class LeashRopeArrow extends AbstractArrow {
private static final int maxLifeTime = LeashPlayerCommonConfig.TheLeashArrowMaxLifeTime.get();
protected LeashRopeArrow(EntityType<? extends AbstractArrow> entityType,Level pLevel) {
super(entityType, pLevel);
}
public LeashRopeArrow(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) {
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity(serverPlayer, (ServerLevel) level());
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.setOwner(null);
}
((PlayerLeashable)serverPlayer).setLeashedTo(this, true);
}
}
public LeashRopeArrow(EntityType<? extends AbstractArrow> entityType, LivingEntity pOwner, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon) {
super(entityType, pOwner, pLevel, pPickupItemStack, pFiredFromWeapon);
if(pOwner instanceof PlayerLeashable lPlayer && !level().isClientSide) {
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) lPlayer, (ServerLevel) level());
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.setOwner(null);
}
lPlayer.setLeashedTo(this, true);
}
}
@Override
protected @NotNull ItemStack getDefaultPickupItem() {
return ModItemRegister.LEASH_ROPE_ARROW.get().getDefaultInstance();
}
@Override
public void setOwner(@Nullable Entity pEntity) {
// super.setOwner(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 boolean tryPickup(@NotNull Player pPlayer) {
//时间1.40 禁止
//时间2.240
// 如果(非仅创造拾取)
// 如果 (按Shift )
// 如果(拥有者) -> 拾取到完整箭,取消绑定(super给父类处理)
// 否则:时间仍为原需时间 ->不能获取完整的箭重绑定当前拥有者的Holder是否为本箭“是”才重绑定
// 否则: 禁止
// 否则:
// 如果 (按Shift )
// 如果(拥有者) -> 且拾取到完整箭,取消绑定
// 否则:时间仍为原需时间 ->不能获取完整的箭,重绑定
// 否则: 禁止
//时间3
// 如果(拥有者) -> 拾取到完整箭,取消绑定
// 否则:不能获取完整的箭,重绑定
if(life <= 40 ) {
return false;
}
else {
PlayerLeashable playerLeashable = (PlayerLeashable) pPlayer;
if(this.getOwner() == null) {//未有Owner始终可检
return true;
}
if(life <= 240) {
if(pPlayer.isShiftKeyDown()) {
Entity leashDataEntity = this.getOwner() instanceof PlayerLeashable ? PlayerLeashable.getLeashDataEntity((ServerPlayer) this.getOwner(), (ServerLevel) level()) : this.getOwner();
if(this.ownedBy(pPlayer)) {
this.pickup = Pickup.ALLOWED;
if(this.equals(leashDataEntity)) playerLeashable.dropLeash(true, false);
} else {
if(life >= 120) {
Entity owner = getOwner();
if( owner != null ) {
// if(this.equals(leashDataEntity)) {
if(owner instanceof PlayerLeashable player) {
player.setLeashedTo(pPlayer, true);
} else if(owner instanceof Leashable leashable) {
leashable.setLeashedTo(pPlayer, true);
}
ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), getOrginalItemStack());
level().addFreshEntity(itemEntity);
discard();
// }
} else return true;
} else return false;
}
} else return false;
}
else {
Entity leashDataEntity = this.getOwner() instanceof PlayerLeashable ? PlayerLeashable.getLeashDataEntity((ServerPlayer) this.getOwner(), (ServerLevel) level()) : this.getOwner();
if(this.ownedBy(pPlayer)) {
this.pickup = Pickup.ALLOWED;
if(this.equals(leashDataEntity)) playerLeashable.dropLeash(true, false);
} else {
Entity owner = getOwner();
if(owner instanceof PlayerLeashable player) {
player.setLeashedTo(pPlayer, true);
} else if(owner instanceof Leashable leashable) {
leashable.setLeashedTo(pPlayer, true);
}
ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), getOrginalItemStack());
level().addFreshEntity(itemEntity);
discard();
}
}
}
return super.tryPickup(pPlayer);
}
protected void hitOnEntityHandler(Entity pEntity) {
//NOOP
}
protected ItemStack getOrginalItemStack() {
return Items.ARROW.getDefaultInstance();
}
protected ItemStack getSelfItemStack() {
return ModItemRegister.LEASH_ROPE_ARROW.get().getDefaultInstance();
}
@Override
protected void tickDespawn() {
this.life++;
if (this.life >= maxLifeTime) {
ItemEntity leash_rope_arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
this.level().addFreshEntity(leash_rope_arrow);
this.discard();
}
}
@Override
protected void onHitBlock(@NotNull BlockHitResult pResult) {
if(!level().isClientSide) {
if (getOwner() instanceof PlayerLeashable pL) {
if (this.level().getBlockState(pResult.getBlockPos()).is(BlockTags.FENCES)) {
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
if(leashDataEntity != null) {
pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow));
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.setOwner(null);
}
}
Entity leashKnotFence = PlayerLeashable.createLeashKnotFence((ServerLevel) this.level(), pResult.getBlockPos());
ILivingEntityExtension pLL = (ILivingEntityExtension) pL;
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
pL.setLeashedTo(leashKnotFence, true);
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
this.level().addFreshEntity(arrow);
discard();
}
} else if(getOwner() instanceof Leashable L) {
if (this.level().getBlockState(pResult.getBlockPos()).is(BlockTags.FENCES)) {
Entity leashDataEntity = this.getOwner();
if(leashDataEntity != null) {
L.dropLeash(true, false);
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.setOwner(null);
}
}
Entity leashKnotFence = LeashFenceKnotEntity.getOrCreateKnot(this.level(), pResult.getBlockPos());
L.setLeashedTo(leashKnotFence, true);
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
this.level().addFreshEntity(arrow);
discard();
}
}
}
super.onHitBlock(pResult);
}
@Override
protected void onHitEntity(@NotNull EntityHitResult pResult) {
if(!level().isClientSide()){
Entity entity = pResult.getEntity();
hitOnEntityHandler(entity);
if(this.getOwner() instanceof LivingEntity livingEntity ) {
MobEffectInstance effect = livingEntity.getEffect(ModEffectRegister.NO_LEASH_EFFECT);
if(effect != null && effect.getDuration() > 0) {
this.setOwner(null);
}
}
if(entity instanceof LivingEntity livingEntity) {
if(livingEntity.equals(this.getOwner())) return;
if(this.getOwner() == null && livingEntity instanceof PlayerLeashable pL) { //发射器发出或命令生成
setOwner(livingEntity);
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
if(leashDataEntity != null) {
pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow));
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.setOwner(null);
}
}
ILivingEntityExtension pLL = (ILivingEntityExtension) pL;
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
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) {
leashRopeArrow.setOwner(null);
}
}
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
ILivingEntityExtension pLL = (ILivingEntityExtension) pL;
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
pL.setLeashedTo(pResult.getEntity(), true);
this.level().addFreshEntity(arrow);
discard();
} else {
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) {
leashRopeArrow.setOwner(null);
}
}
leashable.setLeashedTo(this, true);
this.setOwner(entity);
return;
}
}
if(entity instanceof LivingEntity living) {
if(this.getOwner() != null && this.getOwner()instanceof Leashable leashable) {
leashable.setLeashedTo(living, true);
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
this.level().addFreshEntity(arrow);
discard();
return;
}
}
ItemEntity lead = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, Items.LEAD.getDefaultInstance());
this.level().addFreshEntity(lead);
}
}
else if (entity instanceof LeashFenceKnotEntity leashKnotFence) {
if (getOwner() instanceof PlayerLeashable pL) {
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
if(leashDataEntity != null) {
pL.dropLeash(true, true);
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.setOwner(null);
}
}
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
ILivingEntityExtension pLL = (ILivingEntityExtension) pL;
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
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);
}
}