diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/DroneEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/DroneEntity.java index f0dc2821d..4f117e698 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/DroneEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/DroneEntity.java @@ -9,6 +9,7 @@ import com.atsuishio.superbwarfare.init.ModEntities; import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.init.ModSounds; import com.atsuishio.superbwarfare.item.Monitor; +import com.atsuishio.superbwarfare.tools.ChunkLoadTool; import com.atsuishio.superbwarfare.tools.CustomExplosion; import com.atsuishio.superbwarfare.tools.EntityFindUtil; import com.atsuishio.superbwarfare.tools.ParticleTool; @@ -52,9 +53,7 @@ import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache import software.bernie.geckolib.core.animation.AnimatableManager; import software.bernie.geckolib.util.GeckoLibUtil; -import java.util.Comparator; -import java.util.Objects; -import java.util.UUID; +import java.util.*; public class DroneEntity extends MobileVehicleEntity implements GeoEntity { public static final EntityDataAccessor LINKED = SynchedEntityData.defineId(DroneEntity.class, EntityDataSerializers.BOOLEAN); @@ -76,6 +75,7 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity { public double lastTickVerticalSpeed; public float pitch; public float pitchO; + public Set loadedChunks = new HashSet<>(); public DroneEntity(PlayMessages.SpawnEntity packet, Level world) { this(ModEntities.DRONE.get(), world); @@ -165,6 +165,11 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity { super.baseTick(); + if (this.level() instanceof ServerLevel serverLevel) { + // 更新需要加载的区块 + ChunkLoadTool.updateLoadedChunks(serverLevel, this, this.loadedChunks); + } + lastTickSpeed = this.getDeltaMovement().length(); lastTickVerticalSpeed = this.getDeltaMovement().y; @@ -177,6 +182,7 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity { if (!this.onGround()) { if (controller != null) { + handleSimulationDistance(controller); ItemStack stack = controller.getMainHandItem(); if (stack.is(ModItems.MONITOR.get())) { if (stack.getOrCreateTag().getBoolean("Using") && controller.level().isClientSide) { @@ -193,6 +199,15 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity { if (!controller.level().isClientSide) { this.level().playSound(null, this.getOnPos(), ModSounds.DRONE_SOUND.get(), SoundSource.AMBIENT, 3, 1); } + + if (tickCount %5 == 0) { + controller.getInventory().items.stream().filter(pStack -> pStack.getItem() == ModItems.MONITOR.get()) + .forEach(pStack -> { + if (pStack.getOrCreateTag().getString(Monitor.LINKED_DRONE).equals(this.getStringUUID())) { + Monitor.getDronePos(pStack,this.position()); + } + }); + } } } @@ -222,6 +237,25 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity { this.refreshDimensions(); } + public void handleSimulationDistance(Player player) { + if (player.level() instanceof ServerLevel serverLevel && player instanceof ServerPlayer) { + var distanceManager = serverLevel.getChunkSource().chunkMap.getDistanceManager(); + var playerTicketManager = distanceManager.playerTicketManager; + int maxDistance = playerTicketManager.viewDistance; + + if (this.position().vectorTo(player.position()).horizontalDistance() > maxDistance * 16) { + upInputDown = false; + downInputDown = false; + forwardInputDown = false; + backInputDown = false; + leftInputDown = false; + rightInputDown = false; + Vec3 toVec = position().vectorTo(player.position()).normalize(); + setDeltaMovement(getDeltaMovement().add(new Vec3(toVec.x, 0,toVec.z).scale(0.2))); + } + } + } + public float getPropellerRot() { return this.propellerRot; } @@ -516,4 +550,12 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity { public AnimatableInstanceCache getAnimatableInstanceCache() { return this.cache; } + + @Override + public void onRemovedFromWorld() { + if (this.level() instanceof ServerLevel serverLevel) { + ChunkLoadTool.unloadAllChunks(serverLevel, this, this.loadedChunks); + } + super.onRemovedFromWorld(); + } } diff --git a/src/main/java/com/atsuishio/superbwarfare/item/Monitor.java b/src/main/java/com/atsuishio/superbwarfare/item/Monitor.java index 330bdaa03..fbeaa6646 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/Monitor.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/Monitor.java @@ -21,6 +21,7 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @@ -104,6 +105,12 @@ public class Monitor extends Item { return super.getAttributeModifiers(slot, stack); } + public static void getDronePos(ItemStack itemstack, Vec3 vec3) { + itemstack.getOrCreateTag().putDouble("PosX", vec3.x); + itemstack.getOrCreateTag().putDouble("PosY", vec3.y); + itemstack.getOrCreateTag().putDouble("PosZ", vec3.z); + } + @OnlyIn(Dist.CLIENT) @Override public void appendHoverText(ItemStack stack, Level world, List list, TooltipFlag flag) { @@ -112,11 +119,18 @@ public class Monitor extends Item { Player player = Minecraft.getInstance().player; if (player == null) return; - DroneEntity drone = EntityFindUtil.findDrone(player.level(), stack.getOrCreateTag().getString(LINKED_DRONE)); - if (drone == null) return; + Vec3 droneVec = new Vec3(stack.getOrCreateTag().getDouble("PosX"), stack.getOrCreateTag().getDouble("PosY"), stack.getOrCreateTag().getDouble("PosZ")); - list.add(Component.translatable("des.superbwarfare.monitor", - new DecimalFormat("##.#").format(player.distanceTo(drone)) + "m").withStyle(ChatFormatting.GRAY)); + list.add(Component.translatable("des.superbwarfare.monitor",new DecimalFormat("##.#").format(player.position().distanceTo(droneVec)) + "m").withStyle(ChatFormatting.GRAY)); + list.add(Component.literal("X: " + new DecimalFormat("##.#").format(droneVec.x) + + " Y: " + new DecimalFormat("##.#").format(droneVec.y) + + " Z: " + new DecimalFormat("##.#").format(droneVec.z) + )); + } + + @Override + public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) { + return false; } @Override