diff --git a/src/main/java/com/atsuishio/superbwarfare/client/ClickHandler.java b/src/main/java/com/atsuishio/superbwarfare/client/ClickHandler.java index d8eb921a7..29c55c6d1 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/ClickHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/ClickHandler.java @@ -128,6 +128,12 @@ public class ClickHandler { if (button == GLFW.GLFW_MOUSE_BUTTON_MIDDLE) { if (player.hasEffect(ModMobEffects.SHOCK)) { event.setCanceled(true); + return; + } + if (stack.is(ModItems.ARTILLERY_INDICATOR.get())) { + PacketDistributor.sendToServer(new SetFiringParametersMessage()); + event.setCanceled(true); + return; } } @@ -360,11 +366,11 @@ public class ClickHandler { if (player.hasEffect(ModMobEffects.SHOCK)) return; if (stack.is(ModItems.ARTILLERY_INDICATOR.get())) { - PacketDistributor.sendToServer(new SetFiringParametersMessage(0)); + ClientEventHandler.holdFire = true; } if (stack.is(Items.SPYGLASS) && player.isScoping() && player.getOffhandItem().is(ModItems.FIRING_PARAMETERS.get())) { - PacketDistributor.sendToServer(new SetFiringParametersMessage(0)); + PacketDistributor.sendToServer(new SetFiringParametersMessage()); } if (stack.is(ModItems.MONITOR.get())) { diff --git a/src/main/java/com/atsuishio/superbwarfare/client/overlay/MortarInfoOverlay.java b/src/main/java/com/atsuishio/superbwarfare/client/overlay/MortarInfoOverlay.java index 9150961e7..86c86b4d4 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/overlay/MortarInfoOverlay.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/overlay/MortarInfoOverlay.java @@ -41,7 +41,7 @@ public class MortarInfoOverlay implements LayeredDraw.Layer { .append(Component.literal(FormatTool.format1D(mortar.getYRot(), "°"))), w / 2 - 90, h / 2 - 16, -1, false); guiGraphics.drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.mortar.range") - .append(Component.literal(FormatTool.format1D((int) RangeTool.getRange(-mortar.getXRot(), 11.4, 0.146), "m"))), + .append(Component.literal(FormatTool.format1D((int) RangeTool.getRange(-mortar.getXRot(), 13, 0.11), "m"))), w / 2 - 90, h / 2 - 6, -1, false); } } diff --git a/src/main/java/com/atsuishio/superbwarfare/client/overlay/SpyglassRangeOverlay.java b/src/main/java/com/atsuishio/superbwarfare/client/overlay/SpyglassRangeOverlay.java index 3004017db..aabbf5423 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/overlay/SpyglassRangeOverlay.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/overlay/SpyglassRangeOverlay.java @@ -1,25 +1,31 @@ package com.atsuishio.superbwarfare.client.overlay; import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.client.RenderHelper; +import com.atsuishio.superbwarfare.component.ModDataComponents; import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; import com.atsuishio.superbwarfare.event.ClientEventHandler; import com.atsuishio.superbwarfare.init.ModItems; -import com.atsuishio.superbwarfare.tools.FormatTool; -import com.atsuishio.superbwarfare.tools.TraceTool; +import com.atsuishio.superbwarfare.tools.*; 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.CameraType; import net.minecraft.client.DeltaTracker; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.LayeredDraw; import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.ClipContext; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; @@ -29,26 +35,33 @@ import net.neoforged.api.distmarker.OnlyIn; import javax.annotation.ParametersAreNonnullByDefault; import static com.atsuishio.superbwarfare.client.RenderHelper.preciseBlit; +import static com.atsuishio.superbwarfare.item.ArtilleryIndicator.TAG_MORTARS; @OnlyIn(Dist.CLIENT) public class SpyglassRangeOverlay implements LayeredDraw.Layer { public static final ResourceLocation ID = Mod.loc("spyglass_range"); - + private static final ResourceLocation INDICATOR = Mod.loc("textures/screens/indicator.png"); + private static final ResourceLocation FRIENDLY_INDICATOR = Mod.loc("textures/screens/friendly_indicator.png"); private static float scopeScale = 1; @Override @ParametersAreNonnullByDefault public void render(GuiGraphics guiGraphics, DeltaTracker deltaTracker) { + Minecraft mc = Minecraft.getInstance(); PoseStack poseStack = guiGraphics.pose(); - Player player = Minecraft.getInstance().player; + Player player = mc.player; + Camera camera = mc.gameRenderer.getMainCamera(); + Vec3 cameraPos = camera.getPosition(); + if (player == null) return; var screenWidth = guiGraphics.guiWidth(); var screenHeight = guiGraphics.guiHeight(); if (((player.isUsingItem() && player.getUseItem().is(ModItems.ARTILLERY_INDICATOR.get())) || player.isScoping()) && Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON) { - if (player.getMainHandItem().getItem() == ModItems.ARTILLERY_INDICATOR.get()) { + if (player.getUseItem().is(ModItems.ARTILLERY_INDICATOR.get())) { + ItemStack stack = player.getUseItem(); poseStack.pushPose(); RenderSystem.disableDepthTest(); RenderSystem.depthMask(false); @@ -67,6 +80,44 @@ public class SpyglassRangeOverlay implements LayeredDraw.Layer { float l = ((screenHeight - j) / 2); float w = i * 21 / 9; preciseBlit(guiGraphics, Mod.loc("textures/screens/spyglass.png"), k - (2 * w / 7), l, 0, 0.0F, w, j, w, j); + + // 标记位置 + Vec3 pos; + var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS); + if (parameters != null) { + var blockPos = parameters.pos(); + pos = new Vec3(blockPos.getX(), blockPos.getY(), blockPos.getZ()); + } else { + pos = Vec3.ZERO; + } + Vec3 point = VectorUtil.worldToScreen(pos, cameraPos); + if (point != null) { + float x = (float) point.x; + float y = (float) point.y; + preciseBlit(guiGraphics, INDICATOR, Mth.clamp(x - 6, 0, screenWidth - 12), Mth.clamp(y - 6, 0, screenHeight - 12), 0, 0, 12, 12, 12, 12); + } + + // 火炮位置 + + ListTag tags = NBTTool.getTag(stack).getList(TAG_MORTARS, Tag.TAG_COMPOUND); + for (int m = 0; m < tags.size(); m++) { + var tag = tags.getCompound(m); + Entity entity = EntityFindUtil.findEntity(player.level(), tag.getString("UUID")); + if (entity != null) { + Vec3 posF = entity.getBoundingBox().getCenter(); + Vec3 pointF = VectorUtil.worldToScreen(posF, cameraPos); + if (pointF != null) { + float xf = (float) pointF.x; + float yf = (float) pointF.y; + + preciseBlit(guiGraphics, FRIENDLY_INDICATOR, Mth.clamp(xf - 6, 0, screenWidth - 12), Mth.clamp(yf - 6, 0, screenHeight - 12), 0, 0, 12, 12, 12, 12); + } + } + } + + RenderHelper.fill(guiGraphics, RenderType.guiOverlay(), (float) screenWidth / 2 - 20, (float) (screenHeight / 2 + 44), (float) screenWidth / 2 + 20, (float) screenHeight / 2 + 48, -90, -16777216); + RenderHelper.fill(guiGraphics, RenderType.guiOverlay(), (float) screenWidth / 2 - 20, (float) (screenHeight / 2 + 44), (float) (screenWidth / 2 - 20 + 4 * ClientEventHandler.holdArtilleryIndicator), (float) screenHeight / 2 + 48, -90, -1); + poseStack.popPose(); } diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/Agm65Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/Agm65Entity.java index a9228d03b..700a1439f 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/Agm65Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/Agm65Entity.java @@ -10,6 +10,7 @@ import com.atsuishio.superbwarfare.tools.*; import net.minecraft.core.BlockPos; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; @@ -40,7 +41,9 @@ import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; import software.bernie.geckolib.animation.*; import software.bernie.geckolib.util.GeckoLibUtil; +import java.util.HashSet; import java.util.List; +import java.util.Set; public class Agm65Entity extends FastThrowableProjectile implements GeoEntity, ExplosiveProjectile { @@ -48,6 +51,8 @@ public class Agm65Entity extends FastThrowableProjectile implements GeoEntity, E public static final EntityDataAccessor TARGET_UUID = SynchedEntityData.defineId(Agm65Entity.class, EntityDataSerializers.STRING); private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); + public Set loadedChunks = new HashSet<>(); + private float damage = ExplosionConfig.AGM_65_DAMAGE.get(); private float explosionDamage = ExplosionConfig.AGM_65_EXPLOSION_DAMAGE.get(); private float explosionRadius = ExplosionConfig.AGM_65_EXPLOSION_RADIUS.get().floatValue(); @@ -118,6 +123,14 @@ public class Agm65Entity extends FastThrowableProjectile implements GeoEntity, E if (compound.contains("Durability")) { this.durability = compound.getInt("Durability"); } + + if (compound.contains("Chunks")) { + ListTag listTag = compound.getList("Chunks", 10); + for (int i = 0; i < listTag.size(); i++) { + CompoundTag tag = listTag.getCompound(i); + this.loadedChunks.add(tag.getLong("Pos")); + } + } } @Override @@ -128,6 +141,14 @@ public class Agm65Entity extends FastThrowableProjectile implements GeoEntity, E compound.putFloat("ExplosionDamage", this.explosionDamage); compound.putFloat("Radius", this.explosionRadius); compound.putInt("Durability", this.durability); + + ListTag listTag = new ListTag(); + for (long chunkPos : this.loadedChunks) { + CompoundTag tag = new CompoundTag(); + tag.putLong("Pos", chunkPos); + listTag.add(tag); + } + compound.put("Chunks", listTag); } @Override @@ -204,6 +225,20 @@ public class Agm65Entity extends FastThrowableProjectile implements GeoEntity, E @Override public void tick() { super.tick(); + + if (this.level() instanceof ServerLevel serverLevel && tickCount > 1) { + double l = getDeltaMovement().length(); + for (double i = 0; i < l; i++) { + Vec3 startPos = new Vec3(this.xo, this.yo, this.zo); + Vec3 pos = startPos.add(getDeltaMovement().normalize().scale(-i)); + ParticleTool.sendParticle(serverLevel, ParticleTypes.CAMPFIRE_COSY_SMOKE, pos.x, pos.y, pos.z, + 1, 0, 0, 0, 0.001, true); + } + // 更新需要加载的区块 + ChunkLoadTool.updateLoadedChunks(serverLevel, this, this.loadedChunks); + } + + Entity entity = EntityFindUtil.findEntity(this.level(), entityData.get(TARGET_UUID)); List decoy = SeekTool.seekLivingEntities(this, this.level(), 32, 90); @@ -244,9 +279,6 @@ public class Agm65Entity extends FastThrowableProjectile implements GeoEntity, E } if (this.tickCount > 8) { - if (!this.level().isClientSide() && this.level() instanceof ServerLevel serverLevel) { - ParticleTool.sendParticle(serverLevel, ParticleTypes.CAMPFIRE_COSY_SMOKE, this.xo, this.yo, this.zo, 1, 0, 0, 0, 0, true); - } this.setDeltaMovement(this.getDeltaMovement().multiply(1.06, 1.06, 1.06)); } @@ -265,6 +297,14 @@ public class Agm65Entity extends FastThrowableProjectile implements GeoEntity, E destroyBlock(); } + @Override + public void onRemovedFromLevel() { + if (this.level() instanceof ServerLevel serverLevel) { + ChunkLoadTool.unloadAllChunks(serverLevel, this, this.loadedChunks); + } + super.onRemovedFromLevel(); + } + @Override public boolean isNoGravity() { return true; diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/CannonShellEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/CannonShellEntity.java index 14b1f3596..42ab655aa 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/CannonShellEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/CannonShellEntity.java @@ -203,10 +203,14 @@ public class CannonShellEntity extends FastThrowableProjectile implements GeoEnt @Override public void tick() { super.tick(); - if (this.level() instanceof ServerLevel serverLevel) { - ParticleTool.sendParticle(serverLevel, ParticleTypes.SMOKE, this.xo, this.yo, this.zo, - 1, 0, 0, 0, 0.001, true); - + if (this.level() instanceof ServerLevel serverLevel && tickCount > 1) { + double l = getDeltaMovement().length(); + for (double i = 0; i < l; i++) { + Vec3 startPos = new Vec3(this.xo, this.yo, this.zo); + Vec3 pos = startPos.add(getDeltaMovement().normalize().scale(-i)); + ParticleTool.sendParticle(serverLevel, ParticleTypes.CAMPFIRE_COSY_SMOKE, pos.x, pos.y, pos.z, + 1, 0, 0, 0, 0.001, true); + } // 更新需要加载的区块 ChunkLoadTool.updateLoadedChunks(serverLevel, this, this.loadedChunks); } diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/GunGrenadeEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/GunGrenadeEntity.java index 3670c099f..9889123b3 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/GunGrenadeEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/GunGrenadeEntity.java @@ -23,6 +23,7 @@ import net.minecraft.world.level.block.BellBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.EntityHitResult; +import net.minecraft.world.phys.Vec3; import net.neoforged.neoforge.network.PacketDistributor; import org.jetbrains.annotations.NotNull; import software.bernie.geckolib.animatable.GeoEntity; @@ -171,10 +172,14 @@ public class GunGrenadeEntity extends FastThrowableProjectile implements GeoEnti @Override public void tick() { super.tick(); - - if (!this.level().isClientSide() && this.level() instanceof ServerLevel serverLevel) { - ParticleTool.sendParticle(serverLevel, ParticleTypes.SMOKE, this.xo, this.yo, this.zo, - 1, 0, 0, 0, 0.02, true); + if (this.level() instanceof ServerLevel serverLevel && tickCount > 1) { + double l = getDeltaMovement().length(); + for (double i = 0; i < l; i++) { + Vec3 startPos = new Vec3(this.xo, this.yo, this.zo); + Vec3 pos = startPos.add(getDeltaMovement().normalize().scale(i)); + ParticleTool.sendParticle(serverLevel, ParticleTypes.SMOKE, pos.x, pos.y, pos.z, + 1, 0, 0, 0, 0.001, true); + } } if (this.tickCount > 200 || this.isInWater()) { diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/HeliRocketEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/HeliRocketEntity.java index 04235b96c..7fe8d92d2 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/HeliRocketEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/HeliRocketEntity.java @@ -167,17 +167,23 @@ public class HeliRocketEntity extends FastThrowableProjectile implements GeoEnti @Override public void tick() { super.tick(); + + if (this.level() instanceof ServerLevel serverLevel && tickCount > 1) { + double l = getDeltaMovement().length(); + for (double i = 0; i < l; i++) { + Vec3 startPos = new Vec3(this.xo, this.yo, this.zo); + Vec3 pos = startPos.add(getDeltaMovement().normalize().scale(i)); + ParticleTool.sendParticle(serverLevel, ParticleTypes.CAMPFIRE_COSY_SMOKE, pos.x, pos.y, pos.z, + 1, 0, 0, 0, 0.001, true); + } + } + if (this.tickCount == 3) { if (!this.level().isClientSide() && this.level() instanceof ServerLevel serverLevel) { ParticleTool.sendParticle(serverLevel, ParticleTypes.CLOUD, this.xo, this.yo, this.zo, 15, 0.8, 0.8, 0.8, 0.01, true); ParticleTool.sendParticle(serverLevel, ParticleTypes.CAMPFIRE_COSY_SMOKE, this.xo, this.yo, this.zo, 10, 0.8, 0.8, 0.8, 0.01, true); } } - if (this.tickCount > 2) { - if (!this.level().isClientSide() && this.level() instanceof ServerLevel serverLevel) { - ParticleTool.sendParticle(serverLevel, ParticleTypes.SMOKE, this.xo, this.yo, this.zo, 1, 0, 0, 0, 0, true); - } - } if (this.tickCount > 100 || this.isInWater()) { if (this.level() instanceof ServerLevel) { diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/JavelinMissileEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/JavelinMissileEntity.java index 5efe1b4c8..8e25fb8d5 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/JavelinMissileEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/JavelinMissileEntity.java @@ -234,6 +234,17 @@ public class JavelinMissileEntity extends FastThrowableProjectile implements Geo @Override public void tick() { super.tick(); + + if (this.level() instanceof ServerLevel serverLevel && tickCount > 1) { + double l = getDeltaMovement().length(); + for (double i = 0; i < l; i++) { + Vec3 startPos = new Vec3(this.xo, this.yo, this.zo); + Vec3 pos = startPos.add(getDeltaMovement().normalize().scale(i)); + ParticleTool.sendParticle(serverLevel, ParticleTypes.CAMPFIRE_COSY_SMOKE, pos.x, pos.y, pos.z, + 1, 0, 0, 0, 0.001, true); + } + } + Entity entity = EntityFindUtil.findEntity(this.level(), entityData.get(TARGET_UUID)); List decoy = SeekTool.seekLivingEntities(this, this.level(), 32, 90); @@ -324,12 +335,6 @@ public class JavelinMissileEntity extends FastThrowableProjectile implements Geo } } - if (this.tickCount > 4) { - if (!this.level().isClientSide() && this.level() instanceof ServerLevel serverLevel) { - ParticleTool.sendParticle(serverLevel, ParticleTypes.CAMPFIRE_COSY_SMOKE, this.xo, this.yo, this.zo, 1, 0, 0, 0, 0, true); - } - } - if (this.tickCount > 200 || this.isInWater() || this.entityData.get(HEALTH) <= 0) { if (this.level() instanceof ServerLevel) { ProjectileTool.causeCustomExplode(this, diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/MortarShellEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/MortarShellEntity.java index 7bd3bdae8..f44f9e8f6 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/MortarShellEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/MortarShellEntity.java @@ -226,10 +226,14 @@ public class MortarShellEntity extends FastThrowableProjectile implements GeoEnt @Override public void tick() { super.tick(); - if (this.level() instanceof ServerLevel serverLevel) { - ParticleTool.sendParticle(serverLevel, ParticleTypes.CAMPFIRE_COSY_SMOKE, this.xo, this.yo, this.zo, - 1, 0, 0, 0, 0.001, true); - + if (this.level() instanceof ServerLevel serverLevel && tickCount > 1) { + double l = getDeltaMovement().length(); + for (double i = 0; i < l; i++) { + Vec3 startPos = new Vec3(this.xo, this.yo, this.zo); + Vec3 pos = startPos.add(getDeltaMovement().normalize().scale(i)); + ParticleTool.sendParticle(serverLevel, ParticleTypes.CAMPFIRE_COSY_SMOKE, pos.x, pos.y, pos.z, + 1, 0, 0, 0, 0.001, true); + } // 更新需要加载的区块 ChunkLoadTool.updateLoadedChunks(serverLevel, this, this.loadedChunks); } @@ -271,7 +275,7 @@ public class MortarShellEntity extends FastThrowableProjectile implements GeoEnt @Override protected double getDefaultGravity() { - return 0.146F; + return 0.11; } @Override diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/RpgRocketEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/RpgRocketEntity.java index 02d406a23..a93aa5d32 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/RpgRocketEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/RpgRocketEntity.java @@ -197,6 +197,16 @@ public class RpgRocketEntity extends FastThrowableProjectile implements GeoEntit public void tick() { super.tick(); + if (this.level() instanceof ServerLevel serverLevel && tickCount > 1) { + double l = getDeltaMovement().length(); + for (double i = 0; i < l; i++) { + Vec3 startPos = new Vec3(this.xo, this.yo, this.zo); + Vec3 pos = startPos.add(getDeltaMovement().normalize().scale(i)); + ParticleTool.sendParticle(serverLevel, ParticleTypes.CAMPFIRE_COSY_SMOKE, pos.x, pos.y, pos.z, + 1, 0, 0, 0, 0.001, true); + } + } + if (this.tickCount == 3) { if (!this.level().isClientSide() && this.level() instanceof ServerLevel serverLevel) { ParticleTool.sendParticle(serverLevel, ParticleTypes.CLOUD, this.xo, this.yo, this.zo, 15, 0.8, 0.8, 0.8, 0.01, true); @@ -205,10 +215,6 @@ public class RpgRocketEntity extends FastThrowableProjectile implements GeoEntit } if (this.tickCount > 2) { this.setDeltaMovement(this.getDeltaMovement().multiply(1.03, 1.03, 1.03)); - - if (!this.level().isClientSide() && this.level() instanceof ServerLevel serverLevel) { - ParticleTool.sendParticle(serverLevel, ParticleTypes.SMOKE, this.xo, this.yo, this.zo, 1, 0, 0, 0, 0, true); - } } if (this.tickCount > 100 || this.isInWater()) { diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/WgMissileEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/WgMissileEntity.java index f0722cfbe..1cc74b3f7 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/WgMissileEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/WgMissileEntity.java @@ -193,6 +193,16 @@ public class WgMissileEntity extends FastThrowableProjectile implements GeoEntit public void tick() { super.tick(); + if (this.level() instanceof ServerLevel serverLevel && tickCount > 1) { + double l = getDeltaMovement().length(); + for (double i = 0; i < l; i++) { + Vec3 startPos = new Vec3(this.xo, this.yo, this.zo); + Vec3 pos = startPos.add(getDeltaMovement().normalize().scale(i)); + ParticleTool.sendParticle(serverLevel, ParticleTypes.CAMPFIRE_COSY_SMOKE, pos.x, pos.y, pos.z, + 1, 0, 0, 0, 0.001, true); + } + } + if (this.tickCount == 1) { if (!this.level().isClientSide() && this.level() instanceof ServerLevel serverLevel) { ParticleTool.sendParticle(serverLevel, ParticleTypes.CLOUD, this.xo, this.yo, this.zo, 15, 0.8, 0.8, 0.8, 0.01, true); @@ -201,10 +211,6 @@ public class WgMissileEntity extends FastThrowableProjectile implements GeoEntit } if (this.tickCount > 2) { this.setDeltaMovement(this.getDeltaMovement().multiply(1.03, 1.03, 1.03)); - - if (!this.level().isClientSide() && this.level() instanceof ServerLevel serverLevel) { - ParticleTool.sendParticle(serverLevel, ParticleTypes.SMOKE, this.xo, this.yo, this.zo, 1, 0, 0, 0, 0, true); - } } if (tickCount > 5 && this.getOwner() != null && getOwner().getVehicle() instanceof VehicleEntity vehicle) { diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/MortarEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/MortarEntity.java index ac9f4bc0e..b537e63c4 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/MortarEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/MortarEntity.java @@ -217,6 +217,9 @@ public class MortarEntity extends VehicleEntity implements GeoEntity, Container, if (mainHandItem.getItem() == ModItems.CROWBAR.get()) { this.discard(); ItemHandlerHelper.giveItemToPlayer(player, new ItemStack(ModItems.MORTAR_DEPLOYER.get())); + if (entityData.get(INTELLIGENT)) { + ItemHandlerHelper.giveItemToPlayer(player, new ItemStack(ModItems.MONITOR.get())); + } return InteractionResult.SUCCESS; } entityData.set(YAW, player.getYRot()); @@ -236,7 +239,7 @@ public class MortarEntity extends VehicleEntity implements GeoEntity, Container, var isDepressed = parameters.isDepressed(); try { - Vec3 launchVector = calculateLaunchVector(getEyePosition(), new Vec3(targetX, targetY, targetZ), 11.4, -0.146, isDepressed); + Vec3 launchVector = calculateLaunchVector(getEyePosition(), new Vec3(targetX, targetY, targetZ), 13, -0.11, isDepressed); this.look(new Vec3(targetX, targetY, targetZ)); float angle = (float) -getXRotFromVector(launchVector); if (angle < -89 || angle > -20) { @@ -275,7 +278,7 @@ public class MortarEntity extends VehicleEntity implements GeoEntity, Container, if (level instanceof ServerLevel server) { MortarShellEntity entityToSpawn = MortarShell.createShell(shooter, level, this.stack); entityToSpawn.setPos(this.getX(), this.getEyeY(), this.getZ()); - entityToSpawn.shoot(this.getLookAngle().x, this.getLookAngle().y, this.getLookAngle().z, 11.4f, (float) 0.5); + entityToSpawn.shoot(this.getLookAngle().x, this.getLookAngle().y, this.getLookAngle().z, 13f, (float) 1); level.addFreshEntity(entityToSpawn); server.sendParticles(ParticleTypes.CAMPFIRE_COSY_SMOKE, (this.getX() + 3 * this.getLookAngle().x), (this.getY() + 0.1 + 3 * this.getLookAngle().y), (this.getZ() + 3 * this.getLookAngle().z), 8, 0.4, 0.4, 0.4, 0.007); diff --git a/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java b/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java index 01775bc5a..1549a3572 100644 --- a/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java @@ -169,6 +169,8 @@ public class ClientEventHandler { public static boolean canDoubleJump = false; + public static int holdArtilleryIndicator; + @SubscribeEvent public static void handleWeaponTurn(RenderHandEvent event) { @@ -288,6 +290,17 @@ public class ClientEventHandler { canDoubleJump = false; } + if (stack.is(ModItems.ARTILLERY_INDICATOR.get()) && holdFire) { + holdArtilleryIndicator = Mth.clamp(holdArtilleryIndicator + 1, 0, 10); + if (holdArtilleryIndicator >= 9) { + PacketDistributor.sendToServer(new ArtilleryIndicatorFireMessage()); + } + } else { + holdArtilleryIndicator = Mth.clamp(holdArtilleryIndicator - 1, 0, 10); + } + + isProne(player); + beamShoot(player, stack); handleVariableDecrease(); aimAtVillager(player); staminaSystem(); diff --git a/src/main/java/com/atsuishio/superbwarfare/event/ClientMouseHandler.java b/src/main/java/com/atsuishio/superbwarfare/event/ClientMouseHandler.java index 174fddd54..e158a2201 100644 --- a/src/main/java/com/atsuishio/superbwarfare/event/ClientMouseHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/event/ClientMouseHandler.java @@ -180,7 +180,7 @@ public class ClientMouseHandler { event.setMouseSensitivity((newSensitivity - 0.2) / 0.6); } - public static float invertY() { + public static int invertY() { Minecraft mc = Minecraft.getInstance(); Player player = mc.player; @@ -222,6 +222,10 @@ public class ClientMouseHandler { return 0; } + if (player.isUsingItem() && player.getUseItem().is(ModItems.ARTILLERY_INDICATOR.get()) && mc.options.getCameraType() == CameraType.FIRST_PERSON) { + return original / Math.max(1 + 0.2 * ClientEventHandler.artilleryIndicatorZoom, 0.1); + } + if (player.getVehicle() instanceof VehicleEntity vehicle && vehicle instanceof WeaponVehicleEntity weaponVehicle && weaponVehicle.banHand(player)) { return vehicle.getSensitivity(original, ClientEventHandler.zoomVehicle, vehicle.getSeatIndex(player), vehicle.onGround()); } diff --git a/src/main/java/com/atsuishio/superbwarfare/network/NetworkRegistry.java b/src/main/java/com/atsuishio/superbwarfare/network/NetworkRegistry.java index 0ac776635..03f955589 100644 --- a/src/main/java/com/atsuishio/superbwarfare/network/NetworkRegistry.java +++ b/src/main/java/com/atsuishio/superbwarfare/network/NetworkRegistry.java @@ -48,7 +48,8 @@ public class NetworkRegistry { registrar.playToServer(PlayerStopRidingMessage.TYPE, PlayerStopRidingMessage.STREAM_CODEC, PlayerStopRidingMessage::handler); registrar.playToServer(ZoomMessage.TYPE, ZoomMessage.STREAM_CODEC, ZoomMessage::handler); registrar.playToServer(DroneFireMessage.TYPE, DroneFireMessage.STREAM_CODEC, DroneFireMessage::handler); - registrar.playToServer(SetFiringParametersMessage.TYPE, SetFiringParametersMessage.STREAM_CODEC, SetFiringParametersMessage::handler); + registrar.playToServer(SetFiringParametersMessage.TYPE, SetFiringParametersMessage.STREAM_CODEC, (message, context) -> SetFiringParametersMessage.handler(context)); + registrar.playToServer(ArtilleryIndicatorFireMessage.TYPE, ArtilleryIndicatorFireMessage.STREAM_CODEC, (message, context) -> ArtilleryIndicatorFireMessage.handler(context)); registrar.playToServer(SensitivityMessage.TYPE, SensitivityMessage.STREAM_CODEC, SensitivityMessage::handler); registrar.playToServer(EditMessage.TYPE, EditMessage.STREAM_CODEC, EditMessage::handler); registrar.playToServer(InteractMessage.TYPE, InteractMessage.STREAM_CODEC, InteractMessage::handler); diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/ArtilleryIndicatorFireMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/ArtilleryIndicatorFireMessage.java new file mode 100644 index 000000000..8e2c09120 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/ArtilleryIndicatorFireMessage.java @@ -0,0 +1,109 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.component.ModDataComponents; +import com.atsuishio.superbwarfare.entity.vehicle.MortarEntity; +import com.atsuishio.superbwarfare.init.ModItems; +import com.atsuishio.superbwarfare.init.ModSounds; +import com.atsuishio.superbwarfare.item.FiringParameters; +import com.atsuishio.superbwarfare.tools.EntityFindUtil; +import com.atsuishio.superbwarfare.tools.NBTTool; +import com.atsuishio.superbwarfare.tools.SoundTool; +import com.atsuishio.superbwarfare.tools.TraceTool; +import io.netty.buffer.ByteBuf; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.Tag; +import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ClipContext; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; + +import static com.atsuishio.superbwarfare.item.ArtilleryIndicator.TAG_MORTARS; + +public class ArtilleryIndicatorFireMessage implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("artillery_indicator_fire")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.unit(new ArtilleryIndicatorFireMessage()); + + public static void handler(final IPayloadContext context) { + Player player = context.player(); + ItemStack stack = player.getOffhandItem(); + ItemStack mainStack = player.getMainHandItem(); + boolean lookAtEntity = false; + Entity lookingEntity = TraceTool.findLookingEntity(player, 520); + + BlockHitResult result = player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(player.getViewVector(1).scale(512)), + ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player)); + Vec3 hitPos = result.getLocation(); + + if (lookingEntity != null) { + lookAtEntity = true; + } + if (stack.is(ModItems.FIRING_PARAMETERS.get())) { + + var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS); + var isDepressed = parameters != null && parameters.isDepressed(); + + if (lookAtEntity) { + stack.set(ModDataComponents.FIRING_PARAMETERS, new FiringParameters.Parameters(lookingEntity.blockPosition(), isDepressed)); + } else { + stack.set(ModDataComponents.FIRING_PARAMETERS, new FiringParameters.Parameters(new BlockPos((int) hitPos.x, (int) hitPos.y, (int) hitPos.z), isDepressed)); + } + + var pos = Objects.requireNonNull(stack.get(ModDataComponents.FIRING_PARAMETERS)).pos(); + + player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.target_pos") + .withStyle(ChatFormatting.GRAY) + .append(Component.literal("[" + pos.getX() + + "," + pos.getY() + + "," + pos.getZ() + + "]")), true); + } + + if (mainStack.is(ModItems.ARTILLERY_INDICATOR.get())) { + if (lookAtEntity) { + stack.set(ModDataComponents.FIRING_PARAMETERS, new FiringParameters.Parameters(lookingEntity.blockPosition(), false)); + } else { + stack.set(ModDataComponents.FIRING_PARAMETERS, new FiringParameters.Parameters(new BlockPos((int) hitPos.x, (int) hitPos.y, (int) hitPos.z), false)); + } + + var pos = Objects.requireNonNull(stack.get(ModDataComponents.FIRING_PARAMETERS)).pos(); + + player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.target_pos") + .withStyle(ChatFormatting.GRAY) + .append(Component.literal("[" + pos.getX() + + "," + pos.getY() + + "," + pos.getZ() + + "]")), true); + SoundTool.playLocalSound(player, ModSounds.CANNON_ZOOM_IN.get(), 2, 1); + + var mainTag = NBTTool.getTag(mainStack); + ListTag tags = mainTag.getList(TAG_MORTARS, Tag.TAG_COMPOUND); + for (int i = 0; i < tags.size(); i++) { + var tag = tags.getCompound(i); + Entity entity = EntityFindUtil.findEntity(player.level(), tag.getString("UUID")); + if (entity instanceof MortarEntity mortarEntity) { + if (!mortarEntity.setTarget(mainStack)) { + player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.warn").withStyle(ChatFormatting.RED), true); + } + } + } + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/SetFiringParametersMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/SetFiringParametersMessage.java index c705faa0c..b4d2b1f79 100644 --- a/src/main/java/com/atsuishio/superbwarfare/network/message/send/SetFiringParametersMessage.java +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/SetFiringParametersMessage.java @@ -4,10 +4,11 @@ import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.component.ModDataComponents; import com.atsuishio.superbwarfare.entity.vehicle.MortarEntity; import com.atsuishio.superbwarfare.init.ModItems; +import com.atsuishio.superbwarfare.init.ModSounds; import com.atsuishio.superbwarfare.item.FiringParameters; -import com.atsuishio.superbwarfare.item.common.ammo.MortarShell; import com.atsuishio.superbwarfare.tools.EntityFindUtil; import com.atsuishio.superbwarfare.tools.NBTTool; +import com.atsuishio.superbwarfare.tools.SoundTool; import com.atsuishio.superbwarfare.tools.TraceTool; import io.netty.buffer.ByteBuf; import net.minecraft.ChatFormatting; @@ -15,36 +16,27 @@ import net.minecraft.core.BlockPos; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; -import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.ClipContext; -import net.minecraft.world.level.Level; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; import net.neoforged.neoforge.network.handling.IPayloadContext; import org.jetbrains.annotations.NotNull; -import java.util.List; import java.util.Objects; -import java.util.stream.StreamSupport; -import static com.atsuishio.superbwarfare.entity.vehicle.MortarEntity.FIRE_TIME; import static com.atsuishio.superbwarfare.item.ArtilleryIndicator.TAG_MORTARS; -public record SetFiringParametersMessage(int msgType) implements CustomPacketPayload { +public class SetFiringParametersMessage implements CustomPacketPayload { public static final Type TYPE = new Type<>(Mod.loc("set_firing_parameters")); - public static final StreamCodec STREAM_CODEC = StreamCodec.composite( - ByteBufCodecs.INT, - SetFiringParametersMessage::msgType, - SetFiringParametersMessage::new - ); + public static final StreamCodec STREAM_CODEC = StreamCodec.unit(new SetFiringParametersMessage()); - public static void handler(SetFiringParametersMessage message, final IPayloadContext context) { + public static void handler(final IPayloadContext context) { Player player = context.player(); ItemStack stack = player.getOffhandItem(); ItemStack mainStack = player.getMainHandItem(); @@ -80,54 +72,33 @@ public record SetFiringParametersMessage(int msgType) implements CustomPacketPay } if (mainStack.is(ModItems.ARTILLERY_INDICATOR.get())) { - if (player.isShiftKeyDown()) { - var mainTag = NBTTool.getTag(mainStack); - ListTag tags = mainTag.getList(TAG_MORTARS, Tag.TAG_COMPOUND); - for (int i = 0; i < tags.size(); i++) { - var tag = tags.getCompound(i); - Entity entity = EntityFindUtil.findEntity(player.level(), tag.getString("UUID")); - if (entity instanceof MortarEntity mortarEntity) { - if (player.isShiftKeyDown()) { - if (mortarEntity.stack.getItem() instanceof MortarShell && mortarEntity.getEntityData().get(FIRE_TIME) == 0) { - mortarEntity.fire(player); - } - } else { - if (!mortarEntity.setTarget(mainStack)) { - player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.warn").withStyle(ChatFormatting.RED), true); - } - } + if (lookAtEntity) { + stack.set(ModDataComponents.FIRING_PARAMETERS, new FiringParameters.Parameters(lookingEntity.blockPosition(), false)); + } else { + stack.set(ModDataComponents.FIRING_PARAMETERS, new FiringParameters.Parameters(new BlockPos((int) hitPos.x, (int) hitPos.y, (int) hitPos.z), false)); + } + + var pos = Objects.requireNonNull(stack.get(ModDataComponents.FIRING_PARAMETERS)).pos(); + + player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.target_pos") + .withStyle(ChatFormatting.GRAY) + .append(Component.literal("[" + pos.getX() + + "," + pos.getY() + + "," + pos.getZ() + + "]")), true); + SoundTool.playLocalSound(player, ModSounds.CANNON_ZOOM_IN.get(), 2, 1); + + var mainTag = NBTTool.getTag(mainStack); + ListTag tags = mainTag.getList(TAG_MORTARS, Tag.TAG_COMPOUND); + for (int i = 0; i < tags.size(); i++) { + var tag = tags.getCompound(i); + Entity entity = EntityFindUtil.findEntity(player.level(), tag.getString("UUID")); + if (entity instanceof MortarEntity mortarEntity) { + if (!mortarEntity.setTarget(mainStack)) { + player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.warn").withStyle(ChatFormatting.RED), true); } } - } else { - BlockPos pos; - if (lookAtEntity) { - pos = lookingEntity.blockPosition(); - } else { - pos = new BlockPos((int) hitPos.x, (int) hitPos.y, (int) hitPos.z); - } - mainStack.set(ModDataComponents.FIRING_PARAMETERS, new FiringParameters.Parameters(pos, false)); - - player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.target_pos") - .withStyle(ChatFormatting.GRAY) - .append(Component.literal("[" + pos.getX() - + "," + pos.getY() - + "," + pos.getZ() - + "]")), true); } -// List entities = getCannon(player, player.level(), mainStack.getOrCreateTag().getString("LinkedCannon")); -// for (var e : entities) { -// if (e instanceof MortarEntity mortarEntity) { -// if (player.isShiftKeyDown()) { -// if (!mortarEntity.setTarget(mainStack)) { -// player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.warn").withStyle(ChatFormatting.RED), true); -// } -// } else { -// if (mortarEntity.stack.getItem() instanceof MortarShell && mortarEntity.getEntityData().get(FIRE_TIME) == 0) { -// mortarEntity.fire(player); -// } -// } -// } -// } } } @@ -135,10 +106,4 @@ public record SetFiringParametersMessage(int msgType) implements CustomPacketPay public @NotNull Type type() { return TYPE; } - - public static List getCannon(Player player, Level level, String uuid) { - return StreamSupport.stream(EntityFindUtil.getEntities(level).getAll().spliterator(), false) - .filter(e -> e.getStringUUID().equals(uuid)) - .toList(); - } } diff --git a/src/main/resources/assets/superbwarfare/textures/screens/friendly_indicator.png b/src/main/resources/assets/superbwarfare/textures/screens/friendly_indicator.png new file mode 100644 index 000000000..ca3baae97 Binary files /dev/null and b/src/main/resources/assets/superbwarfare/textures/screens/friendly_indicator.png differ diff --git a/src/main/resources/assets/superbwarfare/textures/screens/indicator.png b/src/main/resources/assets/superbwarfare/textures/screens/indicator.png new file mode 100644 index 000000000..fe2ba1cb5 Binary files /dev/null and b/src/main/resources/assets/superbwarfare/textures/screens/indicator.png differ