package net.minecraft.world.level.gameevent.vibrations; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.Optional; import java.util.UUID; import net.minecraft.core.Holder; import net.minecraft.core.UUIDUtil; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.projectile.Projectile; import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; public record VibrationInfo( Holder gameEvent, float distance, Vec3 pos, @Nullable UUID uuid, @Nullable UUID projectileOwnerUuid, @Nullable Entity entity ) { public static final Codec CODEC = RecordCodecBuilder.create( instance -> instance.group( GameEvent.CODEC.fieldOf("game_event").forGetter(VibrationInfo::gameEvent), Codec.floatRange(0.0F, Float.MAX_VALUE).fieldOf("distance").forGetter(VibrationInfo::distance), Vec3.CODEC.fieldOf("pos").forGetter(VibrationInfo::pos), UUIDUtil.CODEC.lenientOptionalFieldOf("source").forGetter(vibrationInfo -> Optional.ofNullable(vibrationInfo.uuid())), UUIDUtil.CODEC.lenientOptionalFieldOf("projectile_owner").forGetter(vibrationInfo -> Optional.ofNullable(vibrationInfo.projectileOwnerUuid())) ) .apply( instance, (holder, float_, vec3, optional, optional2) -> new VibrationInfo(holder, float_, vec3, (UUID)optional.orElse(null), (UUID)optional2.orElse(null)) ) ); public VibrationInfo(Holder gameEvent, float distance, Vec3 pos, @Nullable UUID uuid, @Nullable UUID projectileOwnerUuid) { this(gameEvent, distance, pos, uuid, projectileOwnerUuid, null); } public VibrationInfo(Holder gameEvent, float distance, Vec3 pos, @Nullable Entity entity) { this(gameEvent, distance, pos, entity == null ? null : entity.getUUID(), getProjectileOwner(entity), entity); } @Nullable private static UUID getProjectileOwner(@Nullable Entity entity) { return entity instanceof Projectile projectile && projectile.getOwner() != null ? projectile.getOwner().getUUID() : null; } public Optional getEntity(ServerLevel level) { return Optional.ofNullable(this.entity).or(() -> Optional.ofNullable(this.uuid).map(level::getEntity)); } public Optional getProjectileOwner(ServerLevel level) { return this.getEntity(level) .filter(entity -> entity instanceof Projectile) .map(entity -> (Projectile)entity) .map(Projectile::getOwner) .or(() -> Optional.ofNullable(this.projectileOwnerUuid).map(level::getEntity)); } }