package net.minecraft.world.item.consume_effects; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.util.ExtraCodecs; import net.minecraft.util.Mth; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.animal.Fox; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.consume_effects.ConsumeEffect.Type; import net.minecraft.world.level.Level; import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.level.gameevent.GameEvent.Context; import net.minecraft.world.phys.Vec3; public record TeleportRandomlyConsumeEffect(float diameter) implements ConsumeEffect { private static final float DEFAULT_DIAMETER = 16.0F; public static final MapCodec CODEC = RecordCodecBuilder.mapCodec( instance -> instance.group(ExtraCodecs.POSITIVE_FLOAT.optionalFieldOf("diameter", 16.0F).forGetter(TeleportRandomlyConsumeEffect::diameter)) .apply(instance, TeleportRandomlyConsumeEffect::new) ); public static final StreamCodec STREAM_CODEC = StreamCodec.composite( ByteBufCodecs.FLOAT, TeleportRandomlyConsumeEffect::diameter, TeleportRandomlyConsumeEffect::new ); public TeleportRandomlyConsumeEffect() { this(16.0F); } @Override public Type getType() { return Type.TELEPORT_RANDOMLY; } @Override public boolean apply(Level level, ItemStack stack, LivingEntity entity) { boolean bl = false; for (int i = 0; i < 16; i++) { double d = entity.getX() + (entity.getRandom().nextDouble() - 0.5) * this.diameter; double e = Mth.clamp( entity.getY() + (entity.getRandom().nextDouble() - 0.5) * this.diameter, (double)level.getMinY(), (double)(level.getMinY() + ((ServerLevel)level).getLogicalHeight() - 1) ); double f = entity.getZ() + (entity.getRandom().nextDouble() - 0.5) * this.diameter; if (entity.isPassenger()) { entity.stopRiding(); } Vec3 vec3 = entity.position(); if (entity.randomTeleport(d, e, f, true)) { level.gameEvent(GameEvent.TELEPORT, vec3, Context.of(entity)); SoundSource soundSource; SoundEvent soundEvent; if (entity instanceof Fox) { soundEvent = SoundEvents.FOX_TELEPORT; soundSource = SoundSource.NEUTRAL; } else { soundEvent = SoundEvents.CHORUS_FRUIT_TELEPORT; soundSource = SoundSource.PLAYERS; } level.playSound(null, entity.getX(), entity.getY(), entity.getZ(), soundEvent, soundSource); entity.resetFallDistance(); bl = true; break; } } if (bl && entity instanceof Player player) { player.resetCurrentImpulseContext(); } return bl; } }