From 062acc30db26d81f4ab0a9446f2e40e370f24805 Mon Sep 17 00:00:00 2001 From: 17146 <1714673995@qq.com> Date: Wed, 26 Jun 2024 01:13:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86customExplosion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../target/entity/ClaymoreEntity.java | 10 +- .../target/entity/GunGrenadeEntity.java | 18 +- .../target/tools/CustomExplosion.java | 169 ++++++++++++++++++ 3 files changed, 187 insertions(+), 10 deletions(-) create mode 100644 src/main/java/net/mcreator/target/tools/CustomExplosion.java diff --git a/src/main/java/net/mcreator/target/entity/ClaymoreEntity.java b/src/main/java/net/mcreator/target/entity/ClaymoreEntity.java index 141a666cc..60a9527ac 100644 --- a/src/main/java/net/mcreator/target/entity/ClaymoreEntity.java +++ b/src/main/java/net/mcreator/target/entity/ClaymoreEntity.java @@ -4,7 +4,6 @@ import net.mcreator.target.TargetMod; import net.mcreator.target.init.TargetModEntities; import net.mcreator.target.init.TargetModItems; import net.mcreator.target.tools.ParticleTool; -import net.minecraft.core.BlockPos; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.protocol.Packet; @@ -15,8 +14,6 @@ import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.damagesource.DamageSource; @@ -24,7 +21,6 @@ import net.minecraft.world.damagesource.DamageTypes; import net.minecraft.world.entity.*; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; -import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.projectile.ThrownPotion; import net.minecraft.world.item.Item; @@ -346,8 +342,10 @@ public class ClaymoreEntity extends TamableAnimal implements GeoEntity, Animated public static void onEntityAttacked(LivingAttackEvent event) { var damagesource = event.getSource(); var entity = event.getEntity(); - var sourceentity = event.getSource().getEntity(); - if (damagesource == null || entity == null || sourceentity == null) return; + if (damagesource == null || entity == null) return; + + var sourceentity = damagesource.getEntity(); + if (sourceentity == null) return; if (entity instanceof ClaymoreEntity tamEnt && tamEnt.getOwner() == sourceentity) { if (tamEnt.getOwner() instanceof Player player && player.isCreative()) { diff --git a/src/main/java/net/mcreator/target/entity/GunGrenadeEntity.java b/src/main/java/net/mcreator/target/entity/GunGrenadeEntity.java index 33e853efc..d95dee9cb 100644 --- a/src/main/java/net/mcreator/target/entity/GunGrenadeEntity.java +++ b/src/main/java/net/mcreator/target/entity/GunGrenadeEntity.java @@ -8,6 +8,7 @@ import net.mcreator.target.init.TargetModEntities; import net.mcreator.target.init.TargetModItems; import net.mcreator.target.init.TargetModSounds; import net.mcreator.target.network.message.ClientIndicatorMessage; +import net.mcreator.target.tools.CustomExplosion; import net.mcreator.target.tools.ParticleTool; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.network.protocol.Packet; @@ -20,6 +21,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.Explosion; import net.minecraft.world.level.Level; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.BlockHitResult; @@ -133,8 +135,7 @@ public class GunGrenadeEntity extends ThrowableItemProjectile { super.onHitBlock(blockHitResult); if (this.getPersistentData().getInt("fuse") > 0) { if (this.level() instanceof ServerLevel) { - this.level().explode(this, this.getX(), this.getY(), this.getZ(), 4.5f, Level.ExplosionInteraction.NONE); - ParticleTool.spawnMediumExplosionParticles(this.level(), this.position()); + causeExplode(); } } @@ -154,10 +155,19 @@ public class GunGrenadeEntity extends ThrowableItemProjectile { if (this.tickCount > 200 || this.isInWater()) { if (this.level() instanceof ServerLevel) { - this.level().explode(this, this.getX(), this.getY(), this.getZ(), 4.5f, Level.ExplosionInteraction.NONE); - ParticleTool.spawnMediumExplosionParticles(this.level(), this.position()); + causeExplode(); } this.discard(); } } + + private void causeExplode() { + CustomExplosion explosion = new CustomExplosion(this.level(), this, 72f, this.getX(), this.getY(), this.getZ(), + 7.5f, Explosion.BlockInteraction.KEEP); + explosion.explode(); + net.minecraftforge.event.ForgeEventFactory.onExplosionStart(this.level(), explosion); + explosion.finalizeExplosion(false); + + ParticleTool.spawnMediumExplosionParticles(this.level(), this.position()); + } } diff --git a/src/main/java/net/mcreator/target/tools/CustomExplosion.java b/src/main/java/net/mcreator/target/tools/CustomExplosion.java new file mode 100644 index 000000000..8d345f9a8 --- /dev/null +++ b/src/main/java/net/mcreator/target/tools/CustomExplosion.java @@ -0,0 +1,169 @@ +package net.mcreator.target.tools; + +import com.google.common.collect.Sets; +import net.minecraft.core.BlockPos; +import net.minecraft.util.Mth; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.item.PrimedTnt; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.enchantment.ProtectionEnchantment; +import net.minecraft.world.level.Explosion; +import net.minecraft.world.level.ExplosionDamageCalculator; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.gameevent.GameEvent; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +public class CustomExplosion extends Explosion { + private final Level level; + private final double x; + private final double y; + private final double z; + @Nullable + private final Entity source; + private final float radius; + private final DamageSource damageSource; + private final ExplosionDamageCalculator damageCalculator; + private final float damage; + private final int fireTime; + + public CustomExplosion(Level pLevel, @Nullable Entity pSource, @Nullable DamageSource source, @Nullable ExplosionDamageCalculator pDamageCalculator, + float damage, double pToBlowX, double pToBlowY, double pToBlowZ, float pRadius, int fireTime, + Explosion.BlockInteraction pBlockInteraction) { + super(pLevel, pSource, source, null, pToBlowX, pToBlowY, pToBlowZ, pRadius, false, pBlockInteraction); + this.level = pLevel; + this.source = pSource; + this.radius = pRadius; + this.damageSource = source == null ? pLevel.damageSources().explosion(this) : source; + this.damageCalculator = pDamageCalculator == null ? new ExplosionDamageCalculator() : pDamageCalculator; + this.x = pToBlowX; + this.y = pToBlowY; + this.z = pToBlowZ; + this.damage = damage; + this.fireTime = fireTime; + } + + public CustomExplosion(Level pLevel, @Nullable Entity pSource, float damage, double pToBlowX, double pToBlowY, double pToBlowZ, float pRadius, Explosion.BlockInteraction pBlockInteraction) { + this(pLevel, pSource, null, null, damage, pToBlowX, pToBlowY, pToBlowZ, pRadius, 0, pBlockInteraction); + } + + public CustomExplosion(Level pLevel, @Nullable Entity pSource, float damage, double pToBlowX, double pToBlowY, double pToBlowZ, float pRadius, int fireTime, Explosion.BlockInteraction pBlockInteraction) { + this(pLevel, pSource, null, null, damage, pToBlowX, pToBlowY, pToBlowZ, pRadius, fireTime, pBlockInteraction); + } + + @Override + public void explode() { + this.level.gameEvent(this.source, GameEvent.EXPLODE, new Vec3(this.x, this.y, this.z)); + Set set = Sets.newHashSet(); + + for (int j = 0; j < 16; ++j) { + for (int k = 0; k < 16; ++k) { + for (int l = 0; l < 16; ++l) { + if (j == 0 || j == 15 || k == 0 || k == 15 || l == 0 || l == 15) { + double d0 = (float) j / 15.0F * 2.0F - 1.0F; + double d1 = (float) k / 15.0F * 2.0F - 1.0F; + double d2 = (float) l / 15.0F * 2.0F - 1.0F; + double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2); + d0 /= d3; + d1 /= d3; + d2 /= d3; + float f = this.radius * (0.7F + this.level.random.nextFloat() * 0.6F); + double d4 = this.x; + double d6 = this.y; + double d8 = this.z; + + for (; f > 0.0F; f -= 0.22500001F) { + BlockPos blockpos = BlockPos.containing(d4, d6, d8); + BlockState blockstate = this.level.getBlockState(blockpos); + FluidState fluidstate = this.level.getFluidState(blockpos); + if (!this.level.isInWorldBounds(blockpos)) { + break; + } + + Optional optional = this.damageCalculator.getBlockExplosionResistance(this, this.level, blockpos, blockstate, fluidstate); + if (optional.isPresent()) { + f -= (optional.get() + 0.3F) * 0.3F; + } + + if (f > 0.0F && this.damageCalculator.shouldBlockExplode(this, this.level, blockpos, blockstate, f)) { + set.add(blockpos); + } + + d4 += d0 * (double) 0.3F; + d6 += d1 * (double) 0.3F; + d8 += d2 * (double) 0.3F; + } + } + } + } + } + + this.getToBlow().addAll(set); + + float diameter = this.radius * 2.0F; + int x0 = Mth.floor(this.x - (double) diameter - 1.0D); + int x1 = Mth.floor(this.x + (double) diameter + 1.0D); + int y0 = Mth.floor(this.y - (double) diameter - 1.0D); + int y1 = Mth.floor(this.y + (double) diameter + 1.0D); + int z0 = Mth.floor(this.z - (double) diameter - 1.0D); + int z1 = Mth.floor(this.z + (double) diameter + 1.0D); + List list = this.level.getEntities(this.source, new AABB(x0, y0, z0, x1, y1, z1)); + net.minecraftforge.event.ForgeEventFactory.onExplosionDetonate(this.level, this, list, diameter); + Vec3 position = new Vec3(this.x, this.y, this.z); + + for (Entity entity : list) { + if (!entity.ignoreExplosion()) { + double distanceRate = Math.sqrt(entity.distanceToSqr(position)) / (double) diameter; + if (distanceRate <= 1.0D) { + double xDistance = entity.getX() - this.x; + double yDistance = (entity instanceof PrimedTnt ? entity.getY() : entity.getEyeY()) - this.y; + double zDistance = entity.getZ() - this.z; + double distance = Math.sqrt(xDistance * xDistance + yDistance * yDistance + zDistance * zDistance); + if (distance != 0.0D) { + xDistance /= distance; + yDistance /= distance; + zDistance /= distance; + double seenPercent = getSeenPercent(position, entity); + double damagePercent = (1.0D - distanceRate) * seenPercent; + + entity.hurt(this.damageSource, (float) ((int) ((damagePercent * damagePercent + damagePercent) / 2.0D * damage))); + + if (fireTime > 0) { + entity.setSecondsOnFire(fireTime); + } + + double d11; + if (entity instanceof LivingEntity livingentity) { + d11 = ProtectionEnchantment.getExplosionKnockbackAfterDampener(livingentity, damagePercent); + } else { + d11 = damagePercent; + } + + xDistance *= d11; + yDistance *= d11; + zDistance *= d11; + + Vec3 knockbackVec = new Vec3(xDistance, yDistance, zDistance); + entity.setDeltaMovement(entity.getDeltaMovement().add(knockbackVec)); + + if (entity instanceof Player player) { + if (!player.isSpectator() && (!player.isCreative() || !player.getAbilities().flying)) { + this.getHitPlayers().put(player, knockbackVec); + } + } + } + } + } + } + } + +}