From 4acee4807c7b07913cee030b739e84467588e087 Mon Sep 17 00:00:00 2001 From: 17146 <1714673995@qq.com> Date: Fri, 17 Jan 2025 21:55:24 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=99=E5=85=B6=E4=BB=96=E6=8A=95=E5=B0=84?= =?UTF-8?q?=E7=89=A9=E6=B7=BB=E5=8A=A0=E5=8A=A0=E8=BD=BD=E5=8C=BA=E5=9D=97?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/projectile/CannonShellEntity.java | 116 ++++++++++++++++-- .../entity/vehicle/Mk42Entity.java | 6 +- .../entity/vehicle/Mle1934Entity.java | 12 +- 3 files changed, 112 insertions(+), 22 deletions(-) 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 f4550dd69..481e12663 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/CannonShellEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/CannonShellEntity.java @@ -10,6 +10,8 @@ import com.atsuishio.superbwarfare.tools.ParticleTool; import com.atsuishio.superbwarfare.tools.ProjectileTool; 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.protocol.Packet; import net.minecraft.network.protocol.game.ClientGamePacketListener; import net.minecraft.network.syncher.EntityDataAccessor; @@ -23,6 +25,7 @@ import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.projectile.ThrowableItemProjectile; import net.minecraft.world.item.Item; +import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.Explosion; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; @@ -32,6 +35,7 @@ import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.EntityHitResult; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; +import net.minecraftforge.common.world.ForgeChunkManager; import net.minecraftforge.network.NetworkHooks; import net.minecraftforge.network.PacketDistributor; import net.minecraftforge.network.PlayMessages; @@ -44,6 +48,9 @@ import software.bernie.geckolib.core.animation.RawAnimation; import software.bernie.geckolib.core.object.PlayState; import software.bernie.geckolib.util.GeckoLibUtil; +import java.util.HashSet; +import java.util.Set; + public class CannonShellEntity extends ThrowableItemProjectile implements GeoEntity, AnimatedEntity { public static final EntityDataAccessor ANIMATION = SynchedEntityData.defineId(CannonShellEntity.class, EntityDataSerializers.STRING); @@ -51,22 +58,23 @@ public class CannonShellEntity extends ThrowableItemProjectile implements GeoEnt public String animationprocedure = "empty"; private float damage = 0; - private float explosionRadius = 0; + private float radius = 0; private float explosionDamage = 0; private float fireProbability = 0; private int fireTime = 0; private int durability = 40; private boolean firstHit = true; + public Set loadedChunks = new HashSet<>(); public CannonShellEntity(EntityType type, Level world) { super(type, world); this.noCulling = true; } - public CannonShellEntity(EntityType type, LivingEntity entity, Level world, float damage, float explosionRadius, float explosionDamage, float fireProbability, int fireTime) { - super(type, entity, world); + public CannonShellEntity(LivingEntity entity, Level world, float damage, float radius, float explosionDamage, float fireProbability, int fireTime) { + super(ModEntities.CANNON_SHELL.get(), entity, world); this.damage = damage; - this.explosionRadius = explosionRadius; + this.radius = radius; this.explosionDamage = explosionDamage; this.fireProbability = fireProbability; this.fireTime = fireTime; @@ -81,6 +89,63 @@ public class CannonShellEntity extends ThrowableItemProjectile implements GeoEnt return this; } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + + pCompound.putFloat("Damage", this.damage); + pCompound.putFloat("ExplosionDamage", this.explosionDamage); + pCompound.putFloat("Radius", this.radius); + pCompound.putFloat("FireProbability", this.fireProbability); + pCompound.putInt("FireTime", this.fireTime); + pCompound.putInt("Durability", this.durability); + + ListTag listTag = new ListTag(); + for (long chunkPos : this.loadedChunks) { + CompoundTag tag = new CompoundTag(); + tag.putLong("Pos", chunkPos); + listTag.add(tag); + } + pCompound.put("Chunks", listTag); + } + + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + + if (pCompound.contains("Damage")) { + this.damage = pCompound.getFloat("Damage"); + } + + if (pCompound.contains("ExplosionDamage")) { + this.explosionDamage = pCompound.getFloat("ExplosionDamage"); + } + + if (pCompound.contains("Radius")) { + this.radius = pCompound.getFloat("Radius"); + } + + if (pCompound.contains("FireProbability")) { + this.fireProbability = pCompound.getFloat("FireProbability"); + } + + if (pCompound.contains("FireTime")) { + this.fireTime = pCompound.getInt("FireTime"); + } + + if (pCompound.contains("Durability")) { + this.durability = pCompound.getInt("Durability"); + } + + if (pCompound.contains("Chunks")) { + ListTag listTag = pCompound.getList("Chunks", 10); + for (int i = 0; i < listTag.size(); i++) { + CompoundTag tag = listTag.getCompound(i); + this.loadedChunks.add(tag.getLong("Pos")); + } + } + } + @Override public Packet getAddEntityPacket() { return NetworkHooks.getEntitySpawningPacket(this); @@ -139,7 +204,6 @@ public class CannonShellEntity extends ThrowableItemProjectile implements GeoEnt int y = blockHitResult.getBlockPos().getY(); int z = blockHitResult.getBlockPos().getZ(); - BlockState blockState = this.level().getBlockState(BlockPos.containing(x, y, z)); if (blockState.is(Blocks.BEDROCK) || blockState.is(Blocks.BARRIER)) { this.discard(); @@ -151,9 +215,9 @@ public class CannonShellEntity extends ThrowableItemProjectile implements GeoEnt this.durability -= (int) hardness; if (ExplosionDestroyConfig.EXPLOSION_DESTROY.get() && hardness != -1 && hardness <= 50) { - BlockPos _pos = BlockPos.containing(x, y, z); - Block.dropResources(this.level().getBlockState(_pos), this.level(), BlockPos.containing(x, y, z), null); - this.level().destroyBlock(_pos, true); + BlockPos blockPos = BlockPos.containing(x, y, z); + Block.dropResources(this.level().getBlockState(blockPos), this.level(), BlockPos.containing(x, y, z), null); + this.level().destroyBlock(blockPos, true); } Vec3 vec = this.getDeltaMovement(); @@ -207,12 +271,28 @@ public class CannonShellEntity extends ThrowableItemProjectile implements GeoEnt if (this.level() instanceof ServerLevel serverLevel) { ParticleTool.sendParticle(serverLevel, ParticleTypes.SMOKE, this.xo, this.yo, this.zo, 1, 0, 0, 0, 0.001, true); + + var movement = this.getDeltaMovement(); + var currentX = this.chunkPosition().x; + var currentZ = this.chunkPosition().z; + var nextX = movement.x > 0 ? currentX + 1 : currentX - 1; + var nextZ = movement.z > 0 ? currentZ + 1 : currentZ - 1; + + ForgeChunkManager.forceChunk(serverLevel, ModUtils.MODID, this, currentX, currentZ, true, false); + ForgeChunkManager.forceChunk(serverLevel, ModUtils.MODID, this, currentX, nextZ, true, false); + ForgeChunkManager.forceChunk(serverLevel, ModUtils.MODID, this, nextX, currentZ, true, false); + ForgeChunkManager.forceChunk(serverLevel, ModUtils.MODID, this, nextX, nextZ, true, false); + + this.loadedChunks.add(ChunkPos.asLong(currentX, currentZ)); + this.loadedChunks.add(ChunkPos.asLong(currentX, nextZ)); + this.loadedChunks.add(ChunkPos.asLong(nextX, currentZ)); + this.loadedChunks.add(ChunkPos.asLong(nextX, nextZ)); } if (this.tickCount > 600 || this.isInWater()) { if (this.level() instanceof ServerLevel) { ProjectileTool.causeCustomExplode(this, ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()), - this, this.explosionDamage, this.explosionRadius, 1.25f); + this, this.explosionDamage, this.radius, 1.25f); } this.discard(); } @@ -231,14 +311,14 @@ public class CannonShellEntity extends ThrowableItemProjectile implements GeoEnt result.getLocation().x, result.getLocation().y, result.getLocation().z, - explosionRadius, + radius, ExplosionDestroyConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP). setDamageMultiplier(1).setFireTime(fireTime); explosion.explode(); net.minecraftforge.event.ForgeEventFactory.onExplosionStart(this.level(), explosion); explosion.finalizeExplosion(false); - if (explosionRadius > 7) { + if (radius > 7) { ParticleTool.spawnHugeExplosionParticles(this.level(), result.getLocation()); } else { ParticleTool.spawnMediumExplosionParticles(this.level(), result.getLocation()); @@ -258,14 +338,14 @@ public class CannonShellEntity extends ThrowableItemProjectile implements GeoEnt result.getLocation().x, result.getLocation().y, result.getLocation().z, - explosionRadius, + radius, ExplosionDestroyConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP). setDamageMultiplier(1).setFireTime(fireTime); explosion.explode(); net.minecraftforge.event.ForgeEventFactory.onExplosionStart(this.level(), explosion); explosion.finalizeExplosion(false); - if (explosionRadius > 7) { + if (radius > 7) { ParticleTool.spawnHugeExplosionParticles(this.level(), result.getLocation()); } else { ParticleTool.spawnMediumExplosionParticles(this.level(), result.getLocation()); @@ -320,4 +400,14 @@ public class CannonShellEntity extends ThrowableItemProjectile implements GeoEnt public AnimatableInstanceCache getAnimatableInstanceCache() { return this.cache; } + + @Override + public void onRemovedFromWorld() { + if (this.level() instanceof ServerLevel serverLevel) { + for (long chunkPos : this.loadedChunks) { + ForgeChunkManager.forceChunk(serverLevel, ModUtils.MODID, this, ChunkPos.getX(chunkPos), ChunkPos.getZ(chunkPos), false, false); + } + } + super.onRemovedFromWorld(); + } } diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Mk42Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Mk42Entity.java index a3d029b95..4c77f703c 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Mk42Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Mk42Entity.java @@ -221,8 +221,8 @@ public class Mk42Entity extends VehicleEntity implements GeoEntity, ICannonEntit stack.shrink(1); } - CannonShellEntity entityToSpawn = new CannonShellEntity(ModEntities.CANNON_SHELL.get(), - player, level, hitDamage, explosionRadius, explosionDamage, fireProbability, fireTime).durability(durability); + CannonShellEntity entityToSpawn = new CannonShellEntity(player, level, hitDamage, explosionRadius, explosionDamage, fireProbability, fireTime) + .durability(durability); entityToSpawn.setPos(this.getX(), this.getEyeY(), this.getZ()); entityToSpawn.shoot(this.getLookAngle().x, this.getLookAngle().y, this.getLookAngle().z, 15, 0.05f); @@ -283,7 +283,7 @@ public class Mk42Entity extends VehicleEntity implements GeoEntity, ICannonEntit float diffX = entity.getXRot() - 1.3f - this.getXRot(); diffX = diffX * 0.15f; - this.setYRot(this.getYRot() + Mth.clamp(0.5f * diffY,-1.75f, 1.75f)); + this.setYRot(this.getYRot() + Mth.clamp(0.5f * diffY, -1.75f, 1.75f)); this.setXRot(Mth.clamp(this.getXRot() + Mth.clamp(diffX, -3f, 3f), -85, 16.3f)); } diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Mle1934Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Mle1934Entity.java index 0b6bbe88b..1ed441df0 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Mle1934Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Mle1934Entity.java @@ -248,8 +248,8 @@ public class Mle1934Entity extends VehicleEntity implements GeoEntity, ICannonEn leftPos.rotateY(-yRot * Mth.DEG_TO_RAD); // 左炮管 - CannonShellEntity entityToSpawnLeft = new CannonShellEntity(ModEntities.CANNON_SHELL.get(), - player, level, hitDamage, explosionRadius, explosionDamage, fireProbability, fireTime).durability(durability); + CannonShellEntity entityToSpawnLeft = new CannonShellEntity(player, level, hitDamage, explosionRadius, explosionDamage, fireProbability, fireTime) + .durability(durability); entityToSpawnLeft.setPos(this.getX() + leftPos.x, this.getEyeY() - 0.2 + leftPos.y, @@ -293,8 +293,8 @@ public class Mle1934Entity extends VehicleEntity implements GeoEntity, ICannonEn rightPos.rotateZ(-this.getXRot() * Mth.DEG_TO_RAD); rightPos.rotateY(-yRot * Mth.DEG_TO_RAD); - CannonShellEntity entityToSpawnRight = new CannonShellEntity(ModEntities.CANNON_SHELL.get(), - player, level, hitDamage, explosionRadius, explosionDamage, fireProbability, fireTime).durability(durability); + CannonShellEntity entityToSpawnRight = new CannonShellEntity(player, level, hitDamage, explosionRadius, explosionDamage, fireProbability, fireTime) + .durability(durability); entityToSpawnRight.setPos(this.getX() + rightPos.x, this.getEyeY() - 0.2 + rightPos.y, @@ -374,7 +374,7 @@ public class Mle1934Entity extends VehicleEntity implements GeoEntity, ICannonEn diffX = diffX * 0.15f; - this.setYRot(this.getYRot() + Mth.clamp(0.5f * diffY,-1.25f, 1.25f)); + this.setYRot(this.getYRot() + Mth.clamp(0.5f * diffY, -1.25f, 1.25f)); this.setXRot(Mth.clamp(this.getXRot() + Mth.clamp(diffX, -2f, 2f), -30, 4)); } @@ -415,7 +415,7 @@ public class Mle1934Entity extends VehicleEntity implements GeoEntity, ICannonEn public float getMaxHealth() { return MAX_HEALTH; } - + @Override public boolean isDriver(Player player) { return player == this.getFirstPassenger();