完善炮击指示器功能,优化弹射物尾迹视觉效果

This commit is contained in:
Atsuishio 2025-07-09 15:09:11 +08:00 committed by Light_Quanta
parent 5354d8e7de
commit 86246f2cd9
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
19 changed files with 339 additions and 111 deletions

View file

@ -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())) {

View file

@ -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);
}
}

View file

@ -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();
}

View file

@ -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<String> TARGET_UUID = SynchedEntityData.defineId(Agm65Entity.class, EntityDataSerializers.STRING);
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
public Set<Long> 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<Entity> 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;

View file

@ -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);
}

View file

@ -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()) {

View file

@ -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) {

View file

@ -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<Entity> 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,

View file

@ -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

View file

@ -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()) {

View file

@ -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) {

View file

@ -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);

View file

@ -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();

View file

@ -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());
}

View file

@ -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);

View file

@ -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<ArtilleryIndicatorFireMessage> TYPE = new Type<>(Mod.loc("artillery_indicator_fire"));
public static final StreamCodec<ByteBuf, ArtilleryIndicatorFireMessage> 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<? extends CustomPacketPayload> type() {
return TYPE;
}
}

View file

@ -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<SetFiringParametersMessage> TYPE = new Type<>(Mod.loc("set_firing_parameters"));
public static final StreamCodec<ByteBuf, SetFiringParametersMessage> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.INT,
SetFiringParametersMessage::msgType,
SetFiringParametersMessage::new
);
public static final StreamCodec<ByteBuf, SetFiringParametersMessage> 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<Entity> 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<? extends CustomPacketPayload> type() {
return TYPE;
}
public static List<Entity> getCannon(Player player, Level level, String uuid) {
return StreamSupport.stream(EntityFindUtil.getEntities(level).getAll().spliterator(), false)
.filter(e -> e.getStringUUID().equals(uuid))
.toList();
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB