95 lines
3.8 KiB
Java
95 lines
3.8 KiB
Java
package net.minecraft.world.item.enchantment.effects;
|
|
|
|
import com.mojang.serialization.Codec;
|
|
import com.mojang.serialization.MapCodec;
|
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
import java.util.Optional;
|
|
import net.minecraft.core.Holder;
|
|
import net.minecraft.core.HolderSet;
|
|
import net.minecraft.core.RegistryCodecs;
|
|
import net.minecraft.core.particles.ParticleOptions;
|
|
import net.minecraft.core.particles.ParticleTypes;
|
|
import net.minecraft.core.registries.Registries;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.sounds.SoundEvent;
|
|
import net.minecraft.world.damagesource.DamageSource;
|
|
import net.minecraft.world.damagesource.DamageType;
|
|
import net.minecraft.world.entity.Entity;
|
|
import net.minecraft.world.item.enchantment.EnchantedItemInUse;
|
|
import net.minecraft.world.item.enchantment.LevelBasedValue;
|
|
import net.minecraft.world.level.Level;
|
|
import net.minecraft.world.level.SimpleExplosionDamageCalculator;
|
|
import net.minecraft.world.level.block.Block;
|
|
import net.minecraft.world.phys.Vec3;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
public record ExplodeEffect(
|
|
boolean attributeToUser,
|
|
Optional<Holder<DamageType>> damageType,
|
|
Optional<LevelBasedValue> knockbackMultiplier,
|
|
Optional<HolderSet<Block>> immuneBlocks,
|
|
Vec3 offset,
|
|
LevelBasedValue radius,
|
|
boolean createFire,
|
|
Level.ExplosionInteraction blockInteraction,
|
|
ParticleOptions smallParticle,
|
|
ParticleOptions largeParticle,
|
|
Holder<SoundEvent> sound
|
|
) implements EnchantmentEntityEffect {
|
|
public static final MapCodec<ExplodeEffect> CODEC = RecordCodecBuilder.mapCodec(
|
|
instance -> instance.group(
|
|
Codec.BOOL.optionalFieldOf("attribute_to_user", false).forGetter(ExplodeEffect::attributeToUser),
|
|
DamageType.CODEC.optionalFieldOf("damage_type").forGetter(ExplodeEffect::damageType),
|
|
LevelBasedValue.CODEC.optionalFieldOf("knockback_multiplier").forGetter(ExplodeEffect::knockbackMultiplier),
|
|
RegistryCodecs.homogeneousList(Registries.BLOCK).optionalFieldOf("immune_blocks").forGetter(ExplodeEffect::immuneBlocks),
|
|
Vec3.CODEC.optionalFieldOf("offset", Vec3.ZERO).forGetter(ExplodeEffect::offset),
|
|
LevelBasedValue.CODEC.fieldOf("radius").forGetter(ExplodeEffect::radius),
|
|
Codec.BOOL.optionalFieldOf("create_fire", false).forGetter(ExplodeEffect::createFire),
|
|
Level.ExplosionInteraction.CODEC.fieldOf("block_interaction").forGetter(ExplodeEffect::blockInteraction),
|
|
ParticleTypes.CODEC.fieldOf("small_particle").forGetter(ExplodeEffect::smallParticle),
|
|
ParticleTypes.CODEC.fieldOf("large_particle").forGetter(ExplodeEffect::largeParticle),
|
|
SoundEvent.CODEC.fieldOf("sound").forGetter(ExplodeEffect::sound)
|
|
)
|
|
.apply(instance, ExplodeEffect::new)
|
|
);
|
|
|
|
@Override
|
|
public void apply(ServerLevel level, int enchantmentLevel, EnchantedItemInUse item, Entity entity, Vec3 origin) {
|
|
Vec3 vec3 = origin.add(this.offset);
|
|
level.explode(
|
|
this.attributeToUser ? entity : null,
|
|
this.getDamageSource(entity, vec3),
|
|
new SimpleExplosionDamageCalculator(
|
|
this.blockInteraction != Level.ExplosionInteraction.NONE,
|
|
this.damageType.isPresent(),
|
|
this.knockbackMultiplier.map(levelBasedValue -> levelBasedValue.calculate(enchantmentLevel)),
|
|
this.immuneBlocks
|
|
),
|
|
vec3.x(),
|
|
vec3.y(),
|
|
vec3.z(),
|
|
Math.max(this.radius.calculate(enchantmentLevel), 0.0F),
|
|
this.createFire,
|
|
this.blockInteraction,
|
|
this.smallParticle,
|
|
this.largeParticle,
|
|
this.sound
|
|
);
|
|
}
|
|
|
|
@Nullable
|
|
private DamageSource getDamageSource(Entity entity, Vec3 pos) {
|
|
if (this.damageType.isEmpty()) {
|
|
return null;
|
|
} else {
|
|
return this.attributeToUser
|
|
? new DamageSource((Holder<DamageType>)this.damageType.get(), entity)
|
|
: new DamageSource((Holder<DamageType>)this.damageType.get(), pos);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public MapCodec<ExplodeEffect> codec() {
|
|
return CODEC;
|
|
}
|
|
}
|