143 lines
7.4 KiB
Java
143 lines
7.4 KiB
Java
|
package net.minecraft.world.item.enchantment.effects;
|
||
|
|
||
|
import com.mojang.serialization.Codec;
|
||
|
import com.mojang.serialization.DataResult;
|
||
|
import com.mojang.serialization.MapCodec;
|
||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||
|
import com.mojang.serialization.codecs.RecordCodecBuilder.Instance;
|
||
|
import net.minecraft.core.particles.ParticleOptions;
|
||
|
import net.minecraft.core.particles.ParticleTypes;
|
||
|
import net.minecraft.server.level.ServerLevel;
|
||
|
import net.minecraft.util.ExtraCodecs;
|
||
|
import net.minecraft.util.RandomSource;
|
||
|
import net.minecraft.util.StringRepresentable;
|
||
|
import net.minecraft.util.valueproviders.ConstantFloat;
|
||
|
import net.minecraft.util.valueproviders.FloatProvider;
|
||
|
import net.minecraft.world.entity.Entity;
|
||
|
import net.minecraft.world.item.enchantment.EnchantedItemInUse;
|
||
|
import net.minecraft.world.phys.Vec3;
|
||
|
|
||
|
public record SpawnParticlesEffect(
|
||
|
ParticleOptions particle,
|
||
|
SpawnParticlesEffect.PositionSource horizontalPosition,
|
||
|
SpawnParticlesEffect.PositionSource verticalPosition,
|
||
|
SpawnParticlesEffect.VelocitySource horizontalVelocity,
|
||
|
SpawnParticlesEffect.VelocitySource verticalVelocity,
|
||
|
FloatProvider speed
|
||
|
) implements EnchantmentEntityEffect {
|
||
|
public static final MapCodec<SpawnParticlesEffect> CODEC = RecordCodecBuilder.mapCodec(
|
||
|
p_342263_ -> p_342263_.group(
|
||
|
ParticleTypes.CODEC.fieldOf("particle").forGetter(SpawnParticlesEffect::particle),
|
||
|
SpawnParticlesEffect.PositionSource.CODEC.fieldOf("horizontal_position").forGetter(SpawnParticlesEffect::horizontalPosition),
|
||
|
SpawnParticlesEffect.PositionSource.CODEC.fieldOf("vertical_position").forGetter(SpawnParticlesEffect::verticalPosition),
|
||
|
SpawnParticlesEffect.VelocitySource.CODEC.fieldOf("horizontal_velocity").forGetter(SpawnParticlesEffect::horizontalVelocity),
|
||
|
SpawnParticlesEffect.VelocitySource.CODEC.fieldOf("vertical_velocity").forGetter(SpawnParticlesEffect::verticalVelocity),
|
||
|
FloatProvider.CODEC.optionalFieldOf("speed", ConstantFloat.ZERO).forGetter(SpawnParticlesEffect::speed)
|
||
|
)
|
||
|
.apply(p_342263_, SpawnParticlesEffect::new)
|
||
|
);
|
||
|
|
||
|
public static SpawnParticlesEffect.PositionSource offsetFromEntityPosition(float p_344734_) {
|
||
|
return new SpawnParticlesEffect.PositionSource(SpawnParticlesEffect.PositionSourceType.ENTITY_POSITION, p_344734_, 1.0F);
|
||
|
}
|
||
|
|
||
|
public static SpawnParticlesEffect.PositionSource inBoundingBox() {
|
||
|
return new SpawnParticlesEffect.PositionSource(SpawnParticlesEffect.PositionSourceType.BOUNDING_BOX, 0.0F, 1.0F);
|
||
|
}
|
||
|
|
||
|
public static SpawnParticlesEffect.VelocitySource movementScaled(float p_342848_) {
|
||
|
return new SpawnParticlesEffect.VelocitySource(p_342848_, ConstantFloat.ZERO);
|
||
|
}
|
||
|
|
||
|
public static SpawnParticlesEffect.VelocitySource fixedVelocity(FloatProvider p_344992_) {
|
||
|
return new SpawnParticlesEffect.VelocitySource(0.0F, p_344992_);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void apply(ServerLevel p_344629_, int p_343825_, EnchantedItemInUse p_342850_, Entity p_342334_, Vec3 p_344096_) {
|
||
|
RandomSource randomsource = p_342334_.getRandom();
|
||
|
Vec3 vec3 = p_342334_.getKnownMovement();
|
||
|
float f = p_342334_.getBbWidth();
|
||
|
float f1 = p_342334_.getBbHeight();
|
||
|
p_344629_.sendParticles(
|
||
|
this.particle,
|
||
|
this.horizontalPosition.getCoordinate(p_344096_.x(), p_344096_.x(), f, randomsource),
|
||
|
this.verticalPosition.getCoordinate(p_344096_.y(), p_344096_.y() + f1 / 2.0F, f1, randomsource),
|
||
|
this.horizontalPosition.getCoordinate(p_344096_.z(), p_344096_.z(), f, randomsource),
|
||
|
0,
|
||
|
this.horizontalVelocity.getVelocity(vec3.x(), randomsource),
|
||
|
this.verticalVelocity.getVelocity(vec3.y(), randomsource),
|
||
|
this.horizontalVelocity.getVelocity(vec3.z(), randomsource),
|
||
|
this.speed.sample(randomsource)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public MapCodec<SpawnParticlesEffect> codec() {
|
||
|
return CODEC;
|
||
|
}
|
||
|
|
||
|
public record PositionSource(SpawnParticlesEffect.PositionSourceType type, float offset, float scale) {
|
||
|
public static final MapCodec<SpawnParticlesEffect.PositionSource> CODEC = RecordCodecBuilder.<SpawnParticlesEffect.PositionSource>mapCodec(
|
||
|
p_344563_ -> p_344563_.group(
|
||
|
SpawnParticlesEffect.PositionSourceType.CODEC.fieldOf("type").forGetter(SpawnParticlesEffect.PositionSource::type),
|
||
|
Codec.FLOAT.optionalFieldOf("offset", 0.0F).forGetter(SpawnParticlesEffect.PositionSource::offset),
|
||
|
ExtraCodecs.POSITIVE_FLOAT.optionalFieldOf("scale", 1.0F).forGetter(SpawnParticlesEffect.PositionSource::scale)
|
||
|
)
|
||
|
.apply(p_344563_, SpawnParticlesEffect.PositionSource::new)
|
||
|
)
|
||
|
.validate(
|
||
|
p_344468_ -> p_344468_.type() == SpawnParticlesEffect.PositionSourceType.ENTITY_POSITION && p_344468_.scale() != 1.0F
|
||
|
? DataResult.error(() -> "Cannot scale an entity position coordinate source")
|
||
|
: DataResult.success(p_344468_)
|
||
|
);
|
||
|
|
||
|
public double getCoordinate(double p_344146_, double p_344860_, float p_343272_, RandomSource p_344191_) {
|
||
|
return this.type.getCoordinate(p_344146_, p_344860_, p_343272_ * this.scale, p_344191_) + this.offset;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static enum PositionSourceType implements StringRepresentable {
|
||
|
ENTITY_POSITION("entity_position", (p_343048_, p_343091_, p_345054_, p_342606_) -> p_343048_),
|
||
|
BOUNDING_BOX("in_bounding_box", (p_343212_, p_344879_, p_342916_, p_343170_) -> p_344879_ + (p_343170_.nextDouble() - 0.5) * p_342916_);
|
||
|
|
||
|
public static final Codec<SpawnParticlesEffect.PositionSourceType> CODEC = StringRepresentable.fromEnum(
|
||
|
SpawnParticlesEffect.PositionSourceType::values
|
||
|
);
|
||
|
private final String id;
|
||
|
private final SpawnParticlesEffect.PositionSourceType.CoordinateSource source;
|
||
|
|
||
|
private PositionSourceType(final String p_343318_, final SpawnParticlesEffect.PositionSourceType.CoordinateSource p_343028_) {
|
||
|
this.id = p_343318_;
|
||
|
this.source = p_343028_;
|
||
|
}
|
||
|
|
||
|
public double getCoordinate(double p_343826_, double p_344958_, float p_345431_, RandomSource p_342492_) {
|
||
|
return this.source.getCoordinate(p_343826_, p_344958_, p_345431_, p_342492_);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public String getSerializedName() {
|
||
|
return this.id;
|
||
|
}
|
||
|
|
||
|
@FunctionalInterface
|
||
|
interface CoordinateSource {
|
||
|
double getCoordinate(double p_343199_, double p_343174_, float p_344504_, RandomSource p_342781_);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public record VelocitySource(float movementScale, FloatProvider base) {
|
||
|
public static final MapCodec<SpawnParticlesEffect.VelocitySource> CODEC = RecordCodecBuilder.mapCodec(
|
||
|
p_343024_ -> p_343024_.group(
|
||
|
Codec.FLOAT.optionalFieldOf("movement_scale", 0.0F).forGetter(SpawnParticlesEffect.VelocitySource::movementScale),
|
||
|
FloatProvider.CODEC.optionalFieldOf("base", ConstantFloat.ZERO).forGetter(SpawnParticlesEffect.VelocitySource::base)
|
||
|
)
|
||
|
.apply(p_343024_, SpawnParticlesEffect.VelocitySource::new)
|
||
|
);
|
||
|
|
||
|
public double getVelocity(double p_344775_, RandomSource p_342972_) {
|
||
|
return p_344775_ * this.movementScale + this.base.sample(p_342972_);
|
||
|
}
|
||
|
}
|
||
|
}
|