package com.atsuishio.superbwarfare.entity.projectile; import com.atsuishio.superbwarfare.config.server.ExplosionConfig; import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier; 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.entity.EntityType; import net.minecraft.world.entity.LivingEntity; 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 { public static final EntityDataAccessor HEALTH = SynchedEntityData.defineId(MelonBombEntity.class, EntityDataSerializers.FLOAT); private float explosionDamage = 500; private float explosionRadius = 10; public MelonBombEntity(EntityType type, Level world) { super(type, world); this.noCulling = true; } public MelonBombEntity(LivingEntity entity, Level level) { super(ModEntities.MELON_BOMB.get(), entity, level); } protected @NotNull Item getDefaultItem() { return Items.MELON; } @Override public boolean shouldRenderAtSqrDistance(double pDistance) { return true; } private static final DamageModifier DAMAGE_MODIFIER = DamageModifier.createDefaultModifier(); @Override public boolean hurt(@NotNull DamageSource source, float amount) { amount = DAMAGE_MODIFIER.compute(source, amount); this.entityData.set(HEALTH, this.entityData.get(HEALTH) - amount); return super.hurt(source, amount); } @Override public boolean isPickable() { return !this.isRemoved(); } @Override protected void defineSynchedData(SynchedEntityData.@NotNull Builder builder) { super.defineSynchedData(builder); builder.define(HEALTH, 10F); } @Override public void readAdditionalSaveData(@NotNull CompoundTag compound) { super.readAdditionalSaveData(compound); if (compound.contains("Health")) { this.entityData.set(HEALTH, compound.getFloat("Health")); } compound.putFloat("ExplosionDamage", this.explosionDamage); compound.putFloat("Radius", this.explosionRadius); } @Override public void addAdditionalSaveData(@NotNull CompoundTag compound) { super.addAdditionalSaveData(compound); compound.putFloat("Health", this.entityData.get(HEALTH)); if (compound.contains("ExplosionDamage")) { this.explosionDamage = compound.getFloat("ExplosionDamage"); } if (compound.contains("Radius")) { this.explosionRadius = compound.getFloat("Radius"); } } @Override public void onHitBlock(@NotNull BlockHitResult blockHitResult) { 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 public void tick() { super.tick(); if (tickCount > 600 || this.entityData.get(HEALTH) <= 0) { this.discard(); if (!this.level().isClientSide) { ProjectileTool.causeCustomExplode(this, this.explosionDamage, this.explosionRadius, 1.5f); } } } @Override protected double getDefaultGravity() { return 0.05F; } @Override public void setDamage(float damage) { } @Override public void setExplosionDamage(float damage) { this.explosionDamage = damage; } @Override public void setExplosionRadius(float radius) { this.explosionRadius = radius; } }