302 lines
17 KiB
Java
302 lines
17 KiB
Java
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);
|
||
}
|
||
|
||
}
|