From 8bccd8426b3203a2e83e8060591f5f5d3248e7d5 Mon Sep 17 00:00:00 2001 From: Atsuishio <842960157@qq.com> Date: Tue, 17 Jun 2025 15:19:50 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E9=AB=98=E6=89=80=E6=9C=89=E5=BC=B9?= =?UTF-8?q?=E5=B0=84=E7=89=A9=E7=9A=84=E7=A9=BF=E9=80=8F=E6=80=A7=EF=BC=88?= =?UTF-8?q?=E6=81=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/projectile/Agm65Entity.java | 105 +++++----- .../entity/projectile/C4Entity.java | 12 ++ .../entity/projectile/CannonShellEntity.java | 104 ++++------ .../entity/projectile/GunGrenadeEntity.java | 24 ++- .../entity/projectile/HeliRocketEntity.java | 115 ++++++++--- .../projectile/JavelinMissileEntity.java | 179 +++++++++++------- .../entity/projectile/MelonBombEntity.java | 20 +- .../entity/projectile/Mk82Entity.java | 19 +- .../entity/projectile/MortarShellEntity.java | 13 +- .../entity/projectile/RpgRocketEntity.java | 119 ++++++++---- .../projectile/SmallCannonShellEntity.java | 13 +- .../entity/projectile/WgMissileEntity.java | 121 +++++++++--- 12 files changed, 552 insertions(+), 292 deletions(-) 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 22d2b07fb..52e9be365 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/Agm65Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/Agm65Entity.java @@ -32,10 +32,9 @@ import net.minecraft.world.entity.projectile.ThrownPotion; import net.minecraft.world.item.Item; import net.minecraft.world.level.Explosion; import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; +import net.minecraft.world.phys.AABB; 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.neoforged.neoforge.event.EventHooks; import net.neoforged.neoforge.network.PacketDistributor; @@ -59,6 +58,8 @@ public class Agm65Entity extends FastThrowableProjectile implements GeoEntity, E private float explosionRadius = ExplosionConfig.AGM_65_EXPLOSION_RADIUS.get().floatValue(); private boolean distracted = false; + private int durability = 100; + public Agm65Entity(EntityType type, Level world) { super(type, world); this.noCulling = true; @@ -147,7 +148,7 @@ public class Agm65Entity extends FastThrowableProjectile implements GeoEntity, E Entity entity = result.getEntity(); if (this.getOwner() != null && this.getOwner().getVehicle() != null && entity == this.getOwner().getVehicle()) return; - if (this.level() instanceof ServerLevel && tickCount > 8) { + if (this.level() instanceof ServerLevel) { if (entity == this.getOwner() || (this.getOwner() != null && entity == this.getOwner().getVehicle())) return; if (this.getOwner() instanceof LivingEntity living) { @@ -165,58 +166,87 @@ public class Agm65Entity extends FastThrowableProjectile implements GeoEntity, E } for (int i = 0; i < 5; i++) { - apExplode(result, i); + apExplode(result.getLocation().add(getDeltaMovement().normalize().scale(i))); } - causeExplode(result); + causeExplode(result.getLocation()); this.discard(); } } - @Override - public boolean isNoGravity() { - return true; - } - @Override public void onHitBlock(@NotNull BlockHitResult blockHitResult) { if (this.level() instanceof ServerLevel) { - double x = blockHitResult.getLocation().x; - double y = blockHitResult.getLocation().y; - double z = blockHitResult.getLocation().z; + BlockPos resultPos = blockHitResult.getBlockPos(); - if (ExplosionConfig.EXPLOSION_DESTROY.get()) { - float hardness = this.level().getBlockState(BlockPos.containing(x, y, z)).getBlock().defaultDestroyTime(); - if (hardness <= 50 && hardness != -1) { - 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); + float hardness = this.level().getBlockState(resultPos).getBlock().defaultDestroyTime(); + + if (hardness == -1) { + this.discard(); + causeExplode(blockHitResult.getLocation()); + return; + } else { + if (ExplosionConfig.EXPLOSION_DESTROY.get()) { + this.level().destroyBlock(resultPos, true); } } - for (int i = 0; i < 5; i++) { - apExplode(blockHitResult, i); - } + causeExplode(blockHitResult.getLocation()); - causeExplode(blockHitResult); + for (int i = 0; i < 8; i++) { + Vec3 hitPos = blockHitResult.getLocation().add(getDeltaMovement().normalize().scale(i)); + AABB aabb = new AABB(hitPos, hitPos).inflate(0.25); + if (durability > 0) { + BlockPos.betweenClosedStream(aabb).forEach((pos) -> { + float hard = this.level().getBlockState(pos).getBlock().defaultDestroyTime(); + durability -= (int) hard; + if (ExplosionConfig.EXPLOSION_DESTROY.get()) { + this.level().destroyBlock(pos, true); + } + apExplode(hitPos); + }); + } + } + if (durability <= 0) { + discard(); + } } } - private void apExplode(HitResult result, int index) { + private void causeExplode(Vec3 vec3) { CustomExplosion explosion = new CustomExplosion(this.level(), this, ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()), explosionDamage, - result.getLocation().x + index * getDeltaMovement().normalize().x, - result.getLocation().y + index * getDeltaMovement().normalize().y, - result.getLocation().z + index * getDeltaMovement().normalize().z, - 0.5f * explosionRadius, + vec3.x, + vec3.y, + vec3.z, + explosionRadius, ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP, true). setDamageMultiplier(1); explosion.explode(); EventHooks.onExplosionStart(this.level(), explosion); explosion.finalizeExplosion(false); + ParticleTool.spawnHugeExplosionParticles(this.level(), vec3); + } + + private void apExplode(Vec3 vec3) { + CustomExplosion explosion = new CustomExplosion(this.level(), this, + ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), + this, + this.getOwner()), + explosionDamage, + vec3.x, + vec3.y, + vec3.z, + explosionRadius * 0.5f, + ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP, true). + setDamageMultiplier(1); + explosion.explode(); + EventHooks.onExplosionStart(this.level(), explosion); + explosion.finalizeExplosion(false); + ParticleTool.spawnMediumExplosionParticles(this.level(), vec3); } @Override @@ -281,22 +311,9 @@ public class Agm65Entity extends FastThrowableProjectile implements GeoEntity, E this.setDeltaMovement(this.getDeltaMovement().multiply(f, f, f)); } - private void causeExplode(HitResult result) { - CustomExplosion explosion = new CustomExplosion(this.level(), this, - ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), - this, - this.getOwner()), - this.explosionDamage, - this.getX(), - this.getEyeY(), - this.getZ(), - this.explosionRadius, - ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP, true). - setDamageMultiplier(1); - explosion.explode(); - EventHooks.onExplosionStart(this.level(), explosion); - explosion.finalizeExplosion(false); - ParticleTool.spawnHugeExplosionParticles(this.level(), result.getLocation()); + @Override + public boolean isNoGravity() { + return true; } private PlayState movementPredicate(AnimationState event) { diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/C4Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/C4Entity.java index 99ce97c93..88554b096 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/C4Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/C4Entity.java @@ -17,6 +17,7 @@ import net.minecraft.nbt.NbtUtils; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.server.level.ServerLevel; import net.minecraft.server.players.OldUsersConverter; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundSource; @@ -412,6 +413,17 @@ public class C4Entity extends Entity implements GeoEntity, OwnableEntity { } } + if (this.level() instanceof ServerLevel) { + AABB aabb = new AABB(pos, pos).inflate(3); + BlockPos.betweenClosedStream(aabb).forEach((blockPos) -> { + float hard = this.level().getBlockState(blockPos).getBlock().defaultDestroyTime(); + if (ExplosionConfig.EXPLOSION_DESTROY.get() && hard != -1 && new Vec3(blockPos.getX(), blockPos.getY(), blockPos.getZ()).distanceTo(position()) < 2) { + this.level().destroyBlock(blockPos, true); + } + + }); + } + CustomExplosion explosion = new CustomExplosion(level(), this, ModDamageTypes.causeProjectileBoomDamage(level().registryAccess(), this, this.getOwner()), ExplosionConfig.C4_EXPLOSION_DAMAGE.get(), pos.x, pos.y, pos.z, ExplosionConfig.C4_EXPLOSION_RADIUS.get(), ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP, true).setDamageMultiplier(1); 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 73c246c7c..d5f92fc4c 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/CannonShellEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/CannonShellEntity.java @@ -2,7 +2,10 @@ package com.atsuishio.superbwarfare.entity.projectile; import com.atsuishio.superbwarfare.config.server.ExplosionConfig; import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; -import com.atsuishio.superbwarfare.init.*; +import com.atsuishio.superbwarfare.init.ModDamageTypes; +import com.atsuishio.superbwarfare.init.ModEntities; +import com.atsuishio.superbwarfare.init.ModItems; +import com.atsuishio.superbwarfare.init.ModSounds; import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage; import com.atsuishio.superbwarfare.network.message.receive.ClientMotionSyncMessage; import com.atsuishio.superbwarfare.tools.ChunkLoadTool; @@ -23,12 +26,9 @@ import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.Item; import net.minecraft.world.level.Explosion; import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; 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.neoforged.neoforge.event.EventHooks; import net.neoforged.neoforge.network.PacketDistributor; @@ -51,7 +51,6 @@ public class CannonShellEntity extends FastThrowableProjectile implements GeoEnt private float fireProbability = 0; private int fireTime = 0; private int durability = 40; - private boolean firstHit = true; public Set loadedChunks = new HashSet<>(); private float gravity = 0.1f; @@ -174,55 +173,38 @@ public class CannonShellEntity extends FastThrowableProjectile implements GeoEnt @Override public void onHitBlock(@NotNull BlockHitResult blockHitResult) { if (this.level() instanceof ServerLevel) { - double x = blockHitResult.getLocation().x; - double y = blockHitResult.getLocation().y; - double z = blockHitResult.getLocation().z; + BlockPos resultPos = blockHitResult.getBlockPos(); - if (ExplosionConfig.EXPLOSION_DESTROY.get()) { - float hardness = this.level().getBlockState(BlockPos.containing(x, y, z)).getBlock().defaultDestroyTime(); - BlockState blockState = this.level().getBlockState(BlockPos.containing(x, y, z)); + float hardness = this.level().getBlockState(resultPos).getBlock().defaultDestroyTime(); - if (hardness == -1) { - this.discard(); - causeExplode(blockHitResult.getLocation()); - return; - } - - this.durability -= (int) hardness; - - if (hardness <= 50) { - 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); - } - - if (blockState.is(ModBlocks.SANDBAG.get()) || blockState.is(Blocks.NETHERITE_BLOCK)) { - this.durability -= 10; - } - - if (blockState.is(Blocks.IRON_BLOCK) || blockState.is(Blocks.COPPER_BLOCK)) { - this.durability -= 5; - } - - if (blockState.is(Blocks.GOLD_BLOCK)) { - this.durability -= 3; - } - - if (this.durability <= 0) { - causeExplode(blockHitResult.getLocation()); - } else { - if (this.firstHit) { - ParticleTool.cannonHitParticles(this.level(), this.position(), this); - causeExplode(blockHitResult.getLocation()); - this.firstHit = false; - } - apExplode(blockHitResult); - } - } else { - if (this.durability > 0) { - apExplode(blockHitResult); - } + if (hardness == -1) { + this.discard(); causeExplode(blockHitResult.getLocation()); + return; + } else { + if (ExplosionConfig.EXPLOSION_DESTROY.get()) { + this.level().destroyBlock(resultPos, true); + } + } + + causeExplode(blockHitResult.getLocation()); + + for (int i = 0; i < 5; i++) { + Vec3 hitPos = blockHitResult.getLocation().add(getDeltaMovement().normalize().scale(i)); + AABB aabb = new AABB(hitPos, hitPos).inflate(0.25); + if (durability > 0) { + BlockPos.betweenClosedStream(aabb).forEach((pos) -> { + float hard = this.level().getBlockState(pos).getBlock().defaultDestroyTime(); + durability -= (int) hard; + if (ExplosionConfig.EXPLOSION_DESTROY.get()) { + this.level().destroyBlock(pos, true); + } + apExplode(hitPos); + }); + } + } + if (durability <= 0) { + discard(); } } } @@ -279,10 +261,9 @@ public class CannonShellEntity extends FastThrowableProjectile implements GeoEnt } else { ParticleTool.spawnMediumExplosionParticles(this.level(), vec); } - this.discard(); } - private void apExplode(HitResult result) { + private void apExplode(Vec3 vec3) { if (Math.random() > fireProbability) { fireTime = 0; } @@ -292,22 +273,15 @@ public class CannonShellEntity extends FastThrowableProjectile implements GeoEnt this, this.getOwner()), explosionDamage, - result.getLocation().x + 5 * getDeltaMovement().normalize().x, - result.getLocation().y + 5 * getDeltaMovement().normalize().y, - result.getLocation().z + 5 * getDeltaMovement().normalize().z, - radius, + vec3.x, + vec3.y, + vec3.z, + radius * 0.5f, ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP, true). setDamageMultiplier(1).setFireTime(fireTime); explosion.explode(); EventHooks.onExplosionStart(this.level(), explosion); explosion.finalizeExplosion(false); - - if (radius > 7) { - ParticleTool.spawnHugeExplosionParticles(this.level(), result.getLocation()); - } else { - ParticleTool.spawnMediumExplosionParticles(this.level(), result.getLocation()); - } - this.discard(); } private PlayState movementPredicate(AnimationState event) { 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 5f90a7ff5..13a9c78c0 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/GunGrenadeEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/GunGrenadeEntity.java @@ -1,5 +1,6 @@ package com.atsuishio.superbwarfare.entity.projectile; +import com.atsuishio.superbwarfare.config.server.ExplosionConfig; import com.atsuishio.superbwarfare.init.ModDamageTypes; import com.atsuishio.superbwarfare.init.ModEntities; import com.atsuishio.superbwarfare.init.ModItems; @@ -152,21 +153,26 @@ public class GunGrenadeEntity extends FastThrowableProjectile implements GeoEnti @Override public void onHitBlock(@NotNull BlockHitResult blockHitResult) { - super.onHitBlock(blockHitResult); BlockPos resultPos = blockHitResult.getBlockPos(); BlockState state = this.level().getBlockState(resultPos); - if (state.getBlock() instanceof BellBlock bell) { - bell.attemptToRing(this.level(), resultPos, blockHitResult.getDirection()); - } - if (this.tickCount > 0) { - if (this.level() instanceof ServerLevel) { - ProjectileTool.causeCustomExplode(this, - ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()), - this, this.explosionDamage, this.explosionRadius, this.monsterMultiplier); + if (this.level() instanceof ServerLevel) { + float hardness = this.level().getBlockState(resultPos).getBlock().defaultDestroyTime(); + if (hardness != -1) { + if (ExplosionConfig.EXPLOSION_DESTROY.get()) { + this.level().destroyBlock(resultPos, true); + } } } + if (state.getBlock() instanceof BellBlock bell) { + bell.attemptToRing(this.level(), resultPos, blockHitResult.getDirection()); + } + if (this.level() instanceof ServerLevel) { + ProjectileTool.causeCustomExplode(this, + ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()), + this, this.explosionDamage, this.explosionRadius, this.monsterMultiplier); + } this.discard(); } 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 e83e238ba..d684dd47f 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/HeliRocketEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/HeliRocketEntity.java @@ -8,6 +8,7 @@ import com.atsuishio.superbwarfare.init.ModSounds; import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage; import com.atsuishio.superbwarfare.tools.CustomExplosion; import com.atsuishio.superbwarfare.tools.ParticleTool; +import net.minecraft.core.BlockPos; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerLevel; @@ -22,8 +23,10 @@ import net.minecraft.world.entity.projectile.ThrowableItemProjectile; import net.minecraft.world.item.Item; import net.minecraft.world.level.Explosion; import net.minecraft.world.level.Level; +import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.EntityHitResult; +import net.minecraft.world.phys.Vec3; import net.neoforged.neoforge.event.EventHooks; import net.neoforged.neoforge.network.PacketDistributor; import org.jetbrains.annotations.NotNull; @@ -41,6 +44,8 @@ public class HeliRocketEntity extends FastThrowableProjectile implements GeoEnti private float explosionDamage = 60f; private float explosionRadius = 5f; + private int durability = 50; + public HeliRocketEntity(EntityType type, Level world) { super(type, world); this.noCulling = true; @@ -95,43 +100,105 @@ public class HeliRocketEntity extends FastThrowableProjectile implements GeoEnti Entity entity = result.getEntity(); if (this.getOwner() != null && this.getOwner().getVehicle() != null && entity == this.getOwner().getVehicle()) return; - if (this.getOwner() instanceof LivingEntity living) { - if (!living.level().isClientSide() && living instanceof ServerPlayer player) { - living.level().playSound(null, living.blockPosition(), ModSounds.INDICATION.get(), SoundSource.VOICE, 1, 1); + if (this.level() instanceof ServerLevel) { + if (entity == this.getOwner() || (this.getOwner() != null && entity == this.getOwner().getVehicle())) + return; + if (this.getOwner() instanceof LivingEntity living) { + if (!living.level().isClientSide() && living instanceof ServerPlayer player) { + living.level().playSound(null, living.blockPosition(), ModSounds.INDICATION.get(), SoundSource.VOICE, 1, 1); - PacketDistributor.sendToPlayer(player, new ClientIndicatorMessage(0, 5)); + PacketDistributor.sendToPlayer(player, new ClientIndicatorMessage(0, 5)); + } } - } - entity.hurt(ModDamageTypes.causeCannonFireDamage(this.level().registryAccess(), this, this.getOwner()), this.damage); + entity.hurt(ModDamageTypes.causeCannonFireDamage(this.level().registryAccess(), this, this.getOwner()), this.damage); - if (entity instanceof LivingEntity) { - entity.invulnerableTime = 0; - } - - if (this.tickCount > 1) { - if (this.level() instanceof ServerLevel) { - causeRocketExplode(this, - ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()), - entity, this.explosionDamage, this.explosionRadius, 1); + if (entity instanceof LivingEntity) { + entity.invulnerableTime = 0; } - } - this.discard(); + for (int i = 0; i < 3; i++) { + apExplode(result.getLocation().add(getDeltaMovement().normalize().scale(i))); + } + + causeExplode(result.getLocation()); + this.discard(); + } } @Override public void onHitBlock(@NotNull BlockHitResult blockHitResult) { - super.onHitBlock(blockHitResult); - if (this.tickCount > 1) { - if (this.level() instanceof ServerLevel) { - causeRocketExplode(this, - ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()), - this, this.explosionDamage, this.explosionRadius, 1); + if (this.level() instanceof ServerLevel) { + BlockPos resultPos = blockHitResult.getBlockPos(); + + float hardness = this.level().getBlockState(resultPos).getBlock().defaultDestroyTime(); + + if (hardness == -1) { + this.discard(); + causeExplode(blockHitResult.getLocation()); + return; + } else { + if (ExplosionConfig.EXPLOSION_DESTROY.get()) { + this.level().destroyBlock(resultPos, true); + } + } + + causeExplode(blockHitResult.getLocation()); + + for (int i = 0; i < 3; i++) { + Vec3 hitPos = blockHitResult.getLocation().add(getDeltaMovement().normalize().scale(i)); + AABB aabb = new AABB(hitPos, hitPos).inflate(0.25); + if (durability > 0) { + BlockPos.betweenClosedStream(aabb).forEach((pos) -> { + float hard = this.level().getBlockState(pos).getBlock().defaultDestroyTime(); + durability -= (int) hard; + if (ExplosionConfig.EXPLOSION_DESTROY.get()) { + this.level().destroyBlock(pos, true); + } + apExplode(hitPos); + }); + } + } + if (durability <= 0) { + discard(); } } + } - this.discard(); + private void causeExplode(Vec3 vec3) { + CustomExplosion explosion = new CustomExplosion(this.level(), this, + ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), + this, + this.getOwner()), + explosionDamage, + vec3.x, + vec3.y, + vec3.z, + explosionRadius, + ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP, true). + setDamageMultiplier(1); + explosion.explode(); + EventHooks.onExplosionStart(this.level(), explosion); + explosion.finalizeExplosion(false); + ParticleTool.spawnHugeExplosionParticles(this.level(), vec3); + } + + private void apExplode(Vec3 vec3) { + CustomExplosion explosion = new CustomExplosion(this.level(), this, + ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), + this, + this.getOwner()), + explosionDamage, + vec3.x, + vec3.y, + vec3.z, + explosionRadius * 0.5f, + ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP, true). + setDamageMultiplier(1); + explosion.explode(); + EventHooks.onExplosionStart(this.level(), explosion); + explosion.finalizeExplosion(false); + ParticleTool.spawnMediumExplosionParticles(this.level(), vec3); } @Override 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 1426abe56..f7b6acfa2 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/JavelinMissileEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/JavelinMissileEntity.java @@ -33,11 +33,9 @@ import net.minecraft.world.entity.projectile.ThrownPotion; import net.minecraft.world.item.Item; import net.minecraft.world.level.Explosion; import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.BellBlock; -import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; 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.neoforged.neoforge.event.EventHooks; import net.neoforged.neoforge.network.PacketDistributor; @@ -63,19 +61,21 @@ public class JavelinMissileEntity extends FastThrowableProjectile implements Geo private float explosionDamage = 140f; private float explosionRadius = 6f; private boolean distracted = false; - private int guide_type = 0; + private int guideType = 0; + + private int durability = 70; public JavelinMissileEntity(EntityType type, Level world) { super(type, world); this.noCulling = true; } - public JavelinMissileEntity(LivingEntity entity, Level level, float damage, float explosionDamage, float explosionRadius, int guide_type, Vec3 targetPos) { + public JavelinMissileEntity(LivingEntity entity, Level level, float damage, float explosionDamage, float explosionRadius, int guideType, Vec3 targetPos) { super(ModEntities.JAVELIN_MISSILE.get(), entity, level); this.damage = damage; this.explosionDamage = explosionDamage; this.explosionRadius = explosionRadius; - this.guide_type = guide_type; + this.guideType = guideType; this.entityData.set(TARGET_X, (float) targetPos.x); this.entityData.set(TARGET_Y, (float) targetPos.y); this.entityData.set(TARGET_Z, (float) targetPos.z); @@ -169,61 +169,120 @@ public class JavelinMissileEntity extends FastThrowableProjectile implements Geo return true; } - @Override - protected void onHitEntity(EntityHitResult result) { - float damageMultiplier = 1 + this.monsterMultiplier; - Entity entity = result.getEntity(); - if (this.getOwner() != null && this.getOwner().getVehicle() != null && entity == this.getOwner().getVehicle()) - return; - if (this.getOwner() instanceof LivingEntity living) { - if (!living.level().isClientSide() && living instanceof ServerPlayer player) { - living.level().playSound(null, living.blockPosition(), ModSounds.INDICATION.get(), SoundSource.VOICE, 1, 1); - - PacketDistributor.sendToPlayer(player, new ClientIndicatorMessage(0, 5)); - } - } - - if (entity instanceof Monster monster) { - monster.hurt(ModDamageTypes.causeCannonFireDamage(this.level().registryAccess(), this, this.getOwner()), (entityData.get(TOP) ? 1.3f : 1f) * this.damage * damageMultiplier); - } else { - entity.hurt(ModDamageTypes.causeCannonFireDamage(this.level().registryAccess(), this, this.getOwner()), (entityData.get(TOP) ? 1.3f : 1f) * this.damage); - } - - if (entity instanceof LivingEntity) { - entity.invulnerableTime = 0; - } - - if (this.tickCount > 1) { - if (this.level() instanceof ServerLevel) { - causeExplode(result); - } - } - - this.discard(); - } - @Override public boolean isNoGravity() { return true; } @Override - public void onHitBlock(@NotNull BlockHitResult blockHitResult) { - super.onHitBlock(blockHitResult); - BlockPos resultPos = blockHitResult.getBlockPos(); - BlockState state = this.level().getBlockState(resultPos); + protected void onHitEntity(EntityHitResult result) { + float damageMultiplier = 1 + this.monsterMultiplier; + Entity entity = result.getEntity(); + if (this.getOwner() != null && this.getOwner().getVehicle() != null && entity == this.getOwner().getVehicle()) + return; + if (this.level() instanceof ServerLevel) { + if (entity == this.getOwner() || (this.getOwner() != null && entity == this.getOwner().getVehicle())) + return; + if (this.getOwner() instanceof LivingEntity living) { + if (!living.level().isClientSide() && living instanceof ServerPlayer player) { + living.level().playSound(null, living.blockPosition(), ModSounds.INDICATION.get(), SoundSource.VOICE, 1, 1); - if (state.getBlock() instanceof BellBlock bell) { - bell.attemptToRing(this.level(), resultPos, blockHitResult.getDirection()); + PacketDistributor.sendToPlayer(player, new ClientIndicatorMessage(0, 5)); + } + } + + if (entity instanceof Monster monster) { + monster.hurt(ModDamageTypes.causeCannonFireDamage(this.level().registryAccess(), this, this.getOwner()), (entityData.get(TOP) ? 1.3f : 1f) * this.damage * damageMultiplier); + } else { + entity.hurt(ModDamageTypes.causeCannonFireDamage(this.level().registryAccess(), this, this.getOwner()), (entityData.get(TOP) ? 1.3f : 1f) * this.damage); + } + + if (entity instanceof LivingEntity) { + entity.invulnerableTime = 0; + } + + for (int i = 0; i < 3; i++) { + apExplode(result.getLocation().add(getDeltaMovement().normalize().scale(i))); + } + + causeExplode(result.getLocation()); + this.discard(); } + } - if (this.tickCount > 1) { - if (this.level() instanceof ServerLevel) { - causeExplode(blockHitResult); + @Override + public void onHitBlock(BlockHitResult blockHitResult) { + if (this.level() instanceof ServerLevel) { + BlockPos resultPos = blockHitResult.getBlockPos(); + + float hardness = this.level().getBlockState(resultPos).getBlock().defaultDestroyTime(); + + if (hardness == -1) { + this.discard(); + causeExplode(blockHitResult.getLocation()); + return; + } else { + if (ExplosionConfig.EXPLOSION_DESTROY.get()) { + this.level().destroyBlock(resultPos, true); + } + } + + causeExplode(blockHitResult.getLocation()); + + for (int i = 0; i < 3; i++) { + Vec3 hitPos = blockHitResult.getLocation().add(getDeltaMovement().normalize().scale(i)); + AABB aabb = new AABB(hitPos, hitPos).inflate(0.25); + if (durability > 0) { + BlockPos.betweenClosedStream(aabb).forEach((pos) -> { + float hard = this.level().getBlockState(pos).getBlock().defaultDestroyTime(); + durability -= (int) hard; + if (ExplosionConfig.EXPLOSION_DESTROY.get()) { + this.level().destroyBlock(pos, true); + } + apExplode(hitPos); + }); + } + } + if (durability <= 0) { + discard(); } } + } - this.discard(); + private void causeExplode(Vec3 vec3) { + CustomExplosion explosion = new CustomExplosion(this.level(), this, + ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), + this, + this.getOwner()), + explosionDamage, + vec3.x, + vec3.y, + vec3.z, + explosionRadius, + ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP, true). + setDamageMultiplier(this.monsterMultiplier); + explosion.explode(); + EventHooks.onExplosionStart(this.level(), explosion); + explosion.finalizeExplosion(false); + ParticleTool.spawnHugeExplosionParticles(this.level(), vec3); + } + + private void apExplode(Vec3 vec3) { + CustomExplosion explosion = new CustomExplosion(this.level(), this, + ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), + this, + this.getOwner()), + explosionDamage, + vec3.x, + vec3.y, + vec3.z, + explosionRadius * 0.5f, + ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP, true). + setDamageMultiplier(this.monsterMultiplier); + explosion.explode(); + EventHooks.onExplosionStart(this.level(), explosion); + explosion.finalizeExplosion(false); + ParticleTool.spawnMediumExplosionParticles(this.level(), vec3); } @Override @@ -239,7 +298,7 @@ public class JavelinMissileEntity extends FastThrowableProjectile implements Geo } } - if (guide_type == 0 || !entityData.get(TARGET_UUID).equals("none")) { + if (guideType == 0 || !entityData.get(TARGET_UUID).equals("none")) { if (entity != null) { if (entity.level() instanceof ServerLevel) { this.entityData.set(TARGET_X, (float) entity.getX()); @@ -280,7 +339,7 @@ public class JavelinMissileEntity extends FastThrowableProjectile implements Geo } } } - } else if (guide_type == 1) { + } else if (guideType == 1) { double px = this.getX(); double ex = this.entityData.get(TARGET_X); double pz = this.getZ(); @@ -345,24 +404,6 @@ public class JavelinMissileEntity extends FastThrowableProjectile implements Geo this.setDeltaMovement(this.getDeltaMovement().multiply(0.96, 0.96, 0.96)); } - private void causeExplode(HitResult result) { - CustomExplosion explosion = new CustomExplosion(this.level(), this, - ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), - this, - this.getOwner()), - explosionDamage, - this.getX(), - this.getEyeY(), - this.getZ(), - explosionRadius, - ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP, true). - setDamageMultiplier(this.monsterMultiplier); - explosion.explode(); - EventHooks.onExplosionStart(this.level(), explosion); - explosion.finalizeExplosion(false); - ParticleTool.spawnMediumExplosionParticles(this.level(), result.getLocation()); - } - private PlayState movementPredicate(AnimationState event) { return event.setAndContinue(RawAnimation.begin().thenLoop("animation.jvm.idle")); } diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/MelonBombEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/MelonBombEntity.java index 7940b6ea0..692b7eb60 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/MelonBombEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/MelonBombEntity.java @@ -1,11 +1,14 @@ package com.atsuishio.superbwarfare.entity.projectile; +import com.atsuishio.superbwarfare.config.server.ExplosionConfig; import com.atsuishio.superbwarfare.init.ModEntities; import com.atsuishio.superbwarfare.tools.ProjectileTool; +import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageTypes; import net.minecraft.world.entity.AreaEffectCloud; @@ -15,7 +18,9 @@ import net.minecraft.world.entity.projectile.ThrownPotion; import net.minecraft.world.item.Item; import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; +import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.NotNull; public class MelonBombEntity extends FastThrowableProjectile implements ExplosiveProjectile { @@ -99,9 +104,18 @@ public class MelonBombEntity extends FastThrowableProjectile implements Explosiv @Override public void onHitBlock(@NotNull BlockHitResult blockHitResult) { - super.onHitBlock(blockHitResult); - ProjectileTool.causeCustomExplode(this, this.explosionDamage, this.explosionRadius, 1.5f); - this.discard(); + if (this.level() instanceof ServerLevel) { + AABB aabb = new AABB(blockHitResult.getLocation(), blockHitResult.getLocation()).inflate(5); + BlockPos.betweenClosedStream(aabb).forEach((pos) -> { + float hard = this.level().getBlockState(pos).getBlock().defaultDestroyTime(); + if (ExplosionConfig.EXPLOSION_DESTROY.get() && hard != -1 && new Vec3(pos.getX(), pos.getY(), pos.getZ()).distanceTo(blockHitResult.getLocation()) < 3) { + this.level().destroyBlock(pos, true); + } + + }); + ProjectileTool.causeCustomExplode(this, this.explosionDamage, this.explosionRadius, 1.5f); + this.discard(); + } } @Override diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/Mk82Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/Mk82Entity.java index 01ca7e653..ded6d91bd 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/Mk82Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/Mk82Entity.java @@ -5,10 +5,12 @@ import com.atsuishio.superbwarfare.init.ModEntities; import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.init.ModSounds; import com.atsuishio.superbwarfare.tools.ProjectileTool; +import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageTypes; @@ -19,7 +21,9 @@ import net.minecraft.world.entity.projectile.ThrowableItemProjectile; import net.minecraft.world.entity.projectile.ThrownPotion; import net.minecraft.world.item.Item; import net.minecraft.world.level.Level; +import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.NotNull; import software.bernie.geckolib.animatable.GeoEntity; import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; @@ -116,9 +120,18 @@ public class Mk82Entity extends FastThrowableProjectile implements GeoEntity, Ex @Override public void onHitBlock(@NotNull BlockHitResult blockHitResult) { - super.onHitBlock(blockHitResult); - ProjectileTool.causeCustomExplode(this, this.explosionDamage, this.explosionRadius, 1.2f); - this.discard(); + if (this.level() instanceof ServerLevel) { + AABB aabb = new AABB(blockHitResult.getLocation(), blockHitResult.getLocation()).inflate(5); + BlockPos.betweenClosedStream(aabb).forEach((pos) -> { + float hard = this.level().getBlockState(pos).getBlock().defaultDestroyTime(); + if (ExplosionConfig.EXPLOSION_DESTROY.get() && hard != -1 && new Vec3(pos.getX(), pos.getY(), pos.getZ()).distanceTo(blockHitResult.getLocation()) < 3) { + this.level().destroyBlock(pos, true); + } + + }); + ProjectileTool.causeCustomExplode(this, this.explosionDamage, this.explosionRadius, 1.2f); + this.discard(); + } } @Override 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 e9f0aa349..07553350e 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/MortarShellEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/MortarShellEntity.java @@ -193,10 +193,19 @@ public class MortarShellEntity extends FastThrowableProjectile implements GeoEnt } @Override - public void onHitBlock(@NotNull BlockHitResult blockHitResult) { - super.onHitBlock(blockHitResult); + public void onHitBlock(BlockHitResult blockHitResult) { BlockPos resultPos = blockHitResult.getBlockPos(); BlockState state = this.level().getBlockState(resultPos); + + if (this.level() instanceof ServerLevel) { + float hardness = this.level().getBlockState(resultPos).getBlock().defaultDestroyTime(); + if (hardness != -1) { + if (ExplosionConfig.EXPLOSION_DESTROY.get()) { + this.level().destroyBlock(resultPos, true); + } + } + } + if (state.getBlock() instanceof BellBlock bell) { bell.attemptToRing(this.level(), resultPos, blockHitResult.getDirection()); } 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 89734802f..715b74531 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/RpgRocketEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/RpgRocketEntity.java @@ -24,10 +24,10 @@ import net.minecraft.world.entity.projectile.ThrowableItemProjectile; import net.minecraft.world.item.Item; import net.minecraft.world.level.Explosion; import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; +import net.minecraft.world.phys.AABB; 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.neoforged.neoforge.event.EventHooks; import net.neoforged.neoforge.network.PacketDistributor; import org.jetbrains.annotations.NotNull; @@ -46,6 +46,8 @@ public class RpgRocketEntity extends FastThrowableProjectile implements GeoEntit private float explosionDamage = 200f; private float explosionRadius = 10; + private int durability = 50; + public RpgRocketEntity(EntityType type, Level world) { super(type, world); this.noCulling = true; @@ -130,76 +132,109 @@ public class RpgRocketEntity extends FastThrowableProjectile implements GeoEntit Entity entity = result.getEntity(); if (this.getOwner() != null && this.getOwner().getVehicle() != null && entity == this.getOwner().getVehicle()) return; - if (this.getOwner() instanceof LivingEntity living) { - if (!living.level().isClientSide() && living instanceof ServerPlayer player) { - living.level().playSound(null, living.blockPosition(), ModSounds.INDICATION.get(), SoundSource.VOICE, 1, 1); + if (this.level() instanceof ServerLevel) { + if (entity == this.getOwner() || (this.getOwner() != null && entity == this.getOwner().getVehicle())) + return; + if (this.getOwner() instanceof LivingEntity living) { + if (!living.level().isClientSide() && living instanceof ServerPlayer player) { + living.level().playSound(null, living.blockPosition(), ModSounds.INDICATION.get(), SoundSource.VOICE, 1, 1); - PacketDistributor.sendToPlayer(player, new ClientIndicatorMessage(0, 5)); + PacketDistributor.sendToPlayer(player, new ClientIndicatorMessage(0, 5)); + } } - } - if (entity instanceof Monster monster) { - monster.hurt(ModDamageTypes.causeCannonFireDamage(this.level().registryAccess(), this, this.getOwner()), 1.2f * this.damage * damageMultiplier); - } else { - entity.hurt(ModDamageTypes.causeCannonFireDamage(this.level().registryAccess(), this, this.getOwner()), this.damage); - } - - if (entity instanceof LivingEntity) { - entity.invulnerableTime = 0; - } - - if (this.tickCount > 1) { - if (this.level() instanceof ServerLevel) { - ProjectileTool.causeCustomExplode(this, this.explosionDamage, this.explosionRadius, this.monsterMultiplier); + if (entity instanceof Monster monster) { + monster.hurt(ModDamageTypes.causeCannonFireDamage(this.level().registryAccess(), this, this.getOwner()), 1.2f * this.damage * damageMultiplier); + } else { + entity.hurt(ModDamageTypes.causeCannonFireDamage(this.level().registryAccess(), this, this.getOwner()), this.damage); } - } - this.discard(); + if (entity instanceof LivingEntity) { + entity.invulnerableTime = 0; + } + + for (int i = 0; i < 5; i++) { + apExplode(result.getLocation().add(getDeltaMovement().normalize().scale(i))); + } + + causeExplode(result.getLocation()); + this.discard(); + } } @Override public void onHitBlock(@NotNull BlockHitResult blockHitResult) { if (this.level() instanceof ServerLevel) { - double x = blockHitResult.getLocation().x; - double y = blockHitResult.getLocation().y; - double z = blockHitResult.getLocation().z; + BlockPos resultPos = blockHitResult.getBlockPos(); - if (ExplosionConfig.EXPLOSION_DESTROY.get()) { - float hardness = this.level().getBlockState(BlockPos.containing(x, y, z)).getBlock().defaultDestroyTime(); - if (hardness <= 10 && hardness != -1) { - 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); + float hardness = this.level().getBlockState(resultPos).getBlock().defaultDestroyTime(); + + if (hardness == -1) { + this.discard(); + causeExplode(blockHitResult.getLocation()); + return; + } else { + if (ExplosionConfig.EXPLOSION_DESTROY.get()) { + this.level().destroyBlock(resultPos, true); } } - if (this.tickCount > 1) { - for (int i = 1; i < 3; i++) { - apExplode(blockHitResult, i); - } + causeExplode(blockHitResult.getLocation()); - if (this.level() instanceof ServerLevel) { - ProjectileTool.causeCustomExplode(this, this.explosionDamage, this.explosionRadius, this.monsterMultiplier); + for (int i = 0; i < 5; i++) { + Vec3 hitPos = blockHitResult.getLocation().add(getDeltaMovement().normalize().scale(i)); + AABB aabb = new AABB(hitPos, hitPos).inflate(0.25); + if (durability > 0) { + BlockPos.betweenClosedStream(aabb).forEach((pos) -> { + float hard = this.level().getBlockState(pos).getBlock().defaultDestroyTime(); + durability -= (int) hard; + if (ExplosionConfig.EXPLOSION_DESTROY.get()) { + this.level().destroyBlock(pos, true); + } + apExplode(hitPos); + }); } } + if (durability <= 0) { + discard(); + } } } - private void apExplode(HitResult result, int index) { + private void causeExplode(Vec3 vec3) { CustomExplosion explosion = new CustomExplosion(this.level(), this, ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()), explosionDamage, - result.getLocation().x + index * getDeltaMovement().normalize().x, - result.getLocation().y + index * getDeltaMovement().normalize().y, - result.getLocation().z + index * getDeltaMovement().normalize().z, - 0.5f * explosionRadius, + vec3.x, + vec3.y, + vec3.z, + explosionRadius, ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP, true). setDamageMultiplier(this.monsterMultiplier); explosion.explode(); EventHooks.onExplosionStart(this.level(), explosion); explosion.finalizeExplosion(false); + ParticleTool.spawnHugeExplosionParticles(this.level(), vec3); + } + + private void apExplode(Vec3 vec3) { + CustomExplosion explosion = new CustomExplosion(this.level(), this, + ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), + this, + this.getOwner()), + explosionDamage, + vec3.x, + vec3.y, + vec3.z, + explosionRadius * 0.5f, + ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP, true). + setDamageMultiplier(this.monsterMultiplier); + explosion.explode(); + EventHooks.onExplosionStart(this.level(), explosion); + explosion.finalizeExplosion(false); + ParticleTool.spawnMediumExplosionParticles(this.level(), vec3); } @Override diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/SmallCannonShellEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/SmallCannonShellEntity.java index eb1a2d3a3..b017f2f76 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/SmallCannonShellEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/SmallCannonShellEntity.java @@ -121,10 +121,19 @@ public class SmallCannonShellEntity extends FastThrowableProjectile implements G } @Override - public void onHitBlock(@NotNull BlockHitResult blockHitResult) { - super.onHitBlock(blockHitResult); + public void onHitBlock(BlockHitResult blockHitResult) { BlockPos resultPos = blockHitResult.getBlockPos(); BlockState state = this.level().getBlockState(resultPos); + + if (this.level() instanceof ServerLevel) { + float hardness = this.level().getBlockState(resultPos).getBlock().defaultDestroyTime(); + if (hardness != -1) { + if (ExplosionConfig.EXPLOSION_DESTROY.get() && this.blockInteraction == null) { + this.level().destroyBlock(resultPos, true); + } + } + } + if (state.getBlock() instanceof BellBlock bell) { bell.attemptToRing(this.level(), resultPos, blockHitResult.getDirection()); } 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 6eb5dacbf..66806d4c4 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/WgMissileEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/WgMissileEntity.java @@ -10,6 +10,7 @@ import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessag import com.atsuishio.superbwarfare.tools.CustomExplosion; import com.atsuishio.superbwarfare.tools.ParticleTool; import com.atsuishio.superbwarfare.tools.TraceTool; +import net.minecraft.core.BlockPos; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.syncher.EntityDataAccessor; @@ -30,6 +31,7 @@ import net.minecraft.world.item.Item; import net.minecraft.world.level.ClipContext; import net.minecraft.world.level.Explosion; import net.minecraft.world.level.Level; +import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.EntityHitResult; import net.minecraft.world.phys.Vec3; @@ -41,8 +43,6 @@ import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; import software.bernie.geckolib.animation.*; import software.bernie.geckolib.util.GeckoLibUtil; -import javax.annotation.Nullable; - public class WgMissileEntity extends FastThrowableProjectile implements GeoEntity, ExplosiveProjectile { public static final EntityDataAccessor HEALTH = SynchedEntityData.defineId(WgMissileEntity.class, EntityDataSerializers.FLOAT); @@ -52,6 +52,8 @@ public class WgMissileEntity extends FastThrowableProjectile implements GeoEntit private float explosionDamage = 200f; private float explosionRadius = 10f; + private int durability = 70; + public WgMissileEntity(EntityType type, Level level) { super(type, level); this.noCulling = true; @@ -135,39 +137,109 @@ public class WgMissileEntity extends FastThrowableProjectile implements GeoEntit @Override protected void onHitEntity(EntityHitResult result) { Entity entity = result.getEntity(); - if (this.tickCount < 1) return; if (this.getOwner() != null && this.getOwner().getVehicle() != null && entity == this.getOwner().getVehicle()) return; + if (this.level() instanceof ServerLevel) { + if (entity == this.getOwner() || (this.getOwner() != null && entity == this.getOwner().getVehicle())) + return; + if (this.getOwner() instanceof LivingEntity living) { + if (!living.level().isClientSide() && living instanceof ServerPlayer player) { + living.level().playSound(null, living.blockPosition(), ModSounds.INDICATION.get(), SoundSource.VOICE, 1, 1); - if (this.getOwner() instanceof LivingEntity living) { - if (!living.level().isClientSide() && living instanceof ServerPlayer player) { - living.level().playSound(null, living.blockPosition(), ModSounds.INDICATION.get(), SoundSource.VOICE, 1, 1); - - PacketDistributor.sendToPlayer(player, new ClientIndicatorMessage(0, 5)); + PacketDistributor.sendToPlayer(player, new ClientIndicatorMessage(0, 5)); + } } - } - entity.hurt(ModDamageTypes.causeCannonFireDamage(this.level().registryAccess(), this, this.getOwner()), this.damage); + entity.hurt(ModDamageTypes.causeCannonFireDamage(this.level().registryAccess(), this, this.getOwner()), this.damage); - if (entity instanceof LivingEntity) { - entity.invulnerableTime = 0; - } - - if (this.tickCount > 2) { - if (this.level() instanceof ServerLevel) { - causeMissileExplode(ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()), this.explosionDamage, this.explosionRadius); + if (entity instanceof LivingEntity) { + entity.invulnerableTime = 0; } + + for (int i = 0; i < 5; i++) { + apExplode(result.getLocation().add(getDeltaMovement().normalize().scale(i))); + } + + causeExplode(result.getLocation()); + this.discard(); } } @Override public void onHitBlock(@NotNull BlockHitResult blockHitResult) { - super.onHitBlock(blockHitResult); if (this.level() instanceof ServerLevel) { - causeMissileExplode(ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()), this.explosionDamage, this.explosionRadius); + BlockPos resultPos = blockHitResult.getBlockPos(); + + float hardness = this.level().getBlockState(resultPos).getBlock().defaultDestroyTime(); + + if (hardness == -1) { + this.discard(); + causeExplode(blockHitResult.getLocation()); + return; + } else { + if (ExplosionConfig.EXPLOSION_DESTROY.get()) { + this.level().destroyBlock(resultPos, true); + } + } + + causeExplode(blockHitResult.getLocation()); + + for (int i = 0; i < 5; i++) { + Vec3 hitPos = blockHitResult.getLocation().add(getDeltaMovement().normalize().scale(i)); + AABB aabb = new AABB(hitPos, hitPos).inflate(0.25); + if (durability > 0) { + BlockPos.betweenClosedStream(aabb).forEach((pos) -> { + float hard = this.level().getBlockState(pos).getBlock().defaultDestroyTime(); + durability -= (int) hard; + if (ExplosionConfig.EXPLOSION_DESTROY.get()) { + this.level().destroyBlock(pos, true); + } + apExplode(hitPos); + }); + } + } + if (durability <= 0) { + discard(); + } } } + private void causeExplode(Vec3 vec3) { + CustomExplosion explosion = new CustomExplosion(this.level(), this, + ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), + this, + this.getOwner()), + explosionDamage, + vec3.x, + vec3.y, + vec3.z, + explosionRadius, + ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP, true). + setDamageMultiplier(1); + explosion.explode(); + EventHooks.onExplosionStart(this.level(), explosion); + explosion.finalizeExplosion(false); + ParticleTool.spawnHugeExplosionParticles(this.level(), vec3); + } + + private void apExplode(Vec3 vec3) { + CustomExplosion explosion = new CustomExplosion(this.level(), this, + ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), + this, + this.getOwner()), + explosionDamage, + vec3.x, + vec3.y, + vec3.z, + explosionRadius * 0.5f, + ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP, true). + setDamageMultiplier(1); + explosion.explode(); + EventHooks.onExplosionStart(this.level(), explosion); + explosion.finalizeExplosion(false); + ParticleTool.spawnMediumExplosionParticles(this.level(), vec3); + } + @Override public void tick() { super.tick(); @@ -210,21 +282,12 @@ public class WgMissileEntity extends FastThrowableProjectile implements GeoEntit if (this.tickCount > 300 || this.isInWater() || this.entityData.get(HEALTH) <= 0) { if (this.level() instanceof ServerLevel) { - causeMissileExplode(ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()), this.explosionDamage, this.explosionRadius); + causeExplode(position()); } this.discard(); } } - public void causeMissileExplode(@Nullable DamageSource source, float damage, float radius) { - CustomExplosion explosion = new CustomExplosion(level(), this, source, damage, - this.getX(), this.getY(), this.getZ(), radius, ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP, true).setDamageMultiplier(1.25f); - explosion.explode(); - EventHooks.onExplosionStart(level(), explosion); - explosion.finalizeExplosion(false); - ParticleTool.spawnMediumExplosionParticles(level(), position()); - discard(); - } private PlayState movementPredicate(AnimationState event) { return event.setAndContinue(RawAnimation.begin().thenLoop("animation.jvm.idle"));