diff --git a/src/main/java/com/atsuishio/superbwarfare/client/model/entity/DroneModel.java b/src/main/java/com/atsuishio/superbwarfare/client/model/entity/DroneModel.java index 31b5d05a4..d257fda80 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/model/entity/DroneModel.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/model/entity/DroneModel.java @@ -61,14 +61,6 @@ public class DroneModel extends GeoModel { float times = Math.min(Minecraft.getInstance().getDeltaFrameTime(), 1); - if (Minecraft.getInstance().options.keyUp.isDown()) { - rotX = Mth.lerp(0.025f * times, rotX, -0.25f); - } else if (Minecraft.getInstance().options.keyDown.isDown()) { - rotX = Mth.lerp(0.025f * times, rotX, 0.25f); - } else { - rotX = Mth.lerp(0.04f * times, rotX, 0); - } - if (Minecraft.getInstance().options.keyRight.isDown()) { rotZ = Mth.lerp(0.025f * times, rotZ, -0.25f); } else if (Minecraft.getInstance().options.keyLeft.isDown()) { @@ -77,10 +69,9 @@ public class DroneModel extends GeoModel { rotZ = Mth.lerp(0.04f * times, rotZ, 0); } - main.setRotX(rotX); main.setRotZ(rotZ); - droneBodyAngle(rotX, rotZ); + droneBodyAngle(rotZ); //螺旋桨控制 diff --git a/src/main/java/com/atsuishio/superbwarfare/client/screens/DroneUIOverlay.java b/src/main/java/com/atsuishio/superbwarfare/client/screens/DroneUIOverlay.java index 77ebfdb77..813dc15c5 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/screens/DroneUIOverlay.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/screens/DroneUIOverlay.java @@ -1,17 +1,22 @@ package com.atsuishio.superbwarfare.client.screens; import com.atsuishio.superbwarfare.ModUtils; -import com.atsuishio.superbwarfare.tools.EntityFindUtil; -import com.mojang.blaze3d.platform.GlStateManager; -import com.mojang.blaze3d.systems.RenderSystem; +import com.atsuishio.superbwarfare.client.RenderHelper; import com.atsuishio.superbwarfare.entity.DroneEntity; import com.atsuishio.superbwarfare.event.ClientEventHandler; import com.atsuishio.superbwarfare.init.ModItems; -import com.atsuishio.superbwarfare.tools.TraceTool; +import com.atsuishio.superbwarfare.tools.EntityFindUtil; +import com.atsuishio.superbwarfare.tools.HudUtil; +import com.atsuishio.superbwarfare.tools.SeekTool; +import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; @@ -24,6 +29,7 @@ import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import java.text.DecimalFormat; +import java.util.List; import static com.atsuishio.superbwarfare.client.RenderHelper.preciseBlit; import static com.atsuishio.superbwarfare.entity.DroneEntity.AMMO; @@ -32,7 +38,7 @@ import static com.atsuishio.superbwarfare.entity.DroneEntity.KAMIKAZE; @Mod.EventBusSubscriber(value = Dist.CLIENT) public class DroneUIOverlay { public static int MAX_DISTANCE = 256; - + private static final ResourceLocation FRAME = ModUtils.loc("textures/screens/javelin/frame.png"); @SubscribeEvent(priority = EventPriority.NORMAL) public static void eventHandler(RenderGuiEvent.Pre event) { int w = event.getWindow().getGuiScaledWidth(); @@ -66,7 +72,7 @@ public class DroneUIOverlay { double entity_range = 0; - Entity lookingEntity = TraceTool.findLookingEntity(entity, 520); + Entity lookingEntity = SeekTool.seekLivingEntity(entity, entity.level(), 512, 2); if (lookingEntity != null) { lookAtEntity = true; @@ -111,6 +117,30 @@ public class DroneUIOverlay { w / 2 + 12, h / 2 - 28, color, false); } } + Minecraft mc = Minecraft.getInstance(); + Camera camera = mc.gameRenderer.getMainCamera(); + Vec3 cameraPos = camera.getPosition(); + PoseStack poseStack = event.getGuiGraphics().pose(); + + List entities = SeekTool.seekLivingEntities(entity, entity.level(), 256, 30); + float fovAdjust2 = (float) (Minecraft.getInstance().options.fov().get() / 30) - 1; + double zoom = 0.975 * ClientEventHandler.droneFovLerp + 0.06 * fovAdjust2; + + for (var e : entities) { + Vec3 pos = new Vec3(e.getX(), e.getEyeY(), e.getZ()); + Vec3 lookAngle = entity.getLookAngle().normalize().scale(pos.distanceTo(cameraPos) * (1 - 1.0 / zoom)); + + var cPos = cameraPos.add(lookAngle); + Vec3 p = RenderHelper.worldToScreen(pos, cPos); + if (p == null) return; + + poseStack.pushPose(); + int x = (int) p.x; + int y = (int) p.y; + + HudUtil.blit(poseStack, FRAME, x - 12, y - 12, 0, 0, 24, 24, 24, 24, 1f); + poseStack.popPose(); + } } } diff --git a/src/main/java/com/atsuishio/superbwarfare/client/screens/JavelinHudOverlay.java b/src/main/java/com/atsuishio/superbwarfare/client/screens/JavelinHudOverlay.java index 216ce43d1..0bf11da2e 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/screens/JavelinHudOverlay.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/screens/JavelinHudOverlay.java @@ -92,14 +92,13 @@ public class JavelinHudOverlay { float fovAdjust = (float) Minecraft.getInstance().options.fov().get() / 80; - Entity targetEntity = EntityFindUtil.findEntity(player.level(), stack.getOrCreateTag().getString("TargetEntity")); - List entities = SeekTool.seekLivingEntities(player, player.level(), 512, 10 * fovAdjust); - Entity naerestEntity = SeekTool.seekLivingEntity(player, player.level(), 512, 8); + List entities = SeekTool.seekLivingEntities(player, player.level(), 512, 8 * fovAdjust); + Entity naerestEntity = SeekTool.seekLivingEntity(player, player.level(), 512, 6); float fovAdjust2 = (float) (Minecraft.getInstance().options.fov().get() / 30) - 1; - double zoom = 3.1 + 0.5 * fovAdjust2; + double zoom = Minecraft.getInstance().options.fov().get() / ClientEventHandler.fov + 0.5 * fovAdjust2; for (var e : entities) { Vec3 pos = new Vec3(e.getX(), e.getEyeY(), e.getZ()); diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/DroneEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/DroneEntity.java index 924d3fdf8..75b05a476 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/DroneEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/DroneEntity.java @@ -67,10 +67,16 @@ public class DroneEntity extends LivingEntity implements GeoEntity { private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); public static double lastTickSpeed = 0; - public double moveX = 0; public double moveY = 0; public double moveZ = 0; + public boolean leftInputDown; + public boolean rightInputDown; + public boolean forwardInputDown; + public boolean backInputDown; + public boolean upInputDown; + public boolean downInputDown; + public boolean fire; public DroneEntity(PlayMessages.SpawnEntity packet, Level world) { this(ModEntities.DRONE.get(), world); @@ -175,16 +181,16 @@ public class DroneEntity extends LivingEntity implements GeoEntity { if (!this.onGround()) { // left and right - if (this.getPersistentData().getBoolean("left")) { + if (leftInputDown) { moveX = Mth.clamp(moveX + 0.3f, 0, 3); - } else if (this.getPersistentData().getBoolean("right")) { + } else if (rightInputDown) { moveX = Mth.clamp(moveX - 0.3f, -3, 0); } // forward and backward - if (this.getPersistentData().getBoolean("forward")) { + if (forwardInputDown) { moveZ = Mth.clamp(moveZ + 0.3f, 0, 3); - } else if (this.getPersistentData().getBoolean("backward")) { + } else if (backInputDown) { moveZ = Mth.clamp(moveZ - 0.3f, -3, 0); } @@ -197,9 +203,9 @@ public class DroneEntity extends LivingEntity implements GeoEntity { } // up and down - if (this.getPersistentData().getBoolean("up")) { + if (upInputDown) { moveY = Mth.clamp(moveY + 0.3f, 0, 3); - } else if (this.getPersistentData().getBoolean("down")) { + } else if (downInputDown) { moveY = Mth.clamp(moveY - 0.15f, -2, 0); } @@ -234,7 +240,7 @@ public class DroneEntity extends LivingEntity implements GeoEntity { this.hurt(new DamageSource(level().registryAccess().registryOrThrow(Registries.DAMAGE_TYPE).getHolderOrThrow(DamageTypes.EXPLOSION), Objects.requireNonNullElse(controller, this)), 0.25f + (float) (2 * lastTickSpeed)); } - if (this.getPersistentData().getBoolean("firing")) { + if (this.fire) { if (this.entityData.get(AMMO) > 0) { this.entityData.set(AMMO, this.entityData.get(AMMO) - 1); if (controller != null) { @@ -242,9 +248,16 @@ public class DroneEntity extends LivingEntity implements GeoEntity { } } if (this.entityData.get(KAMIKAZE)) { - this.hurt(new DamageSource(level().registryAccess().registryOrThrow(Registries.DAMAGE_TYPE).getHolderOrThrow(DamageTypes.EXPLOSION), controller), 10000); + this.discard(); + if (controller != null) { + if (controller.getMainHandItem().is(ModItems.MONITOR.get())) { + Monitor.disLink(controller.getMainHandItem()); + } + kamikazeExplosion(controller); + } + } - this.getPersistentData().putBoolean("firing", false); + this.fire = false; } this.refreshDimensions(); @@ -351,7 +364,7 @@ public class DroneEntity extends LivingEntity implements GeoEntity { if (controller != null) { ItemStack stack = controller.getMainHandItem(); - if (stack.getOrCreateTag().getBoolean("Using")) { + if (stack.is(ModItems.MONITOR.get()) && stack.getOrCreateTag().getBoolean("Using")) { this.setYRot(controller.getYRot()); this.yRotO = this.getYRot(); this.setXRot(Mth.clamp(controller.getXRot(), -25, 90)); @@ -432,10 +445,6 @@ public class DroneEntity extends LivingEntity implements GeoEntity { }); } - if (this.entityData.get(KAMIKAZE)) { - kamikazeExplosion(source.getEntity()); - } - ItemStack stack = new ItemStack(ModItems.RGO_GRENADE.get(), this.entityData.get(AMMO)); if (this.level() instanceof ServerLevel level) { diff --git a/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java b/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java index 0826a9482..8c2b1f5e6 100644 --- a/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java @@ -56,7 +56,6 @@ import static com.atsuishio.superbwarfare.entity.SpeedboatEntity.HEAT; @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE, value = Dist.CLIENT) public class ClientEventHandler { - public static double zoomTime = 0; public static double zoomPos = 0; public static double zoomPosZ = 0; @@ -86,7 +85,6 @@ public class ClientEventHandler { public static double recoilHorizon = 0; public static double recoilY = 0; - public static double droneRotX = 0; public static double droneRotZ = 0; public static double droneFov = 1; public static double droneFovLerp = 1; @@ -693,10 +691,9 @@ public class ClientEventHandler { } } - public static void droneBodyAngle(float RotX, float RotZ) { + public static void droneBodyAngle(float RotZ) { LocalPlayer player = Minecraft.getInstance().player; if (player != null) { - droneRotX = RotX; droneRotZ = RotZ; } @@ -704,13 +701,11 @@ public class ClientEventHandler { private static void handleDroneCamera(ViewportEvent.ComputeCameraAngles event, LivingEntity entity) { ItemStack stack = entity.getMainHandItem(); - double pitch = event.getPitch(); double roll = event.getRoll(); DroneEntity drone = EntityFindUtil.findDrone(entity.level(), stack.getOrCreateTag().getString("LinkedDrone")); if (drone != null) { - event.setPitch((float) (pitch - Mth.RAD_TO_DEG * droneRotX)); event.setRoll((float) (roll - Mth.RAD_TO_DEG * droneRotZ)); } @@ -1195,6 +1190,7 @@ public class ClientEventHandler { if (stack.is(ModItems.MONITOR.get()) && stack.getOrCreateTag().getBoolean("Using") && stack.getOrCreateTag().getBoolean("Linked")) { droneFovLerp = Mth.lerp(0.1 * Minecraft.getInstance().getDeltaFrameTime(), droneFovLerp, droneFov); event.setFOV(event.getFOV() / droneFovLerp); + fov = event.getFOV(); } if (player.getVehicle() instanceof IArmedVehicleEntity && !(player.getVehicle() instanceof ICannonEntity) && zoom) { diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/DroneFireMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/DroneFireMessage.java index 500098d32..d6bfc8e30 100644 --- a/src/main/java/com/atsuishio/superbwarfare/network/message/DroneFireMessage.java +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/DroneFireMessage.java @@ -3,7 +3,7 @@ package com.atsuishio.superbwarfare.network.message; import com.atsuishio.superbwarfare.entity.DroneEntity; import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.tools.EntityFindUtil; -import com.atsuishio.superbwarfare.tools.TraceTool; +import com.atsuishio.superbwarfare.tools.SeekTool; import net.minecraft.ChatFormatting; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; @@ -44,12 +44,12 @@ public class DroneFireMessage { DroneEntity drone = EntityFindUtil.findDrone(player.level(), stack.getOrCreateTag().getString("LinkedDrone")); if (drone != null) { if (!player.getOffhandItem().is(ModItems.FIRING_PARAMETERS.get())) { - drone.getPersistentData().putBoolean("firing", true); + drone.fire = true; } else { ItemStack offStack = player.getOffhandItem(); boolean lookAtEntity = false; - Entity lookingEntity = TraceTool.findLookingEntity(drone, 520); + Entity lookingEntity = SeekTool.seekLivingEntity(drone, drone.level(), 512, 2); Vec3 looking = Vec3.atLowerCornerOf(player.level().clip(new ClipContext(drone.getEyePosition(), drone.getEyePosition().add(drone.getLookAngle().scale(512)), ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player)).getBlockPos()); if (lookingEntity != null) { diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/DroneMovementMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/DroneMovementMessage.java index fd30fed41..15c1fee72 100644 --- a/src/main/java/com/atsuishio/superbwarfare/network/message/DroneMovementMessage.java +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/DroneMovementMessage.java @@ -40,22 +40,22 @@ public class DroneMovementMessage { if (drone != null) { switch (message.direction) { case 0: - drone.getPersistentData().putBoolean("left", message.clicked); + drone.leftInputDown = message.clicked; break; case 1: - drone.getPersistentData().putBoolean("right", message.clicked); + drone.rightInputDown = message.clicked; break; case 2: - drone.getPersistentData().putBoolean("forward", message.clicked); + drone.forwardInputDown = message.clicked; break; case 3: - drone.getPersistentData().putBoolean("backward", message.clicked); + drone.backInputDown = message.clicked; break; case 4: - drone.getPersistentData().putBoolean("up", message.clicked); + drone.upInputDown = message.clicked; break; case 5: - drone.getPersistentData().putBoolean("down", message.clicked); + drone.downInputDown = message.clicked; break; } } diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/SeekTool.java b/src/main/java/com/atsuishio/superbwarfare/tools/SeekTool.java index aa896400b..587afcb91 100644 --- a/src/main/java/com/atsuishio/superbwarfare/tools/SeekTool.java +++ b/src/main/java/com/atsuishio/superbwarfare/tools/SeekTool.java @@ -1,6 +1,7 @@ package com.atsuishio.superbwarfare.tools; import com.atsuishio.superbwarfare.entity.IArmedVehicleEntity; +import com.atsuishio.superbwarfare.entity.VehicleEntity; import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; import net.minecraft.core.BlockPos; import net.minecraft.util.Mth; @@ -46,7 +47,7 @@ public class SeekTool { && e != entity && e.isAlive() && !(e instanceof ItemEntity || e instanceof ExperienceOrb || e instanceof HangingEntity || e instanceof ProjectileEntity || e instanceof Projectile || e instanceof ArmorStand) - && (e instanceof LivingEntity || e instanceof IArmedVehicleEntity) + && (e instanceof LivingEntity || e instanceof VehicleEntity) && !(e instanceof Player player && (player.isSpectator())) && (!e.isAlliedTo(entity) || e.getTeam() == null || e.getTeam().getName().equals("TDM"))) { return level.clip(new ClipContext(entity.getEyePosition(), e.getEyePosition(), @@ -63,7 +64,7 @@ public class SeekTool { && e != entity && e.isAlive() && !(e instanceof ItemEntity || e instanceof ExperienceOrb || e instanceof HangingEntity || e instanceof ProjectileEntity || e instanceof Projectile || e instanceof ArmorStand) - && (e instanceof LivingEntity || e instanceof IArmedVehicleEntity) + && (e instanceof LivingEntity || e instanceof VehicleEntity) && !(e instanceof Player player && (player.isCreative() || player.isSpectator())) && (!e.isAlliedTo(entity) || e.getTeam() == null || e.getTeam().getName().equals("TDM"))) { return level.clip(new ClipContext(entity.getEyePosition(), e.getEyePosition(),